From 96e00913096c3ec644c817f5fb294fd633d38116 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Wed, 13 Dec 2023 15:03:38 +0700 Subject: [PATCH 1/7] Delete request daily study reminders logic after step solved --- .../view/fragment/StageStepWrapperFragment.kt | 13 +---- .../step/view/delegate/StepDelegate.kt | 50 ++----------------- .../step/view/fragment/StepFragment.kt | 13 +---- ...RequestDailyStudyReminderDialogFragment.kt | 34 ------------- .../Sources/Models/Constants/Strings.swift | 5 -- .../Sources/Modules/Step/StepAssembly.swift | 5 -- .../Sources/Modules/Step/StepViewModel.swift | 29 ----------- .../Sources/Modules/Step/Views/StepView.swift | 34 ------------- .../hyperskill/HyperskillAnalyticPart.kt | 2 - .../hyperskill/HyperskillAnalyticTarget.kt | 3 -- .../cache/NotificationCacheDataSourceImpl.kt | 17 ------- .../local/cache/NotificationCacheKeyValues.kt | 4 -- .../repository/NotificationRepositoryImpl.kt | 10 ---- .../source/NotificationCacheDataSource.kt | 4 -- .../interactor/NotificationInteractor.kt | 31 ------------ .../repository/NotificationRepository.kt | 4 -- .../injection/NotificationComponentImpl.kt | 1 - .../NotificationsOnboardingComponentImpl.kt | 1 - .../NotificationsOnboardingFeatureBuilder.kt | 5 +- ...NotificationsOnboardingActionDispatcher.kt | 4 -- .../NotificationsOnboardingFeature.kt | 1 - .../NotificationsOnboardingReducer.kt | 2 - ...ificationsNoticeHyperskillAnalyticEvent.kt | 31 ------------ ...ificationsNoticeHyperskillAnalyticEvent.kt | 30 ----------- .../injection/StepCompletionComponentImpl.kt | 3 +- .../StepCompletionActionDispatcher.kt | 29 +---------- .../presentation/StepCompletionFeature.kt | 11 ---- .../presentation/StepCompletionReducer.kt | 24 --------- .../commonMain/resources/MR/base/strings.xml | 4 -- 29 files changed, 8 insertions(+), 396 deletions(-) delete mode 100644 androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/dialog/RequestDailyStudyReminderDialogFragment.kt delete mode 100644 shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/domain/analytic/StepCompletionHiddenDailyNotificationsNoticeHyperskillAnalyticEvent.kt delete mode 100644 shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/domain/analytic/StepCompletionShownDailyNotificationsNoticeHyperskillAnalyticEvent.kt diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/stage_implementation/view/fragment/StageStepWrapperFragment.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/stage_implementation/view/fragment/StageStepWrapperFragment.kt index 8ee6c4b0db..37aad19abc 100644 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/stage_implementation/view/fragment/StageStepWrapperFragment.kt +++ b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/stage_implementation/view/fragment/StageStepWrapperFragment.kt @@ -18,7 +18,6 @@ import org.hyperskill.app.android.step.view.fragment.StepFragment import org.hyperskill.app.android.step.view.model.StepCompletionHost import org.hyperskill.app.android.step.view.model.StepCompletionView import org.hyperskill.app.android.step_practice.view.fragment.StepPracticeDetailsFragment -import org.hyperskill.app.android.step_quiz.view.dialog.RequestDailyStudyReminderDialogFragment import org.hyperskill.app.android.step_quiz.view.factory.StepQuizFragmentFactory import org.hyperskill.app.step.domain.model.Step import org.hyperskill.app.step.domain.model.StepRoute @@ -42,7 +41,6 @@ class StageStepWrapperFragment : Fragment(R.layout.fragment_stage_step_wrapper), ReduxView, StepCompletionHost, - RequestDailyStudyReminderDialogFragment.Callback, ShareStreakDialogFragment.Callback { companion object { @@ -83,12 +81,7 @@ class StageStepWrapperFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) injectComponent() - stepDelegate = StepDelegate( - fragment = this, - onRequestDailyStudyRemindersPermissionResult = { isGranted -> - onNewMessage(StepCompletionFeature.Message.RequestDailyStudyRemindersPermissionResult(isGranted)) - } - ) + stepDelegate = StepDelegate(fragment = this) } private fun injectComponent() { @@ -161,10 +154,6 @@ class StageStepWrapperFragment : stepViewModel.onNewMessage(StepFeature.Message.StepCompletionMessage(message)) } - override fun onPermissionResult(isGranted: Boolean) { - stepDelegate?.onPermissionResult(isGranted) - } - override fun onShareStreakBottomSheetShown(streak: Int) { stepViewModel.onShareStreakBottomSheetShown(streak) } diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step/view/delegate/StepDelegate.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step/view/delegate/StepDelegate.kt index 082585f39a..f016290f73 100644 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step/view/delegate/StepDelegate.kt +++ b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step/view/delegate/StepDelegate.kt @@ -4,39 +4,28 @@ import android.content.ActivityNotFoundException import android.content.Context import android.util.Log import androidx.annotation.DrawableRes -import androidx.core.app.NotificationManagerCompat import androidx.fragment.app.Fragment import org.hyperskill.app.R import org.hyperskill.app.android.core.extensions.ShareUtils -import org.hyperskill.app.android.core.extensions.checkNotificationChannelAvailability import org.hyperskill.app.android.core.view.ui.navigation.requireRouter import org.hyperskill.app.android.databinding.ErrorNoConnectionWithButtonBinding import org.hyperskill.app.android.main.view.ui.navigation.MainScreen import org.hyperskill.app.android.main.view.ui.navigation.MainScreenRouter import org.hyperskill.app.android.main.view.ui.navigation.Tabs import org.hyperskill.app.android.main.view.ui.navigation.switch -import org.hyperskill.app.android.notification.model.HyperskillNotificationChannel -import org.hyperskill.app.android.notification.permission.NotificationPermissionDelegate import org.hyperskill.app.android.share_streak.fragment.ShareStreakDialogFragment import org.hyperskill.app.android.step.view.dialog.TopicPracticeCompletedBottomSheet import org.hyperskill.app.android.step.view.screen.StepScreen import org.hyperskill.app.android.step_quiz.view.dialog.CompletedStepOfTheDayDialogFragment -import org.hyperskill.app.android.step_quiz.view.dialog.RequestDailyStudyReminderDialogFragment import org.hyperskill.app.android.view.base.ui.extension.snackbar import org.hyperskill.app.step.presentation.StepFeature import org.hyperskill.app.step_completion.presentation.StepCompletionFeature import ru.nobird.android.view.base.ui.extension.showIfNotExists class StepDelegate( - private val fragment: TFragment, - private val onRequestDailyStudyRemindersPermissionResult: (Boolean) -> Unit -) : RequestDailyStudyReminderDialogFragment.Callback - where TFragment : Fragment, - TFragment : RequestDailyStudyReminderDialogFragment.Callback, - TFragment : ShareStreakDialogFragment.Callback { - - private val notificationPermissionDelegate: NotificationPermissionDelegate = - NotificationPermissionDelegate(fragment, ::onNotificationPermissionResult) + private val fragment: TFragment +) where TFragment : Fragment, + TFragment : ShareStreakDialogFragment.Callback { fun init(errorBinding: ErrorNoConnectionWithButtonBinding, onNewMessage: (StepFeature.Message) -> Unit) { onNewMessage(StepFeature.Message.ViewedEventMessage) @@ -80,10 +69,6 @@ class StepDelegate( TopicPracticeCompletedBottomSheet.Tag ) } - StepCompletionFeature.Action.ViewAction.RequestDailyStudyRemindersPermission -> { - RequestDailyStudyReminderDialogFragment.newInstance() - .showIfNotExists(fragment.childFragmentManager, RequestDailyStudyReminderDialogFragment.TAG) - } is StepCompletionFeature.Action.ViewAction.ShowProblemOfDaySolvedModal -> { CompletedStepOfTheDayDialogFragment .newInstance( @@ -108,35 +93,6 @@ class StepDelegate( } } - override fun onPermissionResult(isGranted: Boolean) { - if (isGranted) { - notificationPermissionDelegate.requestNotificationPermission() - } else { - onRequestDailyStudyRemindersPermissionResult(false) - } - } - - private fun onNotificationPermissionResult(result: NotificationPermissionDelegate.Result) { - when (result) { - NotificationPermissionDelegate.Result.GRANTED -> { - onNotificationPermissionGranted() - } - NotificationPermissionDelegate.Result.DENIED, - NotificationPermissionDelegate.Result.DONT_ASK -> { - onRequestDailyStudyRemindersPermissionResult(false) - } - } - } - - private fun onNotificationPermissionGranted() { - onRequestDailyStudyRemindersPermissionResult(true) - val context = fragment.context - if (context != null) { - NotificationManagerCompat.from(context) - .checkNotificationChannelAvailability(context, HyperskillNotificationChannel.DailyReminder) - } - } - @DrawableRes private fun getShareStreakDrawableRes(streak: Int): Int = when (streak) { diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step/view/fragment/StepFragment.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step/view/fragment/StepFragment.kt index 71709b3a35..e302accf32 100644 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step/view/fragment/StepFragment.kt +++ b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step/view/fragment/StepFragment.kt @@ -16,7 +16,6 @@ import org.hyperskill.app.android.step.view.delegate.StepDelegate import org.hyperskill.app.android.step.view.model.StepCompletionHost import org.hyperskill.app.android.step.view.model.StepCompletionView import org.hyperskill.app.android.step_practice.view.fragment.StepPracticeFragment -import org.hyperskill.app.android.step_quiz.view.dialog.RequestDailyStudyReminderDialogFragment import org.hyperskill.app.android.step_theory.view.fragment.StepTheoryFragment import org.hyperskill.app.step.domain.model.Step import org.hyperskill.app.step.domain.model.StepRoute @@ -31,7 +30,6 @@ class StepFragment : Fragment(R.layout.fragment_step), ReduxView, StepCompletionHost, - RequestDailyStudyReminderDialogFragment.Callback, ShareStreakDialogFragment.Callback { companion object { @@ -59,12 +57,7 @@ class StepFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) injectComponent() - stepDelegate = StepDelegate( - fragment = this, - onRequestDailyStudyRemindersPermissionResult = { isGranted -> - onNewMessage(StepCompletionFeature.Message.RequestDailyStudyRemindersPermissionResult(isGranted)) - } - ) + stepDelegate = StepDelegate(fragment = this) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -129,10 +122,6 @@ class StepFragment : ) } - override fun onPermissionResult(isGranted: Boolean) { - stepDelegate?.onPermissionResult(isGranted) - } - override fun onShareStreakBottomSheetShown(streak: Int) { stepViewModel.onShareStreakBottomSheetShown(streak) } diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/dialog/RequestDailyStudyReminderDialogFragment.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/dialog/RequestDailyStudyReminderDialogFragment.kt deleted file mode 100644 index e073ca14d0..0000000000 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/dialog/RequestDailyStudyReminderDialogFragment.kt +++ /dev/null @@ -1,34 +0,0 @@ -package org.hyperskill.app.android.step_quiz.view.dialog - -import android.app.Dialog -import android.os.Bundle -import androidx.fragment.app.DialogFragment -import com.google.android.material.dialog.MaterialAlertDialogBuilder - -class RequestDailyStudyReminderDialogFragment : DialogFragment() { - - companion object { - const val TAG: String = "RequestDailyStudyReminderDialogFragment" - - fun newInstance(): RequestDailyStudyReminderDialogFragment = - RequestDailyStudyReminderDialogFragment() - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = - MaterialAlertDialogBuilder(requireContext()) - .setTitle(org.hyperskill.app.R.string.after_daily_step_completed_dialog_title) - .setMessage(org.hyperskill.app.R.string.after_daily_step_completed_dialog_text) - .setPositiveButton(org.hyperskill.app.R.string.ok) { dialog, _ -> - (parentFragment as Callback).onPermissionResult(true) - dialog.dismiss() - } - .setNegativeButton(org.hyperskill.app.R.string.later) { dialog, _ -> - (parentFragment as Callback).onPermissionResult(false) - dialog.dismiss() - } - .show() - - interface Callback { - fun onPermissionResult(isGranted: Boolean) - } -} \ No newline at end of file diff --git a/iosHyperskillApp/iosHyperskillApp/Sources/Models/Constants/Strings.swift b/iosHyperskillApp/iosHyperskillApp/Sources/Models/Constants/Strings.swift index baef2d90ff..9d25387dc3 100644 --- a/iosHyperskillApp/iosHyperskillApp/Sources/Models/Constants/Strings.swift +++ b/iosHyperskillApp/iosHyperskillApp/Sources/Models/Constants/Strings.swift @@ -75,11 +75,6 @@ enum Strings { enum Step { static let startPracticing = sharedStrings.step_start_practicing_text.localized() static let theory = sharedStrings.step_theory_text.localized() - - enum RequestDailyNotificationsAlert { - static let title = sharedStrings.after_daily_step_completed_dialog_title.localized() - static let text = sharedStrings.after_daily_step_completed_dialog_text.localized() - } } // MARK: - StepQuiz - diff --git a/iosHyperskillApp/iosHyperskillApp/Sources/Modules/Step/StepAssembly.swift b/iosHyperskillApp/iosHyperskillApp/Sources/Modules/Step/StepAssembly.swift index d7fc9a77c7..7a6a503d1f 100644 --- a/iosHyperskillApp/iosHyperskillApp/Sources/Modules/Step/StepAssembly.swift +++ b/iosHyperskillApp/iosHyperskillApp/Sources/Modules/Step/StepAssembly.swift @@ -55,7 +55,6 @@ final class StepAssembly: Assembly, UIKitAssembly { private func makeViewModel() -> StepViewModel { let commonComponent = AppGraphBridge.sharedAppGraph.commonComponent let stepComponent = AppGraphBridge.sharedAppGraph.buildStepComponent(stepRoute: stepRoute) - let notificationComponent = AppGraphBridge.sharedAppGraph.buildNotificationComponent() return StepViewModel( stepRoute: stepRoute, @@ -64,10 +63,6 @@ final class StepAssembly: Assembly, UIKitAssembly { resourceProvider: commonComponent.resourceProvider, commentThreadTitleMapper: stepComponent.commentThreadTitleMapper ), - notificationService: NotificationsService( - notificationInteractor: notificationComponent.notificationInteractor - ), - notificationsRegistrationService: .shared, feature: stepComponent.stepFeature ) } diff --git a/iosHyperskillApp/iosHyperskillApp/Sources/Modules/Step/StepViewModel.swift b/iosHyperskillApp/iosHyperskillApp/Sources/Modules/Step/StepViewModel.swift index 9afe5b0cc5..18251d14e6 100644 --- a/iosHyperskillApp/iosHyperskillApp/Sources/Modules/Step/StepViewModel.swift +++ b/iosHyperskillApp/iosHyperskillApp/Sources/Modules/Step/StepViewModel.swift @@ -10,9 +10,6 @@ final class StepViewModel: FeatureViewModel= 1L - - val lastTimeAsked = notificationRepository.getLastTimeUserAskedToEnableDailyReminders() ?: return true - val isAskedAtLeastTwoDaysAgo = (lastTimeAsked + TWO_DAYS_IN_MILLIS) <= Clock.System.now().toEpochMilliseconds() - - val isNotReachedMaxUserAskedCount = - getUserAskedToEnableDailyRemindersCount() < MAX_USER_ASKED_TO_ENABLE_DAILY_REMINDERS_COUNT - - return isFirstStepSolved && isAskedAtLeastTwoDaysAgo && isNotReachedMaxUserAskedCount - } - - fun updateLastTimeUserAskedToEnableDailyReminders() { - notificationRepository.setLastTimeUserAskedToEnableDailyReminders( - Clock.System.now().toEpochMilliseconds() - ) - } - - private fun getUserAskedToEnableDailyRemindersCount(): Long = - notificationRepository.getUserAskedToEnableDailyRemindersCount() - /** * Sets the daily study reminder notification time & set current timeZone * diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/domain/repository/NotificationRepository.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/domain/repository/NotificationRepository.kt index f566fb51b4..d7f01aacea 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/domain/repository/NotificationRepository.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/domain/repository/NotificationRepository.kt @@ -16,8 +16,4 @@ interface NotificationRepository { fun setDailyStudyRemindersIntervalStartHour(hour: Int) fun getRandomDailyStudyRemindersNotificationDescription(): NotificationDescription - - fun getLastTimeUserAskedToEnableDailyReminders(): Long? - fun setLastTimeUserAskedToEnableDailyReminders(timestamp: Long) - fun getUserAskedToEnableDailyRemindersCount(): Long } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/injection/NotificationComponentImpl.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/injection/NotificationComponentImpl.kt index 14dba11716..6fa709b01e 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/injection/NotificationComponentImpl.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/injection/NotificationComponentImpl.kt @@ -21,7 +21,6 @@ class NotificationComponentImpl(appGraph: AppGraph) : NotificationComponent { override val notificationInteractor: NotificationInteractor = NotificationInteractor( notificationRepository, - appGraph.submissionDataComponent.submissionRepository, appGraph.notificationFlowDataComponent.dailyStudyRemindersEnabledFlow, profileDataComponent.currentProfileStateRepository, profileDataComponent.profileRepository diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt index a92cb3f96a..9f7e7f5455 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt @@ -12,7 +12,6 @@ internal class NotificationsOnboardingComponentImpl( override val notificationsOnboardingFeature: Feature get() = NotificationsOnboardingFeatureBuilder.build( analyticInteractor = appGraph.analyticComponent.analyticInteractor, - notificationInteractor = appGraph.buildNotificationComponent().notificationInteractor, logger = appGraph.loggerComponent.logger, buildVariant = appGraph.commonComponent.buildKonfig.buildVariant ) diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt index 0ef512f50a..ef3b35bf58 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt @@ -5,7 +5,6 @@ import org.hyperskill.app.analytic.domain.interactor.AnalyticInteractor import org.hyperskill.app.core.domain.BuildVariant import org.hyperskill.app.core.presentation.ActionDispatcherOptions import org.hyperskill.app.logging.presentation.wrapWithLogger -import org.hyperskill.app.notification.local.domain.interactor.NotificationInteractor import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingActionDispatcher import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Action import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Message @@ -20,15 +19,13 @@ internal object NotificationsOnboardingFeatureBuilder { fun build( analyticInteractor: AnalyticInteractor, - notificationInteractor: NotificationInteractor, buildVariant: BuildVariant, logger: Logger ): Feature { val reducer = NotificationsOnboardingReducer().wrapWithLogger(buildVariant, logger, LOG_TAG) val actionDispatcher = NotificationsOnboardingActionDispatcher( config = ActionDispatcherOptions(), - analyticInteractor = analyticInteractor, - notificationInteractor = notificationInteractor + analyticInteractor = analyticInteractor ) return ReduxFeature(State, reducer).wrapWithActionDispatcher(actionDispatcher) } diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingActionDispatcher.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingActionDispatcher.kt index 131add1162..a381789827 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingActionDispatcher.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingActionDispatcher.kt @@ -2,7 +2,6 @@ package org.hyperskill.app.notifications_onboarding.presentation import org.hyperskill.app.analytic.domain.interactor.AnalyticInteractor import org.hyperskill.app.core.presentation.ActionDispatcherOptions -import org.hyperskill.app.notification.local.domain.interactor.NotificationInteractor import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Action import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.InternalAction import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Message @@ -10,14 +9,11 @@ import ru.nobird.app.presentation.redux.dispatcher.CoroutineActionDispatcher internal class NotificationsOnboardingActionDispatcher( config: ActionDispatcherOptions, - private val notificationInteractor: NotificationInteractor, private val analyticInteractor: AnalyticInteractor ) : CoroutineActionDispatcher(config.createConfig()) { override suspend fun doSuspendableAction(action: Action) { when (action) { - InternalAction.UpdateLastNotificationPermissionRequestTime -> - notificationInteractor.updateLastTimeUserAskedToEnableDailyReminders() is InternalAction.LogAnalyticEvent -> analyticInteractor.logEvent(action.analyticEvent) else -> { diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt index 961e51c938..769e1dcf86 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt @@ -21,6 +21,5 @@ object NotificationsOnboardingFeature { internal sealed interface InternalAction : Action { data class LogAnalyticEvent(val analyticEvent: AnalyticEvent) : InternalAction - object UpdateLastNotificationPermissionRequestTime : InternalAction } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt index 6523da21a0..a6e057cca2 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt @@ -26,7 +26,6 @@ internal class NotificationsOnboardingReducer : StateReducer @@ -52,7 +51,6 @@ internal class NotificationsOnboardingReducer : StateReducer diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/domain/analytic/StepCompletionHiddenDailyNotificationsNoticeHyperskillAnalyticEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/domain/analytic/StepCompletionHiddenDailyNotificationsNoticeHyperskillAnalyticEvent.kt deleted file mode 100644 index dc27825165..0000000000 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/domain/analytic/StepCompletionHiddenDailyNotificationsNoticeHyperskillAnalyticEvent.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.hyperskill.app.step_completion.domain.analytic - -import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticAction -import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticEvent -import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticPart -import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticRoute -import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTarget - -/** - * Represents a hidden analytic event of the prompt to receive daily study reminders. - * - * JSON payload: - * ``` - * { - * "route": "/learn/step/1", - * "action": "hidden", - * "part": "daily_notifications_notice", - * "target": "ok / later" - * } - * ``` - * @see HyperskillAnalyticEvent - */ -class StepCompletionHiddenDailyNotificationsNoticeHyperskillAnalyticEvent( - route: HyperskillAnalyticRoute, - isAgreed: Boolean -) : HyperskillAnalyticEvent( - route, - HyperskillAnalyticAction.HIDDEN, - HyperskillAnalyticPart.DAILY_NOTIFICATIONS_NOTICE, - target = if (isAgreed) HyperskillAnalyticTarget.OK else HyperskillAnalyticTarget.LATER -) \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/domain/analytic/StepCompletionShownDailyNotificationsNoticeHyperskillAnalyticEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/domain/analytic/StepCompletionShownDailyNotificationsNoticeHyperskillAnalyticEvent.kt deleted file mode 100644 index a7d9d1b736..0000000000 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/domain/analytic/StepCompletionShownDailyNotificationsNoticeHyperskillAnalyticEvent.kt +++ /dev/null @@ -1,30 +0,0 @@ -package org.hyperskill.app.step_completion.domain.analytic - -import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticAction -import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticEvent -import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticPart -import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticRoute -import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTarget - -/** - * Represents a shown analytic event of the prompt to receive daily study reminders. - * - * JSON payload: - * ``` - * { - * "route": "/learn/step/1", - * "action": "hidden", - * "part": "notice", - * "target": "daily_notifications_notice" - * } - * ``` - * @see HyperskillAnalyticEvent - */ -class StepCompletionShownDailyNotificationsNoticeHyperskillAnalyticEvent( - route: HyperskillAnalyticRoute, -) : HyperskillAnalyticEvent( - route, - HyperskillAnalyticAction.SHOWN, - HyperskillAnalyticPart.NOTICE, - HyperskillAnalyticTarget.DAILY_NOTIFICATIONS_NOTICE -) \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/injection/StepCompletionComponentImpl.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/injection/StepCompletionComponentImpl.kt index effa484b9e..aa8d5e726c 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/injection/StepCompletionComponentImpl.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/injection/StepCompletionComponentImpl.kt @@ -30,7 +30,6 @@ internal class StepCompletionComponentImpl( appGraph.stateRepositoriesComponent.currentGamificationToolbarDataStateRepository, appGraph.stepCompletionFlowDataComponent.dailyStepCompletedFlow, appGraph.stepCompletionFlowDataComponent.topicCompletedFlow, - appGraph.progressesFlowDataComponent.topicProgressFlow, - appGraph.buildNotificationComponent().notificationInteractor + appGraph.progressesFlowDataComponent.topicProgressFlow ) } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionActionDispatcher.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionActionDispatcher.kt index cfb464023a..f1db77431d 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionActionDispatcher.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionActionDispatcher.kt @@ -11,8 +11,6 @@ import org.hyperskill.app.core.view.mapper.ResourceProvider import org.hyperskill.app.freemium.domain.interactor.FreemiumInteractor import org.hyperskill.app.gamification_toolbar.domain.repository.CurrentGamificationToolbarDataStateRepository import org.hyperskill.app.learning_activities.domain.repository.NextLearningActivityStateRepository -import org.hyperskill.app.notification.local.cache.NotificationCacheKeyValues -import org.hyperskill.app.notification.local.domain.interactor.NotificationInteractor import org.hyperskill.app.profile.domain.repository.CurrentProfileStateRepository import org.hyperskill.app.progresses.domain.flow.TopicProgressFlow import org.hyperskill.app.progresses.domain.interactor.ProgressesInteractor @@ -49,8 +47,7 @@ class StepCompletionActionDispatcher( private val currentGamificationToolbarDataStateRepository: CurrentGamificationToolbarDataStateRepository, private val dailyStepCompletedFlow: DailyStepCompletedFlow, private val topicCompletedFlow: TopicCompletedFlow, - private val topicProgressFlow: TopicProgressFlow, - private val notificationInteractor: NotificationInteractor + private val topicProgressFlow: TopicProgressFlow ) : CoroutineActionDispatcher(config.createConfig()) { init { @@ -97,12 +94,6 @@ class StepCompletionActionDispatcher( is Action.UpdateProblemsLimit -> { freemiumInteractor.onStepSolved() } - is Action.TurnOnDailyStudyReminder -> { - handleTurnOnDailyStudyReminderAction() - } - is Action.PostponeDailyStudyReminder -> { - handlePostponeDailyStudyReminderAction() - } is Action.UpdateLastTimeShareStreakShown -> { shareStreakInteractor.setLastTimeShareStreakShown() } @@ -186,17 +177,6 @@ class StepCompletionActionDispatcher( } } - private suspend fun handleTurnOnDailyStudyReminderAction() { - notificationInteractor.setDailyStudyRemindersEnabled(true) - notificationInteractor.setDailyStudyReminderNotificationTime( - NotificationCacheKeyValues.DAILY_STUDY_REMINDERS_START_HOUR_AFTER_STEP_SOLVED - ) - } - - private fun handlePostponeDailyStudyReminderAction() { - notificationInteractor.updateLastTimeUserAskedToEnableDailyReminders() - } - private suspend fun handleStepSolved(stepId: Long) { // update problems limit onNewMessage(Message.StepSolved(stepId)) @@ -237,13 +217,6 @@ class StepCompletionActionDispatcher( false } - // TODO: ALTUX-2415 Enhance the user experience of "Daily Study Reminders" - if (notificationInteractor.isRequiredToAskUserToEnableDailyReminders()) { - onNewMessage(Message.RequestDailyStudyRemindersPermission) - updateCurrentProfileHypercoinsBalanceRemotely() - return - } - if (cachedProfile.dailyStep == stepId) { val currentProfileHypercoinsBalance = updateCurrentProfileHypercoinsBalanceRemotely() if (currentProfileHypercoinsBalance != null) { diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionFeature.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionFeature.kt index 51132340cc..fe31bbba82 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionFeature.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionFeature.kt @@ -100,12 +100,6 @@ interface StepCompletionFeature { object ProblemOfDaySolvedModalGoBackClicked : Message data class ProblemOfDaySolvedModalShareStreakClicked(val streak: Int) : Message - /** - * Daily study reminders - */ - object RequestDailyStudyRemindersPermission : Message - data class RequestDailyStudyRemindersPermissionResult(val isGranted: Boolean) : Message - /** * Share streak */ @@ -134,9 +128,6 @@ interface StepCompletionFeature { object UpdateProblemsLimit : Action - object TurnOnDailyStudyReminder : Action - object PostponeDailyStudyReminder : Action - object UpdateLastTimeShareStreakShown : Action sealed interface ViewAction : Action { @@ -153,8 +144,6 @@ interface StepCompletionFeature { data class ShowShareStreakModal(val streak: Int) : ViewAction data class ShowShareStreakSystemModal(val streak: Int) : ViewAction - object RequestDailyStudyRemindersPermission : ViewAction - data class ShowStartPracticingError(val message: String) : ViewAction data class ReloadStep(val stepRoute: StepRoute) : ViewAction diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionReducer.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionReducer.kt index 903fab45d7..3006961a5d 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionReducer.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/step_completion/presentation/StepCompletionReducer.kt @@ -10,12 +10,10 @@ import org.hyperskill.app.step_completion.domain.analytic.StepCompletionDailySte import org.hyperskill.app.step_completion.domain.analytic.StepCompletionDailyStepCompletedModalClickedShareStreakHyperskillAnalyticEvent import org.hyperskill.app.step_completion.domain.analytic.StepCompletionDailyStepCompletedModalHiddenHyperskillAnalyticEvent import org.hyperskill.app.step_completion.domain.analytic.StepCompletionDailyStepCompletedModalShownHyperskillAnalyticEvent -import org.hyperskill.app.step_completion.domain.analytic.StepCompletionHiddenDailyNotificationsNoticeHyperskillAnalyticEvent import org.hyperskill.app.step_completion.domain.analytic.StepCompletionShareStreakModalClickedNoThanksHyperskillAnalyticEvent import org.hyperskill.app.step_completion.domain.analytic.StepCompletionShareStreakModalClickedShareHyperskillAnalyticEvent import org.hyperskill.app.step_completion.domain.analytic.StepCompletionShareStreakModalHiddenHyperskillAnalyticEvent import org.hyperskill.app.step_completion.domain.analytic.StepCompletionShareStreakModalShownHyperskillAnalyticEvent -import org.hyperskill.app.step_completion.domain.analytic.StepCompletionShownDailyNotificationsNoticeHyperskillAnalyticEvent import org.hyperskill.app.step_completion.domain.analytic.StepCompletionTopicCompletedModalClickedContinueNextTopicHyperskillAnalyticEvent import org.hyperskill.app.step_completion.domain.analytic.StepCompletionTopicCompletedModalClickedGoToStudyPlanHyperskillAnalyticEvent import org.hyperskill.app.step_completion.domain.analytic.StepCompletionTopicCompletedModalHiddenHyperskillAnalyticEvent @@ -158,28 +156,6 @@ class StepCompletionReducer(private val stepRoute: StepRoute) : StateReducer { - state to setOfNotNull( - Action.ViewAction.RequestDailyStudyRemindersPermission, - Action.LogAnalyticEvent( - StepCompletionShownDailyNotificationsNoticeHyperskillAnalyticEvent(stepRoute.analyticRoute) - ) - ) - } - is Message.RequestDailyStudyRemindersPermissionResult -> { - val analyticEvent = StepCompletionHiddenDailyNotificationsNoticeHyperskillAnalyticEvent( - route = stepRoute.analyticRoute, - isAgreed = message.isGranted - ) - state to setOf( - if (message.isGranted) { - Action.TurnOnDailyStudyReminder - } else { - Action.PostponeDailyStudyReminder - }, - Action.LogAnalyticEvent(analyticEvent) - ) - } is Message.ShareStreak -> { state to setOf(Action.ViewAction.ShowShareStreakModal(streak = message.streak)) } diff --git a/shared/src/commonMain/resources/MR/base/strings.xml b/shared/src/commonMain/resources/MR/base/strings.xml index 3ea3d76dcc..cf111690ca 100644 --- a/shared/src/commonMain/resources/MR/base/strings.xml +++ b/shared/src/commonMain/resources/MR/base/strings.xml @@ -412,10 +412,6 @@ Start learning Failed to load first problem - - Stay motivated with daily reminders - The app will send you notifications to practice everyday and keep up your learning streak - Learn next From 20dbaf7eae38373cdad3b9e0c6bcf4b2ceb381fe Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Wed, 13 Dec 2023 17:32:03 +0700 Subject: [PATCH 2/7] Add daily study reminders interval start hour logic --- .../NotificationsOnboardingFragment.kt | 1 + .../Views/NotificationsOnboardingView.swift | 2 + .../hyperskill/HyperskillAnalyticPart.kt | 3 +- .../hyperskill/HyperskillAnalyticTarget.kt | 3 +- .../local/cache/NotificationCacheKeyValues.kt | 2 +- .../NotificationsOnboardingAnalyticParams.kt | 5 ++ ...owNotificationsHyperskillAnalyticsEvent.kt | 21 ++++++- ...ndsIntervalHourHyperskillAnalyticsEvent.kt | 43 ++++++++++++++ ...edRemindMeLaterHyperskillAnalyticsEvent.kt | 1 + ...lStartHourPickerModalHiddenEventMessage.kt | 30 ++++++++++ ...alStartHourPickerModalShownEventMessage.kt | 30 ++++++++++ ...nboardingViewedHyperskillAnalyticsEvent.kt | 1 + .../NotificationsOnboardingComponentImpl.kt | 1 + .../NotificationsOnboardingFeatureBuilder.kt | 9 ++- ...NotificationsOnboardingActionDispatcher.kt | 9 ++- .../NotificationsOnboardingFeature.kt | 20 ++++++- .../NotificationsOnboardingReducer.kt | 59 +++++++++++++++---- 17 files changed, 221 insertions(+), 19 deletions(-) create mode 100644 shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingAnalyticParams.kt create mode 100644 shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent.kt create mode 100644 shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage.kt create mode 100644 shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage.kt diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/fragment/NotificationsOnboardingFragment.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/fragment/NotificationsOnboardingFragment.kt index d1b1cefb29..d097db3b7e 100644 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/fragment/NotificationsOnboardingFragment.kt +++ b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/fragment/NotificationsOnboardingFragment.kt @@ -108,6 +108,7 @@ class NotificationsOnboardingFragment : Fragment() { ViewAction.RequestNotificationPermission -> { notificationPermissionDelegate?.requestNotificationPermission() } + ViewAction.ShowDailyStudyRemindersIntervalStartHourPickerModal -> TODO() } } diff --git a/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/Views/NotificationsOnboardingView.swift b/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/Views/NotificationsOnboardingView.swift index c4730ed1c8..ff5fd677aa 100644 --- a/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/Views/NotificationsOnboardingView.swift +++ b/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/Views/NotificationsOnboardingView.swift @@ -45,6 +45,8 @@ private extension NotificationsOnboardingView { viewModel.doCompleteOnboarding() case .requestNotificationPermission: viewModel.doRequestNotificationPermission() + case .showDailyStudyRemindersIntervalStartHourPickerModal: + #warning("TODO: ALTAPPS-1070 handle this") } } } diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticPart.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticPart.kt index 13e2cec177..14f7796ae9 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticPart.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticPart.kt @@ -38,5 +38,6 @@ enum class HyperskillAnalyticPart(val partName: String) { CODE_EDITOR("code_editor"), SHARE_STREAK_MODAL("share_streak_modal"), LEADERBOARD_DAY_TAB("leaderboard_day_tab"), - LEADERBOARD_WEEK_TAB("leaderboard_week_tab") + LEADERBOARD_WEEK_TAB("leaderboard_week_tab"), + DAILY_STUDY_REMINDERS_HOUR_INTERVAL_PICKER_MODAL("daily_study_reminders_hour_interval_picker_modal") } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt index f509c19801..010b7be444 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt @@ -105,5 +105,6 @@ enum class HyperskillAnalyticTarget(val targetName: String) { COLLECT_REWARD("collect_reward"), DAY("day"), WEEK("week"), - LEADERBOARD_ITEM("leaderboard_item") + LEADERBOARD_ITEM("leaderboard_item"), + DAILY_STUDY_REMINDERS_HOUR_INTERVAL_PICKER_MODAL("daily_study_reminders_hour_interval_picker_modal") } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/cache/NotificationCacheKeyValues.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/cache/NotificationCacheKeyValues.kt index 62edee8f3a..7cbbf14ae1 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/cache/NotificationCacheKeyValues.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notification/local/cache/NotificationCacheKeyValues.kt @@ -6,5 +6,5 @@ internal object NotificationCacheKeyValues { const val DAILY_STUDY_REMINDERS_ENABLED = "notifications_daily_reminder_enabled" const val DAILY_STUDY_REMINDERS_START_HOUR = "notifications_daily_reminder_start_hour" const val DAILY_STUDY_REMINDERS_START_HOUR_DEFAULT = 20 - const val DAILY_STUDY_REMINDERS_START_HOUR_AFTER_STEP_SOLVED = 12 + const val DAILY_STUDY_REMINDERS_START_HOUR_ONBOARDING = 12 } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingAnalyticParams.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingAnalyticParams.kt new file mode 100644 index 0000000000..77bae9e683 --- /dev/null +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingAnalyticParams.kt @@ -0,0 +1,5 @@ +package org.hyperskill.app.notifications_onboarding.domain.analytic + +internal object NotificationsOnboardingAnalyticParams { + const val PARAM_START_HOUR = "start_hour" +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent.kt index 3e34926405..93650a5548 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent.kt @@ -15,14 +15,29 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTar * "route": "/onboarding/notifications", * "action": "click", * "part": "main", - * "target": "allow_notifications" + * "target": "allow_notifications", + * "context": + * { + * "start_hour": 12 + * } * } * ``` + * * @see HyperskillAnalyticEvent */ -object NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent : HyperskillAnalyticEvent( +class NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent( + private val selectedDailyStudyRemindersStartHour: Int +) : HyperskillAnalyticEvent( route = HyperskillAnalyticRoute.Onboarding.Notifications, action = HyperskillAnalyticAction.CLICK, part = HyperskillAnalyticPart.MAIN, target = HyperskillAnalyticTarget.ALLOW_NOTIFICATIONS -) \ No newline at end of file +) { + override val params: Map + get() = super.params + + mapOf( + PARAM_CONTEXT to mapOf( + NotificationsOnboardingAnalyticParams.PARAM_START_HOUR to selectedDailyStudyRemindersStartHour + ) + ) +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent.kt new file mode 100644 index 0000000000..c806215ac0 --- /dev/null +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent.kt @@ -0,0 +1,43 @@ +package org.hyperskill.app.notifications_onboarding.domain.analytic + +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticAction +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticEvent +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticPart +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticRoute +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTarget + +/** + * Represents click on the daily study reminds formatted time button analytic event. + * + * JSON payload: + * ``` + * { + * "route": "/onboarding/notifications", + * "action": "click", + * "part": "main", + * "target": "daily_study_reminds_time", + * "context": + * { + * "start_hour": 12 + * } + * } + * ``` + * + * @see HyperskillAnalyticEvent + */ +class NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent( + private val currentDailyStudyRemindersStartHour: Int +) : HyperskillAnalyticEvent( + route = HyperskillAnalyticRoute.Onboarding.Notifications, + action = HyperskillAnalyticAction.CLICK, + part = HyperskillAnalyticPart.MAIN, + target = HyperskillAnalyticTarget.DAILY_STUDY_REMINDS_TIME +) { + override val params: Map + get() = super.params + + mapOf( + PARAM_CONTEXT to mapOf( + NotificationsOnboardingAnalyticParams.PARAM_START_HOUR to currentDailyStudyRemindersStartHour + ) + ) +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent.kt index 82df3af657..477dda087f 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent.kt @@ -18,6 +18,7 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTar * "target": "remind_me_later" * } * ``` + * * @see HyperskillAnalyticEvent */ object NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent : HyperskillAnalyticEvent( diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage.kt new file mode 100644 index 0000000000..d67bca1e64 --- /dev/null +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage.kt @@ -0,0 +1,30 @@ +package org.hyperskill.app.notifications_onboarding.domain.analytic + +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticAction +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticEvent +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticPart +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticRoute +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTarget + +/** + * Represents a hidden analytic event of the daily study reminders hour interval picker modal. + * + * JSON payload: + * ``` + * { + * "route": "/onboarding/notifications", + * "action": "hidden", + * "part": "daily_study_reminders_hour_interval_picker_modal", + * "target": "close" + * } + * ``` + * + * @see HyperskillAnalyticEvent + */ +object NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage : + HyperskillAnalyticEvent( + route = HyperskillAnalyticRoute.Onboarding.Notifications, + action = HyperskillAnalyticAction.HIDDEN, + part = HyperskillAnalyticPart.DAILY_STUDY_REMINDERS_HOUR_INTERVAL_PICKER_MODAL, + target = HyperskillAnalyticTarget.CLOSE + ) \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage.kt new file mode 100644 index 0000000000..41af102cba --- /dev/null +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage.kt @@ -0,0 +1,30 @@ +package org.hyperskill.app.notifications_onboarding.domain.analytic + +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticAction +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticEvent +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticPart +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticRoute +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTarget + +/** + * Represents a shown analytic event of the daily study reminders hour interval picker modal. + * + * JSON payload: + * ``` + * { + * "route": "/onboarding/notifications", + * "action": "shown", + * "part": "modal", + * "target": "daily_study_reminders_hour_interval_picker_modal" + * } + * ``` + * + * @see HyperskillAnalyticEvent + */ +object NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage : + HyperskillAnalyticEvent( + route = HyperskillAnalyticRoute.Onboarding.Notifications, + action = HyperskillAnalyticAction.SHOWN, + part = HyperskillAnalyticPart.MODAL, + target = HyperskillAnalyticTarget.DAILY_STUDY_REMINDERS_HOUR_INTERVAL_PICKER_MODAL + ) \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingViewedHyperskillAnalyticsEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingViewedHyperskillAnalyticsEvent.kt index a46ede32a1..0dfae025a5 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingViewedHyperskillAnalyticsEvent.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingViewedHyperskillAnalyticsEvent.kt @@ -14,6 +14,7 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticRou * "action": "view" * } * ``` + * * @see HyperskillAnalyticEvent */ object NotificationsOnboardingViewedHyperskillAnalyticsEvent : diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt index 9f7e7f5455..01f7187d45 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt @@ -11,6 +11,7 @@ internal class NotificationsOnboardingComponentImpl( ) : NotificationsOnboardingComponent { override val notificationsOnboardingFeature: Feature get() = NotificationsOnboardingFeatureBuilder.build( + notificationInteractor = appGraph.buildNotificationComponent().notificationInteractor, analyticInteractor = appGraph.analyticComponent.analyticInteractor, logger = appGraph.loggerComponent.logger, buildVariant = appGraph.commonComponent.buildKonfig.buildVariant diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt index ef3b35bf58..0f58952380 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt @@ -5,7 +5,9 @@ import org.hyperskill.app.analytic.domain.interactor.AnalyticInteractor import org.hyperskill.app.core.domain.BuildVariant import org.hyperskill.app.core.presentation.ActionDispatcherOptions import org.hyperskill.app.logging.presentation.wrapWithLogger +import org.hyperskill.app.notification.local.domain.interactor.NotificationInteractor import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingActionDispatcher +import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Action import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Message import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.State @@ -18,6 +20,7 @@ internal object NotificationsOnboardingFeatureBuilder { private const val LOG_TAG = "NotificationsOnboardingFeature" fun build( + notificationInteractor: NotificationInteractor, analyticInteractor: AnalyticInteractor, buildVariant: BuildVariant, logger: Logger @@ -25,8 +28,12 @@ internal object NotificationsOnboardingFeatureBuilder { val reducer = NotificationsOnboardingReducer().wrapWithLogger(buildVariant, logger, LOG_TAG) val actionDispatcher = NotificationsOnboardingActionDispatcher( config = ActionDispatcherOptions(), + notificationInteractor = notificationInteractor, analyticInteractor = analyticInteractor ) - return ReduxFeature(State, reducer).wrapWithActionDispatcher(actionDispatcher) + return ReduxFeature( + NotificationsOnboardingFeature.initialState(), + reducer + ).wrapWithActionDispatcher(actionDispatcher) } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingActionDispatcher.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingActionDispatcher.kt index a381789827..04cd2768c0 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingActionDispatcher.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingActionDispatcher.kt @@ -2,6 +2,7 @@ package org.hyperskill.app.notifications_onboarding.presentation import org.hyperskill.app.analytic.domain.interactor.AnalyticInteractor import org.hyperskill.app.core.presentation.ActionDispatcherOptions +import org.hyperskill.app.notification.local.domain.interactor.NotificationInteractor import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Action import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.InternalAction import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Message @@ -9,13 +10,19 @@ import ru.nobird.app.presentation.redux.dispatcher.CoroutineActionDispatcher internal class NotificationsOnboardingActionDispatcher( config: ActionDispatcherOptions, + private val notificationInteractor: NotificationInteractor, private val analyticInteractor: AnalyticInteractor ) : CoroutineActionDispatcher(config.createConfig()) { override suspend fun doSuspendableAction(action: Action) { when (action) { - is InternalAction.LogAnalyticEvent -> + is InternalAction.SaveDailyStudyRemindersIntervalStartHour -> { + notificationInteractor.setDailyStudyRemindersEnabled(enabled = true) + notificationInteractor.setDailyStudyReminderNotificationTime(notificationHour = action.startHour) + } + is InternalAction.LogAnalyticEvent -> { analyticInteractor.logEvent(action.analyticEvent) + } else -> { // no op } diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt index 769e1dcf86..de8fd9f51a 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt @@ -1,25 +1,43 @@ package org.hyperskill.app.notifications_onboarding.presentation import org.hyperskill.app.analytic.domain.model.AnalyticEvent +import org.hyperskill.app.notification.local.cache.NotificationCacheKeyValues object NotificationsOnboardingFeature { - object State + data class State(val dailyStudyRemindersStartHour: Int) + + internal fun initialState() = + State(dailyStudyRemindersStartHour = NotificationCacheKeyValues.DAILY_STUDY_REMINDERS_START_HOUR_ONBOARDING) sealed interface Message { object AllowNotificationClicked : Message object RemindMeLaterClicked : Message data class NotificationPermissionRequestResult(val isPermissionGranted: Boolean) : Message + + object DailyStudyRemindsIntervalHourClicked : Message + data class DailyStudyRemindsIntervalStartHourSelected(val startHour: Int) : Message + + /** + * Analytic + */ object ViewedEventMessage : Message + + object DailyStudyRemindersIntervalStartHourPickerModalShownEventMessage : Message + object DailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage : Message } sealed interface Action { sealed interface ViewAction : Action { object RequestNotificationPermission : ViewAction object CompleteNotificationOnboarding : ViewAction + + object ShowDailyStudyRemindersIntervalStartHourPickerModal : ViewAction } } internal sealed interface InternalAction : Action { + data class SaveDailyStudyRemindersIntervalStartHour(val startHour: Int) : InternalAction + data class LogAnalyticEvent(val analyticEvent: AnalyticEvent) : InternalAction } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt index a6e057cca2..5a6582e6b9 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt @@ -4,8 +4,11 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticRou import org.hyperskill.app.notification.local.domain.analytic.NotificationSystemNoticeHiddenHyperskillAnalyticEvent import org.hyperskill.app.notification.local.domain.analytic.NotificationSystemNoticeShownHyperskillAnalyticEvent import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent +import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingCompletionAppsFlyerAnalyticEvent +import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage +import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingViewedHyperskillAnalyticsEvent import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Action import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.InternalAction @@ -15,21 +18,27 @@ import ru.nobird.app.presentation.redux.reducer.StateReducer internal class NotificationsOnboardingReducer : StateReducer { override fun reduce(state: State, message: Message): Pair> = - state to when (message) { - Message.AllowNotificationClicked -> - setOf( + when (message) { + Message.AllowNotificationClicked -> { + state to setOf( InternalAction.LogAnalyticEvent( - NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent + NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent( + selectedDailyStudyRemindersStartHour = state.dailyStudyRemindersStartHour + ) ), InternalAction.LogAnalyticEvent( NotificationSystemNoticeShownHyperskillAnalyticEvent( HyperskillAnalyticRoute.Onboarding.Notifications ) ), + InternalAction.SaveDailyStudyRemindersIntervalStartHour( + startHour = state.dailyStudyRemindersStartHour + ), Action.ViewAction.RequestNotificationPermission ) - is Message.NotificationPermissionRequestResult -> - setOf( + } + is Message.NotificationPermissionRequestResult -> { + state to setOf( InternalAction.LogAnalyticEvent( NotificationSystemNoticeHiddenHyperskillAnalyticEvent( route = HyperskillAnalyticRoute.Onboarding.Notifications, @@ -43,8 +52,9 @@ internal class NotificationsOnboardingReducer : StateReducer - setOf( + } + Message.RemindMeLaterClicked -> { + state to setOf( InternalAction.LogAnalyticEvent( NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent ), @@ -53,7 +63,36 @@ internal class NotificationsOnboardingReducer : StateReducer - setOf(InternalAction.LogAnalyticEvent(NotificationsOnboardingViewedHyperskillAnalyticsEvent)) + } + Message.DailyStudyRemindsIntervalHourClicked -> { + state to setOf( + InternalAction.LogAnalyticEvent( + NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent( + currentDailyStudyRemindersStartHour = state.dailyStudyRemindersStartHour + ) + ), + Action.ViewAction.ShowDailyStudyRemindersIntervalStartHourPickerModal + ) + } + is Message.DailyStudyRemindsIntervalStartHourSelected -> { + state.copy(dailyStudyRemindersStartHour = message.startHour) to emptySet() + } + Message.DailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage -> { + state to setOf( + InternalAction.LogAnalyticEvent( + NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage + ) + ) + } + Message.DailyStudyRemindersIntervalStartHourPickerModalShownEventMessage -> { + state to setOf( + InternalAction.LogAnalyticEvent( + NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage + ) + ) + } + Message.ViewedEventMessage -> { + state to setOf(InternalAction.LogAnalyticEvent(NotificationsOnboardingViewedHyperskillAnalyticsEvent)) + } } } \ No newline at end of file From 98345b5afd98a3bb6319ccc2a3cb334474720b27 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Wed, 13 Dec 2023 17:50:22 +0700 Subject: [PATCH 3/7] Add string resources --- .../ui/NotificationsOnboardingScreen.kt | 6 +++--- .../Sources/Models/Constants/Strings.swift | 2 +- .../NotificationsOnboardingViewModel.swift | 4 ++-- .../domain/model/hyperskill/HyperskillAnalyticTarget.kt | 2 +- ...onsOnboardingClickedNotNowHyperskillAnalyticsEvent.kt} | 6 +++--- .../presentation/NotificationsOnboardingFeature.kt | 4 ++-- .../presentation/NotificationsOnboardingReducer.kt | 8 ++++---- shared/src/commonMain/resources/MR/base/strings.xml | 7 ++++++- 8 files changed, 22 insertions(+), 17 deletions(-) rename shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/{NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent.kt => NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent.kt} (82%) diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/ui/NotificationsOnboardingScreen.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/ui/NotificationsOnboardingScreen.kt index 04cc52d3b2..bcd31da02e 100644 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/ui/NotificationsOnboardingScreen.kt +++ b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/ui/NotificationsOnboardingScreen.kt @@ -52,10 +52,10 @@ fun NotificationsOnboardingScreen( onNewMessage: (NotificationsOnboardingFeature.Message) -> Unit ) { val onAllowNotificationsClick by rememberUpdatedState { - onNewMessage(NotificationsOnboardingFeature.Message.AllowNotificationClicked) + onNewMessage(NotificationsOnboardingFeature.Message.AllowNotificationsClicked) } val onRemindMeLaterClick by rememberUpdatedState { - onNewMessage(NotificationsOnboardingFeature.Message.RemindMeLaterClicked) + onNewMessage(NotificationsOnboardingFeature.Message.NotNowClicked) } Column( modifier = Modifier @@ -124,7 +124,7 @@ fun NotificationsOnboardingButtons( modifier = Modifier.fillMaxWidth() ) { Text( - text = stringResource(id = R.string.notifications_onboarding_button_later) + text = stringResource(id = R.string.notifications_onboarding_button_not_now) ) } } diff --git a/iosHyperskillApp/iosHyperskillApp/Sources/Models/Constants/Strings.swift b/iosHyperskillApp/iosHyperskillApp/Sources/Models/Constants/Strings.swift index 9d25387dc3..9eeb1cadf0 100644 --- a/iosHyperskillApp/iosHyperskillApp/Sources/Models/Constants/Strings.swift +++ b/iosHyperskillApp/iosHyperskillApp/Sources/Models/Constants/Strings.swift @@ -472,7 +472,7 @@ enum Strings { static let subtitle = sharedStrings.notifications_onboarding_description.localized() static let buttonPrimary = sharedStrings.notifications_onboarding_button_allow.localized() - static let buttonSecondary = sharedStrings.notifications_onboarding_button_later.localized() + static let buttonSecondary = sharedStrings.notifications_onboarding_button_not_now.localized() } // MARK: - FirstProblemOnboarding - diff --git a/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/NotificationsOnboardingViewModel.swift b/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/NotificationsOnboardingViewModel.swift index a9f98ca8c8..672153d71f 100644 --- a/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/NotificationsOnboardingViewModel.swift +++ b/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/NotificationsOnboardingViewModel.swift @@ -26,11 +26,11 @@ final class NotificationsOnboardingViewModel: FeatureViewModel< } func doPrimaryAction() { - onNewMessage(NotificationsOnboardingFeatureMessageAllowNotificationClicked()) + onNewMessage(NotificationsOnboardingFeatureMessageAllowNotificationsClicked()) } func doSecondaryAction() { - onNewMessage(NotificationsOnboardingFeatureMessageRemindMeLaterClicked()) + onNewMessage(NotificationsOnboardingFeatureMessageNotNowClicked()) } func doRequestNotificationPermission() { diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt index 010b7be444..3524c3fa4b 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt @@ -95,7 +95,7 @@ enum class HyperskillAnalyticTarget(val targetName: String) { ALLOW_NOTIFICATIONS("allow_notifications"), KEEP_LEARNING("keep_learning"), START_LEARNING("start_learning"), - REMIND_ME_LATER("remind_me_later"), + NOT_NOW("not_now"), FULL_SCREEN_CODE_EDITOR("full_screen_code_editor"), CODE_INPUT_ACCESSORY_BUTTON("code_input_accessory_button"), SHARE_YOUR_STREAK("share_your_streak"), diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent.kt similarity index 82% rename from shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent.kt rename to shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent.kt index 477dda087f..c72b82aba3 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent.kt @@ -15,15 +15,15 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTar * "route": "/onboarding/notifications", * "action": "click", * "part": "main", - * "target": "remind_me_later" + * "target": "not_now" * } * ``` * * @see HyperskillAnalyticEvent */ -object NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent : HyperskillAnalyticEvent( +object NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent : HyperskillAnalyticEvent( route = HyperskillAnalyticRoute.Onboarding.Notifications, action = HyperskillAnalyticAction.CLICK, part = HyperskillAnalyticPart.MAIN, - target = HyperskillAnalyticTarget.REMIND_ME_LATER + target = HyperskillAnalyticTarget.NOT_NOW ) \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt index de8fd9f51a..934c710404 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt @@ -10,8 +10,8 @@ object NotificationsOnboardingFeature { State(dailyStudyRemindersStartHour = NotificationCacheKeyValues.DAILY_STUDY_REMINDERS_START_HOUR_ONBOARDING) sealed interface Message { - object AllowNotificationClicked : Message - object RemindMeLaterClicked : Message + object AllowNotificationsClicked : Message + object NotNowClicked : Message data class NotificationPermissionRequestResult(val isPermissionGranted: Boolean) : Message object DailyStudyRemindsIntervalHourClicked : Message diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt index 5a6582e6b9..641e130438 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt @@ -5,7 +5,7 @@ import org.hyperskill.app.notification.local.domain.analytic.NotificationSystemN import org.hyperskill.app.notification.local.domain.analytic.NotificationSystemNoticeShownHyperskillAnalyticEvent import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent -import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent +import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingCompletionAppsFlyerAnalyticEvent import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage @@ -19,7 +19,7 @@ import ru.nobird.app.presentation.redux.reducer.StateReducer internal class NotificationsOnboardingReducer : StateReducer { override fun reduce(state: State, message: Message): Pair> = when (message) { - Message.AllowNotificationClicked -> { + Message.AllowNotificationsClicked -> { state to setOf( InternalAction.LogAnalyticEvent( NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent( @@ -53,10 +53,10 @@ internal class NotificationsOnboardingReducer : StateReducer { + Message.NotNowClicked -> { state to setOf( InternalAction.LogAnalyticEvent( - NotificationsOnboardingClickedRemindMeLaterHyperskillAnalyticsEvent + NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent ), InternalAction.LogAnalyticEvent( NotificationsOnboardingCompletionAppsFlyerAnalyticEvent(isSuccess = false) diff --git a/shared/src/commonMain/resources/MR/base/strings.xml b/shared/src/commonMain/resources/MR/base/strings.xml index cf111690ca..b26936774a 100644 --- a/shared/src/commonMain/resources/MR/base/strings.xml +++ b/shared/src/commonMain/resources/MR/base/strings.xml @@ -396,12 +396,17 @@ Sign up + Track your progress + Choose a time for your daily practice and we\'ll remind you to + stay on track + Enable notifications to keep your streak alive and stay consistently on top of your learning + Set time Allow notifications - Remind me later + Not now Let\'s keep going! From 9e434f4a958e148d047d39da99de2eae4d7cdf50 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Wed, 13 Dec 2023 18:02:09 +0700 Subject: [PATCH 4/7] Add ViewState --- .../NotificationsOnboardingViewModel.swift | 6 ++--- .../NotificationsOnboardingViewModel.kt | 6 ++--- .../NotificationsOnboardingComponent.kt | 4 +-- .../NotificationsOnboardingComponentImpl.kt | 4 +-- .../NotificationsOnboardingFeatureBuilder.kt | 14 +++++++---- .../NotificationsOnboardingFeature.kt | 7 +++++- .../NotificationsOnboardingViewStateMapper.kt | 25 +++++++++++++++++++ 7 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt diff --git a/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/NotificationsOnboardingViewModel.swift b/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/NotificationsOnboardingViewModel.swift index 672153d71f..486bda8473 100644 --- a/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/NotificationsOnboardingViewModel.swift +++ b/iosHyperskillApp/iosHyperskillApp/Sources/Modules/NotificationsOnboarding/NotificationsOnboardingViewModel.swift @@ -2,7 +2,7 @@ import Foundation import shared final class NotificationsOnboardingViewModel: FeatureViewModel< - NotificationsOnboardingFeature.State, + NotificationsOnboardingFeature.ViewState, NotificationsOnboardingFeatureMessage, NotificationsOnboardingFeatureActionViewAction > { @@ -19,8 +19,8 @@ final class NotificationsOnboardingViewModel: FeatureViewModel< } override func shouldNotifyStateDidChange( - oldState: NotificationsOnboardingFeature.State, - newState: NotificationsOnboardingFeature.State + oldState: NotificationsOnboardingFeature.ViewState, + newState: NotificationsOnboardingFeature.ViewState ) -> Bool { false } diff --git a/shared/src/androidMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingViewModel.kt b/shared/src/androidMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingViewModel.kt index 28c7c8f36b..6d7982494b 100644 --- a/shared/src/androidMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingViewModel.kt +++ b/shared/src/androidMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingViewModel.kt @@ -4,8 +4,8 @@ import org.hyperskill.app.core.flowredux.presentation.FlowView import org.hyperskill.app.core.flowredux.presentation.ReduxFlowViewModel import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Action.ViewAction import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Message -import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.State +import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.ViewState class NotificationsOnboardingViewModel( - viewContainer: FlowView -) : ReduxFlowViewModel(viewContainer) \ No newline at end of file + viewContainer: FlowView +) : ReduxFlowViewModel(viewContainer) \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponent.kt index 7d8afff9ad..04365756f7 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponent.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponent.kt @@ -2,9 +2,9 @@ package org.hyperskill.app.notifications_onboarding.injection import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Action import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Message -import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.State +import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.ViewState import ru.nobird.app.presentation.redux.feature.Feature interface NotificationsOnboardingComponent { - val notificationsOnboardingFeature: Feature + val notificationsOnboardingFeature: Feature } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt index 01f7187d45..d5185a5d2d 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingComponentImpl.kt @@ -3,13 +3,13 @@ package org.hyperskill.app.notifications_onboarding.injection import org.hyperskill.app.core.injection.AppGraph import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Action import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Message -import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.State +import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.ViewState import ru.nobird.app.presentation.redux.feature.Feature internal class NotificationsOnboardingComponentImpl( private val appGraph: AppGraph ) : NotificationsOnboardingComponent { - override val notificationsOnboardingFeature: Feature + override val notificationsOnboardingFeature: Feature get() = NotificationsOnboardingFeatureBuilder.build( notificationInteractor = appGraph.buildNotificationComponent().notificationInteractor, analyticInteractor = appGraph.analyticComponent.analyticInteractor, diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt index 0f58952380..a7c044675d 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/injection/NotificationsOnboardingFeatureBuilder.kt @@ -4,14 +4,16 @@ import co.touchlab.kermit.Logger import org.hyperskill.app.analytic.domain.interactor.AnalyticInteractor import org.hyperskill.app.core.domain.BuildVariant import org.hyperskill.app.core.presentation.ActionDispatcherOptions +import org.hyperskill.app.core.presentation.transformState import org.hyperskill.app.logging.presentation.wrapWithLogger import org.hyperskill.app.notification.local.domain.interactor.NotificationInteractor import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingActionDispatcher import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Action import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Message -import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.State +import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.ViewState import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingReducer +import org.hyperskill.app.notifications_onboarding.view.mapper.NotificationsOnboardingViewStateMapper import ru.nobird.app.presentation.redux.dispatcher.wrapWithActionDispatcher import ru.nobird.app.presentation.redux.feature.Feature import ru.nobird.app.presentation.redux.feature.ReduxFeature @@ -24,7 +26,7 @@ internal object NotificationsOnboardingFeatureBuilder { analyticInteractor: AnalyticInteractor, buildVariant: BuildVariant, logger: Logger - ): Feature { + ): Feature { val reducer = NotificationsOnboardingReducer().wrapWithLogger(buildVariant, logger, LOG_TAG) val actionDispatcher = NotificationsOnboardingActionDispatcher( config = ActionDispatcherOptions(), @@ -32,8 +34,10 @@ internal object NotificationsOnboardingFeatureBuilder { analyticInteractor = analyticInteractor ) return ReduxFeature( - NotificationsOnboardingFeature.initialState(), - reducer - ).wrapWithActionDispatcher(actionDispatcher) + initialState = NotificationsOnboardingFeature.initialState(), + reducer = reducer + ) + .wrapWithActionDispatcher(actionDispatcher) + .transformState(NotificationsOnboardingViewStateMapper::mapState) } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt index 934c710404..5f2ff7e339 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt @@ -4,7 +4,12 @@ import org.hyperskill.app.analytic.domain.model.AnalyticEvent import org.hyperskill.app.notification.local.cache.NotificationCacheKeyValues object NotificationsOnboardingFeature { - data class State(val dailyStudyRemindersStartHour: Int) + internal data class State(val dailyStudyRemindersStartHour: Int) + + data class ViewState( + val dailyStudyRemindersStartHour: Int, + val formattedDailyStudyRemindersInterval: String + ) internal fun initialState() = State(dailyStudyRemindersStartHour = NotificationCacheKeyValues.DAILY_STUDY_REMINDERS_START_HOUR_ONBOARDING) diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt new file mode 100644 index 0000000000..53ee366b35 --- /dev/null +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt @@ -0,0 +1,25 @@ +package org.hyperskill.app.notifications_onboarding.view.mapper + +import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature + +internal object NotificationsOnboardingViewStateMapper { + fun mapState(state: NotificationsOnboardingFeature.State): NotificationsOnboardingFeature.ViewState = + NotificationsOnboardingFeature.ViewState( + dailyStudyRemindersStartHour = state.dailyStudyRemindersStartHour, + formattedDailyStudyRemindersInterval = formatDailyStudyRemindersInterval( + startHour = state.dailyStudyRemindersStartHour + ) + ) + + private fun formatDailyStudyRemindersInterval(startHour: Int): String { + val endHour = startHour + 1 + return buildString { + append(if (startHour < 10) "0" else "") + append(startHour) + append(":00 - ") + append(if (endHour < 10) "0" else "") + append(endHour) + append(":00") + } + } +} \ No newline at end of file From 119e24fcaa0a15cf37c59f2c48990d258571d57d Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Wed, 13 Dec 2023 21:45:06 +0700 Subject: [PATCH 5/7] Update show modal & add missing analytic --- .../NotificationsOnboardingFragment.kt | 4 +- .../hyperskill/HyperskillAnalyticTarget.kt | 3 +- ...owNotificationsHyperskillAnalyticEvent.kt} | 2 +- ...ndsIntervalHourHyperskillAnalyticEvent.kt} | 2 +- ...ngClickedNotNowHyperskillAnalyticEvent.kt} | 2 +- ...alClickedConfirmHyperskillAnalyticEvent.kt | 39 ++++++++++++++++++ ...ckerModalHiddenHyperskillAnalyticEvent.kt} | 2 +- ...ickerModalShownHyperskillAnalyticEvent.kt} | 2 +- ...nboardingViewedHyperskillAnalyticEvent.kt} | 2 +- .../NotificationsOnboardingFeature.kt | 4 +- .../NotificationsOnboardingReducer.kt | 40 ++++++++++++------- .../NotificationsOnboardingViewStateMapper.kt | 2 +- 12 files changed, 80 insertions(+), 24 deletions(-) rename shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/{NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent.kt => NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticEvent.kt} (98%) rename shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/{NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent.kt => NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticEvent.kt} (98%) rename shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/{NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent.kt => NotificationsOnboardingClickedNotNowHyperskillAnalyticEvent.kt} (90%) create mode 100644 shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent.kt rename shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/{NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage.kt => NotificationsOnboardingDailyStudyRemindersIntervalPickerModalHiddenHyperskillAnalyticEvent.kt} (91%) rename shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/{NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage.kt => NotificationsOnboardingDailyStudyRemindersIntervalPickerModalShownHyperskillAnalyticEvent.kt} (91%) rename shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/{NotificationsOnboardingViewedHyperskillAnalyticsEvent.kt => NotificationsOnboardingViewedHyperskillAnalyticEvent.kt} (90%) diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/fragment/NotificationsOnboardingFragment.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/fragment/NotificationsOnboardingFragment.kt index d097db3b7e..d88284a1c9 100644 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/fragment/NotificationsOnboardingFragment.kt +++ b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/notification_onboarding/fragment/NotificationsOnboardingFragment.kt @@ -108,7 +108,9 @@ class NotificationsOnboardingFragment : Fragment() { ViewAction.RequestNotificationPermission -> { notificationPermissionDelegate?.requestNotificationPermission() } - ViewAction.ShowDailyStudyRemindersIntervalStartHourPickerModal -> TODO() + is ViewAction.ShowDailyStudyRemindersIntervalStartHourPickerModal -> { + // TODO: ALTAPPS-1071 show modal + } } } diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt index 3524c3fa4b..2b2ff22a92 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/analytic/domain/model/hyperskill/HyperskillAnalyticTarget.kt @@ -106,5 +106,6 @@ enum class HyperskillAnalyticTarget(val targetName: String) { DAY("day"), WEEK("week"), LEADERBOARD_ITEM("leaderboard_item"), - DAILY_STUDY_REMINDERS_HOUR_INTERVAL_PICKER_MODAL("daily_study_reminders_hour_interval_picker_modal") + DAILY_STUDY_REMINDERS_HOUR_INTERVAL_PICKER_MODAL("daily_study_reminders_hour_interval_picker_modal"), + CONFIRM("confirm") } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticEvent.kt similarity index 98% rename from shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent.kt rename to shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticEvent.kt index 93650a5548..e145aeaa3a 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticEvent.kt @@ -25,7 +25,7 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTar * * @see HyperskillAnalyticEvent */ -class NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent( +class NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticEvent( private val selectedDailyStudyRemindersStartHour: Int ) : HyperskillAnalyticEvent( route = HyperskillAnalyticRoute.Onboarding.Notifications, diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticEvent.kt similarity index 98% rename from shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent.kt rename to shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticEvent.kt index c806215ac0..b9e441ffd1 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticEvent.kt @@ -25,7 +25,7 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTar * * @see HyperskillAnalyticEvent */ -class NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent( +class NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticEvent( private val currentDailyStudyRemindersStartHour: Int ) : HyperskillAnalyticEvent( route = HyperskillAnalyticRoute.Onboarding.Notifications, diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedNotNowHyperskillAnalyticEvent.kt similarity index 90% rename from shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent.kt rename to shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedNotNowHyperskillAnalyticEvent.kt index c72b82aba3..1292694ef7 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingClickedNotNowHyperskillAnalyticEvent.kt @@ -21,7 +21,7 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTar * * @see HyperskillAnalyticEvent */ -object NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent : HyperskillAnalyticEvent( +object NotificationsOnboardingClickedNotNowHyperskillAnalyticEvent : HyperskillAnalyticEvent( route = HyperskillAnalyticRoute.Onboarding.Notifications, action = HyperskillAnalyticAction.CLICK, part = HyperskillAnalyticPart.MAIN, diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent.kt new file mode 100644 index 0000000000..5514bd1fe3 --- /dev/null +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent.kt @@ -0,0 +1,39 @@ +package org.hyperskill.app.notifications_onboarding.domain.analytic + +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticAction +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticEvent +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticPart +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticRoute +import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTarget + +/** + * Represents a click on the "Confirm" button of the daily study reminders hour interval picker modal analytic event. + * + * JSON payload: + * ``` + * { + * "route": "/onboarding/notifications", + * "action": "click", + * "part": "daily_study_reminders_hour_interval_picker_modal", + * "target": "confirm" + * } + * ``` + * + * @see HyperskillAnalyticEvent + */ +class NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent( + private val selectedDailyStudyRemindersStartHour: Int +) : HyperskillAnalyticEvent( + route = HyperskillAnalyticRoute.Onboarding.Notifications, + action = HyperskillAnalyticAction.CLICK, + part = HyperskillAnalyticPart.DAILY_STUDY_REMINDERS_HOUR_INTERVAL_PICKER_MODAL, + target = HyperskillAnalyticTarget.CONFIRM +) { + override val params: Map + get() = super.params + + mapOf( + PARAM_CONTEXT to mapOf( + NotificationsOnboardingAnalyticParams.PARAM_START_HOUR to selectedDailyStudyRemindersStartHour + ) + ) +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalHiddenHyperskillAnalyticEvent.kt similarity index 91% rename from shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage.kt rename to shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalHiddenHyperskillAnalyticEvent.kt index d67bca1e64..91e82b5c6a 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalHiddenHyperskillAnalyticEvent.kt @@ -21,7 +21,7 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTar * * @see HyperskillAnalyticEvent */ -object NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage : +object NotificationsOnboardingDailyStudyRemindersIntervalPickerModalHiddenHyperskillAnalyticEvent : HyperskillAnalyticEvent( route = HyperskillAnalyticRoute.Onboarding.Notifications, action = HyperskillAnalyticAction.HIDDEN, diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalShownHyperskillAnalyticEvent.kt similarity index 91% rename from shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage.kt rename to shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalShownHyperskillAnalyticEvent.kt index 41af102cba..deaa44a0d8 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalShownHyperskillAnalyticEvent.kt @@ -21,7 +21,7 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTar * * @see HyperskillAnalyticEvent */ -object NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage : +object NotificationsOnboardingDailyStudyRemindersIntervalPickerModalShownHyperskillAnalyticEvent : HyperskillAnalyticEvent( route = HyperskillAnalyticRoute.Onboarding.Notifications, action = HyperskillAnalyticAction.SHOWN, diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingViewedHyperskillAnalyticsEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingViewedHyperskillAnalyticEvent.kt similarity index 90% rename from shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingViewedHyperskillAnalyticsEvent.kt rename to shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingViewedHyperskillAnalyticEvent.kt index 0dfae025a5..bd947b8e9f 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingViewedHyperskillAnalyticsEvent.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingViewedHyperskillAnalyticEvent.kt @@ -17,5 +17,5 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticRou * * @see HyperskillAnalyticEvent */ -object NotificationsOnboardingViewedHyperskillAnalyticsEvent : +object NotificationsOnboardingViewedHyperskillAnalyticEvent : HyperskillAnalyticEvent(HyperskillAnalyticRoute.Onboarding.Notifications, HyperskillAnalyticAction.VIEW) \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt index 5f2ff7e339..9e10436377 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt @@ -36,7 +36,9 @@ object NotificationsOnboardingFeature { object RequestNotificationPermission : ViewAction object CompleteNotificationOnboarding : ViewAction - object ShowDailyStudyRemindersIntervalStartHourPickerModal : ViewAction + data class ShowDailyStudyRemindersIntervalStartHourPickerModal( + val intervals: List + ) : ViewAction } } diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt index 641e130438..3dd1bc988f 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt @@ -3,17 +3,19 @@ package org.hyperskill.app.notifications_onboarding.presentation import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticRoute import org.hyperskill.app.notification.local.domain.analytic.NotificationSystemNoticeHiddenHyperskillAnalyticEvent import org.hyperskill.app.notification.local.domain.analytic.NotificationSystemNoticeShownHyperskillAnalyticEvent -import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent -import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent -import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent +import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticEvent +import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticEvent +import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingClickedNotNowHyperskillAnalyticEvent import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingCompletionAppsFlyerAnalyticEvent -import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage -import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage -import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingViewedHyperskillAnalyticsEvent +import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent +import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingDailyStudyRemindersIntervalPickerModalHiddenHyperskillAnalyticEvent +import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingDailyStudyRemindersIntervalPickerModalShownHyperskillAnalyticEvent +import org.hyperskill.app.notifications_onboarding.domain.analytic.NotificationsOnboardingViewedHyperskillAnalyticEvent import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Action import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.InternalAction import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.Message import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnboardingFeature.State +import org.hyperskill.app.notifications_onboarding.view.mapper.NotificationsOnboardingViewStateMapper import ru.nobird.app.presentation.redux.reducer.StateReducer internal class NotificationsOnboardingReducer : StateReducer { @@ -22,7 +24,7 @@ internal class NotificationsOnboardingReducer : StateReducer { state to setOf( InternalAction.LogAnalyticEvent( - NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticsEvent( + NotificationsOnboardingClickedAllowNotificationsHyperskillAnalyticEvent( selectedDailyStudyRemindersStartHour = state.dailyStudyRemindersStartHour ) ), @@ -56,7 +58,7 @@ internal class NotificationsOnboardingReducer : StateReducer { state to setOf( InternalAction.LogAnalyticEvent( - NotificationsOnboardingClickedNotNowHyperskillAnalyticsEvent + NotificationsOnboardingClickedNotNowHyperskillAnalyticEvent ), InternalAction.LogAnalyticEvent( NotificationsOnboardingCompletionAppsFlyerAnalyticEvent(isSuccess = false) @@ -67,32 +69,42 @@ internal class NotificationsOnboardingReducer : StateReducer { state to setOf( InternalAction.LogAnalyticEvent( - NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticsEvent( + NotificationsOnboardingClickedDailyStudyRemindsIntervalHourHyperskillAnalyticEvent( currentDailyStudyRemindersStartHour = state.dailyStudyRemindersStartHour ) ), - Action.ViewAction.ShowDailyStudyRemindersIntervalStartHourPickerModal + Action.ViewAction.ShowDailyStudyRemindersIntervalStartHourPickerModal( + intervals = (0..23).map { hour -> + NotificationsOnboardingViewStateMapper.formatDailyStudyRemindersInterval(startHour = hour) + } + ) ) } is Message.DailyStudyRemindsIntervalStartHourSelected -> { - state.copy(dailyStudyRemindersStartHour = message.startHour) to emptySet() + val analyticEvent = + NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent( + selectedDailyStudyRemindersStartHour = message.startHour + ) + state.copy( + dailyStudyRemindersStartHour = message.startHour + ) to setOf(InternalAction.LogAnalyticEvent(analyticEvent)) } Message.DailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage -> { state to setOf( InternalAction.LogAnalyticEvent( - NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalHiddenEventMessage + NotificationsOnboardingDailyStudyRemindersIntervalPickerModalHiddenHyperskillAnalyticEvent ) ) } Message.DailyStudyRemindersIntervalStartHourPickerModalShownEventMessage -> { state to setOf( InternalAction.LogAnalyticEvent( - NotificationsOnboardingDailyStudyRemindersIntervalStartHourPickerModalShownEventMessage + NotificationsOnboardingDailyStudyRemindersIntervalPickerModalShownHyperskillAnalyticEvent ) ) } Message.ViewedEventMessage -> { - state to setOf(InternalAction.LogAnalyticEvent(NotificationsOnboardingViewedHyperskillAnalyticsEvent)) + state to setOf(InternalAction.LogAnalyticEvent(NotificationsOnboardingViewedHyperskillAnalyticEvent)) } } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt index 53ee366b35..d25bc1013c 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt @@ -11,7 +11,7 @@ internal object NotificationsOnboardingViewStateMapper { ) ) - private fun formatDailyStudyRemindersInterval(startHour: Int): String { + fun formatDailyStudyRemindersInterval(startHour: Int): String { val endHour = startHour + 1 return buildString { append(if (startHour < 10) "0" else "") From 9086e31af11fa4a4112ddb4bb0a55665324d2aeb Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Fri, 15 Dec 2023 11:24:59 +0700 Subject: [PATCH 6/7] Delete dailyStudyRemindersStartHour from ViewState --- .../presentation/NotificationsOnboardingFeature.kt | 8 +++----- .../presentation/NotificationsOnboardingReducer.kt | 3 ++- .../view/mapper/NotificationsOnboardingViewStateMapper.kt | 1 - 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt index 9e10436377..7182d57197 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingFeature.kt @@ -6,10 +6,7 @@ import org.hyperskill.app.notification.local.cache.NotificationCacheKeyValues object NotificationsOnboardingFeature { internal data class State(val dailyStudyRemindersStartHour: Int) - data class ViewState( - val dailyStudyRemindersStartHour: Int, - val formattedDailyStudyRemindersInterval: String - ) + data class ViewState(val formattedDailyStudyRemindersInterval: String) internal fun initialState() = State(dailyStudyRemindersStartHour = NotificationCacheKeyValues.DAILY_STUDY_REMINDERS_START_HOUR_ONBOARDING) @@ -37,7 +34,8 @@ object NotificationsOnboardingFeature { object CompleteNotificationOnboarding : ViewAction data class ShowDailyStudyRemindersIntervalStartHourPickerModal( - val intervals: List + val intervals: List, + val dailyStudyRemindersStartHour: Int ) : ViewAction } } diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt index 3dd1bc988f..c4626525d4 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/presentation/NotificationsOnboardingReducer.kt @@ -76,7 +76,8 @@ internal class NotificationsOnboardingReducer : StateReducer NotificationsOnboardingViewStateMapper.formatDailyStudyRemindersInterval(startHour = hour) - } + }, + dailyStudyRemindersStartHour = state.dailyStudyRemindersStartHour ) ) } diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt index d25bc1013c..409a1bdea9 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/view/mapper/NotificationsOnboardingViewStateMapper.kt @@ -5,7 +5,6 @@ import org.hyperskill.app.notifications_onboarding.presentation.NotificationsOnb internal object NotificationsOnboardingViewStateMapper { fun mapState(state: NotificationsOnboardingFeature.State): NotificationsOnboardingFeature.ViewState = NotificationsOnboardingFeature.ViewState( - dailyStudyRemindersStartHour = state.dailyStudyRemindersStartHour, formattedDailyStudyRemindersInterval = formatDailyStudyRemindersInterval( startHour = state.dailyStudyRemindersStartHour ) From f7b1d9d0848a53f1b95b2337bdf6c8f4e8a6caa0 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Fri, 15 Dec 2023 11:32:53 +0700 Subject: [PATCH 7/7] Fix docs for NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent --- ...ervalPickerModalClickedConfirmHyperskillAnalyticEvent.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent.kt index 5514bd1fe3..ed8d0a44d5 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/notifications_onboarding/domain/analytic/NotificationsOnboardingDailyStudyRemindersIntervalPickerModalClickedConfirmHyperskillAnalyticEvent.kt @@ -15,7 +15,11 @@ import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticTar * "route": "/onboarding/notifications", * "action": "click", * "part": "daily_study_reminders_hour_interval_picker_modal", - * "target": "confirm" + * "target": "confirm", + * "context": + * { + * "start_hour": 12 + * } * } * ``` *