RoomListActions: handle room notification state. Still need to branch UI

This commit is contained in:
ganfra 2019-10-25 18:23:47 +02:00
parent cb275aee37
commit 00ca5dc70a
23 changed files with 544 additions and 27 deletions

View File

@ -20,6 +20,7 @@ import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
import im.vector.matrix.android.api.session.room.model.ReadReceipt
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
import im.vector.matrix.android.api.session.room.send.UserDraft
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.util.Optional
@ -67,6 +68,10 @@ class RxRoom(private val room: Room) {
fun liveDrafts(): Observable<List<UserDraft>> {
return room.getDraftsLive().asObservable()
}
fun liveNotificationState(): Observable<RoomNotificationState> {
return room.getLiveRoomNotificationState().asObservable()
}
}
fun Room.rx(): RxRoom {

View File

@ -21,7 +21,7 @@ import timber.log.Timber
sealed class Action {
object Notify : Action()
object DoNotNotify : Action()
data class Sound(val sound: String) : Action()
data class Sound(val sound: String = ACTION_OBJECT_VALUE_VALUE_DEFAULT) : Action()
data class Highlight(val highlight: Boolean) : Action()
}
@ -63,6 +63,30 @@ private const val ACTION_OBJECT_VALUE_VALUE_DEFAULT = "default"
*
* </pre>
*/
@Suppress("IMPLICIT_CAST_TO_ANY")
fun List<Action>.toJson(): List<Any> {
return map { action ->
when (action) {
is Action.Notify -> ACTION_NOTIFY
is Action.DoNotNotify -> ACTION_DONT_NOTIFY
is Action.Sound -> {
mapOf(
ACTION_OBJECT_SET_TWEAK_KEY to ACTION_OBJECT_SET_TWEAK_VALUE_SOUND,
ACTION_OBJECT_VALUE_KEY to action.sound
)
}
is Action.Highlight -> {
mapOf(
ACTION_OBJECT_SET_TWEAK_KEY to ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT,
ACTION_OBJECT_VALUE_KEY to action.highlight
)
}
}
}
}
fun PushRule.getActions(): List<Action> {
val result = ArrayList<Action>()

View File

@ -34,6 +34,10 @@ interface PushRuleService {
fun updatePushRuleEnableStatus(kind: RuleKind, pushRule: PushRule, enabled: Boolean, callback: MatrixCallback<Unit>): Cancelable
fun addPushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable
fun removePushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable
fun addPushRuleListener(listener: PushRuleListener)
fun removePushRuleListener(listener: PushRuleListener)

View File

@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.room.crypto.RoomCryptoService
import im.vector.matrix.android.api.session.room.members.MembershipService
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.relation.RelationService
import im.vector.matrix.android.api.session.room.notification.RoomPushRuleService
import im.vector.matrix.android.api.session.room.reporting.ReportingService
import im.vector.matrix.android.api.session.room.read.ReadService
import im.vector.matrix.android.api.session.room.send.DraftService
@ -41,7 +42,8 @@ interface Room :
StateService,
ReportingService,
RelationService,
RoomCryptoService {
RoomCryptoService,
RoomPushRuleService {
/**
* The roomId of this room

View File

@ -0,0 +1,42 @@
/*
* Copyright 2019 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.matrix.android.api.session.room.notification
/**
* Defines the room notification state
*/
enum class RoomNotificationState {
/**
* All the messages will trigger a noisy notification
*/
ALL_MESSAGES_NOISY,
/**
* All the messages will trigger a notification
*/
ALL_MESSAGES,
/**
* Only the messages with user display name / user name will trigger notifications
*/
MENTIONS_ONLY,
/**
* No notifications
*/
MUTE
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2019 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.matrix.android.api.session.room.notification
import androidx.lifecycle.LiveData
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.util.Cancelable
interface RoomPushRuleService {
fun getLiveRoomNotificationState(): LiveData<RoomNotificationState>
fun setRoomNotificationState(roomNotificationState: RoomNotificationState, matrixCallback: MatrixCallback<Unit>): Cancelable
}

View File

@ -17,6 +17,8 @@ package im.vector.matrix.android.internal.database.model
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.LinkingObjects
internal open class PushRuleEntity(
// Required. The actions to perform when this rule is matched.
@ -33,5 +35,8 @@ internal open class PushRuleEntity(
var pattern: String? = null
) : RealmObject() {
@LinkingObjects("pushRules")
val parent: RealmResults<PushRulesEntity>? = null
companion object
}

View File

@ -16,10 +16,10 @@
package im.vector.matrix.android.internal.database.query
import im.vector.matrix.android.api.pushrules.RuleKind
import im.vector.matrix.android.internal.database.model.*
import im.vector.matrix.android.internal.database.model.PushRuleEntity
import im.vector.matrix.android.internal.database.model.PushRulesEntity
import im.vector.matrix.android.internal.database.model.PushRulesEntityFields
import im.vector.matrix.android.internal.database.model.PusherEntity
import im.vector.matrix.android.internal.database.model.PusherEntityFields
import io.realm.Realm
import io.realm.RealmQuery
import io.realm.kotlin.where
@ -41,3 +41,12 @@ internal fun PushRulesEntity.Companion.where(realm: Realm,
.equalTo(PushRulesEntityFields.SCOPE, scope)
.equalTo(PushRulesEntityFields.KIND_STR, kind.name)
}
internal fun PushRuleEntity.Companion.where(realm: Realm,
scope: String,
ruleId: String): RealmQuery<PushRuleEntity> {
return realm.where<PushRuleEntity>()
.equalTo("${PushRuleEntityFields.PARENT}.${PushRulesEntityFields.SCOPE}", scope)
.equalTo(PushRuleEntityFields.RULE_ID, ruleId)
}

View File

@ -28,7 +28,9 @@ import im.vector.matrix.android.internal.database.mapper.PushRulesMapper
import im.vector.matrix.android.internal.database.model.PushRulesEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.pushers.AddPushRuleTask
import im.vector.matrix.android.internal.session.pushers.GetPushRulesTask
import im.vector.matrix.android.internal.session.pushers.RemovePushRuleTask
import im.vector.matrix.android.internal.session.pushers.UpdatePushRuleEnableStatusTask
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
@ -38,6 +40,8 @@ import javax.inject.Inject
@SessionScope
internal class DefaultPushRuleService @Inject constructor(private val getPushRulesTask: GetPushRulesTask,
private val updatePushRuleEnableStatusTask: UpdatePushRuleEnableStatusTask,
private val addPushRuleTask: AddPushRuleTask,
private val removePushRuleTask: RemovePushRuleTask,
private val taskExecutor: TaskExecutor,
private val monarchy: Monarchy
) : PushRuleService {
@ -98,6 +102,22 @@ internal class DefaultPushRuleService @Inject constructor(private val getPushRul
.executeBy(taskExecutor)
}
override fun addPushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable {
return addPushRuleTask
.configureWith(AddPushRuleTask.Params(kind, pushRule)) {
this.callback = callback
}
.executeBy(taskExecutor)
}
override fun removePushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable {
return removePushRuleTask
.configureWith(RemovePushRuleTask.Params(kind, pushRule)) {
this.callback = callback
}
.executeBy(taskExecutor)
}
override fun removePushRuleListener(listener: PushRuleService.PushRuleListener) {
synchronized(listeners) {
listeners.remove(listener)

View File

@ -0,0 +1,39 @@
/*
* Copyright 2019 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.matrix.android.internal.session.pushers
import im.vector.matrix.android.api.pushrules.RuleKind
import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject
internal interface AddPushRuleTask : Task<AddPushRuleTask.Params, Unit> {
data class Params(
val kind: RuleKind,
val pushRule: PushRule
)
}
internal class DefaultAddPushRuleTask @Inject constructor(private val pushRulesApi: PushRulesApi)
: AddPushRuleTask {
override suspend fun execute(params: AddPushRuleTask.Params) {
return executeRequest {
apiCall = pushRulesApi.addRule(params.kind.value, params.pushRule.ruleId, params.pushRule)
}
}
}

View File

@ -25,6 +25,8 @@ import im.vector.matrix.android.api.session.pushers.PushersService
import im.vector.matrix.android.internal.session.notification.DefaultProcessEventForPushTask
import im.vector.matrix.android.internal.session.notification.DefaultPushRuleService
import im.vector.matrix.android.internal.session.notification.ProcessEventForPushTask
import im.vector.matrix.android.internal.session.room.notification.DefaultSetRoomNotificationStateTask
import im.vector.matrix.android.internal.session.room.notification.SetRoomNotificationStateTask
import retrofit2.Retrofit
@Module
@ -67,6 +69,15 @@ internal abstract class PushersModule {
@Binds
abstract fun bindUpdatePushRuleEnableStatusTask(updatePushRuleEnableStatusTask: DefaultUpdatePushRuleEnableStatusTask): UpdatePushRuleEnableStatusTask
@Binds
abstract fun bindAddPushRuleTask(addPushRuleTask: DefaultAddPushRuleTask): AddPushRuleTask
@Binds
abstract fun bindRemovePushRuleTask(removePushRuleTask: DefaultRemovePushRuleTask): RemovePushRuleTask
@Binds
abstract fun bindSetRoomNotificationStateTask(setRoomNotificationStateTask: DefaultSetRoomNotificationStateTask): SetRoomNotificationStateTask
@Binds
abstract fun bindPushRuleService(pushRuleService: DefaultPushRuleService): PushRuleService

View File

@ -0,0 +1,39 @@
/*
* Copyright 2019 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.matrix.android.internal.session.pushers
import im.vector.matrix.android.api.pushrules.RuleKind
import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject
internal interface RemovePushRuleTask : Task<RemovePushRuleTask.Params, Unit> {
data class Params(
val kind: RuleKind,
val pushRule: PushRule
)
}
internal class DefaultRemovePushRuleTask @Inject constructor(private val pushRulesApi: PushRulesApi)
: RemovePushRuleTask {
override suspend fun execute(params: RemovePushRuleTask.Params) {
return executeRequest {
apiCall = pushRulesApi.deleteRule(params.kind.value, params.pushRule.ruleId)
}
}
}

View File

@ -24,6 +24,7 @@ import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.members.MembershipService
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.relation.RelationService
import im.vector.matrix.android.api.session.room.notification.RoomPushRuleService
import im.vector.matrix.android.api.session.room.reporting.ReportingService
import im.vector.matrix.android.api.session.room.read.ReadService
import im.vector.matrix.android.api.session.room.send.DraftService
@ -49,7 +50,8 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
private val readService: ReadService,
private val cryptoService: CryptoService,
private val relationService: RelationService,
private val roomMembersService: MembershipService) :
private val roomMembersService: MembershipService,
private val roomPushRuleService: RoomPushRuleService) :
Room,
TimelineService by timelineService,
SendService by sendService,
@ -58,7 +60,8 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
ReportingService by reportingService,
ReadService by readService,
RelationService by relationService,
MembershipService by roomMembersService {
MembershipService by roomMembersService,
RoomPushRuleService by roomPushRuleService {
override fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>> {
val liveData = monarchy.findAllMappedWithChanges(

View File

@ -19,9 +19,11 @@ package im.vector.matrix.android.internal.session.room
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.notification.RoomPushRuleService
import im.vector.matrix.android.internal.database.mapper.RoomSummaryMapper
import im.vector.matrix.android.internal.session.room.draft.DefaultDraftService
import im.vector.matrix.android.internal.session.room.membership.DefaultMembershipService
import im.vector.matrix.android.internal.session.room.notification.DefaultRoomPushRuleService
import im.vector.matrix.android.internal.session.room.read.DefaultReadService
import im.vector.matrix.android.internal.session.room.relation.DefaultRelationService
import im.vector.matrix.android.internal.session.room.reporting.DefaultReportingService
@ -44,7 +46,8 @@ internal class DefaultRoomFactory @Inject constructor(private val monarchy: Mona
private val reportingServiceFactory: DefaultReportingService.Factory,
private val readServiceFactory: DefaultReadService.Factory,
private val relationServiceFactory: DefaultRelationService.Factory,
private val membershipServiceFactory: DefaultMembershipService.Factory) :
private val membershipServiceFactory: DefaultMembershipService.Factory,
private val roomPushRuleServiceFactory: DefaultRoomPushRuleService.Factory) :
RoomFactory {
override fun create(roomId: String): Room {
@ -60,7 +63,8 @@ internal class DefaultRoomFactory @Inject constructor(private val monarchy: Mona
readServiceFactory.create(roomId),
cryptoService,
relationServiceFactory.create(roomId),
membershipServiceFactory.create(roomId)
membershipServiceFactory.create(roomId),
roomPushRuleServiceFactory.create(roomId)
)
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright 2019 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.matrix.android.internal.session.room.notification
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.pushrules.RuleScope
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
import im.vector.matrix.android.api.session.room.notification.RoomPushRuleService
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.database.model.PushRuleEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
internal class DefaultRoomPushRuleService @AssistedInject constructor(@Assisted private val roomId: String,
private val setRoomNotificationStateTask: SetRoomNotificationStateTask,
private val monarchy: Monarchy,
private val taskExecutor: TaskExecutor)
: RoomPushRuleService {
@AssistedInject.Factory
interface Factory {
fun create(roomId: String): RoomPushRuleService
}
override fun getLiveRoomNotificationState(): LiveData<RoomNotificationState> {
return Transformations.map(getPushRuleForRoom()) {
it?.toRoomNotificationState() ?: RoomNotificationState.ALL_MESSAGES
}
}
override fun setRoomNotificationState(roomNotificationState: RoomNotificationState, matrixCallback: MatrixCallback<Unit>): Cancelable {
return setRoomNotificationStateTask
.configureWith(SetRoomNotificationStateTask.Params(roomId, roomNotificationState)) {
this.callback = callback
}
.executeBy(taskExecutor)
}
private fun getPushRuleForRoom(): LiveData<RoomPushRule?> {
val liveData = monarchy.findAllMappedWithChanges(
{ realm ->
PushRuleEntity.where(realm, scope = RuleScope.GLOBAL, ruleId = roomId)
},
{ result ->
result.toRoomPushRule()
}
)
return Transformations.map(liveData) { results ->
results.firstOrNull()
}
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2019 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.matrix.android.internal.session.room.notification
import im.vector.matrix.android.api.pushrules.RuleKind
import im.vector.matrix.android.api.pushrules.rest.PushRule
internal data class RoomPushRule(
val kind: RuleKind,
val rule: PushRule
)

View File

@ -0,0 +1,102 @@
/*
* Copyright 2019 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.matrix.android.internal.session.room.notification
import im.vector.matrix.android.api.pushrules.*
import im.vector.matrix.android.api.pushrules.rest.PushCondition
import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
import im.vector.matrix.android.internal.database.mapper.PushRulesMapper
import im.vector.matrix.android.internal.database.model.PushRuleEntity
internal fun PushRuleEntity.toRoomPushRule(): RoomPushRule? {
val kind = parent?.firstOrNull()?.kind
val pushRule = when (kind) {
RuleSetKey.OVERRIDE -> {
PushRulesMapper.map(this)
}
RuleSetKey.ROOM -> {
PushRulesMapper.mapRoomRule(this)
}
else -> null
}
return if (pushRule == null || kind == null) {
null
} else {
RoomPushRule(kind, pushRule)
}
}
internal fun RoomNotificationState.toRoomPushRule(roomId: String): RoomPushRule? {
return when {
this == RoomNotificationState.ALL_MESSAGES -> null
this == RoomNotificationState.ALL_MESSAGES_NOISY -> {
val rule = PushRule(
actions = listOf(Action.Notify, Action.Sound()).toJson(),
enabled = true,
ruleId = roomId
)
return RoomPushRule(RuleSetKey.ROOM, rule)
}
else -> {
val condition = PushCondition(
kind = Condition.Kind.event_match.value,
key = "room_id",
pattern = roomId
)
val rule = PushRule(
actions = listOf(Action.DoNotNotify).toJson(),
enabled = true,
ruleId = roomId,
conditions = listOf(condition)
)
val kind = if (this == RoomNotificationState.MUTE) {
RuleSetKey.OVERRIDE
} else {
RuleSetKey.ROOM
}
return RoomPushRule(kind, rule)
}
}
}
internal fun RoomPushRule.toRoomNotificationState(): RoomNotificationState {
return if (rule.enabled) {
val actions = rule.getActions()
if (actions.contains(Action.DoNotNotify)) {
if (kind == RuleSetKey.OVERRIDE) {
RoomNotificationState.MUTE
} else {
RoomNotificationState.MENTIONS_ONLY
}
} else if (actions.contains(Action.Notify)) {
val hasSoundAction = actions.find {
it is Action.Sound
} != null
if (hasSoundAction) {
RoomNotificationState.ALL_MESSAGES_NOISY
} else {
RoomNotificationState.ALL_MESSAGES
}
} else {
RoomNotificationState.ALL_MESSAGES
}
} else {
RoomNotificationState.ALL_MESSAGES
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2019 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.matrix.android.internal.session.room.notification
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.pushrules.RuleScope
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
import im.vector.matrix.android.internal.database.model.PushRuleEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.session.pushers.AddPushRuleTask
import im.vector.matrix.android.internal.session.pushers.RemovePushRuleTask
import im.vector.matrix.android.internal.task.Task
import io.realm.Realm
import javax.inject.Inject
internal interface SetRoomNotificationStateTask : Task<SetRoomNotificationStateTask.Params, Unit> {
data class Params(
val roomId: String,
val roomNotificationState: RoomNotificationState
)
}
internal class DefaultSetRoomNotificationStateTask @Inject constructor(private val monarchy: Monarchy,
private val removePushRuleTask: RemovePushRuleTask,
private val addPushRuleTask: AddPushRuleTask)
: SetRoomNotificationStateTask {
override suspend fun execute(params: SetRoomNotificationStateTask.Params) {
val currentRoomPushRule = Realm.getInstance(monarchy.realmConfiguration).use {
PushRuleEntity.where(it, scope = RuleScope.GLOBAL, ruleId = params.roomId).findFirst()?.toRoomPushRule()
}
if (currentRoomPushRule != null) {
removePushRuleTask.execute(RemovePushRuleTask.Params(currentRoomPushRule.kind, currentRoomPushRule.rule))
}
val newRoomPushRule = params.roomNotificationState.toRoomPushRule(params.roomId)
if (newRoomPushRule != null) {
addPushRuleTask.execute(AddPushRuleTask.Params(newRoomPushRule.kind, newRoomPushRule.rule))
}
}
}

View File

@ -17,6 +17,7 @@
package im.vector.riotx.features.home.room.list
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
sealed class RoomListActions {
data class SelectRoom(val roomSummary: RoomSummary) : RoomListActions()
@ -24,7 +25,7 @@ sealed class RoomListActions {
data class AcceptInvitation(val roomSummary: RoomSummary) : RoomListActions()
data class RejectInvitation(val roomSummary: RoomSummary) : RoomListActions()
data class FilterWith(val filter: String) : RoomListActions()
data class ChangeNotificationMode(val notificationMode: String) : RoomListActions()
data class ChangeRoomNotificationState(val roomId: String, val notificationState: RoomNotificationState) : RoomListActions()
data class LeaveRoom(val roomId: String) : RoomListActions()
object MarkAllRoomsRead : RoomListActions()
}

View File

@ -31,6 +31,7 @@ import com.google.android.material.snackbar.Snackbar
import im.vector.matrix.android.api.failure.Failure
import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
import im.vector.riotx.R
import im.vector.riotx.core.di.ScreenComponent
import im.vector.riotx.core.epoxy.LayoutManagerStateRestorer
@ -216,12 +217,24 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O
private fun handleQuickActions(quickActions: RoomListQuickActions) {
when (quickActions) {
is RoomListQuickActions.NotificationsAllNoisy -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode(""))
is RoomListQuickActions.NotificationsAll -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode(""))
is RoomListQuickActions.NotificationsMentionsOnly -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode(""))
is RoomListQuickActions.NotificationsMute -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode(""))
is RoomListQuickActions.Settings -> navigator.openRoomSettings(requireContext(), quickActions.roomId)
is RoomListQuickActions.Leave -> roomListViewModel.accept(RoomListActions.LeaveRoom(quickActions.roomId))
is RoomListQuickActions.NotificationsAllNoisy -> {
roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.ALL_MESSAGES_NOISY))
}
is RoomListQuickActions.NotificationsAll -> {
roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.ALL_MESSAGES))
}
is RoomListQuickActions.NotificationsMentionsOnly -> {
roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.MENTIONS_ONLY))
}
is RoomListQuickActions.NotificationsMute -> {
roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.MUTE))
}
is RoomListQuickActions.Settings -> {
navigator.openRoomSettings(requireContext(), quickActions.roomId)
}
is RoomListQuickActions.Leave -> {
roomListViewModel.accept(RoomListActions.LeaveRoom(quickActions.roomId))
}
}
}

View File

@ -73,14 +73,14 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
fun accept(action: RoomListActions) {
when (action) {
is RoomListActions.SelectRoom -> handleSelectRoom(action)
is RoomListActions.ToggleCategory -> handleToggleCategory(action)
is RoomListActions.AcceptInvitation -> handleAcceptInvitation(action)
is RoomListActions.RejectInvitation -> handleRejectInvitation(action)
is RoomListActions.FilterWith -> handleFilter(action)
is RoomListActions.MarkAllRoomsRead -> handleMarkAllRoomsRead()
is RoomListActions.LeaveRoom -> handleLeaveRoom(action)
is RoomListActions.ChangeNotificationMode -> handleChangeNotificationMode(action)
is RoomListActions.SelectRoom -> handleSelectRoom(action)
is RoomListActions.ToggleCategory -> handleToggleCategory(action)
is RoomListActions.AcceptInvitation -> handleAcceptInvitation(action)
is RoomListActions.RejectInvitation -> handleRejectInvitation(action)
is RoomListActions.FilterWith -> handleFilter(action)
is RoomListActions.MarkAllRoomsRead -> handleMarkAllRoomsRead()
is RoomListActions.LeaveRoom -> handleLeaveRoom(action)
is RoomListActions.ChangeRoomNotificationState -> handleChangeNotificationMode(action)
}
}
@ -205,9 +205,10 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
?.let { session.markAllAsRead(it, object : MatrixCallback<Unit> {}) }
}
private fun handleChangeNotificationMode(action: RoomListActions.ChangeNotificationMode) {
//TODO handle this
Timber.v("Not handled yet: $action")
private fun handleChangeNotificationMode(action: RoomListActions.ChangeRoomNotificationState) {
session.getRoom(action.roomId)?.also {
it.setRoomNotificationState(action.notificationState, object : MatrixCallback<Unit> {})
}
}
private fun handleLeaveRoom(action: RoomListActions.LeaveRoom) {

View File

@ -20,10 +20,12 @@ import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MvRxState
import com.airbnb.mvrx.Uninitialized
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
data class RoomListQuickActionsState(
val roomId: String,
val roomSummary: Async<RoomSummary> = Uninitialized
val roomSummary: Async<RoomSummary> = Uninitialized,
val roomNotificationState: Async<RoomNotificationState> = Uninitialized
) : MvRxState {
constructor(args: RoomListActionsArgs) : this(roomId = args.roomId)

View File

@ -51,6 +51,16 @@ class RoomListActionsViewModel @AssistedInject constructor(@Assisted
init {
observeRoomSummary()
observeNotificationState()
}
private fun observeNotificationState() {
room
.rx()
.liveNotificationState()
.execute {
copy(roomNotificationState = it)
}
}
private fun observeRoomSummary() {