From 9f6d3ec380d00284562435a7b6103d12b83b6a36 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 28 Feb 2022 16:52:43 +0000 Subject: [PATCH 1/9] playing confetti effect when unable to personalise account on account creation - extracts the logic to an extension for reuse from the timeline --- .../im/vector/app/core/animations/Konfetti.kt | 35 +++++++++++++++++++ .../home/room/detail/TimelineFragment.kt | 14 ++------ .../FtueAuthAccountCreatedFragment.kt | 9 +++++ .../layout/fragment_ftue_account_created.xml | 6 ++++ 4 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/animations/Konfetti.kt diff --git a/vector/src/main/java/im/vector/app/core/animations/Konfetti.kt b/vector/src/main/java/im/vector/app/core/animations/Konfetti.kt new file mode 100644 index 0000000000..18f135d527 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/animations/Konfetti.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.animations + +import android.graphics.Color +import nl.dionsegijn.konfetti.KonfettiView +import nl.dionsegijn.konfetti.models.Shape +import nl.dionsegijn.konfetti.models.Size + +fun KonfettiView.play() { + build() + .addColors(Color.YELLOW, Color.GREEN, Color.MAGENTA) + .setDirection(0.0, 359.0) + .setSpeed(2f, 5f) + .setFadeOutEnabled(true) + .setTimeToLive(2000L) + .addShapes(Shape.Square, Shape.Circle) + .addSizes(Size(12)) + .setPosition(-50f, width + 50f, -50f, -50f) + .streamFor(150, 3000L) +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index c638666cd7..969805e3ca 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -68,6 +68,7 @@ import com.airbnb.mvrx.withState import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.vanniktech.emoji.EmojiPopup import im.vector.app.R +import im.vector.app.core.animations.play import im.vector.app.core.dialogs.ConfirmationDialogBuilder import im.vector.app.core.dialogs.GalleryOrCameraDialogHelper import im.vector.app.core.epoxy.LayoutManagerStateRestorer @@ -203,8 +204,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import nl.dionsegijn.konfetti.models.Shape -import nl.dionsegijn.konfetti.models.Size import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.commonmark.parser.Parser import org.matrix.android.sdk.api.session.Session @@ -562,16 +561,7 @@ class TimelineFragment @Inject constructor( when (chatEffect) { ChatEffect.CONFETTI -> { views.viewKonfetti.isVisible = true - views.viewKonfetti.build() - .addColors(Color.YELLOW, Color.GREEN, Color.MAGENTA) - .setDirection(0.0, 359.0) - .setSpeed(2f, 5f) - .setFadeOutEnabled(true) - .setTimeToLive(2000L) - .addShapes(Shape.Square, Shape.Circle) - .addSizes(Size(12)) - .setPosition(-50f, views.viewKonfetti.width + 50f, -50f, -50f) - .streamFor(150, 3000L) + views.viewKonfetti.play() } ChatEffect.SNOWFALL -> { views.viewSnowFall.isVisible = true diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthAccountCreatedFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthAccountCreatedFragment.kt index ccfb863a5b..49db52da67 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthAccountCreatedFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthAccountCreatedFragment.kt @@ -22,6 +22,7 @@ import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible import im.vector.app.R +import im.vector.app.core.animations.play import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.databinding.FragmentFtueAccountCreatedBinding import im.vector.app.features.onboarding.OnboardingAction @@ -33,6 +34,8 @@ class FtueAuthAccountCreatedFragment @Inject constructor( private val activeSessionHolder: ActiveSessionHolder ) : AbstractFtueAuthFragment() { + private var hasPlayedConfetti = false + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueAccountCreatedBinding { return FragmentFtueAccountCreatedBinding.inflate(inflater, container, false) } @@ -53,6 +56,12 @@ class FtueAuthAccountCreatedFragment @Inject constructor( val canPersonalize = state.personalizationState.supportsPersonalization() views.personalizeButtonGroup.isVisible = canPersonalize views.takeMeHomeButtonGroup.isVisible = !canPersonalize + + if (!hasPlayedConfetti && !canPersonalize) { + hasPlayedConfetti = true + views.viewKonfetti.isVisible = true + views.viewKonfetti.play() + } } override fun resetViewModel() { diff --git a/vector/src/main/res/layout/fragment_ftue_account_created.xml b/vector/src/main/res/layout/fragment_ftue_account_created.xml index 65bcdf2b63..89e94804af 100644 --- a/vector/src/main/res/layout/fragment_ftue_account_created.xml +++ b/vector/src/main/res/layout/fragment_ftue_account_created.xml @@ -6,6 +6,12 @@ android:layout_height="match_parent" android:background="?colorSecondary"> + + Date: Mon, 28 Feb 2022 17:37:49 +0000 Subject: [PATCH 2/9] adding personalization complete screen --- .../im/vector/app/core/di/FragmentModule.kt | 6 + ...FtueAuthPersonalizationCompleteFragment.kt | 61 ++++++++++ .../onboarding/ftueauth/FtueAuthVariant.kt | 14 ++- .../src/main/res/drawable/ic_celebration.xml | 22 ++++ ...fragment_ftue_personalization_complete.xml | 113 ++++++++++++++++++ vector/src/main/res/values/donottranslate.xml | 4 +- 6 files changed, 217 insertions(+), 3 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthPersonalizationCompleteFragment.kt create mode 100644 vector/src/main/res/drawable/ic_celebration.xml create mode 100644 vector/src/main/res/layout/fragment_ftue_personalization_complete.xml diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 2ffdd7ddf3..4dcfbe16f8 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -103,6 +103,7 @@ import im.vector.app.features.onboarding.ftueauth.FtueAuthChooseDisplayNameFragm import im.vector.app.features.onboarding.ftueauth.FtueAuthChooseProfilePictureFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthGenericTextInputFormFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthLoginFragment +import im.vector.app.features.onboarding.ftueauth.FtueAuthPersonalizationCompleteFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthResetPasswordFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthResetPasswordMailConfirmationFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthResetPasswordSuccessFragment @@ -491,6 +492,11 @@ interface FragmentModule { @FragmentKey(FtueAuthChooseProfilePictureFragment::class) fun bindFtueAuthChooseProfilePictureFragment(fragment: FtueAuthChooseProfilePictureFragment): Fragment + @Binds + @IntoMap + @FragmentKey(FtueAuthPersonalizationCompleteFragment::class) + fun bindFtueAuthPersonalizationCompleteFragment(fragment: FtueAuthPersonalizationCompleteFragment): Fragment + @Binds @IntoMap @FragmentKey(UserListFragment::class) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthPersonalizationCompleteFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthPersonalizationCompleteFragment.kt new file mode 100644 index 0000000000..6b47b9830c --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthPersonalizationCompleteFragment.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.onboarding.ftueauth + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.view.isVisible +import im.vector.app.core.animations.play +import im.vector.app.databinding.FragmentFtuePersonalizationCompleteBinding +import im.vector.app.features.onboarding.OnboardingAction +import im.vector.app.features.onboarding.OnboardingViewEvents +import javax.inject.Inject + +class FtueAuthPersonalizationCompleteFragment @Inject constructor() : AbstractFtueAuthFragment() { + + private var hasPlayedConfetti = false + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtuePersonalizationCompleteBinding { + return FragmentFtuePersonalizationCompleteBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupViews() + } + + private fun setupViews() { + views.personalizationCompleteCta.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnTakeMeHome)) } + + if (!hasPlayedConfetti) { + hasPlayedConfetti = true + views.viewKonfetti.isVisible = true + views.viewKonfetti.play() + } + } + + override fun resetViewModel() { + // Nothing to do + } + + override fun onBackPressed(toolbarButton: Boolean): Boolean { + viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnTakeMeHome)) + return true + } +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index 2008726ac3..79a974038b 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -227,7 +227,7 @@ class FtueAuthVariant( OnboardingViewEvents.OnChooseDisplayName -> onChooseDisplayName() OnboardingViewEvents.OnTakeMeHome -> navigateToHome(createdAccount = true) OnboardingViewEvents.OnChooseProfilePicture -> onChooseProfilePicture() - OnboardingViewEvents.OnPersonalizationComplete -> navigateToHome(createdAccount = true) + OnboardingViewEvents.OnPersonalizationComplete -> onPersonalizationComplete() OnboardingViewEvents.OnBack -> activity.popBackstack() }.exhaustive } @@ -393,7 +393,8 @@ class FtueAuthVariant( activity.supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) activity.replaceFragment( views.loginFragmentContainer, - FtueAuthAccountCreatedFragment::class.java + FtueAuthAccountCreatedFragment::class.java, + useCustomAnimation = true ) } @@ -416,4 +417,13 @@ class FtueAuthVariant( option = commonOption ) } + + private fun onPersonalizationComplete() { + activity.supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) + activity.replaceFragment( + views.loginFragmentContainer, + FtueAuthPersonalizationCompleteFragment::class.java, + useCustomAnimation = true + ) + } } diff --git a/vector/src/main/res/drawable/ic_celebration.xml b/vector/src/main/res/drawable/ic_celebration.xml new file mode 100644 index 0000000000..3868a60a60 --- /dev/null +++ b/vector/src/main/res/drawable/ic_celebration.xml @@ -0,0 +1,22 @@ + + + + + diff --git a/vector/src/main/res/layout/fragment_ftue_personalization_complete.xml b/vector/src/main/res/layout/fragment_ftue_personalization_complete.xml new file mode 100644 index 0000000000..64908a4133 --- /dev/null +++ b/vector/src/main/res/layout/fragment_ftue_personalization_complete.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + +