Handling change of notification method

This commit is contained in:
Maxime NATUREL 2022-11-30 12:04:52 +01:00
parent 95556d2551
commit 2673979ef8
10 changed files with 67 additions and 42 deletions

View File

@ -29,12 +29,12 @@ class RegisterUnifiedPushUseCase @Inject constructor(
sealed interface RegisterUnifiedPushResult { sealed interface RegisterUnifiedPushResult {
object Success : RegisterUnifiedPushResult object Success : RegisterUnifiedPushResult
data class NeedToAskUserForDistributor(val distributors: List<String>) : RegisterUnifiedPushResult object NeedToAskUserForDistributor : RegisterUnifiedPushResult
} }
// TODO add unit tests // TODO add unit tests
fun execute(distributor: String = ""): RegisterUnifiedPushResult { fun execute(distributor: String = ""): RegisterUnifiedPushResult {
if(distributor.isNotEmpty()) { if (distributor.isNotEmpty()) {
saveAndRegisterApp(distributor) saveAndRegisterApp(distributor)
return RegisterUnifiedPushResult.Success return RegisterUnifiedPushResult.Success
} }
@ -55,7 +55,7 @@ class RegisterUnifiedPushUseCase @Inject constructor(
saveAndRegisterApp(distributors.first()) saveAndRegisterApp(distributors.first())
RegisterUnifiedPushResult.Success RegisterUnifiedPushResult.Success
} else { } else {
RegisterUnifiedPushResult.NeedToAskUserForDistributor(distributors) RegisterUnifiedPushResult.NeedToAskUserForDistributor
} }
} }

View File

@ -52,7 +52,7 @@ class UnifiedPushHelper @Inject constructor(
// Called when the home activity starts // Called when the home activity starts
// or when notifications are enabled // or when notifications are enabled
// TODO remove and replace by use case // TODO remove
fun register( fun register(
activity: FragmentActivity, activity: FragmentActivity,
onDoneRunnable: Runnable? = null, onDoneRunnable: Runnable? = null,
@ -70,7 +70,7 @@ class UnifiedPushHelper @Inject constructor(
// The registration is forced in 2 cases : // The registration is forced in 2 cases :
// * in the settings // * in the settings
// * in the troubleshoot list (doFix) // * in the troubleshoot list (doFix)
// TODO remove and replace by use case // TODO remove
fun forceRegister( fun forceRegister(
activity: FragmentActivity, activity: FragmentActivity,
pushersManager: PushersManager, pushersManager: PushersManager,
@ -132,6 +132,7 @@ class UnifiedPushHelper @Inject constructor(
} }
} }
// TODO remove
// There is no case where this function is called // There is no case where this function is called
// with a saved distributor and/or a pusher // with a saved distributor and/or a pusher
private fun openDistributorDialogInternal( private fun openDistributorDialogInternal(
@ -180,7 +181,6 @@ class UnifiedPushHelper @Inject constructor(
@MainThread @MainThread
fun showSelectDistributorDialog( fun showSelectDistributorDialog(
context: Context, context: Context,
distributors: List<String>,
onDistributorSelected: (String) -> Unit, onDistributorSelected: (String) -> Unit,
) { ) {
val internalDistributorName = stringProvider.getString( val internalDistributorName = stringProvider.getString(
@ -191,6 +191,7 @@ class UnifiedPushHelper @Inject constructor(
} }
) )
val distributors = UnifiedPush.getDistributors(context)
val distributorsName = distributors.map { val distributorsName = distributors.map {
if (it == context.packageName) { if (it == context.packageName) {
internalDistributorName internalDistributorName

View File

@ -266,7 +266,7 @@ class HomeActivity :
HomeActivityViewEvents.ShowReleaseNotes -> handleShowReleaseNotes() HomeActivityViewEvents.ShowReleaseNotes -> handleShowReleaseNotes()
HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration() HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration()
is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession) is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession)
is HomeActivityViewEvents.AskUserForPushDistributor -> askUserToSelectPushDistributor(it.distributors) is HomeActivityViewEvents.AskUserForPushDistributor -> askUserToSelectPushDistributor()
} }
} }
homeActivityViewModel.onEach { renderState(it) } homeActivityViewModel.onEach { renderState(it) }
@ -279,8 +279,8 @@ class HomeActivity :
homeActivityViewModel.handle(HomeActivityViewActions.ViewStarted) homeActivityViewModel.handle(HomeActivityViewActions.ViewStarted)
} }
private fun askUserToSelectPushDistributor(distributors: List<String>) { private fun askUserToSelectPushDistributor() {
unifiedPushHelper.showSelectDistributorDialog(this, distributors) { selection -> unifiedPushHelper.showSelectDistributorDialog(this) { selection ->
homeActivityViewModel.handle(HomeActivityViewActions.RegisterPushDistributor(selection)) homeActivityViewModel.handle(HomeActivityViewActions.RegisterPushDistributor(selection))
} }
} }

View File

@ -39,5 +39,5 @@ sealed interface HomeActivityViewEvents : VectorViewEvents {
data class MigrateThreads(val checkSession: Boolean) : HomeActivityViewEvents data class MigrateThreads(val checkSession: Boolean) : HomeActivityViewEvents
object StartRecoverySetupFlow : HomeActivityViewEvents object StartRecoverySetupFlow : HomeActivityViewEvents
data class ForceVerification(val sendRequest: Boolean) : HomeActivityViewEvents data class ForceVerification(val sendRequest: Boolean) : HomeActivityViewEvents
data class AskUserForPushDistributor(val distributors: List<String>) : HomeActivityViewEvents object AskUserForPushDistributor : HomeActivityViewEvents
} }

View File

@ -129,9 +129,9 @@ class HomeActivityViewModel @AssistedInject constructor(
private fun registerUnifiedPush(distributor: String) { private fun registerUnifiedPush(distributor: String) {
viewModelScope.launch { viewModelScope.launch {
when (val result = registerUnifiedPushUseCase.execute(distributor = distributor)) { when (registerUnifiedPushUseCase.execute(distributor = distributor)) {
is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> { is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> {
_viewEvents.post(HomeActivityViewEvents.AskUserForPushDistributor(result.distributors)) _viewEvents.post(HomeActivityViewEvents.AskUserForPushDistributor)
} }
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> { RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = vectorPreferences.areNotificationEnabledForDevice()) ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = vectorPreferences.areNotificationEnabledForDevice())

View File

@ -34,16 +34,16 @@ class EnableNotificationsForCurrentSessionUseCase @Inject constructor(
sealed interface EnableNotificationsResult { sealed interface EnableNotificationsResult {
object Success : EnableNotificationsResult object Success : EnableNotificationsResult
object Failure : EnableNotificationsResult object Failure : EnableNotificationsResult
data class NeedToAskUserForDistributor(val distributors: List<String>) : EnableNotificationsResult object NeedToAskUserForDistributor : EnableNotificationsResult
} }
// TODO update unit tests // TODO update unit tests
suspend fun execute(distributor: String = ""): EnableNotificationsResult { suspend fun execute(distributor: String = ""): EnableNotificationsResult {
val pusherForCurrentSession = pushersManager.getPusherForCurrentSession() val pusherForCurrentSession = pushersManager.getPusherForCurrentSession()
if (pusherForCurrentSession == null) { if (pusherForCurrentSession == null) {
when (val result = registerUnifiedPushUseCase.execute(distributor)) { when (registerUnifiedPushUseCase.execute(distributor)) {
is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> { is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> {
return EnableNotificationsResult.NeedToAskUserForDistributor(result.distributors) return EnableNotificationsResult.NeedToAskUserForDistributor
} }
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> { RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = true) ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = true)

View File

@ -116,10 +116,11 @@ class VectorSettingsNotificationPreferenceFragment :
private fun observeViewEvents() { private fun observeViewEvents() {
viewModel.observeViewEvents { viewModel.observeViewEvents {
when (it) { when (it) {
VectorSettingsNotificationPreferenceViewEvent.NotificationForDeviceEnabled -> onNotificationsForDeviceEnabled() VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled -> onNotificationsForDeviceEnabled()
VectorSettingsNotificationPreferenceViewEvent.NotificationForDeviceDisabled -> onNotificationsForDeviceDisabled() VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled -> onNotificationsForDeviceDisabled()
is VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor -> askUserToSelectPushDistributor(it.distributors) is VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor -> askUserToSelectPushDistributor()
VectorSettingsNotificationPreferenceViewEvent.EnableNotificationForDeviceFailure -> displayErrorDialog(throwable = null) VectorSettingsNotificationPreferenceViewEvent.EnableNotificationForDeviceFailure -> displayErrorDialog(throwable = null)
VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged -> onNotificationMethodChanged()
} }
} }
} }
@ -194,14 +195,7 @@ class VectorSettingsNotificationPreferenceFragment :
if (vectorFeatures.allowExternalUnifiedPushDistributors()) { if (vectorFeatures.allowExternalUnifiedPushDistributors()) {
it.summary = unifiedPushHelper.getCurrentDistributorName() it.summary = unifiedPushHelper.getCurrentDistributorName()
it.onPreferenceClickListener = Preference.OnPreferenceClickListener { it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
// TODO show dialog to pick a distributor askUserToSelectPushDistributor(withUnregister = true)
// TODO call unregister then register only when a new distributor has been selected => use UnifiedPushHelper method
unifiedPushHelper.forceRegister(requireActivity(), pushersManager) {
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = vectorPreferences.areNotificationEnabledForDevice())
it.summary = unifiedPushHelper.getCurrentDistributorName()
session.pushersService().refreshPushers()
refreshBackgroundSyncPrefs()
}
true true
} }
} else { } else {
@ -235,13 +229,22 @@ class VectorSettingsNotificationPreferenceFragment :
notificationPermissionManager.eventuallyRevokePermission(requireActivity()) notificationPermissionManager.eventuallyRevokePermission(requireActivity())
} }
// TODO add an argument to know if unregister should be called private fun askUserToSelectPushDistributor(withUnregister: Boolean = false) {
private fun askUserToSelectPushDistributor(distributors: List<String>) { unifiedPushHelper.showSelectDistributorDialog(requireContext()) { selection ->
unifiedPushHelper.showSelectDistributorDialog(requireContext(), distributors) { selection -> if (withUnregister) {
viewModel.handle(VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(selection)) viewModel.handle(VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(selection))
} else {
viewModel.handle(VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(selection))
}
} }
} }
private fun onNotificationMethodChanged() {
findPreference<VectorPreference>(VectorPreferences.SETTINGS_NOTIFICATION_METHOD_KEY)?.summary = unifiedPushHelper.getCurrentDistributorName()
session.pushersService().refreshPushers()
refreshBackgroundSyncPrefs()
}
private fun bindEmailNotifications() { private fun bindEmailNotifications() {
val initialEmails = session.getEmailsWithPushInformation() val initialEmails = session.getEmailsWithPushInformation()
bindEmailNotificationCategory(initialEmails) bindEmailNotificationCategory(initialEmails)

View File

@ -19,8 +19,9 @@ package im.vector.app.features.settings.notifications
import im.vector.app.core.platform.VectorViewEvents import im.vector.app.core.platform.VectorViewEvents
sealed interface VectorSettingsNotificationPreferenceViewEvent : VectorViewEvents { sealed interface VectorSettingsNotificationPreferenceViewEvent : VectorViewEvents {
object NotificationForDeviceEnabled : VectorSettingsNotificationPreferenceViewEvent object NotificationsForDeviceEnabled : VectorSettingsNotificationPreferenceViewEvent
object EnableNotificationForDeviceFailure : VectorSettingsNotificationPreferenceViewEvent object EnableNotificationForDeviceFailure : VectorSettingsNotificationPreferenceViewEvent
object NotificationForDeviceDisabled : VectorSettingsNotificationPreferenceViewEvent object NotificationsForDeviceDisabled : VectorSettingsNotificationPreferenceViewEvent
data class AskUserForPushDistributor(val distributors: List<String>) : VectorSettingsNotificationPreferenceViewEvent object AskUserForPushDistributor : VectorSettingsNotificationPreferenceViewEvent
object NotificationMethodChanged : VectorSettingsNotificationPreferenceViewEvent
} }

View File

@ -24,12 +24,22 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.VectorDummyViewState import im.vector.app.core.platform.VectorDummyViewState
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
import im.vector.app.core.pushers.PushersManager
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
import im.vector.app.features.settings.VectorPreferences
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor( class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
@Assisted initialState: VectorDummyViewState, @Assisted initialState: VectorDummyViewState,
private val pushersManager: PushersManager,
private val vectorPreferences: VectorPreferences,
private val enableNotificationsForCurrentSessionUseCase: EnableNotificationsForCurrentSessionUseCase, private val enableNotificationsForCurrentSessionUseCase: EnableNotificationsForCurrentSessionUseCase,
private val disableNotificationsForCurrentSessionUseCase: DisableNotificationsForCurrentSessionUseCase, private val disableNotificationsForCurrentSessionUseCase: DisableNotificationsForCurrentSessionUseCase,
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
) : VectorViewModel<VectorDummyViewState, VectorSettingsNotificationPreferenceViewAction, VectorSettingsNotificationPreferenceViewEvent>(initialState) { ) : VectorViewModel<VectorDummyViewState, VectorSettingsNotificationPreferenceViewAction, VectorSettingsNotificationPreferenceViewEvent>(initialState) {
@AssistedFactory @AssistedFactory
@ -51,27 +61,38 @@ class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
private fun handleDisableNotificationsForDevice() { private fun handleDisableNotificationsForDevice() {
viewModelScope.launch { viewModelScope.launch {
disableNotificationsForCurrentSessionUseCase.execute() disableNotificationsForCurrentSessionUseCase.execute()
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationForDeviceDisabled) _viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled)
} }
} }
private fun handleEnableNotificationsForDevice(distributor: String) { private fun handleEnableNotificationsForDevice(distributor: String) {
viewModelScope.launch { viewModelScope.launch {
when (val result = enableNotificationsForCurrentSessionUseCase.execute(distributor)) { when (enableNotificationsForCurrentSessionUseCase.execute(distributor)) {
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Failure -> { EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Failure -> {
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.EnableNotificationForDeviceFailure) _viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.EnableNotificationForDeviceFailure)
} }
is EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor -> { is EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor -> {
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor(result.distributors)) _viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor)
} }
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success -> { EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success -> {
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationForDeviceEnabled) _viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled)
} }
} }
} }
} }
private fun handleRegisterPushDistributor(distributor: String) { private fun handleRegisterPushDistributor(distributor: String) {
handleEnableNotificationsForDevice(distributor) viewModelScope.launch {
unregisterUnifiedPushUseCase.execute(pushersManager)
when (registerUnifiedPushUseCase.execute(distributor)) {
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> {
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor)
}
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = vectorPreferences.areNotificationEnabledForDevice())
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged)
}
}
}
} }
} }

View File

@ -83,9 +83,9 @@ class TestEndpointAsTokenRegistration @Inject constructor(
testParameters: TestParameters, testParameters: TestParameters,
pushKey: String, pushKey: String,
) { ) {
when (val result = registerUnifiedPushUseCase.execute(distributor)) { when (registerUnifiedPushUseCase.execute(distributor)) {
is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor ->
askUserForDistributor(result.distributors, testParameters, pushKey) askUserForDistributor(testParameters, pushKey)
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> { RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
val workId = pushersManager.enqueueRegisterPusherWithFcmKey(pushKey) val workId = pushersManager.enqueueRegisterPusherWithFcmKey(pushKey)
WorkManager.getInstance(context).getWorkInfoByIdLiveData(workId).observe(context) { workInfo -> WorkManager.getInstance(context).getWorkInfoByIdLiveData(workId).observe(context) { workInfo ->
@ -102,11 +102,10 @@ class TestEndpointAsTokenRegistration @Inject constructor(
} }
private fun askUserForDistributor( private fun askUserForDistributor(
distributors: List<String>,
testParameters: TestParameters, testParameters: TestParameters,
pushKey: String, pushKey: String,
) { ) {
unifiedPushHelper.showSelectDistributorDialog(context, distributors) { selection -> unifiedPushHelper.showSelectDistributorDialog(context) { selection ->
registerUnifiedPush(distributor = selection, testParameters, pushKey) registerUnifiedPush(distributor = selection, testParameters, pushKey)
} }
} }