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

View File

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

View File

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

View File

@ -39,5 +39,5 @@ sealed interface HomeActivityViewEvents : VectorViewEvents {
data class MigrateThreads(val checkSession: Boolean) : HomeActivityViewEvents
object StartRecoverySetupFlow : 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) {
viewModelScope.launch {
when (val result = registerUnifiedPushUseCase.execute(distributor = distributor)) {
when (registerUnifiedPushUseCase.execute(distributor = distributor)) {
is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> {
_viewEvents.post(HomeActivityViewEvents.AskUserForPushDistributor(result.distributors))
_viewEvents.post(HomeActivityViewEvents.AskUserForPushDistributor)
}
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = vectorPreferences.areNotificationEnabledForDevice())

View File

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

View File

@ -116,10 +116,11 @@ class VectorSettingsNotificationPreferenceFragment :
private fun observeViewEvents() {
viewModel.observeViewEvents {
when (it) {
VectorSettingsNotificationPreferenceViewEvent.NotificationForDeviceEnabled -> onNotificationsForDeviceEnabled()
VectorSettingsNotificationPreferenceViewEvent.NotificationForDeviceDisabled -> onNotificationsForDeviceDisabled()
is VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor -> askUserToSelectPushDistributor(it.distributors)
VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled -> onNotificationsForDeviceEnabled()
VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled -> onNotificationsForDeviceDisabled()
is VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor -> askUserToSelectPushDistributor()
VectorSettingsNotificationPreferenceViewEvent.EnableNotificationForDeviceFailure -> displayErrorDialog(throwable = null)
VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged -> onNotificationMethodChanged()
}
}
}
@ -194,14 +195,7 @@ class VectorSettingsNotificationPreferenceFragment :
if (vectorFeatures.allowExternalUnifiedPushDistributors()) {
it.summary = unifiedPushHelper.getCurrentDistributorName()
it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
// TODO show dialog to pick a distributor
// 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()
}
askUserToSelectPushDistributor(withUnregister = true)
true
}
} else {
@ -235,13 +229,22 @@ class VectorSettingsNotificationPreferenceFragment :
notificationPermissionManager.eventuallyRevokePermission(requireActivity())
}
// TODO add an argument to know if unregister should be called
private fun askUserToSelectPushDistributor(distributors: List<String>) {
unifiedPushHelper.showSelectDistributorDialog(requireContext(), distributors) { selection ->
viewModel.handle(VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(selection))
private fun askUserToSelectPushDistributor(withUnregister: Boolean = false) {
unifiedPushHelper.showSelectDistributorDialog(requireContext()) { selection ->
if (withUnregister) {
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() {
val initialEmails = session.getEmailsWithPushInformation()
bindEmailNotificationCategory(initialEmails)

View File

@ -19,8 +19,9 @@ package im.vector.app.features.settings.notifications
import im.vector.app.core.platform.VectorViewEvents
sealed interface VectorSettingsNotificationPreferenceViewEvent : VectorViewEvents {
object NotificationForDeviceEnabled : VectorSettingsNotificationPreferenceViewEvent
object NotificationsForDeviceEnabled : VectorSettingsNotificationPreferenceViewEvent
object EnableNotificationForDeviceFailure : VectorSettingsNotificationPreferenceViewEvent
object NotificationForDeviceDisabled : VectorSettingsNotificationPreferenceViewEvent
data class AskUserForPushDistributor(val distributors: List<String>) : VectorSettingsNotificationPreferenceViewEvent
object NotificationsForDeviceDisabled : 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.platform.VectorDummyViewState
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
class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
@Assisted initialState: VectorDummyViewState,
private val pushersManager: PushersManager,
private val vectorPreferences: VectorPreferences,
private val enableNotificationsForCurrentSessionUseCase: EnableNotificationsForCurrentSessionUseCase,
private val disableNotificationsForCurrentSessionUseCase: DisableNotificationsForCurrentSessionUseCase,
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
) : VectorViewModel<VectorDummyViewState, VectorSettingsNotificationPreferenceViewAction, VectorSettingsNotificationPreferenceViewEvent>(initialState) {
@AssistedFactory
@ -51,27 +61,38 @@ class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
private fun handleDisableNotificationsForDevice() {
viewModelScope.launch {
disableNotificationsForCurrentSessionUseCase.execute()
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationForDeviceDisabled)
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled)
}
}
private fun handleEnableNotificationsForDevice(distributor: String) {
viewModelScope.launch {
when (val result = enableNotificationsForCurrentSessionUseCase.execute(distributor)) {
when (enableNotificationsForCurrentSessionUseCase.execute(distributor)) {
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Failure -> {
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.EnableNotificationForDeviceFailure)
}
is EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor -> {
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor(result.distributors))
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor)
}
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success -> {
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationForDeviceEnabled)
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled)
}
}
}
}
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,
pushKey: String,
) {
when (val result = registerUnifiedPushUseCase.execute(distributor)) {
when (registerUnifiedPushUseCase.execute(distributor)) {
is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor ->
askUserForDistributor(result.distributors, testParameters, pushKey)
askUserForDistributor(testParameters, pushKey)
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
val workId = pushersManager.enqueueRegisterPusherWithFcmKey(pushKey)
WorkManager.getInstance(context).getWorkInfoByIdLiveData(workId).observe(context) { workInfo ->
@ -102,11 +102,10 @@ class TestEndpointAsTokenRegistration @Inject constructor(
}
private fun askUserForDistributor(
distributors: List<String>,
testParameters: TestParameters,
pushKey: String,
) {
unifiedPushHelper.showSelectDistributorDialog(context, distributors) { selection ->
unifiedPushHelper.showSelectDistributorDialog(context) { selection ->
registerUnifiedPush(distributor = selection, testParameters, pushKey)
}
}