Skip to content

Commit 17d363c

Browse files
authored
Merge pull request #5389 from vector-im/feature/adm/personalisation-complete
FTUE - Personalisation complete
2 parents 9ef235f + 9d49ef5 commit 17d363c

14 files changed

+307
-24
lines changed

changelog.d/5389.wip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Introduces FTUE personalisation complete screen along with confetti celebration
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2022 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.core.animations
18+
19+
import android.content.Context
20+
import androidx.annotation.ColorInt
21+
import androidx.core.content.ContextCompat
22+
import im.vector.app.R
23+
import nl.dionsegijn.konfetti.KonfettiView
24+
import nl.dionsegijn.konfetti.models.Shape
25+
import nl.dionsegijn.konfetti.models.Size
26+
27+
fun KonfettiView.play() {
28+
val confettiColors = listOf(
29+
R.color.palette_azure,
30+
R.color.palette_grape,
31+
R.color.palette_verde,
32+
R.color.palette_polly,
33+
R.color.palette_melon,
34+
R.color.palette_aqua,
35+
R.color.palette_prune,
36+
R.color.palette_kiwi
37+
)
38+
build()
39+
.addColors(confettiColors.toColorInt(context))
40+
.setDirection(0.0, 359.0)
41+
.setSpeed(2f, 5f)
42+
.setFadeOutEnabled(true)
43+
.setTimeToLive(2000L)
44+
.addShapes(Shape.Square, Shape.Circle)
45+
.addSizes(Size(12))
46+
.setPosition(-50f, width + 50f, -50f, -50f)
47+
.streamFor(150, 3000L)
48+
}
49+
50+
@ColorInt
51+
private fun List<Int>.toColorInt(context: Context) = map { ContextCompat.getColor(context, it) }

vector/src/main/java/im/vector/app/core/di/FragmentModule.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ import im.vector.app.features.onboarding.ftueauth.FtueAuthChooseDisplayNameFragm
103103
import im.vector.app.features.onboarding.ftueauth.FtueAuthChooseProfilePictureFragment
104104
import im.vector.app.features.onboarding.ftueauth.FtueAuthGenericTextInputFormFragment
105105
import im.vector.app.features.onboarding.ftueauth.FtueAuthLoginFragment
106+
import im.vector.app.features.onboarding.ftueauth.FtueAuthPersonalizationCompleteFragment
106107
import im.vector.app.features.onboarding.ftueauth.FtueAuthResetPasswordFragment
107108
import im.vector.app.features.onboarding.ftueauth.FtueAuthResetPasswordMailConfirmationFragment
108109
import im.vector.app.features.onboarding.ftueauth.FtueAuthResetPasswordSuccessFragment
@@ -491,6 +492,11 @@ interface FragmentModule {
491492
@FragmentKey(FtueAuthChooseProfilePictureFragment::class)
492493
fun bindFtueAuthChooseProfilePictureFragment(fragment: FtueAuthChooseProfilePictureFragment): Fragment
493494

495+
@Binds
496+
@IntoMap
497+
@FragmentKey(FtueAuthPersonalizationCompleteFragment::class)
498+
fun bindFtueAuthPersonalizationCompleteFragment(fragment: FtueAuthPersonalizationCompleteFragment): Fragment
499+
494500
@Binds
495501
@IntoMap
496502
@FragmentKey(UserListFragment::class)

vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import android.annotation.SuppressLint
2020
import android.app.Activity
2121
import android.content.Intent
2222
import android.content.res.Configuration
23-
import android.graphics.Color
2423
import android.net.Uri
2524
import android.os.Build
2625
import android.os.Bundle
@@ -68,6 +67,7 @@ import com.airbnb.mvrx.withState
6867
import com.google.android.material.dialog.MaterialAlertDialogBuilder
6968
import com.vanniktech.emoji.EmojiPopup
7069
import im.vector.app.R
70+
import im.vector.app.core.animations.play
7171
import im.vector.app.core.dialogs.ConfirmationDialogBuilder
7272
import im.vector.app.core.dialogs.GalleryOrCameraDialogHelper
7373
import im.vector.app.core.epoxy.LayoutManagerStateRestorer
@@ -203,8 +203,6 @@ import kotlinx.coroutines.flow.map
203203
import kotlinx.coroutines.flow.onEach
204204
import kotlinx.coroutines.launch
205205
import kotlinx.coroutines.withContext
206-
import nl.dionsegijn.konfetti.models.Shape
207-
import nl.dionsegijn.konfetti.models.Size
208206
import org.billcarsonfr.jsonviewer.JSonViewerDialog
209207
import org.commonmark.parser.Parser
210208
import org.matrix.android.sdk.api.session.Session
@@ -562,16 +560,7 @@ class TimelineFragment @Inject constructor(
562560
when (chatEffect) {
563561
ChatEffect.CONFETTI -> {
564562
views.viewKonfetti.isVisible = true
565-
views.viewKonfetti.build()
566-
.addColors(Color.YELLOW, Color.GREEN, Color.MAGENTA)
567-
.setDirection(0.0, 359.0)
568-
.setSpeed(2f, 5f)
569-
.setFadeOutEnabled(true)
570-
.setTimeToLive(2000L)
571-
.addShapes(Shape.Square, Shape.Circle)
572-
.addSizes(Size(12))
573-
.setPosition(-50f, views.viewKonfetti.width + 50f, -50f, -50f)
574-
.streamFor(150, 3000L)
563+
views.viewKonfetti.play()
575564
}
576565
ChatEffect.SNOWFALL -> {
577566
views.viewSnowFall.isVisible = true

vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthAccountCreatedFragment.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import android.view.View
2222
import android.view.ViewGroup
2323
import androidx.core.view.isVisible
2424
import im.vector.app.R
25+
import im.vector.app.core.animations.play
2526
import im.vector.app.core.di.ActiveSessionHolder
2627
import im.vector.app.databinding.FragmentFtueAccountCreatedBinding
2728
import im.vector.app.features.onboarding.OnboardingAction
@@ -33,6 +34,8 @@ class FtueAuthAccountCreatedFragment @Inject constructor(
3334
private val activeSessionHolder: ActiveSessionHolder
3435
) : AbstractFtueAuthFragment<FragmentFtueAccountCreatedBinding>() {
3536

37+
private var hasPlayedConfetti = false
38+
3639
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueAccountCreatedBinding {
3740
return FragmentFtueAccountCreatedBinding.inflate(inflater, container, false)
3841
}
@@ -53,6 +56,12 @@ class FtueAuthAccountCreatedFragment @Inject constructor(
5356
val canPersonalize = state.personalizationState.supportsPersonalization()
5457
views.personalizeButtonGroup.isVisible = canPersonalize
5558
views.takeMeHomeButtonGroup.isVisible = !canPersonalize
59+
60+
if (!hasPlayedConfetti && !canPersonalize) {
61+
hasPlayedConfetti = true
62+
views.viewKonfetti.isVisible = true
63+
views.viewKonfetti.play()
64+
}
5665
}
5766

5867
override fun resetViewModel() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2021 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.features.onboarding.ftueauth
18+
19+
import android.os.Bundle
20+
import android.view.LayoutInflater
21+
import android.view.View
22+
import android.view.ViewGroup
23+
import androidx.core.view.isVisible
24+
import im.vector.app.core.animations.play
25+
import im.vector.app.databinding.FragmentFtuePersonalizationCompleteBinding
26+
import im.vector.app.features.onboarding.OnboardingAction
27+
import im.vector.app.features.onboarding.OnboardingViewEvents
28+
import javax.inject.Inject
29+
30+
class FtueAuthPersonalizationCompleteFragment @Inject constructor() : AbstractFtueAuthFragment<FragmentFtuePersonalizationCompleteBinding>() {
31+
32+
private var hasPlayedConfetti = false
33+
34+
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtuePersonalizationCompleteBinding {
35+
return FragmentFtuePersonalizationCompleteBinding.inflate(inflater, container, false)
36+
}
37+
38+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
39+
super.onViewCreated(view, savedInstanceState)
40+
setupViews()
41+
}
42+
43+
private fun setupViews() {
44+
views.personalizationCompleteCta.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnTakeMeHome)) }
45+
46+
if (!hasPlayedConfetti) {
47+
hasPlayedConfetti = true
48+
views.viewKonfetti.isVisible = true
49+
views.viewKonfetti.play()
50+
}
51+
}
52+
53+
override fun resetViewModel() {
54+
// Nothing to do
55+
}
56+
57+
override fun onBackPressed(toolbarButton: Boolean): Boolean {
58+
viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnTakeMeHome))
59+
return true
60+
}
61+
}

vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ class FtueAuthVariant(
227227
OnboardingViewEvents.OnChooseDisplayName -> onChooseDisplayName()
228228
OnboardingViewEvents.OnTakeMeHome -> navigateToHome(createdAccount = true)
229229
OnboardingViewEvents.OnChooseProfilePicture -> onChooseProfilePicture()
230-
OnboardingViewEvents.OnPersonalizationComplete -> navigateToHome(createdAccount = true)
230+
OnboardingViewEvents.OnPersonalizationComplete -> onPersonalizationComplete()
231231
OnboardingViewEvents.OnBack -> activity.popBackstack()
232232
}.exhaustive
233233
}
@@ -393,7 +393,8 @@ class FtueAuthVariant(
393393
activity.supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
394394
activity.replaceFragment(
395395
views.loginFragmentContainer,
396-
FtueAuthAccountCreatedFragment::class.java
396+
FtueAuthAccountCreatedFragment::class.java,
397+
useCustomAnimation = true
397398
)
398399
}
399400

@@ -416,4 +417,13 @@ class FtueAuthVariant(
416417
option = commonOption
417418
)
418419
}
420+
421+
private fun onPersonalizationComplete() {
422+
activity.supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
423+
activity.replaceFragment(
424+
views.loginFragmentContainer,
425+
FtueAuthPersonalizationCompleteFragment::class.java,
426+
useCustomAnimation = true
427+
)
428+
}
419429
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="70dp"
3+
android:height="70dp"
4+
android:viewportWidth="70"
5+
android:viewportHeight="70">
6+
<path
7+
android:pathData="M21,23L19,27L23,25L27,27L25,23L27,19L23,21L19,19L21,23Z"
8+
android:strokeLineJoin="round"
9+
android:strokeWidth="2"
10+
android:fillColor="#FF0000"
11+
android:strokeColor="#FF0000"/>
12+
<path
13+
android:pathData="M35.653,41.423L38.538,50.076L41.422,41.423L50.076,38.538L41.422,35.654L38.538,27L35.653,35.654L27,38.538L35.653,41.423Z"
14+
android:strokeLineJoin="round"
15+
android:strokeWidth="2"
16+
android:fillColor="#FF0000"
17+
android:strokeColor="#FF0000"/>
18+
</vector>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="70dp"
3+
android:height="70dp"
4+
android:viewportWidth="70"
5+
android:viewportHeight="70">
6+
<path
7+
android:pathData="M35,36.742C40.771,36.742 45.45,31.673 45.45,25.421C45.45,19.169 40.771,14.1 35,14.1C29.229,14.1 24.55,19.169 24.55,25.421C24.55,31.673 29.229,36.742 35,36.742ZM35,62.867C42.531,62.867 49.364,59.879 54.379,55.025C51.278,47.368 43.77,41.967 35,41.967C26.23,41.967 18.722,47.368 15.621,55.025C20.636,59.879 27.469,62.867 35,62.867Z"
8+
android:fillColor="#FF0000"
9+
android:fillType="evenOdd"/>
10+
</vector>

vector/src/main/res/layout/fragment_ftue_account_created.xml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
android:layout_height="match_parent"
77
android:background="?colorSecondary">
88

9+
<nl.dionsegijn.konfetti.KonfettiView
10+
android:id="@+id/viewKonfetti"
11+
android:layout_width="match_parent"
12+
android:layout_height="match_parent"
13+
android:visibility="gone" />
14+
915
<androidx.constraintlayout.widget.Guideline
1016
android:id="@+id/ftueAuthGutterStart"
1117
android:layout_width="wrap_content"
@@ -34,14 +40,16 @@
3440
android:layout_width="wrap_content"
3541
android:layout_height="0dp"
3642
android:adjustViewBounds="true"
43+
android:background="@drawable/circle"
44+
android:backgroundTint="@color/element_background_light"
3745
android:importantForAccessibility="no"
38-
android:src="@drawable/ic_user_round"
46+
android:src="@drawable/ic_user_fg"
3947
app:layout_constraintBottom_toTopOf="@id/accountCreatedSpace2"
4048
app:layout_constraintEnd_toEndOf="parent"
41-
app:layout_constraintHeight_percent="0.15"
49+
app:layout_constraintHeight_percent="0.12"
4250
app:layout_constraintStart_toStartOf="parent"
4351
app:layout_constraintTop_toBottomOf="@id/accountCreatedSpace1"
44-
app:tint="@color/element_background_light" />
52+
app:tint="?colorSecondary" />
4553

4654
<Space
4755
android:id="@+id/accountCreatedSpace2"

0 commit comments

Comments
 (0)