mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-25 19:05:56 +03:00
Listen for pusher or account data changes to update the local setting
This commit is contained in:
parent
67d2a6faab
commit
24a5cfa9e5
15 changed files with 206 additions and 46 deletions
|
@ -16,6 +16,9 @@
|
|||
|
||||
package org.matrix.android.sdk.api.session.homeserver
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
|
||||
/**
|
||||
* This interface defines a method to retrieve the homeserver capabilities.
|
||||
*/
|
||||
|
@ -30,4 +33,9 @@ interface HomeServerCapabilitiesService {
|
|||
* Get the HomeServer capabilities.
|
||||
*/
|
||||
fun getHomeServerCapabilities(): HomeServerCapabilities
|
||||
|
||||
/**
|
||||
* Get a LiveData on the HomeServer capabilities.
|
||||
*/
|
||||
fun getHomeServerCapabilitiesLive(): LiveData<Optional<HomeServerCapabilities>>
|
||||
}
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
|
||||
package org.matrix.android.sdk.internal.session.homeserver
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
|
||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultHomeServerCapabilitiesService @Inject constructor(
|
||||
|
@ -33,4 +35,8 @@ internal class DefaultHomeServerCapabilitiesService @Inject constructor(
|
|||
return homeServerCapabilitiesDataSource.getHomeServerCapabilities()
|
||||
?: HomeServerCapabilities()
|
||||
}
|
||||
|
||||
override fun getHomeServerCapabilitiesLive(): LiveData<Optional<HomeServerCapabilities>> {
|
||||
return homeServerCapabilitiesDataSource.getHomeServerCapabilitiesLive()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,14 @@
|
|||
|
||||
package org.matrix.android.sdk.internal.session.homeserver
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.where
|
||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.api.util.toOptional
|
||||
import org.matrix.android.sdk.internal.database.mapper.HomeServerCapabilitiesMapper
|
||||
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntity
|
||||
import org.matrix.android.sdk.internal.database.query.get
|
||||
|
@ -26,7 +31,7 @@ import org.matrix.android.sdk.internal.di.SessionDatabase
|
|||
import javax.inject.Inject
|
||||
|
||||
internal class HomeServerCapabilitiesDataSource @Inject constructor(
|
||||
@SessionDatabase private val monarchy: Monarchy
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
) {
|
||||
fun getHomeServerCapabilities(): HomeServerCapabilities? {
|
||||
return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
||||
|
@ -35,4 +40,14 @@ internal class HomeServerCapabilitiesDataSource @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getHomeServerCapabilitiesLive(): LiveData<Optional<HomeServerCapabilities>> {
|
||||
val liveData = monarchy.findAllMappedWithChanges(
|
||||
{ realm: Realm -> realm.where<HomeServerCapabilitiesEntity>() },
|
||||
{ HomeServerCapabilitiesMapper.map(it) }
|
||||
)
|
||||
return Transformations.map(liveData) {
|
||||
it.firstOrNull().toOptional()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.core.di
|
|||
import android.content.Context
|
||||
import im.vector.app.ActiveSessionDataSource
|
||||
import im.vector.app.core.extensions.startSyncing
|
||||
import im.vector.app.core.notification.EnableNotificationsSettingUpdater
|
||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
||||
import im.vector.app.core.services.GuardServiceStarter
|
||||
import im.vector.app.core.session.ConfigureAndStartSessionUseCase
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.core.notification
|
||||
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class EnableNotificationsSettingUpdater @Inject constructor(
|
||||
private val updateEnableNotificationsSettingOnChangeUseCase: UpdateEnableNotificationsSettingOnChangeUseCase,
|
||||
) {
|
||||
|
||||
private var job: Job? = null
|
||||
|
||||
fun onSessionsStarted(session: Session) {
|
||||
job?.cancel()
|
||||
job = session.coroutineScope.launch {
|
||||
updateEnableNotificationsSettingOnChangeUseCase.execute(session)
|
||||
.launchIn(this)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.core.notification
|
||||
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.features.settings.devices.v2.notification.GetNotificationsStatusUseCase
|
||||
import im.vector.app.features.settings.devices.v2.notification.NotificationsStatus
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Listen for changes in either Pusher or Account data to update the local enable notifications
|
||||
* setting for the current device.
|
||||
*/
|
||||
class UpdateEnableNotificationsSettingOnChangeUseCase @Inject constructor(
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val getNotificationsStatusUseCase: GetNotificationsStatusUseCase,
|
||||
) {
|
||||
|
||||
// TODO add unit tests
|
||||
fun execute(session: Session): Flow<NotificationsStatus> {
|
||||
val deviceId = session.sessionParams.deviceId ?: return emptyFlow()
|
||||
return getNotificationsStatusUseCase.execute(session, deviceId)
|
||||
.onEach(::updatePreference)
|
||||
}
|
||||
|
||||
private fun updatePreference(notificationStatus: NotificationsStatus) {
|
||||
Timber.d("updatePreference with status=$notificationStatus")
|
||||
when (notificationStatus) {
|
||||
NotificationsStatus.ENABLED -> vectorPreferences.setNotificationEnabledForDevice(true)
|
||||
NotificationsStatus.DISABLED -> vectorPreferences.setNotificationEnabledForDevice(false)
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ package im.vector.app.core.session
|
|||
import android.content.Context
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import im.vector.app.core.extensions.startSyncing
|
||||
import im.vector.app.core.notification.EnableNotificationsSettingUpdater
|
||||
import im.vector.app.core.session.clientinfo.UpdateMatrixClientInfoUseCase
|
||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
|
@ -32,8 +33,10 @@ class ConfigureAndStartSessionUseCase @Inject constructor(
|
|||
private val webRtcCallManager: WebRtcCallManager,
|
||||
private val updateMatrixClientInfoUseCase: UpdateMatrixClientInfoUseCase,
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val enableNotificationsSettingUpdater: EnableNotificationsSettingUpdater,
|
||||
) {
|
||||
|
||||
// TODO update unit tests
|
||||
suspend fun execute(session: Session, startSyncing: Boolean = true) {
|
||||
Timber.i("Configure and start session for ${session.myUserId}. startSyncing: $startSyncing")
|
||||
session.open()
|
||||
|
@ -46,5 +49,6 @@ class ConfigureAndStartSessionUseCase @Inject constructor(
|
|||
if (vectorPreferences.isClientInfoRecordingEnabled()) {
|
||||
updateMatrixClientInfoUseCase.execute(session)
|
||||
}
|
||||
enableNotificationsSettingUpdater.onSessionsStarted(session)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.features.settings.devices.v2.notification
|
||||
|
||||
import androidx.lifecycle.asFlow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.flow.unwrap
|
||||
import javax.inject.Inject
|
||||
|
||||
class CanTogglePushNotificationsViaPusherUseCase @Inject constructor() {
|
||||
|
||||
fun execute(session: Session): Flow<Boolean> {
|
||||
return session
|
||||
.homeServerCapabilitiesService()
|
||||
.getHomeServerCapabilitiesLive()
|
||||
.asFlow()
|
||||
.unwrap()
|
||||
.map { it.canRemotelyTogglePushNotificationsOfDevices }
|
||||
}
|
||||
}
|
|
@ -16,18 +16,15 @@
|
|||
|
||||
package im.vector.app.features.settings.devices.v2.notification
|
||||
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
|
||||
import javax.inject.Inject
|
||||
|
||||
class CheckIfCanTogglePushNotificationsViaAccountDataUseCase @Inject constructor(
|
||||
private val activeSessionHolder: ActiveSessionHolder,
|
||||
) {
|
||||
class CheckIfCanTogglePushNotificationsViaAccountDataUseCase @Inject constructor() {
|
||||
|
||||
fun execute(deviceId: String): Boolean {
|
||||
return activeSessionHolder
|
||||
.getSafeActiveSession()
|
||||
?.accountDataService()
|
||||
?.getUserAccountDataEvent(UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId) != null
|
||||
fun execute(session: Session, deviceId: String): Boolean {
|
||||
return session
|
||||
.accountDataService()
|
||||
.getUserAccountDataEvent(UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId) != null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,20 +16,15 @@
|
|||
|
||||
package im.vector.app.features.settings.devices.v2.notification
|
||||
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import javax.inject.Inject
|
||||
|
||||
class CheckIfCanTogglePushNotificationsViaPusherUseCase @Inject constructor(
|
||||
private val activeSessionHolder: ActiveSessionHolder,
|
||||
) {
|
||||
class CheckIfCanTogglePushNotificationsViaPusherUseCase @Inject constructor() {
|
||||
|
||||
fun execute(): Boolean {
|
||||
return activeSessionHolder
|
||||
.getSafeActiveSession()
|
||||
?.homeServerCapabilitiesService()
|
||||
?.getHomeServerCapabilities()
|
||||
?.canRemotelyTogglePushNotificationsOfDevices
|
||||
.orFalse()
|
||||
fun execute(session: Session): Boolean {
|
||||
return session
|
||||
.homeServerCapabilitiesService()
|
||||
.getHomeServerCapabilities()
|
||||
.canRemotelyTogglePushNotificationsOfDevices
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
|
||||
package im.vector.app.features.settings.devices.v2.notification
|
||||
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.matrix.android.sdk.api.account.LocalNotificationSettingsContent
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
|
@ -29,16 +30,13 @@ import org.matrix.android.sdk.flow.unwrap
|
|||
import javax.inject.Inject
|
||||
|
||||
class GetNotificationsStatusUseCase @Inject constructor(
|
||||
private val activeSessionHolder: ActiveSessionHolder,
|
||||
private val checkIfCanTogglePushNotificationsViaPusherUseCase: CheckIfCanTogglePushNotificationsViaPusherUseCase,
|
||||
private val canTogglePushNotificationsViaPusherUseCase: CanTogglePushNotificationsViaPusherUseCase,
|
||||
private val checkIfCanTogglePushNotificationsViaAccountDataUseCase: CheckIfCanTogglePushNotificationsViaAccountDataUseCase,
|
||||
) {
|
||||
|
||||
fun execute(deviceId: String): Flow<NotificationsStatus> {
|
||||
val session = activeSessionHolder.getSafeActiveSession()
|
||||
fun execute(session: Session, deviceId: String): Flow<NotificationsStatus> {
|
||||
return when {
|
||||
session == null -> flowOf(NotificationsStatus.NOT_SUPPORTED)
|
||||
checkIfCanTogglePushNotificationsViaAccountDataUseCase.execute(deviceId) -> {
|
||||
checkIfCanTogglePushNotificationsViaAccountDataUseCase.execute(session, deviceId) -> {
|
||||
session.flow()
|
||||
.liveUserAccountData(UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId)
|
||||
.unwrap()
|
||||
|
@ -46,15 +44,19 @@ class GetNotificationsStatusUseCase @Inject constructor(
|
|||
.map { if (it == true) NotificationsStatus.ENABLED else NotificationsStatus.DISABLED }
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
checkIfCanTogglePushNotificationsViaPusherUseCase.execute() -> {
|
||||
session.flow()
|
||||
.livePushers()
|
||||
.map { it.filter { pusher -> pusher.deviceId == deviceId } }
|
||||
.map { it.takeIf { it.isNotEmpty() }?.any { pusher -> pusher.enabled } }
|
||||
.map { if (it == true) NotificationsStatus.ENABLED else NotificationsStatus.DISABLED }
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
else -> flowOf(NotificationsStatus.NOT_SUPPORTED)
|
||||
else -> canTogglePushNotificationsViaPusherUseCase.execute(session)
|
||||
.flatMapLatest { canToggle ->
|
||||
if (canToggle) {
|
||||
session.flow()
|
||||
.livePushers()
|
||||
.map { it.filter { pusher -> pusher.deviceId == deviceId } }
|
||||
.map { it.takeIf { it.isNotEmpty() }?.any { pusher -> pusher.enabled } }
|
||||
.map { if (it == true) NotificationsStatus.ENABLED else NotificationsStatus.DISABLED }
|
||||
.distinctUntilChanged()
|
||||
} else {
|
||||
flowOf(NotificationsStatus.NOT_SUPPORTED)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,14 +31,14 @@ class TogglePushNotificationUseCase @Inject constructor(
|
|||
suspend fun execute(deviceId: String, enabled: Boolean) {
|
||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||
|
||||
if (checkIfCanTogglePushNotificationsViaPusherUseCase.execute()) {
|
||||
if (checkIfCanTogglePushNotificationsViaPusherUseCase.execute(session)) {
|
||||
val devicePusher = session.pushersService().getPushers().firstOrNull { it.deviceId == deviceId }
|
||||
devicePusher?.let { pusher ->
|
||||
session.pushersService().togglePusher(pusher, enabled)
|
||||
}
|
||||
}
|
||||
|
||||
if (checkIfCanTogglePushNotificationsViaAccountDataUseCase.execute(deviceId)) {
|
||||
if (checkIfCanTogglePushNotificationsViaAccountDataUseCase.execute(session, deviceId)) {
|
||||
val newNotificationSettingsContent = LocalNotificationSettingsContent(isSilenced = !enabled)
|
||||
session.accountDataService().updateUserAccountData(
|
||||
UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId,
|
||||
|
|
|
@ -96,9 +96,11 @@ class SessionOverviewViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private fun observeNotificationsStatus(deviceId: String) {
|
||||
getNotificationsStatusUseCase.execute(deviceId)
|
||||
.onEach { setState { copy(notificationsStatus = it) } }
|
||||
.launchIn(viewModelScope)
|
||||
activeSessionHolder.getSafeActiveSession()?.let { session ->
|
||||
getNotificationsStatusUseCase.execute(session, deviceId)
|
||||
.onEach { setState { copy(notificationsStatus = it) } }
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
}
|
||||
|
||||
override fun handle(action: SessionOverviewAction) {
|
||||
|
|
|
@ -35,7 +35,7 @@ class DisableNotificationsForCurrentSessionUseCase @Inject constructor(
|
|||
suspend fun execute() {
|
||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||
val deviceId = session.sessionParams.deviceId ?: return
|
||||
if (checkIfCanTogglePushNotificationsViaPusherUseCase.execute()) {
|
||||
if (checkIfCanTogglePushNotificationsViaPusherUseCase.execute(session)) {
|
||||
togglePushNotificationUseCase.execute(deviceId, enabled = false)
|
||||
} else {
|
||||
unifiedPushHelper.unregister(pushersManager)
|
||||
|
|
|
@ -44,8 +44,8 @@ class EnableNotificationsForCurrentSessionUseCase @Inject constructor(
|
|||
registerPusher(fragmentActivity)
|
||||
}
|
||||
|
||||
if (checkIfCanTogglePushNotificationsViaPusherUseCase.execute()) {
|
||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||
if (checkIfCanTogglePushNotificationsViaPusherUseCase.execute(session)) {
|
||||
val deviceId = session.sessionParams.deviceId ?: return
|
||||
togglePushNotificationUseCase.execute(deviceId, enabled = true)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue