Local Notification Settings Event (#7300)

* Adds push notifications switch

* Adds functionality to Push notification toggle

* Adds DefaultPushersServiceTest for togglePusher

* Adds DefaultTogglePusherTaskTest

* Adds SessionOverviewViewModelTest for toggling pusher

* Hides pusher toggle if there are no pushers of the device

* Adds changelog file

* Edits changelog file

* Fixes copyrights

* Unregisters checkedChangelistener in onDetachedFromWindow for switch view

* Links notification settings toggle to pusher service

* Adds changelog file

* Adds error handling to VectorSettingsNotificationPreferenceFragment

* Removes comment in FakePushersService

* Adds parsing for LocalNotificationSettings event

* Adds changelog file

* Fixes post merge errors

* Fixes imports and improves string name

* Fixes legal copies

* Fixes kdoc punctuation

* Fixes string error

* Removes unused imports

* Moves LocalNotificationSettingsContent

* Fixes lint errors

* Fixes test errors

* Fixes test errors

* Fixes error

* Fixes error

* Fixes error

* Fixes error

* Fixes error

* Fixes error

* Fixes error

* Adds lost tests

* Adds PusherEntity migration

* Fixes session overview layout overlap

* Fixes switch being enabled by default

* Adds device id and unstable prefix
This commit is contained in:
Eric Decanini 2022-10-12 23:11:27 -04:00 committed by GitHub
parent f8f416e979
commit 963c0e5a50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 1 deletions

1
changelog.d/7300.wip Normal file
View File

@ -0,0 +1 @@
Implements client-side of local notification settings event

View File

@ -0,0 +1,25 @@
/*
* Copyright 2022 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.matrix.android.sdk.api.account
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class LocalNotificationSettingsContent(
@Json(name = "is_silenced") val isSilenced: Boolean = false
)

View File

@ -28,4 +28,5 @@ object UserAccountDataTypes {
const val TYPE_IDENTITY_SERVER = "m.identity_server" const val TYPE_IDENTITY_SERVER = "m.identity_server"
const val TYPE_ACCEPTED_TERMS = "m.accepted_terms" const val TYPE_ACCEPTED_TERMS = "m.accepted_terms"
const val TYPE_OVERRIDE_COLORS = "im.vector.setting.override_colors" const val TYPE_OVERRIDE_COLORS = "im.vector.setting.override_colors"
const val TYPE_LOCAL_NOTIFICATION_SETTINGS = "org.matrix.msc3890.local_notification_settings."
} }

View File

@ -215,6 +215,7 @@ class HomeActivity :
) )
} }
} }
sharedActionViewModel = viewModelProvider[HomeSharedActionViewModel::class.java] sharedActionViewModel = viewModelProvider[HomeSharedActionViewModel::class.java]
roomListSharedActionViewModel = viewModelProvider[RoomListSharedActionViewModel::class.java] roomListSharedActionViewModel = viewModelProvider[RoomListSharedActionViewModel::class.java]
views.drawerLayout.addDrawerListener(drawerListener) views.drawerLayout.addDrawerListener(drawerListener)
@ -406,6 +407,14 @@ class HomeActivity :
} }
private fun renderState(state: HomeActivityViewState) { private fun renderState(state: HomeActivityViewState) {
lifecycleScope.launch {
if (state.areNotificationsSilenced) {
unifiedPushHelper.unregister(pushersManager)
} else {
unifiedPushHelper.register(this@HomeActivity)
}
}
when (val status = state.syncRequestState) { when (val status = state.syncRequestState) {
is SyncRequestState.InitialSyncProgressing -> { is SyncRequestState.InitialSyncProgressing -> {
val initSyncStepStr = initSyncStepFormatter.format(status.initialSyncStep) val initSyncStepStr = initSyncStepFormatter.format(status.initialSyncStep)

View File

@ -16,6 +16,7 @@
package im.vector.app.features.home package im.vector.app.features.home
import androidx.lifecycle.asFlow
import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.ViewModelContext import com.airbnb.mvrx.ViewModelContext
@ -45,10 +46,12 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.account.LocalNotificationSettingsContent
import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UIABaseAuth
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.UserPasswordAuth
@ -57,9 +60,11 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage
import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.api.raw.RawService
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.getUserOrDefault import org.matrix.android.sdk.api.session.getUserOrDefault
import org.matrix.android.sdk.api.session.pushrules.RuleIds import org.matrix.android.sdk.api.session.pushrules.RuleIds
import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.Membership
@ -115,6 +120,7 @@ class HomeActivityViewModel @AssistedInject constructor(
observeCrossSigningReset() observeCrossSigningReset()
observeAnalytics() observeAnalytics()
observeReleaseNotes() observeReleaseNotes()
observeLocalNotificationsSilenced()
initThreadsMigration() initThreadsMigration()
} }
@ -136,6 +142,18 @@ class HomeActivityViewModel @AssistedInject constructor(
} }
} }
fun observeLocalNotificationsSilenced() {
val currentSession = activeSessionHolder.getActiveSession()
val deviceId = currentSession.cryptoService().getMyDevice().deviceId
viewModelScope.launch {
currentSession.accountDataService()
.getLiveUserAccountDataEvent(UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId)
.asFlow()
.map { it.getOrNull()?.content?.toModel<LocalNotificationSettingsContent>()?.isSilenced ?: false }
.onEach { setState { copy(areNotificationsSilenced = it) } }
}
}
private fun observeAnalytics() { private fun observeAnalytics() {
if (analyticsConfig.isEnabled) { if (analyticsConfig.isEnabled) {
analyticsStore.didAskUserConsentFlow analyticsStore.didAskUserConsentFlow

View File

@ -22,5 +22,6 @@ import org.matrix.android.sdk.api.session.sync.SyncRequestState
data class HomeActivityViewState( data class HomeActivityViewState(
val syncRequestState: SyncRequestState = SyncRequestState.Idle, val syncRequestState: SyncRequestState = SyncRequestState.Idle,
val authenticationDescription: AuthenticationDescription? = null val authenticationDescription: AuthenticationDescription? = null,
val areNotificationsSilenced: Boolean = false,
) : MavericksState ) : MavericksState