mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-17 19:58:57 +03:00
Merge branch 'develop' into feature/perf_again
This commit is contained in:
commit
1bd2c0d220
176 changed files with 3114 additions and 1353 deletions
|
@ -2,7 +2,8 @@ Changes in RiotX 0.8.0 (2019-XX-XX)
|
|||
===================================================
|
||||
|
||||
Features ✨:
|
||||
-
|
||||
- Handle long click on room in the room list (#395)
|
||||
- Ignore/UnIgnore users, and display list of ignored users (#542, #617)
|
||||
|
||||
Improvements 🙌:
|
||||
- Search reaction by name or keyword in emoji picker
|
||||
|
@ -38,6 +39,7 @@ Improvements:
|
|||
- Attachments: start using system pickers (#52)
|
||||
- Mark all messages as read (#396)
|
||||
|
||||
|
||||
Other changes:
|
||||
- Accessibility improvements to read receipts in the room timeline and reactions emoji chooser
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -54,6 +54,10 @@ class RxSession(private val session: Session) {
|
|||
return session.liveUsers().asObservable()
|
||||
}
|
||||
|
||||
fun liveIgnoredUsers(): Observable<List<User>> {
|
||||
return session.liveIgnoredUsers().asObservable()
|
||||
}
|
||||
|
||||
fun livePagedUsers(filter: String? = null): Observable<PagedList<User>> {
|
||||
return session.livePagedUsers(filter).asObservable()
|
||||
}
|
||||
|
|
|
@ -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,29 @@ 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>()
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -19,7 +19,7 @@ package im.vector.matrix.android.api.session.cache
|
|||
import im.vector.matrix.android.api.MatrixCallback
|
||||
|
||||
/**
|
||||
* This interface defines a method to sign out. It's implemented at the session level.
|
||||
* This interface defines a method to clear the cache. It's implemented at the session level.
|
||||
*/
|
||||
interface CacheService {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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
|
||||
}
|
|
@ -64,4 +64,19 @@ interface UserService {
|
|||
* @return a Livedata of users
|
||||
*/
|
||||
fun livePagedUsers(filter: String? = null): LiveData<PagedList<User>>
|
||||
|
||||
/**
|
||||
* Get list of ignored users
|
||||
*/
|
||||
fun liveIgnoredUsers(): LiveData<List<User>>
|
||||
|
||||
/**
|
||||
* Ignore users
|
||||
*/
|
||||
fun ignoreUserIds(userIds: List<String>, callback: MatrixCallback<Unit>): Cancelable
|
||||
|
||||
/**
|
||||
* Un-ignore some users
|
||||
*/
|
||||
fun unIgnoreUserIds(userIds: List<String>, callback: MatrixCallback<Unit>): Cancelable
|
||||
}
|
||||
|
|
|
@ -21,4 +21,6 @@ import java.lang.reflect.ParameterizedType
|
|||
|
||||
typealias JsonDict = Map<String, @JvmSuppressWildcards Any>
|
||||
|
||||
val emptyJsonDict = emptyMap<String, Any>()
|
||||
|
||||
internal val JSON_DICT_PARAMETERIZED_TYPE: ParameterizedType = Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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.database.model
|
||||
|
||||
import io.realm.RealmObject
|
||||
|
||||
internal open class IgnoredUserEntity(var userId: String = "") : RealmObject() {
|
||||
|
||||
companion object
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import io.realm.annotations.RealmModule
|
|||
RoomTagEntity::class,
|
||||
SyncEntity::class,
|
||||
UserEntity::class,
|
||||
IgnoredUserEntity::class,
|
||||
EventAnnotationsSummaryEntity::class,
|
||||
ReactionAggregatedSummaryEntity::class,
|
||||
EditAggregatedSummaryEntity::class,
|
||||
|
|
|
@ -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,11 @@ 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)
|
||||
}
|
||||
|
|
|
@ -20,10 +20,11 @@ import com.squareup.moshi.Moshi
|
|||
import im.vector.matrix.android.api.session.room.model.message.*
|
||||
import im.vector.matrix.android.internal.network.parsing.RuntimeJsonAdapterFactory
|
||||
import im.vector.matrix.android.internal.network.parsing.UriMoshiAdapter
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountData
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountDataDirectMessages
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountDataFallback
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountDataPushRules
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataDirectMessages
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataFallback
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataPushRules
|
||||
|
||||
object MoshiProvider {
|
||||
|
||||
|
@ -31,6 +32,7 @@ object MoshiProvider {
|
|||
.add(UriMoshiAdapter())
|
||||
.add(RuntimeJsonAdapterFactory.of(UserAccountData::class.java, "type", UserAccountDataFallback::class.java)
|
||||
.registerSubtype(UserAccountDataDirectMessages::class.java, UserAccountData.TYPE_DIRECT_MESSAGES)
|
||||
.registerSubtype(UserAccountDataIgnoredUsers::class.java, UserAccountData.TYPE_IGNORED_USER_LIST)
|
||||
.registerSubtype(UserAccountDataPushRules::class.java, UserAccountData.TYPE_PUSH_RULES)
|
||||
)
|
||||
.add(RuntimeJsonAdapterFactory.of(MessageContent::class.java, "msgtype", MessageDefaultContent::class.java)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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(
|
||||
|
|
|
@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.room.Room
|
|||
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 +45,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 +62,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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
)
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,10 +27,9 @@ import im.vector.matrix.android.internal.di.UserId
|
|||
import im.vector.matrix.android.internal.session.pushers.SavePushRulesTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountDataDirectMessages
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountDataPushRules
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountDataSync
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.*
|
||||
import im.vector.matrix.android.internal.session.user.accountdata.DirectChatsHelper
|
||||
import im.vector.matrix.android.internal.session.user.accountdata.SaveIgnoredUsersTask
|
||||
import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
|
@ -44,6 +43,7 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc
|
|||
private val directChatsHelper: DirectChatsHelper,
|
||||
private val updateUserAccountDataTask: UpdateUserAccountDataTask,
|
||||
private val savePushRulesTask: SavePushRulesTask,
|
||||
private val saveIgnoredUsersTask: SaveIgnoredUsersTask,
|
||||
private val taskExecutor: TaskExecutor) {
|
||||
|
||||
suspend fun handle(accountData: UserAccountDataSync?, invites: Map<String, InvitedRoomSync>?) {
|
||||
|
@ -51,9 +51,18 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc
|
|||
when (it) {
|
||||
is UserAccountDataDirectMessages -> handleDirectChatRooms(it)
|
||||
is UserAccountDataPushRules -> handlePushRules(it)
|
||||
else -> return@forEach
|
||||
is UserAccountDataIgnoredUsers -> handleIgnoredUsers(it)
|
||||
is UserAccountDataFallback -> Timber.d("Receive account data of unhandled type ${it.type}")
|
||||
else -> error("Missing code here!")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Store all account data, app can be interested of it
|
||||
// accountData?.list?.forEach {
|
||||
// it.toString()
|
||||
// MoshiProvider.providesMoshi()
|
||||
// }
|
||||
|
||||
monarchy.doWithRealm { realm ->
|
||||
synchronizeWithServerIfNeeded(realm, invites)
|
||||
}
|
||||
|
@ -114,4 +123,11 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc
|
|||
updateUserAccountDataTask.configureWith(updateUserAccountParams).executeBy(taskExecutor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleIgnoredUsers(userAccountDataIgnoredUsers: UserAccountDataIgnoredUsers) {
|
||||
saveIgnoredUsersTask
|
||||
.configureWith(SaveIgnoredUsersTask.Params(userAccountDataIgnoredUsers.content.ignoredUsers.keys.toList()))
|
||||
.executeBy(taskExecutor)
|
||||
// TODO If not initial sync, we should execute a init sync
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.session.sync.model
|
|||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataSync
|
||||
|
||||
// SyncResponse represents the request response for server sync v2.
|
||||
@JsonClass(generateAdapter = true)
|
||||
|
|
|
@ -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.sync.model.accountdata
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.util.JsonDict
|
||||
import im.vector.matrix.android.api.util.emptyJsonDict
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class IgnoredUsersContent(
|
||||
/**
|
||||
* Required. The map of users to ignore. UserId -> empty object for future enhancement
|
||||
*/
|
||||
@Json(name = "ignored_users") val ignoredUsers: Map<String, JsonDict>
|
||||
) {
|
||||
|
||||
companion object {
|
||||
fun createWithUserIds(userIds: List<String>): IgnoredUsersContent {
|
||||
return IgnoredUsersContent(
|
||||
ignoredUsers = userIds.associateWith { emptyJsonDict }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,9 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.sync.model
|
||||
package im.vector.matrix.android.internal.session.sync.model.accountdata
|
||||
|
||||
internal interface UserAccountData {
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
internal abstract class UserAccountData {
|
||||
|
||||
@Json(name = "type") abstract val type: String
|
||||
|
||||
companion object {
|
||||
const val TYPE_IGNORED_USER_LIST = "m.ignored_user_list"
|
|
@ -14,12 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.sync.model
|
||||
package im.vector.matrix.android.internal.session.sync.model.accountdata
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class UserAccountDataDirectMessages(
|
||||
@Json(name = "type") override val type: String = TYPE_DIRECT_MESSAGES,
|
||||
@Json(name = "content") val content: Map<String, List<String>>
|
||||
) : UserAccountData
|
||||
) : UserAccountData()
|
|
@ -14,12 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.sync.model
|
||||
package im.vector.matrix.android.internal.session.sync.model.accountdata
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class UserAccountDataFallback(
|
||||
@Json(name = "type") override val type: String,
|
||||
@Json(name = "content") val content: Map<String, Any>
|
||||
) : UserAccountData
|
||||
) : UserAccountData()
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.sync.model.accountdata
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class UserAccountDataIgnoredUsers(
|
||||
@Json(name = "type") override val type: String = TYPE_IGNORED_USER_LIST,
|
||||
@Json(name = "content") val content: IgnoredUsersContent
|
||||
) : UserAccountData()
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.sync.model
|
||||
package im.vector.matrix.android.internal.session.sync.model.accountdata
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
@ -22,5 +22,6 @@ import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse
|
|||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class UserAccountDataPushRules(
|
||||
@Json(name = "type") override val type: String = TYPE_PUSH_RULES,
|
||||
@Json(name = "content") val content: GetPushRulesResponse
|
||||
) : UserAccountData
|
||||
) : UserAccountData()
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.sync.model
|
||||
package im.vector.matrix.android.internal.session.sync.model.accountdata
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
|
@ -29,9 +29,12 @@ import im.vector.matrix.android.api.util.Cancelable
|
|||
import im.vector.matrix.android.api.util.Optional
|
||||
import im.vector.matrix.android.api.util.toOptional
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.IgnoredUserEntity
|
||||
import im.vector.matrix.android.internal.database.model.IgnoredUserEntityFields
|
||||
import im.vector.matrix.android.internal.database.model.UserEntity
|
||||
import im.vector.matrix.android.internal.database.model.UserEntityFields
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.user.accountdata.UpdateIgnoredUserIdsTask
|
||||
import im.vector.matrix.android.internal.session.user.model.SearchUserTask
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
|
@ -40,8 +43,8 @@ import javax.inject.Inject
|
|||
|
||||
internal class DefaultUserService @Inject constructor(private val monarchy: Monarchy,
|
||||
private val searchUserTask: SearchUserTask,
|
||||
private val updateIgnoredUserIdsTask: UpdateIgnoredUserIdsTask,
|
||||
private val taskExecutor: TaskExecutor) : UserService {
|
||||
|
||||
private val realmDataSourceFactory: Monarchy.RealmDataSourceFactory<UserEntity> by lazy {
|
||||
monarchy.createDataSourceFactory { realm ->
|
||||
realm.where(UserEntity::class.java)
|
||||
|
@ -62,7 +65,7 @@ internal class DefaultUserService @Inject constructor(private val monarchy: Mona
|
|||
|
||||
override fun getUser(userId: String): User? {
|
||||
val userEntity = monarchy.fetchCopied { UserEntity.where(it, userId).findFirst() }
|
||||
?: return null
|
||||
?: return null
|
||||
|
||||
return userEntity.asDomain()
|
||||
}
|
||||
|
@ -117,4 +120,33 @@ internal class DefaultUserService @Inject constructor(private val monarchy: Mona
|
|||
}
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
override fun liveIgnoredUsers(): LiveData<List<User>> {
|
||||
return monarchy.findAllMappedWithChanges(
|
||||
{ realm ->
|
||||
realm.where(IgnoredUserEntity::class.java)
|
||||
.isNotEmpty(IgnoredUserEntityFields.USER_ID)
|
||||
.sort(IgnoredUserEntityFields.USER_ID)
|
||||
},
|
||||
{ getUser(it.userId) ?: User(userId = it.userId) }
|
||||
)
|
||||
}
|
||||
|
||||
override fun ignoreUserIds(userIds: List<String>, callback: MatrixCallback<Unit>): Cancelable {
|
||||
val params = UpdateIgnoredUserIdsTask.Params(userIdsToIgnore = userIds.toList())
|
||||
return updateIgnoredUserIdsTask
|
||||
.configureWith(params) {
|
||||
this.callback = callback
|
||||
}
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
override fun unIgnoreUserIds(userIds: List<String>, callback: MatrixCallback<Unit>): Cancelable {
|
||||
val params = UpdateIgnoredUserIdsTask.Params(userIdsToUnIgnore = userIds.toList())
|
||||
return updateIgnoredUserIdsTask
|
||||
.configureWith(params) {
|
||||
this.callback = callback
|
||||
}
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ import dagger.Module
|
|||
import dagger.Provides
|
||||
import im.vector.matrix.android.api.session.user.UserService
|
||||
import im.vector.matrix.android.internal.session.SessionScope
|
||||
import im.vector.matrix.android.internal.session.user.accountdata.DefaultSaveIgnoredUsersTask
|
||||
import im.vector.matrix.android.internal.session.user.accountdata.DefaultUpdateIgnoredUserIdsTask
|
||||
import im.vector.matrix.android.internal.session.user.accountdata.SaveIgnoredUsersTask
|
||||
import im.vector.matrix.android.internal.session.user.accountdata.UpdateIgnoredUserIdsTask
|
||||
import im.vector.matrix.android.internal.session.user.model.DefaultSearchUserTask
|
||||
import im.vector.matrix.android.internal.session.user.model.SearchUserTask
|
||||
import retrofit2.Retrofit
|
||||
|
@ -43,4 +47,10 @@ internal abstract class UserModule {
|
|||
|
||||
@Binds
|
||||
abstract fun bindSearchUserTask(searchUserTask: DefaultSearchUserTask): SearchUserTask
|
||||
|
||||
@Binds
|
||||
abstract fun bindSaveIgnoredUsersTask(task: DefaultSaveIgnoredUsersTask): SaveIgnoredUsersTask
|
||||
|
||||
@Binds
|
||||
abstract fun bindUpdateIgnoredUserIdsTask(task: DefaultUpdateIgnoredUserIdsTask): UpdateIgnoredUserIdsTask
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.user.accountdata
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.internal.database.model.IgnoredUserEntity
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import im.vector.matrix.android.internal.util.awaitTransaction
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Save the ignored users list in DB
|
||||
*/
|
||||
internal interface SaveIgnoredUsersTask : Task<SaveIgnoredUsersTask.Params, Unit> {
|
||||
data class Params(
|
||||
val userIds: List<String>
|
||||
)
|
||||
}
|
||||
|
||||
internal class DefaultSaveIgnoredUsersTask @Inject constructor(private val monarchy: Monarchy) : SaveIgnoredUsersTask {
|
||||
|
||||
override suspend fun execute(params: SaveIgnoredUsersTask.Params) {
|
||||
monarchy.awaitTransaction { realm ->
|
||||
// clear current ignored users
|
||||
realm.where(IgnoredUserEntity::class.java)
|
||||
.findAll()
|
||||
.deleteAllFromRealm()
|
||||
|
||||
// And save the new received list
|
||||
params.userIds.forEach { realm.createObject(IgnoredUserEntity::class.java).apply { userId = it } }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.user.accountdata
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.internal.database.model.IgnoredUserEntity
|
||||
import im.vector.matrix.android.internal.di.UserId
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.IgnoredUsersContent
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import javax.inject.Inject
|
||||
|
||||
internal interface UpdateIgnoredUserIdsTask : Task<UpdateIgnoredUserIdsTask.Params, Unit> {
|
||||
|
||||
data class Params(
|
||||
val userIdsToIgnore: List<String> = emptyList(),
|
||||
val userIdsToUnIgnore: List<String> = emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor(private val accountDataApi: AccountDataAPI,
|
||||
private val monarchy: Monarchy,
|
||||
private val saveIgnoredUsersTask: SaveIgnoredUsersTask,
|
||||
@UserId private val userId: String) : UpdateIgnoredUserIdsTask {
|
||||
|
||||
override suspend fun execute(params: UpdateIgnoredUserIdsTask.Params) {
|
||||
// Get current list
|
||||
val ignoredUserIds = monarchy.fetchAllMappedSync(
|
||||
{ realm -> realm.where(IgnoredUserEntity::class.java) },
|
||||
{ it.userId }
|
||||
).toMutableSet()
|
||||
|
||||
val original = ignoredUserIds.toList()
|
||||
|
||||
ignoredUserIds.removeAll { it in params.userIdsToUnIgnore }
|
||||
ignoredUserIds.addAll(params.userIdsToIgnore)
|
||||
|
||||
if (original == ignoredUserIds) {
|
||||
// No change
|
||||
return
|
||||
}
|
||||
|
||||
val list = ignoredUserIds.toList()
|
||||
val body = IgnoredUsersContent.createWithUserIds(list)
|
||||
|
||||
executeRequest<Unit> {
|
||||
apiCall = accountDataApi.setAccountData(userId, UserAccountData.TYPE_IGNORED_USER_LIST, body)
|
||||
}
|
||||
|
||||
// Update the DB right now (do not wait for the sync to come back with updated data, for a faster UI update)
|
||||
saveIgnoredUsersTask.execute(SaveIgnoredUsersTask.Params(list))
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ package im.vector.matrix.android.internal.session.user.accountdata
|
|||
|
||||
import im.vector.matrix.android.internal.di.UserId
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountData
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -29,6 +29,7 @@ internal interface UpdateUserAccountDataTask : Task<UpdateUserAccountDataTask.Pa
|
|||
fun getData(): Any
|
||||
}
|
||||
|
||||
// TODO Use [UserAccountDataDirectMessages] class?
|
||||
data class DirectChatParams(override val type: String = UserAccountData.TYPE_DIRECT_MESSAGES,
|
||||
private val directMessages: Map<String, List<String>>
|
||||
) : Params {
|
||||
|
|
|
@ -16,23 +16,15 @@
|
|||
|
||||
package im.vector.matrix.android.api.pushrules
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.content.ContentAttachmentData
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.toContent
|
||||
import im.vector.matrix.android.api.session.room.Room
|
||||
import im.vector.matrix.android.api.session.room.RoomService
|
||||
import im.vector.matrix.android.api.session.room.model.*
|
||||
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
|
||||
import im.vector.matrix.android.api.session.room.send.UserDraft
|
||||
import im.vector.matrix.android.api.session.room.timeline.Timeline
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineSettings
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.api.util.Optional
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
|
@ -133,17 +125,20 @@ class PushrulesConditionTest {
|
|||
val conditionEqual3Bis = RoomMemberCountCondition("==3")
|
||||
val conditionLessThan3 = RoomMemberCountCondition("<3")
|
||||
|
||||
val session = MockRoomService()
|
||||
val room2JoinedId = "2joined"
|
||||
val room3JoinedId = "3joined"
|
||||
|
||||
Event(
|
||||
type = "m.room.message",
|
||||
eventId = "mx0",
|
||||
content = MessageTextContent("m.text", "A").toContent(),
|
||||
originServerTs = 0,
|
||||
roomId = "2joined").also {
|
||||
Assert.assertFalse("This room does not have 3 members", conditionEqual3.isSatisfied(it, session))
|
||||
Assert.assertFalse("This room does not have 3 members", conditionEqual3Bis.isSatisfied(it, session))
|
||||
Assert.assertTrue("This room has less than 3 members", conditionLessThan3.isSatisfied(it, session))
|
||||
val roomStub2Joined = mockk<Room> {
|
||||
every { getNumberOfJoinedMembers() } returns 2
|
||||
}
|
||||
|
||||
val roomStub3Joined = mockk<Room> {
|
||||
every { getNumberOfJoinedMembers() } returns 3
|
||||
}
|
||||
|
||||
val sessionStub = mockk<RoomService> {
|
||||
every { getRoom(room2JoinedId) } returns roomStub2Joined
|
||||
every { getRoom(room3JoinedId) } returns roomStub3Joined
|
||||
}
|
||||
|
||||
Event(
|
||||
|
@ -151,10 +146,21 @@ class PushrulesConditionTest {
|
|||
eventId = "mx0",
|
||||
content = MessageTextContent("m.text", "A").toContent(),
|
||||
originServerTs = 0,
|
||||
roomId = "3joined").also {
|
||||
Assert.assertTrue("This room has 3 members", conditionEqual3.isSatisfied(it, session))
|
||||
Assert.assertTrue("This room has 3 members", conditionEqual3Bis.isSatisfied(it, session))
|
||||
Assert.assertFalse("This room has more than 3 members", conditionLessThan3.isSatisfied(it, session))
|
||||
roomId = room2JoinedId).also {
|
||||
Assert.assertFalse("This room does not have 3 members", conditionEqual3.isSatisfied(it, sessionStub))
|
||||
Assert.assertFalse("This room does not have 3 members", conditionEqual3Bis.isSatisfied(it, sessionStub))
|
||||
Assert.assertTrue("This room has less than 3 members", conditionLessThan3.isSatisfied(it, sessionStub))
|
||||
}
|
||||
|
||||
Event(
|
||||
type = "m.room.message",
|
||||
eventId = "mx0",
|
||||
content = MessageTextContent("m.text", "A").toContent(),
|
||||
originServerTs = 0,
|
||||
roomId = room3JoinedId).also {
|
||||
Assert.assertTrue("This room has 3 members", conditionEqual3.isSatisfied(it, sessionStub))
|
||||
Assert.assertTrue("This room has 3 members", conditionEqual3Bis.isSatisfied(it, sessionStub))
|
||||
Assert.assertFalse("This room has more than 3 members", conditionLessThan3.isSatisfied(it, sessionStub))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,212 +177,4 @@ class PushrulesConditionTest {
|
|||
Assert.assertTrue("Notice", conditionEqual.isSatisfied(it))
|
||||
}
|
||||
}
|
||||
|
||||
class MockRoomService() : RoomService {
|
||||
override fun createRoom(createRoomParams: CreateRoomParams, callback: MatrixCallback<String>): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun joinRoom(roomId: String, viaServers: List<String>, callback: MatrixCallback<Unit>): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getRoom(roomId: String): Room? {
|
||||
return when (roomId) {
|
||||
"2joined" -> MockRoom(roomId, 2)
|
||||
"3joined" -> MockRoom(roomId, 3)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun liveRoomSummaries(): LiveData<List<RoomSummary>> {
|
||||
return MutableLiveData()
|
||||
}
|
||||
|
||||
override fun markAllAsRead(roomIds: List<String>, callback: MatrixCallback<Unit>): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
class MockRoom(override val roomId: String, val _numberOfJoinedMembers: Int) : Room {
|
||||
override fun reportContent(eventId: String, score: Int, reason: String, callback: MatrixCallback<Unit>): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getReadMarkerLive(): LiveData<Optional<String>> {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getMyReadReceiptLive(): LiveData<Optional<String>> {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun resendTextMessage(localEcho: TimelineEvent): Cancelable? {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun resendMediaMessage(localEcho: TimelineEvent): Cancelable? {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun deleteFailedEcho(localEcho: TimelineEvent) {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun clearSendingQueue() {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun resendAllFailedMessages() {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun saveDraft(draft: UserDraft) {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun deleteDraft() {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getDraftsLive(): LiveData<List<UserDraft>> {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getEventReadReceiptsLive(eventId: String): LiveData<List<ReadReceipt>> {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getStateEvent(eventType: String): Event? {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun editReply(replyToEdit: TimelineEvent, originalTimelineEvent: TimelineEvent, newBodyText: String, compatibilityBodyText: String): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun fetchEditHistory(eventId: String, callback: MatrixCallback<List<Event>>) {
|
||||
}
|
||||
|
||||
override fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>> {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getNumberOfJoinedMembers(): Int {
|
||||
return _numberOfJoinedMembers
|
||||
}
|
||||
|
||||
override fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>> {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun roomSummary(): RoomSummary? {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun createTimeline(eventId: String?, settings: TimelineSettings): Timeline {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getTimeLineEvent(eventId: String): TimelineEvent? {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun sendTextMessage(text: String, msgType: String, autoMarkdown: Boolean): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun sendFormattedTextMessage(text: String, formattedText: String): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun sendMedia(attachment: ContentAttachmentData): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun sendMedias(attachments: List<ContentAttachmentData>): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun redactEvent(event: Event, reason: String?): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun markAllAsRead(callback: MatrixCallback<Unit>) {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun setReadReceipt(eventId: String, callback: MatrixCallback<Unit>) {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun setReadMarker(fullyReadEventId: String, callback: MatrixCallback<Unit>) {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun isEventRead(eventId: String): Boolean {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun loadRoomMembersIfNeeded(matrixCallback: MatrixCallback<Unit>): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getRoomMember(userId: String): RoomMember? {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getRoomMemberIdsLive(): LiveData<List<String>> {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun invite(userId: String, callback: MatrixCallback<Unit>): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun join(viaServers: List<String>, callback: MatrixCallback<Unit>): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun leave(callback: MatrixCallback<Unit>): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun updateTopic(topic: String, callback: MatrixCallback<Unit>) {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun sendReaction(targetEventId: String, reaction: String): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun undoReaction(targetEventId: String, reaction: String): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun editTextMessage(targetEventId: String, msgType: String, newBodyText: String,
|
||||
newBodyAutoMarkdown: Boolean, compatibilityBodyText: String): Cancelable {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun replyToMessage(eventReplied: TimelineEvent, replyText: String, autoMarkdown: Boolean): Cancelable? {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getEventSummaryLive(eventId: String): LiveData<Optional<EventAnnotationsSummary>> {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun isEncrypted(): Boolean {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun encryptionAlgorithm(): String? {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun shouldEncryptForInvitedMembers(): Boolean {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -217,6 +217,7 @@ android {
|
|||
dependencies {
|
||||
|
||||
def epoxy_version = '3.8.0'
|
||||
def fragment_version = '1.2.0-rc01'
|
||||
def arrow_version = "0.8.2"
|
||||
def coroutines_version = "1.3.2"
|
||||
def markwon_version = '4.1.2'
|
||||
|
@ -234,6 +235,8 @@ dependencies {
|
|||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation "androidx.fragment:fragment:$fragment_version"
|
||||
implementation "androidx.fragment:fragment-ktx:$fragment_version"
|
||||
//Do not use beta2 at the moment, as it breaks things
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1'
|
||||
implementation 'androidx.core:core-ktx:1.1.0'
|
||||
|
|
|
@ -19,9 +19,9 @@ package im.vector.riotx
|
|||
|
||||
import arrow.core.Option
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.riotx.core.utils.RxStore
|
||||
import im.vector.riotx.core.utils.BehaviorDataSource
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class ActiveSessionObservableStore @Inject constructor() : RxStore<Option<Session>>()
|
||||
class ActiveSessionDataSource @Inject constructor() : BehaviorDataSource<Option<Session>>()
|
|
@ -23,9 +23,9 @@ import arrow.core.Option
|
|||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.rx.rx
|
||||
import im.vector.riotx.features.home.HomeRoomListObservableStore
|
||||
import im.vector.riotx.features.home.HomeRoomListDataSource
|
||||
import im.vector.riotx.features.home.group.ALL_COMMUNITIES_GROUP_ID
|
||||
import im.vector.riotx.features.home.group.SelectedGroupStore
|
||||
import im.vector.riotx.features.home.group.SelectedGroupDataSource
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
@ -41,9 +41,9 @@ import javax.inject.Singleton
|
|||
*/
|
||||
@Singleton
|
||||
class AppStateHandler @Inject constructor(
|
||||
private val sessionObservableStore: ActiveSessionObservableStore,
|
||||
private val homeRoomListObservableStore: HomeRoomListObservableStore,
|
||||
private val selectedGroupStore: SelectedGroupStore) : LifecycleObserver {
|
||||
private val sessionDataSource: ActiveSessionDataSource,
|
||||
private val homeRoomListDataSource: HomeRoomListDataSource,
|
||||
private val selectedGroupDataSource: SelectedGroupDataSource) : LifecycleObserver {
|
||||
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
|
||||
|
@ -60,14 +60,14 @@ class AppStateHandler @Inject constructor(
|
|||
private fun observeRoomsAndGroup() {
|
||||
Observable
|
||||
.combineLatest<List<RoomSummary>, Option<GroupSummary>, List<RoomSummary>>(
|
||||
sessionObservableStore.observe()
|
||||
sessionDataSource.observe()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.switchMap {
|
||||
it.orNull()?.rx()?.liveRoomSummaries()
|
||||
?: Observable.just(emptyList())
|
||||
}
|
||||
.throttleLast(300, TimeUnit.MILLISECONDS),
|
||||
selectedGroupStore.observe(),
|
||||
selectedGroupDataSource.observe(),
|
||||
BiFunction { rooms, selectedGroupOption ->
|
||||
val selectedGroup = selectedGroupOption.orNull()
|
||||
val filteredDirectRooms = rooms
|
||||
|
@ -92,7 +92,7 @@ class AppStateHandler @Inject constructor(
|
|||
}
|
||||
)
|
||||
.subscribe {
|
||||
homeRoomListObservableStore.post(it)
|
||||
homeRoomListDataSource.post(it)
|
||||
}
|
||||
.addTo(compositeDisposable)
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ package im.vector.riotx.core.di
|
|||
import arrow.core.Option
|
||||
import im.vector.matrix.android.api.auth.Authenticator
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.riotx.ActiveSessionObservableStore
|
||||
import im.vector.riotx.ActiveSessionDataSource
|
||||
import im.vector.riotx.features.crypto.keysrequest.KeyRequestHandler
|
||||
import im.vector.riotx.features.crypto.verification.IncomingVerificationRequestHandler
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
@ -28,7 +28,7 @@ import javax.inject.Singleton
|
|||
|
||||
@Singleton
|
||||
class ActiveSessionHolder @Inject constructor(private val authenticator: Authenticator,
|
||||
private val sessionObservableStore: ActiveSessionObservableStore,
|
||||
private val sessionObservableStore: ActiveSessionDataSource,
|
||||
private val keyRequestHandler: KeyRequestHandler,
|
||||
private val incomingVerificationRequestHandler: IncomingVerificationRequestHandler
|
||||
) {
|
||||
|
|
27
vector/src/main/java/im/vector/riotx/core/di/FragmentKey.kt
Normal file
27
vector/src/main/java/im/vector/riotx/core/di/FragmentKey.kt
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.riotx.core.di
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import dagger.MapKey
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@MapKey
|
||||
annotation class FragmentKey(val value: KClass<out Fragment>)
|
197
vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt
Normal file
197
vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* 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.riotx.core.di
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentFactory
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.multibindings.IntoMap
|
||||
import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupSettingsFragment
|
||||
import im.vector.riotx.features.crypto.verification.SASVerificationIncomingFragment
|
||||
import im.vector.riotx.features.crypto.verification.SASVerificationShortCodeFragment
|
||||
import im.vector.riotx.features.crypto.verification.SASVerificationStartFragment
|
||||
import im.vector.riotx.features.crypto.verification.SASVerificationVerifiedFragment
|
||||
import im.vector.riotx.features.home.HomeDetailFragment
|
||||
import im.vector.riotx.features.home.HomeDrawerFragment
|
||||
import im.vector.riotx.features.home.LoadingFragment
|
||||
import im.vector.riotx.features.home.createdirect.CreateDirectRoomDirectoryUsersFragment
|
||||
import im.vector.riotx.features.home.createdirect.CreateDirectRoomKnownUsersFragment
|
||||
import im.vector.riotx.features.home.group.GroupListFragment
|
||||
import im.vector.riotx.features.home.room.detail.RoomDetailFragment
|
||||
import im.vector.riotx.features.home.room.list.RoomListFragment
|
||||
import im.vector.riotx.features.login.LoginFragment
|
||||
import im.vector.riotx.features.login.LoginSsoFallbackFragment
|
||||
import im.vector.riotx.features.reactions.EmojiSearchResultFragment
|
||||
import im.vector.riotx.features.roomdirectory.PublicRoomsFragment
|
||||
import im.vector.riotx.features.roomdirectory.createroom.CreateRoomFragment
|
||||
import im.vector.riotx.features.roomdirectory.picker.RoomDirectoryPickerFragment
|
||||
import im.vector.riotx.features.roomdirectory.roompreview.RoomPreviewNoPreviewFragment
|
||||
import im.vector.riotx.features.settings.*
|
||||
import im.vector.riotx.features.settings.ignored.VectorSettingsIgnoredUsersFragment
|
||||
import im.vector.riotx.features.settings.push.PushGatewaysFragment
|
||||
|
||||
@Module
|
||||
interface FragmentModule {
|
||||
|
||||
/**
|
||||
* Fragments with @IntoMap will be injected by this factory
|
||||
*/
|
||||
@Binds
|
||||
fun bindFragmentFactory(factory: VectorFragmentFactory): FragmentFactory
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(RoomListFragment::class)
|
||||
fun bindRoomListFragment(fragment: RoomListFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(GroupListFragment::class)
|
||||
fun bindGroupListFragment(fragment: GroupListFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(RoomDetailFragment::class)
|
||||
fun bindRoomDetailFragment(fragment: RoomDetailFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(RoomDirectoryPickerFragment::class)
|
||||
fun bindRoomDirectoryPickerFragment(fragment: RoomDirectoryPickerFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(CreateRoomFragment::class)
|
||||
fun bindCreateRoomFragment(fragment: CreateRoomFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(RoomPreviewNoPreviewFragment::class)
|
||||
fun bindRoomPreviewNoPreviewFragment(fragment: RoomPreviewNoPreviewFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(KeysBackupSettingsFragment::class)
|
||||
fun bindKeysBackupSettingsFragment(fragment: KeysBackupSettingsFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(LoadingFragment::class)
|
||||
fun bindLoadingFragment(fragment: LoadingFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(HomeDrawerFragment::class)
|
||||
fun bindHomeDrawerFragment(fragment: HomeDrawerFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(HomeDetailFragment::class)
|
||||
fun bindHomeDetailFragment(fragment: HomeDetailFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(EmojiSearchResultFragment::class)
|
||||
fun bindEmojiSearchResultFragment(fragment: EmojiSearchResultFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(LoginFragment::class)
|
||||
fun bindLoginFragment(fragment: LoginFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(LoginSsoFallbackFragment::class)
|
||||
fun bindLoginSsoFallbackFragment(fragment: LoginSsoFallbackFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(CreateDirectRoomDirectoryUsersFragment::class)
|
||||
fun bindCreateDirectRoomDirectoryUsersFragment(fragment: CreateDirectRoomDirectoryUsersFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(CreateDirectRoomKnownUsersFragment::class)
|
||||
fun bindCreateDirectRoomKnownUsersFragment(fragment: CreateDirectRoomKnownUsersFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(PushGatewaysFragment::class)
|
||||
fun bindPushGatewaysFragment(fragment: PushGatewaysFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(VectorSettingsNotificationsTroubleshootFragment::class)
|
||||
fun bindVectorSettingsNotificationsTroubleshootFragment(fragment: VectorSettingsNotificationsTroubleshootFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(VectorSettingsAdvancedNotificationPreferenceFragment::class)
|
||||
fun bindVectorSettingsAdvancedNotificationPreferenceFragment(fragment: VectorSettingsAdvancedNotificationPreferenceFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(VectorSettingsNotificationPreferenceFragment::class)
|
||||
fun bindVectorSettingsNotificationPreferenceFragment(fragment: VectorSettingsNotificationPreferenceFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(VectorSettingsPreferencesFragment::class)
|
||||
fun bindVectorSettingsPreferencesFragment(fragment: VectorSettingsPreferencesFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(VectorSettingsSecurityPrivacyFragment::class)
|
||||
fun bindVectorSettingsSecurityPrivacyFragment(fragment: VectorSettingsSecurityPrivacyFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(VectorSettingsHelpAboutFragment::class)
|
||||
fun bindVectorSettingsHelpAboutFragment(fragment: VectorSettingsHelpAboutFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(VectorSettingsIgnoredUsersFragment::class)
|
||||
fun bindVectorSettingsIgnoredUsersFragment(fragment: VectorSettingsIgnoredUsersFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(SASVerificationIncomingFragment::class)
|
||||
fun bindSASVerificationIncomingFragment(fragment: SASVerificationIncomingFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(SASVerificationShortCodeFragment::class)
|
||||
fun bindSASVerificationShortCodeFragment(fragment: SASVerificationShortCodeFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(SASVerificationVerifiedFragment::class)
|
||||
fun bindSASVerificationVerifiedFragment(fragment: SASVerificationVerifiedFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(SASVerificationStartFragment::class)
|
||||
fun bindSASVerificationStartFragment(fragment: SASVerificationStartFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(PublicRoomsFragment::class)
|
||||
fun bindPublicRoomsFragment(fragment: PublicRoomsFragment): Fragment
|
||||
}
|
|
@ -17,41 +17,26 @@
|
|||
package im.vector.riotx.core.di
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.FragmentFactory
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
import im.vector.fragments.keysbackup.restore.KeysBackupRestoreFromPassphraseFragment
|
||||
import im.vector.riotx.core.preference.UserAvatarPreference
|
||||
import im.vector.riotx.features.MainActivity
|
||||
import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromKeyFragment
|
||||
import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreSuccessFragment
|
||||
import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActivity
|
||||
import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupSettingsFragment
|
||||
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupStep1Fragment
|
||||
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupStep2Fragment
|
||||
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupStep3Fragment
|
||||
import im.vector.riotx.features.crypto.verification.SASVerificationIncomingFragment
|
||||
import im.vector.riotx.features.home.HomeActivity
|
||||
import im.vector.riotx.features.home.HomeDetailFragment
|
||||
import im.vector.riotx.features.home.HomeDrawerFragment
|
||||
import im.vector.riotx.features.home.HomeModule
|
||||
import im.vector.riotx.features.home.createdirect.CreateDirectRoomActivity
|
||||
import im.vector.riotx.features.home.createdirect.CreateDirectRoomDirectoryUsersFragment
|
||||
import im.vector.riotx.features.home.createdirect.CreateDirectRoomKnownUsersFragment
|
||||
import im.vector.riotx.features.home.group.GroupListFragment
|
||||
import im.vector.riotx.features.home.room.detail.RoomDetailFragment
|
||||
import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet
|
||||
import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsBottomSheet
|
||||
import im.vector.riotx.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet
|
||||
import im.vector.riotx.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet
|
||||
import im.vector.riotx.features.home.room.filtered.FilteredRoomsActivity
|
||||
import im.vector.riotx.features.home.room.list.RoomListFragment
|
||||
import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsBottomSheet
|
||||
import im.vector.riotx.features.home.room.list.RoomListModule
|
||||
import im.vector.riotx.features.invite.VectorInviteView
|
||||
import im.vector.riotx.features.link.LinkHandlerActivity
|
||||
import im.vector.riotx.features.login.LoginActivity
|
||||
import im.vector.riotx.features.login.LoginFragment
|
||||
import im.vector.riotx.features.login.LoginSsoFallbackFragment
|
||||
import im.vector.riotx.features.media.ImageMediaViewerActivity
|
||||
import im.vector.riotx.features.media.VideoMediaViewerActivity
|
||||
import im.vector.riotx.features.navigation.Navigator
|
||||
|
@ -59,16 +44,10 @@ import im.vector.riotx.features.rageshake.BugReportActivity
|
|||
import im.vector.riotx.features.rageshake.BugReporter
|
||||
import im.vector.riotx.features.rageshake.RageShake
|
||||
import im.vector.riotx.features.reactions.EmojiReactionPickerActivity
|
||||
import im.vector.riotx.features.reactions.EmojiSearchResultFragment
|
||||
import im.vector.riotx.features.reactions.widget.ReactionButton
|
||||
import im.vector.riotx.features.roomdirectory.PublicRoomsFragment
|
||||
import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity
|
||||
import im.vector.riotx.features.roomdirectory.createroom.CreateRoomActivity
|
||||
import im.vector.riotx.features.roomdirectory.createroom.CreateRoomFragment
|
||||
import im.vector.riotx.features.roomdirectory.picker.RoomDirectoryPickerFragment
|
||||
import im.vector.riotx.features.roomdirectory.roompreview.RoomPreviewNoPreviewFragment
|
||||
import im.vector.riotx.features.settings.*
|
||||
import im.vector.riotx.features.settings.push.PushGatewaysFragment
|
||||
import im.vector.riotx.features.share.IncomingShareActivity
|
||||
import im.vector.riotx.features.ui.UiStateRepository
|
||||
|
||||
|
@ -79,6 +58,7 @@ import im.vector.riotx.features.ui.UiStateRepository
|
|||
modules = [
|
||||
AssistedInjectModule::class,
|
||||
ViewModelModule::class,
|
||||
FragmentModule::class,
|
||||
HomeModule::class,
|
||||
RoomListModule::class
|
||||
]
|
||||
|
@ -88,6 +68,8 @@ interface ScreenComponent {
|
|||
|
||||
fun activeSessionHolder(): ActiveSessionHolder
|
||||
|
||||
fun fragmentFactory(): FragmentFactory
|
||||
|
||||
fun viewModelFactory(): ViewModelProvider.Factory
|
||||
|
||||
fun bugReporter(): BugReporter
|
||||
|
@ -100,22 +82,6 @@ interface ScreenComponent {
|
|||
|
||||
fun inject(activity: HomeActivity)
|
||||
|
||||
fun inject(roomDetailFragment: RoomDetailFragment)
|
||||
|
||||
fun inject(roomListFragment: RoomListFragment)
|
||||
|
||||
fun inject(groupListFragment: GroupListFragment)
|
||||
|
||||
fun inject(roomDirectoryPickerFragment: RoomDirectoryPickerFragment)
|
||||
|
||||
fun inject(roomPreviewNoPreviewFragment: RoomPreviewNoPreviewFragment)
|
||||
|
||||
fun inject(keysBackupSettingsFragment: KeysBackupSettingsFragment)
|
||||
|
||||
fun inject(homeDrawerFragment: HomeDrawerFragment)
|
||||
|
||||
fun inject(homeDetailFragment: HomeDetailFragment)
|
||||
|
||||
fun inject(messageActionsBottomSheet: MessageActionsBottomSheet)
|
||||
|
||||
fun inject(viewReactionsBottomSheet: ViewReactionsBottomSheet)
|
||||
|
@ -124,30 +90,8 @@ interface ScreenComponent {
|
|||
|
||||
fun inject(vectorSettingsActivity: VectorSettingsActivity)
|
||||
|
||||
fun inject(createRoomFragment: CreateRoomFragment)
|
||||
|
||||
fun inject(keysBackupManageActivity: KeysBackupManageActivity)
|
||||
|
||||
fun inject(keysBackupRestoreFromKeyFragment: KeysBackupRestoreFromKeyFragment)
|
||||
|
||||
fun inject(keysBackupRestoreFromPassphraseFragment: KeysBackupRestoreFromPassphraseFragment)
|
||||
|
||||
fun inject(keysBackupRestoreSuccessFragment: KeysBackupRestoreSuccessFragment)
|
||||
|
||||
fun inject(keysBackupSetupStep1Fragment: KeysBackupSetupStep1Fragment)
|
||||
|
||||
fun inject(keysBackupSetupStep2Fragment: KeysBackupSetupStep2Fragment)
|
||||
|
||||
fun inject(keysBackupSetupStep3Fragment: KeysBackupSetupStep3Fragment)
|
||||
|
||||
fun inject(publicRoomsFragment: PublicRoomsFragment)
|
||||
|
||||
fun inject(loginFragment: LoginFragment)
|
||||
|
||||
fun inject(loginSsoFallbackFragment: LoginSsoFallbackFragment)
|
||||
|
||||
fun inject(sasVerificationIncomingFragment: SASVerificationIncomingFragment)
|
||||
|
||||
fun inject(emojiReactionPickerActivity: EmojiReactionPickerActivity)
|
||||
|
||||
fun inject(loginActivity: LoginActivity)
|
||||
|
@ -170,26 +114,8 @@ interface ScreenComponent {
|
|||
|
||||
fun inject(videoMediaViewerActivity: VideoMediaViewerActivity)
|
||||
|
||||
fun inject(vectorSettingsNotificationPreferenceFragment: VectorSettingsNotificationPreferenceFragment)
|
||||
|
||||
fun inject(vectorSettingsPreferencesFragment: VectorSettingsPreferencesFragment)
|
||||
|
||||
fun inject(vectorSettingsAdvancedNotificationPreferenceFragment: VectorSettingsAdvancedNotificationPreferenceFragment)
|
||||
|
||||
fun inject(vectorSettingsSecurityPrivacyFragment: VectorSettingsSecurityPrivacyFragment)
|
||||
|
||||
fun inject(vectorSettingsHelpAboutFragment: VectorSettingsHelpAboutFragment)
|
||||
|
||||
fun inject(userAvatarPreference: UserAvatarPreference)
|
||||
|
||||
fun inject(vectorSettingsNotificationsTroubleshootFragment: VectorSettingsNotificationsTroubleshootFragment)
|
||||
|
||||
fun inject(pushGatewaysFragment: PushGatewaysFragment)
|
||||
|
||||
fun inject(createDirectRoomKnownUsersFragment: CreateDirectRoomKnownUsersFragment)
|
||||
|
||||
fun inject(createDirectRoomDirectoryUsersFragment: CreateDirectRoomDirectoryUsersFragment)
|
||||
|
||||
fun inject(createDirectRoomActivity: CreateDirectRoomActivity)
|
||||
|
||||
fun inject(displayReadReceiptsBottomSheet: DisplayReadReceiptsBottomSheet)
|
||||
|
@ -198,7 +124,7 @@ interface ScreenComponent {
|
|||
|
||||
fun inject(incomingShareActivity: IncomingShareActivity)
|
||||
|
||||
fun inject(emojiSearchResultFragment: EmojiSearchResultFragment)
|
||||
fun inject(roomListActionsBottomSheet: RoomListQuickActionsBottomSheet)
|
||||
|
||||
@Component.Factory
|
||||
interface Factory {
|
||||
|
|
|
@ -23,7 +23,7 @@ import dagger.Component
|
|||
import im.vector.matrix.android.api.Matrix
|
||||
import im.vector.matrix.android.api.auth.Authenticator
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.riotx.ActiveSessionObservableStore
|
||||
import im.vector.riotx.ActiveSessionDataSource
|
||||
import im.vector.riotx.EmojiCompatFontProvider
|
||||
import im.vector.riotx.EmojiCompatWrapper
|
||||
import im.vector.riotx.VectorApplication
|
||||
|
@ -33,8 +33,8 @@ import im.vector.riotx.features.configuration.VectorConfiguration
|
|||
import im.vector.riotx.features.crypto.keysrequest.KeyRequestHandler
|
||||
import im.vector.riotx.features.crypto.verification.IncomingVerificationRequestHandler
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import im.vector.riotx.features.home.HomeRoomListObservableStore
|
||||
import im.vector.riotx.features.home.group.SelectedGroupStore
|
||||
import im.vector.riotx.features.home.HomeRoomListDataSource
|
||||
import im.vector.riotx.features.home.group.SelectedGroupDataSource
|
||||
import im.vector.riotx.features.html.EventHtmlRenderer
|
||||
import im.vector.riotx.features.navigation.Navigator
|
||||
import im.vector.riotx.features.notifications.*
|
||||
|
@ -43,7 +43,7 @@ import im.vector.riotx.features.rageshake.VectorFileLogger
|
|||
import im.vector.riotx.features.rageshake.VectorUncaughtExceptionHandler
|
||||
import im.vector.riotx.features.session.SessionListener
|
||||
import im.vector.riotx.features.settings.VectorPreferences
|
||||
import im.vector.riotx.features.share.ShareRoomListObservableStore
|
||||
import im.vector.riotx.features.share.ShareRoomListDataSource
|
||||
import im.vector.riotx.features.ui.UiStateRepository
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
@ -85,13 +85,13 @@ interface VectorComponent {
|
|||
|
||||
fun navigator(): Navigator
|
||||
|
||||
fun homeRoomListObservableStore(): HomeRoomListObservableStore
|
||||
fun homeRoomListObservableStore(): HomeRoomListDataSource
|
||||
|
||||
fun shareRoomListObservableStore(): ShareRoomListObservableStore
|
||||
fun shareRoomListObservableStore(): ShareRoomListDataSource
|
||||
|
||||
fun selectedGroupStore(): SelectedGroupStore
|
||||
fun selectedGroupStore(): SelectedGroupDataSource
|
||||
|
||||
fun activeSessionObservableStore(): ActiveSessionObservableStore
|
||||
fun activeSessionObservableStore(): ActiveSessionDataSource
|
||||
|
||||
fun incomingVerificationRequestHandler(): IncomingVerificationRequestHandler
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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.riotx.core.di
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentFactory
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
||||
/**
|
||||
* FragmentFactory which uses Dagger to create the instances.
|
||||
*/
|
||||
class VectorFragmentFactory @Inject constructor(
|
||||
private val creators: @JvmSuppressWildcards Map<Class<out Fragment>, Provider<Fragment>>
|
||||
) : FragmentFactory() {
|
||||
|
||||
override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
|
||||
val fragmentClass = loadFragmentClass(classLoader, className)
|
||||
val creator: Provider<out Fragment>? = creators[fragmentClass]
|
||||
return if (creator == null) {
|
||||
Timber.v("Unknown model class: $className, fallback to default instance")
|
||||
super.instantiate(classLoader, className)
|
||||
} else {
|
||||
creator.get()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,10 +27,7 @@ import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromP
|
|||
import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel
|
||||
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupSharedViewModel
|
||||
import im.vector.riotx.features.crypto.verification.SasVerificationViewModel
|
||||
import im.vector.riotx.features.home.HomeNavigationViewModel
|
||||
import im.vector.riotx.features.home.createdirect.CreateDirectRoomNavigationViewModel
|
||||
import im.vector.riotx.features.reactions.EmojiChooserViewModel
|
||||
import im.vector.riotx.features.roomdirectory.RoomDirectoryNavigationViewModel
|
||||
import im.vector.riotx.features.workers.signout.SignOutViewModel
|
||||
|
||||
@Module
|
||||
|
@ -76,16 +73,6 @@ interface ViewModelModule {
|
|||
@ViewModelKey(KeysBackupRestoreFromPassphraseViewModel::class)
|
||||
fun bindKeysBackupRestoreFromPassphraseViewModel(viewModel: KeysBackupRestoreFromPassphraseViewModel): ViewModel
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ViewModelKey(RoomDirectoryNavigationViewModel::class)
|
||||
fun bindRoomDirectoryNavigationViewModel(viewModel: RoomDirectoryNavigationViewModel): ViewModel
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ViewModelKey(HomeNavigationViewModel::class)
|
||||
fun bindHomeNavigationViewModel(viewModel: HomeNavigationViewModel): ViewModel
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ViewModelKey(KeysBackupSetupSharedViewModel::class)
|
||||
|
@ -95,9 +82,4 @@ interface ViewModelModule {
|
|||
@IntoMap
|
||||
@ViewModelKey(ConfigurationViewModel::class)
|
||||
fun bindConfigurationViewModel(viewModel: ConfigurationViewModel): ViewModel
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ViewModelKey(CreateDirectRoomNavigationViewModel::class)
|
||||
fun bindCreateDirectRoomNavigationViewModel(viewModel: CreateDirectRoomNavigationViewModel): ViewModel
|
||||
}
|
||||
|
|
|
@ -5,26 +5,33 @@
|
|||
* 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
|
||||
* 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.riotx.features.home.room.detail.timeline.action
|
||||
package im.vector.riotx.core.epoxy.bottomsheet
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.ImageViewCompat
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.riotx.features.themes.ThemeUtils
|
||||
|
||||
/**
|
||||
* A action for bottom sheet.
|
||||
|
@ -42,28 +49,48 @@ abstract class BottomSheetItemAction : VectorEpoxyModel<BottomSheetItemAction.Ho
|
|||
@EpoxyAttribute
|
||||
var expanded = false
|
||||
@EpoxyAttribute
|
||||
var selected = false
|
||||
@EpoxyAttribute
|
||||
var subMenuItem = false
|
||||
@EpoxyAttribute
|
||||
var destructive = false
|
||||
@EpoxyAttribute
|
||||
lateinit var listener: View.OnClickListener
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
holder.view.setOnClickListener {
|
||||
listener.onClick(it)
|
||||
}
|
||||
|
||||
holder.startSpace.isVisible = subMenuItem
|
||||
val tintColor = if (destructive) {
|
||||
ContextCompat.getColor(holder.view.context, R.color.riotx_notice)
|
||||
} else {
|
||||
ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_secondary)
|
||||
}
|
||||
holder.icon.setImageResource(iconRes)
|
||||
ImageViewCompat.setImageTintList(holder.icon, ColorStateList.valueOf(tintColor))
|
||||
holder.text.setText(textRes)
|
||||
holder.expand.isVisible = showExpand
|
||||
holder.text.setTextColor(tintColor)
|
||||
holder.selected.isInvisible = !selected
|
||||
if (showExpand) {
|
||||
holder.expand.setImageResource(if (expanded) R.drawable.ic_material_expand_less_black else R.drawable.ic_material_expand_more_black)
|
||||
val expandDrawable = if (expanded) {
|
||||
ContextCompat.getDrawable(holder.view.context, R.drawable.ic_material_expand_less_black)
|
||||
} else {
|
||||
ContextCompat.getDrawable(holder.view.context, R.drawable.ic_material_expand_more_black)
|
||||
}
|
||||
expandDrawable?.also {
|
||||
DrawableCompat.setTint(it, tintColor)
|
||||
}
|
||||
holder.text.setCompoundDrawablesWithIntrinsicBounds(null, null, expandDrawable, null)
|
||||
} else {
|
||||
holder.text.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
|
||||
}
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
val startSpace by bind<View>(R.id.action_start_space)
|
||||
val icon by bind<ImageView>(R.id.action_icon)
|
||||
val text by bind<TextView>(R.id.action_title)
|
||||
val expand by bind<ImageView>(R.id.action_expand)
|
||||
val startSpace by bind<View>(R.id.actionStartSpace)
|
||||
val icon by bind<ImageView>(R.id.actionIcon)
|
||||
val text by bind<TextView>(R.id.actionTitle)
|
||||
val selected by bind<ImageView>(R.id.actionSelected)
|
||||
}
|
||||
}
|
|
@ -5,15 +5,16 @@
|
|||
* 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
|
||||
* 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.riotx.features.home.room.detail.timeline.action
|
||||
package im.vector.riotx.core.epoxy.bottomsheet
|
||||
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
|
@ -24,7 +25,6 @@ import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
|||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.riotx.core.extensions.setTextOrHide
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData
|
||||
|
||||
/**
|
||||
* A message preview for bottom sheet.
|
||||
|
@ -35,7 +35,9 @@ abstract class BottomSheetItemMessagePreview : VectorEpoxyModel<BottomSheetItemM
|
|||
@EpoxyAttribute
|
||||
lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute
|
||||
lateinit var informationData: MessageInformationData
|
||||
lateinit var avatarUrl: String
|
||||
@EpoxyAttribute
|
||||
lateinit var senderId: String
|
||||
@EpoxyAttribute
|
||||
var senderName: String? = null
|
||||
@EpoxyAttribute
|
||||
|
@ -44,7 +46,7 @@ abstract class BottomSheetItemMessagePreview : VectorEpoxyModel<BottomSheetItemM
|
|||
var time: CharSequence? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
avatarRenderer.render(informationData.avatarUrl, informationData.senderId, senderName, holder.avatar)
|
||||
avatarRenderer.render(avatarUrl, senderId, senderName, holder.avatar)
|
||||
holder.sender.setTextOrHide(senderName)
|
||||
holder.body.text = body
|
||||
holder.timestamp.setTextOrHide(time)
|
|
@ -5,15 +5,16 @@
|
|||
* 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
|
||||
* 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.riotx.features.home.room.detail.timeline.action
|
||||
package im.vector.riotx.core.epoxy.bottomsheet
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.widget.TextView
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.riotx.core.epoxy.bottomsheet
|
||||
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.riotx.core.extensions.setTextOrHide
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
|
||||
/**
|
||||
* A room preview for bottom sheet.
|
||||
*/
|
||||
@EpoxyModelClass(layout = R.layout.item_bottom_sheet_room_preview)
|
||||
abstract class BottomSheetItemRoomPreview : VectorEpoxyModel<BottomSheetItemRoomPreview.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute
|
||||
lateinit var avatarUrl: String
|
||||
@EpoxyAttribute
|
||||
lateinit var roomId: String
|
||||
@EpoxyAttribute
|
||||
var roomName: String? = null
|
||||
@EpoxyAttribute var settingsClickListener: View.OnClickListener? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
avatarRenderer.render(avatarUrl, roomId, roomName, holder.avatar)
|
||||
holder.roomName.setTextOrHide(roomName)
|
||||
holder.roomSettings.setOnClickListener(settingsClickListener)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
val avatar by bind<ImageView>(R.id.bottomSheetRoomPreviewAvatar)
|
||||
val roomName by bind<TextView>(R.id.bottomSheetRoomPreviewName)
|
||||
val roomSettings by bind<View>(R.id.bottomSheetRoomPreviewSettings)
|
||||
}
|
||||
}
|
|
@ -5,15 +5,16 @@
|
|||
* 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
|
||||
* 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.riotx.features.home.room.detail.timeline.action
|
||||
package im.vector.riotx.core.epoxy.bottomsheet
|
||||
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
|
@ -5,15 +5,16 @@
|
|||
* 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
|
||||
* 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.riotx.features.home.room.detail.timeline.action
|
||||
package im.vector.riotx.core.epoxy.bottomsheet
|
||||
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.riotx.R
|
|
@ -16,21 +16,40 @@
|
|||
|
||||
package im.vector.riotx.core.extensions
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Parcelable
|
||||
import androidx.fragment.app.Fragment
|
||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
|
||||
fun AppCompatActivity.addFragment(fragment: Fragment, frameId: Int) {
|
||||
fun VectorBaseActivity.addFragment(frameId: Int, fragment: Fragment) {
|
||||
supportFragmentManager.inTransaction { add(frameId, fragment) }
|
||||
}
|
||||
|
||||
fun AppCompatActivity.replaceFragment(fragment: Fragment, frameId: Int, tag: String? = null) {
|
||||
fun <T : Fragment> VectorBaseActivity.addFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) {
|
||||
supportFragmentManager.inTransaction {
|
||||
add(frameId, fragmentClass, params.toMvRxBundle(), tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun VectorBaseActivity.replaceFragment(frameId: Int, fragment: Fragment, tag: String? = null) {
|
||||
supportFragmentManager.inTransaction { replace(frameId, fragment, tag) }
|
||||
}
|
||||
|
||||
fun AppCompatActivity.addFragmentToBackstack(fragment: Fragment, frameId: Int, tag: String? = null) {
|
||||
fun <T : Fragment> VectorBaseActivity.replaceFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) {
|
||||
supportFragmentManager.inTransaction {
|
||||
replace(frameId, fragmentClass, params.toMvRxBundle(), tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun VectorBaseActivity.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) {
|
||||
supportFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) }
|
||||
}
|
||||
|
||||
fun AppCompatActivity.hideKeyboard() {
|
||||
fun <T : Fragment> VectorBaseActivity.addFragmentToBackstack(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) {
|
||||
supportFragmentManager.inTransaction {
|
||||
replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun VectorBaseActivity.hideKeyboard() {
|
||||
currentFocus?.hideKeyboard()
|
||||
}
|
||||
|
|
|
@ -16,28 +16,66 @@
|
|||
|
||||
package im.vector.riotx.core.extensions
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.fragment.app.Fragment
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
|
||||
fun Fragment.addFragment(fragment: Fragment, frameId: Int) {
|
||||
fragmentManager?.inTransaction { add(frameId, fragment) }
|
||||
fun VectorBaseFragment.addFragment(frameId: Int, fragment: Fragment) {
|
||||
parentFragmentManager.inTransaction { add(frameId, fragment) }
|
||||
}
|
||||
|
||||
fun Fragment.replaceFragment(fragment: Fragment, frameId: Int) {
|
||||
fragmentManager?.inTransaction { replace(frameId, fragment) }
|
||||
fun <T : Fragment> VectorBaseFragment.addFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) {
|
||||
parentFragmentManager.inTransaction {
|
||||
add(frameId, fragmentClass, params.toMvRxBundle(), tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun Fragment.addFragmentToBackstack(fragment: Fragment, frameId: Int, tag: String? = null) {
|
||||
fragmentManager?.inTransaction { replace(frameId, fragment).addToBackStack(tag) }
|
||||
fun VectorBaseFragment.replaceFragment(frameId: Int, fragment: Fragment) {
|
||||
parentFragmentManager.inTransaction { replace(frameId, fragment) }
|
||||
}
|
||||
|
||||
fun Fragment.addChildFragment(fragment: Fragment, frameId: Int) {
|
||||
fun <T : Fragment> VectorBaseFragment.replaceFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) {
|
||||
parentFragmentManager.inTransaction {
|
||||
replace(frameId, fragmentClass, params.toMvRxBundle(), tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) {
|
||||
parentFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) {
|
||||
parentFragmentManager.inTransaction {
|
||||
replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun VectorBaseFragment.addChildFragment(frameId: Int, fragment: Fragment) {
|
||||
childFragmentManager.inTransaction { add(frameId, fragment) }
|
||||
}
|
||||
|
||||
fun Fragment.replaceChildFragment(fragment: Fragment, frameId: Int) {
|
||||
fun <T : Fragment> VectorBaseFragment.addChildFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) {
|
||||
childFragmentManager.inTransaction {
|
||||
add(frameId, fragmentClass, params.toMvRxBundle(), tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragment: Fragment) {
|
||||
childFragmentManager.inTransaction { replace(frameId, fragment) }
|
||||
}
|
||||
|
||||
fun Fragment.addChildFragmentToBackstack(fragment: Fragment, frameId: Int, tag: String? = null) {
|
||||
fun <T : Fragment> VectorBaseFragment.replaceChildFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) {
|
||||
childFragmentManager.inTransaction {
|
||||
replace(frameId, fragmentClass, params.toMvRxBundle(), tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) {
|
||||
childFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) {
|
||||
childFragmentManager.inTransaction {
|
||||
replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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.riotx.core.mvrx
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import im.vector.riotx.core.extensions.postLiveEvent
|
||||
import im.vector.riotx.core.utils.LiveEvent
|
||||
|
||||
abstract class NavigationViewModel<NavigationClass> : ViewModel() {
|
||||
|
||||
private val _navigateTo = MutableLiveData<LiveEvent<NavigationClass>>()
|
||||
val navigateTo: LiveData<LiveEvent<NavigationClass>>
|
||||
get() = _navigateTo
|
||||
|
||||
fun goTo(navigation: NavigationClass) {
|
||||
_navigateTo.postLiveEvent(navigation)
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ package im.vector.riotx.core.platform
|
|||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
|
@ -34,6 +35,7 @@ import butterknife.BindView
|
|||
import butterknife.ButterKnife
|
||||
import butterknife.Unbinder
|
||||
import com.airbnb.mvrx.BaseMvRxActivity
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import com.bumptech.glide.util.Util
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import im.vector.riotx.BuildConfig
|
||||
|
@ -125,7 +127,7 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasScreenInjector {
|
|||
}
|
||||
Timber.v("Injecting dependencies into ${javaClass.simpleName} took $timeForInjection ms")
|
||||
ThemeUtils.setActivityTheme(this, getOtherThemes())
|
||||
|
||||
supportFragmentManager.fragmentFactory = screenComponent.fragmentFactory()
|
||||
super.onCreate(savedInstanceState)
|
||||
viewModelFactory = screenComponent.viewModelFactory()
|
||||
configurationViewModel = ViewModelProviders.of(this, viewModelFactory).get(ConfigurationViewModel::class.java)
|
||||
|
@ -331,6 +333,10 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasScreenInjector {
|
|||
}
|
||||
}
|
||||
|
||||
fun Parcelable?.toMvRxBundle(): Bundle? {
|
||||
return this?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } }
|
||||
}
|
||||
|
||||
// ==============================================================================================
|
||||
// Handle loading view (also called waiting view or spinner view)
|
||||
// ==============================================================================================
|
||||
|
|
|
@ -63,6 +63,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
|||
screenComponent = DaggerScreenComponent.factory().create(vectorBaseActivity.getVectorComponent(), vectorBaseActivity)
|
||||
navigator = screenComponent.navigator()
|
||||
viewModelFactory = screenComponent.viewModelFactory()
|
||||
childFragmentManager.fragmentFactory = screenComponent.fragmentFactory()
|
||||
injectWith(injector())
|
||||
super.onAttach(context)
|
||||
}
|
||||
|
@ -134,7 +135,11 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
|||
}
|
||||
|
||||
protected fun setArguments(args: Parcelable? = null) {
|
||||
arguments = args?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } }
|
||||
arguments = args.toMvRxBundle()
|
||||
}
|
||||
|
||||
fun Parcelable?.toMvRxBundle(): Bundle? {
|
||||
return this?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } }
|
||||
}
|
||||
|
||||
@MainThread
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* 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.riotx.core.platform
|
||||
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.utils.toast
|
||||
import timber.log.Timber
|
||||
|
||||
abstract class VectorPreferenceFragment : PreferenceFragmentCompat() {
|
||||
|
||||
val vectorActivity: VectorBaseActivity by lazy {
|
||||
activity as VectorBaseActivity
|
||||
}
|
||||
|
||||
abstract var titleRes: Int
|
||||
|
||||
/* ==========================================================================================
|
||||
* Life cycle
|
||||
* ========================================================================================== */
|
||||
|
||||
@CallSuper
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
(activity as? VectorBaseActivity)?.supportActionBar?.setTitle(titleRes)
|
||||
Timber.v("onResume Fragment ${this.javaClass.simpleName}")
|
||||
}
|
||||
|
||||
/* ==========================================================================================
|
||||
* Protected
|
||||
* ========================================================================================== */
|
||||
|
||||
protected fun notImplemented() {
|
||||
// Snackbar cannot be display on PreferenceFragment
|
||||
// Snackbar.make(view!!, R.string.not_implemented, Snackbar.LENGTH_SHORT)
|
||||
activity?.toast(R.string.not_implemented)
|
||||
}
|
||||
}
|
|
@ -16,13 +16,21 @@
|
|||
|
||||
package im.vector.riotx.core.platform
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.airbnb.mvrx.*
|
||||
import im.vector.riotx.core.utils.LiveEvent
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
|
||||
abstract class VectorViewModel<S : MvRxState>(initialState: S)
|
||||
: BaseMvRxViewModel<S>(initialState, false) {
|
||||
|
||||
// Generic handling of any request error
|
||||
protected val _requestErrorLiveData = MutableLiveData<LiveEvent<Throwable>>()
|
||||
val requestErrorLiveData: LiveData<LiveEvent<Throwable>>
|
||||
get() = _requestErrorLiveData
|
||||
|
||||
/**
|
||||
* This method does the same thing as the execute function, but it doesn't subscribe to the stream
|
||||
* so you can use this in a switchMap or a flatMap
|
||||
|
|
|
@ -17,18 +17,30 @@
|
|||
package im.vector.riotx.core.utils
|
||||
|
||||
import com.jakewharton.rxrelay2.BehaviorRelay
|
||||
import com.jakewharton.rxrelay2.PublishRelay
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
open class RxStore<T>(private val defaultValue: T? = null) {
|
||||
interface DataSource<T> {
|
||||
fun observe(): Observable<T>
|
||||
}
|
||||
|
||||
interface MutableDataSource<T> : DataSource<T> {
|
||||
fun post(value: T)
|
||||
}
|
||||
|
||||
/**
|
||||
* This datasource emits the most recent value it has observed and all subsequent observed values to each subscriber.
|
||||
*/
|
||||
open class BehaviorDataSource<T>(private val defaultValue: T? = null) : MutableDataSource<T> {
|
||||
|
||||
private val storeRelay = createRelay()
|
||||
|
||||
fun observe(): Observable<T> {
|
||||
override fun observe(): Observable<T> {
|
||||
return storeRelay.hide().observeOn(Schedulers.computation())
|
||||
}
|
||||
|
||||
fun post(value: T) {
|
||||
override fun post(value: T) {
|
||||
storeRelay.accept(value)
|
||||
}
|
||||
|
||||
|
@ -40,3 +52,19 @@ open class RxStore<T>(private val defaultValue: T? = null) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This datasource only emits all subsequent observed values to each subscriber.
|
||||
*/
|
||||
open class PublishDataSource<T> : MutableDataSource<T> {
|
||||
|
||||
private val storeRelay = PublishRelay.create<T>()
|
||||
|
||||
override fun observe(): Observable<T> {
|
||||
return storeRelay.hide()
|
||||
}
|
||||
|
||||
override fun post(value: T) {
|
||||
storeRelay.accept(value)
|
||||
}
|
||||
}
|
|
@ -22,9 +22,10 @@ import androidx.appcompat.app.AlertDialog
|
|||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import im.vector.fragments.keysbackup.restore.KeysBackupRestoreFromPassphraseFragment
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.addFragmentToBackstack
|
||||
import im.vector.riotx.core.extensions.observeEvent
|
||||
import im.vector.riotx.core.extensions.replaceFragment
|
||||
import im.vector.riotx.core.platform.SimpleFragmentActivity
|
||||
|
||||
class KeysBackupRestoreActivity : SimpleFragmentActivity() {
|
||||
|
@ -49,13 +50,9 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
|
|||
if (keyVersion != null && supportFragmentManager.fragments.isEmpty()) {
|
||||
val isBackupCreatedFromPassphrase = keyVersion.getAuthDataAsMegolmBackupAuthData()?.privateKeySalt != null
|
||||
if (isBackupCreatedFromPassphrase) {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.container, KeysBackupRestoreFromPassphraseFragment.newInstance())
|
||||
.commitNow()
|
||||
replaceFragment(R.id.container, KeysBackupRestoreFromPassphraseFragment::class.java)
|
||||
} else {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.container, KeysBackupRestoreFromKeyFragment.newInstance())
|
||||
.commitNow()
|
||||
replaceFragment(R.id.container, KeysBackupRestoreFromKeyFragment::class.java)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -80,16 +77,11 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
|
|||
viewModel.navigateEvent.observeEvent(this) { uxStateEvent ->
|
||||
when (uxStateEvent) {
|
||||
KeysBackupRestoreSharedViewModel.NAVIGATE_TO_RECOVER_WITH_KEY -> {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.container, KeysBackupRestoreFromKeyFragment.newInstance())
|
||||
.addToBackStack(null)
|
||||
.commit()
|
||||
addFragmentToBackstack(R.id.container, KeysBackupRestoreFromKeyFragment::class.java)
|
||||
}
|
||||
KeysBackupRestoreSharedViewModel.NAVIGATE_TO_SUCCESS -> {
|
||||
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.container, KeysBackupRestoreSuccessFragment.newInstance())
|
||||
.commit()
|
||||
replaceFragment(R.id.container, KeysBackupRestoreSuccessFragment::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,15 +28,15 @@ import butterknife.OnClick
|
|||
import butterknife.OnTextChanged
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.core.utils.startImportTextFromFileIntent
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupRestoreFromKeyFragment : VectorBaseFragment() {
|
||||
class KeysBackupRestoreFromKeyFragment @Inject constructor()
|
||||
: VectorBaseFragment() {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = KeysBackupRestoreFromKeyFragment()
|
||||
|
||||
private const val REQUEST_TEXT_FILE_GET = 1
|
||||
}
|
||||
|
@ -51,10 +51,6 @@ class KeysBackupRestoreFromKeyFragment : VectorBaseFragment() {
|
|||
@BindView(R.id.keys_restore_key_enter_edittext)
|
||||
lateinit var mKeyTextEdit: EditText
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreFromKeyViewModel::class.java)
|
||||
|
@ -72,7 +68,7 @@ class KeysBackupRestoreFromKeyFragment : VectorBaseFragment() {
|
|||
}
|
||||
|
||||
mKeyInputLayout.error = viewModel.recoveryCodeErrorText.value
|
||||
viewModel.recoveryCodeErrorText.observe(this, Observer { newValue ->
|
||||
viewModel.recoveryCodeErrorText.observe(viewLifecycleOwner, Observer { newValue ->
|
||||
mKeyInputLayout.error = newValue
|
||||
})
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.fragments.keysbackup.restore
|
||||
package im.vector.riotx.features.crypto.keysbackup.restore
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
|
@ -33,13 +33,11 @@ import butterknife.OnClick
|
|||
import butterknife.OnTextChanged
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.showPassword
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromPassphraseViewModel
|
||||
import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupRestoreFromPassphraseFragment : VectorBaseFragment() {
|
||||
class KeysBackupRestoreFromPassphraseFragment @Inject constructor(): VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_restore_from_passphrase
|
||||
|
||||
|
@ -63,14 +61,6 @@ class KeysBackupRestoreFromPassphraseFragment : VectorBaseFragment() {
|
|||
viewModel.showPasswordMode.value = !(viewModel.showPasswordMode.value ?: false)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance() = KeysBackupRestoreFromPassphraseFragment()
|
||||
}
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
|
@ -79,13 +69,13 @@ class KeysBackupRestoreFromPassphraseFragment : VectorBaseFragment() {
|
|||
ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java)
|
||||
} ?: throw Exception("Invalid Activity")
|
||||
|
||||
viewModel.passphraseErrorText.observe(this, Observer { newValue ->
|
||||
viewModel.passphraseErrorText.observe(viewLifecycleOwner, Observer { newValue ->
|
||||
mPassphraseInputLayout.error = newValue
|
||||
})
|
||||
|
||||
helperTextWithLink.text = spannableStringForHelperText(context!!)
|
||||
|
||||
viewModel.showPasswordMode.observe(this, Observer {
|
||||
viewModel.showPasswordMode.observe(viewLifecycleOwner, Observer {
|
||||
val shouldBeVisible = it ?: false
|
||||
mPassphraseTextEdit.showPassword(shouldBeVisible)
|
||||
mPassphraseReveal.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black)
|
||||
|
|
|
@ -21,11 +21,11 @@ import androidx.lifecycle.ViewModelProviders
|
|||
import butterknife.BindView
|
||||
import butterknife.OnClick
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.core.utils.LiveEvent
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupRestoreSuccessFragment : VectorBaseFragment() {
|
||||
class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_restore_success
|
||||
|
||||
|
@ -36,10 +36,6 @@ class KeysBackupRestoreSuccessFragment : VectorBaseFragment() {
|
|||
|
||||
private lateinit var sharedViewModel: KeysBackupRestoreSharedViewModel
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
sharedViewModel = activity?.run {
|
||||
|
@ -62,8 +58,4 @@ class KeysBackupRestoreSuccessFragment : VectorBaseFragment() {
|
|||
fun onDone() {
|
||||
sharedViewModel.importRoomKeysFinishWithResult.value = LiveEvent(sharedViewModel.importKeyResult!!)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance() = KeysBackupRestoreSuccessFragment()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.airbnb.mvrx.Loading
|
|||
import com.airbnb.mvrx.viewModel
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.replaceFragment
|
||||
import im.vector.riotx.core.platform.SimpleFragmentActivity
|
||||
import im.vector.riotx.core.platform.WaitingViewData
|
||||
import javax.inject.Inject
|
||||
|
@ -49,10 +50,7 @@ class KeysBackupManageActivity : SimpleFragmentActivity() {
|
|||
override fun initUiAndData() {
|
||||
super.initUiAndData()
|
||||
if (supportFragmentManager.fragments.isEmpty()) {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.container, KeysBackupSettingsFragment.newInstance())
|
||||
.commitNow()
|
||||
|
||||
replaceFragment(R.id.container, KeysBackupSettingsFragment::class.java)
|
||||
viewModel.init()
|
||||
}
|
||||
|
||||
|
|
|
@ -21,29 +21,20 @@ import androidx.appcompat.app.AlertDialog
|
|||
import com.airbnb.mvrx.activityViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreActivity
|
||||
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupActivity
|
||||
import kotlinx.android.synthetic.main.fragment_keys_backup_settings.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupSettingsFragment : VectorBaseFragment(),
|
||||
KeysBackupSettingsRecyclerViewController.Listener {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = KeysBackupSettingsFragment()
|
||||
}
|
||||
class KeysBackupSettingsFragment @Inject constructor(private val keysBackupSettingsRecyclerViewController: KeysBackupSettingsRecyclerViewController)
|
||||
: VectorBaseFragment(),
|
||||
KeysBackupSettingsRecyclerViewController.Listener {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_settings
|
||||
|
||||
@Inject lateinit var keysBackupSettingsRecyclerViewController: KeysBackupSettingsRecyclerViewController
|
||||
private val viewModel: KeysBackupSettingsViewModel by activityViewModel()
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import im.vector.matrix.android.api.MatrixCallback
|
|||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.dialogs.ExportKeysDialog
|
||||
import im.vector.riotx.core.extensions.observeEvent
|
||||
import im.vector.riotx.core.extensions.replaceFragment
|
||||
import im.vector.riotx.core.platform.SimpleFragmentActivity
|
||||
import im.vector.riotx.core.utils.*
|
||||
import im.vector.riotx.features.crypto.keys.KeysExporter
|
||||
|
@ -39,9 +40,7 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
|
|||
override fun initUiAndData() {
|
||||
super.initUiAndData()
|
||||
if (isFirstCreation()) {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.container, KeysBackupSetupStep1Fragment.newInstance())
|
||||
.commitNow()
|
||||
replaceFragment(R.id.container, KeysBackupSetupStep1Fragment::class.java)
|
||||
}
|
||||
|
||||
viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java)
|
||||
|
@ -67,15 +66,11 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
|
|||
when (uxStateEvent) {
|
||||
KeysBackupSetupSharedViewModel.NAVIGATE_TO_STEP_2 -> {
|
||||
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.container, KeysBackupSetupStep2Fragment.newInstance())
|
||||
.commit()
|
||||
replaceFragment(R.id.container, KeysBackupSetupStep2Fragment::class.java)
|
||||
}
|
||||
KeysBackupSetupSharedViewModel.NAVIGATE_TO_STEP_3 -> {
|
||||
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.container, KeysBackupSetupStep3Fragment.newInstance())
|
||||
.commit()
|
||||
replaceFragment(R.id.container, KeysBackupSetupStep3Fragment::class.java)
|
||||
}
|
||||
KeysBackupSetupSharedViewModel.NAVIGATE_FINISH -> {
|
||||
val resultIntent = Intent()
|
||||
|
|
|
@ -25,15 +25,11 @@ import androidx.lifecycle.ViewModelProviders
|
|||
import butterknife.BindView
|
||||
import butterknife.OnClick
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.core.utils.LiveEvent
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupSetupStep1Fragment : VectorBaseFragment() {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = KeysBackupSetupStep1Fragment()
|
||||
}
|
||||
class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step1
|
||||
|
||||
|
@ -45,10 +41,6 @@ class KeysBackupSetupStep1Fragment : VectorBaseFragment() {
|
|||
@BindView(R.id.keys_backup_setup_step1_manualExport)
|
||||
lateinit var manualExportButton: Button
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
|
@ -56,7 +48,7 @@ class KeysBackupSetupStep1Fragment : VectorBaseFragment() {
|
|||
ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java)
|
||||
} ?: throw Exception("Invalid Activity")
|
||||
|
||||
viewModel.showManualExport.observe(this, Observer {
|
||||
viewModel.showManualExport.observe(viewLifecycleOwner, Observer {
|
||||
val showOption = it ?: false
|
||||
// Can't use isVisible because the kotlin compiler will crash with Back-end (JVM) Internal error: wrong code generated
|
||||
advancedOptionText.visibility = if (showOption) View.VISIBLE else View.GONE
|
||||
|
|
|
@ -30,13 +30,13 @@ import butterknife.OnTextChanged
|
|||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.nulabinc.zxcvbn.Zxcvbn
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.showPassword
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.core.ui.views.PasswordStrengthBar
|
||||
import im.vector.riotx.features.settings.VectorLocale
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupSetupStep2Fragment : VectorBaseFragment() {
|
||||
class KeysBackupSetupStep2Fragment @Inject constructor() : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step2
|
||||
|
||||
|
@ -76,10 +76,6 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() {
|
|||
|
||||
private lateinit var viewModel: KeysBackupSetupSharedViewModel
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
|
@ -96,7 +92,7 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() {
|
|||
* ========================================================================================== */
|
||||
|
||||
private fun bindViewToViewModel() {
|
||||
viewModel.passwordStrength.observe(this, Observer { strength ->
|
||||
viewModel.passwordStrength.observe(viewLifecycleOwner, Observer { strength ->
|
||||
if (strength == null) {
|
||||
mPassphraseProgressLevel.strength = 0
|
||||
mPassphraseInputLayout.error = null
|
||||
|
@ -120,7 +116,7 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() {
|
|||
}
|
||||
})
|
||||
|
||||
viewModel.passphrase.observe(this, Observer<String> { newValue ->
|
||||
viewModel.passphrase.observe(viewLifecycleOwner, Observer<String> { newValue ->
|
||||
if (newValue.isEmpty()) {
|
||||
viewModel.passwordStrength.value = null
|
||||
} else {
|
||||
|
@ -135,21 +131,21 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() {
|
|||
|
||||
mPassphraseTextEdit.setText(viewModel.passphrase.value)
|
||||
|
||||
viewModel.passphraseError.observe(this, Observer {
|
||||
viewModel.passphraseError.observe(viewLifecycleOwner, Observer {
|
||||
TransitionManager.beginDelayedTransition(rootGroup)
|
||||
mPassphraseInputLayout.error = it
|
||||
})
|
||||
|
||||
mPassphraseConfirmTextEdit.setText(viewModel.confirmPassphrase.value)
|
||||
|
||||
viewModel.showPasswordMode.observe(this, Observer {
|
||||
viewModel.showPasswordMode.observe(viewLifecycleOwner, Observer {
|
||||
val shouldBeVisible = it ?: false
|
||||
mPassphraseTextEdit.showPassword(shouldBeVisible)
|
||||
mPassphraseConfirmTextEdit.showPassword(shouldBeVisible)
|
||||
mPassphraseReveal.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black)
|
||||
})
|
||||
|
||||
viewModel.confirmPassphraseError.observe(this, Observer {
|
||||
viewModel.confirmPassphraseError.observe(viewLifecycleOwner, Observer {
|
||||
TransitionManager.beginDelayedTransition(rootGroup)
|
||||
mPassphraseConfirmInputLayout.error = it
|
||||
})
|
||||
|
@ -203,8 +199,4 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance() = KeysBackupSetupStep2Fragment()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ import butterknife.BindView
|
|||
import butterknife.OnClick
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.files.addEntryToDownloadManager
|
||||
import im.vector.riotx.core.files.writeToFile
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
|
@ -40,8 +39,9 @@ import kotlinx.coroutines.GlobalScope
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupSetupStep3Fragment : VectorBaseFragment() {
|
||||
class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step3
|
||||
|
||||
|
@ -54,16 +54,8 @@ class KeysBackupSetupStep3Fragment : VectorBaseFragment() {
|
|||
@BindView(R.id.keys_backup_setup_step3_line2_text)
|
||||
lateinit var mRecoveryKeyLabel2TextView: TextView
|
||||
|
||||
companion object {
|
||||
fun newInstance() = KeysBackupSetupStep3Fragment()
|
||||
}
|
||||
|
||||
private lateinit var viewModel: KeysBackupSetupSharedViewModel
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
viewModel = activity?.run {
|
||||
|
@ -72,7 +64,7 @@ class KeysBackupSetupStep3Fragment : VectorBaseFragment() {
|
|||
|
||||
viewModel.shouldPromptOnBack = false
|
||||
|
||||
viewModel.passphrase.observe(this, Observer {
|
||||
viewModel.passphrase.observe(viewLifecycleOwner, Observer {
|
||||
if (it.isNullOrBlank()) {
|
||||
// Recovery was generated, so show key and options to save
|
||||
mRecoveryKeyLabel2TextView.text = getString(R.string.keys_backup_setup_step3_text_line2_no_passphrase)
|
||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTr
|
|||
import im.vector.matrix.android.api.session.crypto.sas.OutgoingSasVerificationRequest
|
||||
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.inTransaction
|
||||
import im.vector.riotx.core.extensions.observeEvent
|
||||
import im.vector.riotx.core.platform.SimpleFragmentActivity
|
||||
import im.vector.riotx.core.platform.WaitingViewData
|
||||
|
@ -102,23 +103,23 @@ class SASVerificationActivity : SimpleFragmentActivity() {
|
|||
IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT,
|
||||
IncomingSasVerificationTransaction.UxState.WAIT_FOR_KEY_AGREEMENT -> {
|
||||
supportActionBar?.setTitle(R.string.sas_incoming_request_title)
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
.replace(R.id.container, SASVerificationIncomingFragment.newInstance())
|
||||
.commitNow()
|
||||
supportFragmentManager.inTransaction {
|
||||
setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
replace(R.id.container, SASVerificationIncomingFragment::class.java, null)
|
||||
}
|
||||
}
|
||||
IncomingSasVerificationTransaction.UxState.WAIT_FOR_VERIFICATION,
|
||||
IncomingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
.replace(R.id.container, SASVerificationShortCodeFragment.newInstance())
|
||||
.commitNow()
|
||||
supportFragmentManager.inTransaction {
|
||||
setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
replace(R.id.container, SASVerificationShortCodeFragment::class.java, null)
|
||||
}
|
||||
}
|
||||
IncomingSasVerificationTransaction.UxState.VERIFIED -> {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
.replace(R.id.container, SASVerificationVerifiedFragment.newInstance())
|
||||
.commitNow()
|
||||
supportFragmentManager.inTransaction {
|
||||
setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
replace(R.id.container, SASVerificationVerifiedFragment::class.java, null)
|
||||
}
|
||||
}
|
||||
IncomingSasVerificationTransaction.UxState.CANCELLED_BY_ME,
|
||||
IncomingSasVerificationTransaction.UxState.CANCELLED_BY_OTHER -> {
|
||||
|
@ -133,23 +134,23 @@ class SASVerificationActivity : SimpleFragmentActivity() {
|
|||
OutgoingSasVerificationRequest.UxState.UNKNOWN,
|
||||
OutgoingSasVerificationRequest.UxState.WAIT_FOR_START,
|
||||
OutgoingSasVerificationRequest.UxState.WAIT_FOR_KEY_AGREEMENT -> {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
.replace(R.id.container, SASVerificationStartFragment.newInstance())
|
||||
.commitNow()
|
||||
supportFragmentManager.inTransaction {
|
||||
setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
replace(R.id.container, SASVerificationStartFragment::class.java, null)
|
||||
}
|
||||
}
|
||||
OutgoingSasVerificationRequest.UxState.SHOW_SAS,
|
||||
OutgoingSasVerificationRequest.UxState.WAIT_FOR_VERIFICATION -> {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
.replace(R.id.container, SASVerificationShortCodeFragment.newInstance())
|
||||
.commitNow()
|
||||
supportFragmentManager.inTransaction {
|
||||
setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
replace(R.id.container, SASVerificationShortCodeFragment::class.java, null)
|
||||
}
|
||||
}
|
||||
OutgoingSasVerificationRequest.UxState.VERIFIED -> {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
.replace(R.id.container, SASVerificationVerifiedFragment.newInstance())
|
||||
.commitNow()
|
||||
supportFragmentManager.inTransaction {
|
||||
setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out)
|
||||
replace(R.id.container, SASVerificationVerifiedFragment::class.java, null)
|
||||
}
|
||||
}
|
||||
OutgoingSasVerificationRequest.UxState.CANCELLED_BY_ME,
|
||||
OutgoingSasVerificationRequest.UxState.CANCELLED_BY_OTHER -> {
|
||||
|
@ -172,16 +173,16 @@ class SASVerificationActivity : SimpleFragmentActivity() {
|
|||
finish()
|
||||
}
|
||||
SasVerificationViewModel.NAVIGATE_SAS_DISPLAY -> {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out)
|
||||
.replace(R.id.container, SASVerificationShortCodeFragment.newInstance())
|
||||
.commitNow()
|
||||
supportFragmentManager.inTransaction {
|
||||
setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out)
|
||||
replace(R.id.container, SASVerificationShortCodeFragment::class.java, null)
|
||||
}
|
||||
}
|
||||
SasVerificationViewModel.NAVIGATE_SUCCESS -> {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out)
|
||||
.replace(R.id.container, SASVerificationVerifiedFragment.newInstance())
|
||||
.commitNow()
|
||||
supportFragmentManager.inTransaction {
|
||||
setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out)
|
||||
replace(R.id.container, SASVerificationVerifiedFragment::class.java, null)
|
||||
}
|
||||
}
|
||||
SasVerificationViewModel.NAVIGATE_CANCELLED -> {
|
||||
val isCancelledByMe = viewModel.transaction?.state == SasVerificationTxState.Cancelled
|
||||
|
|
|
@ -24,16 +24,13 @@ import butterknife.BindView
|
|||
import butterknife.OnClick
|
||||
import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTransaction
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import javax.inject.Inject
|
||||
|
||||
class SASVerificationIncomingFragment : VectorBaseFragment() {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = SASVerificationIncomingFragment()
|
||||
}
|
||||
class SASVerificationIncomingFragment @Inject constructor(
|
||||
private var avatarRenderer: AvatarRenderer
|
||||
) : VectorBaseFragment() {
|
||||
|
||||
@BindView(R.id.sas_incoming_request_user_display_name)
|
||||
lateinit var otherUserDisplayNameTextView: TextView
|
||||
|
@ -49,13 +46,8 @@ class SASVerificationIncomingFragment : VectorBaseFragment() {
|
|||
|
||||
override fun getLayoutResId() = R.layout.fragment_sas_verification_incoming_request
|
||||
|
||||
@Inject lateinit var avatarRenderer: AvatarRenderer
|
||||
private lateinit var viewModel: SasVerificationViewModel
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
|
@ -74,7 +66,7 @@ class SASVerificationIncomingFragment : VectorBaseFragment() {
|
|||
avatarRenderer.render(null, viewModel.otherUserId ?: "", viewModel.otherUserId, avatarImageView)
|
||||
}
|
||||
|
||||
viewModel.transactionState.observe(this, Observer {
|
||||
viewModel.transactionState.observe(viewLifecycleOwner, Observer {
|
||||
val uxState = (viewModel.transaction as? IncomingSasVerificationTransaction)?.uxState
|
||||
when (uxState) {
|
||||
IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> {
|
||||
|
|
|
@ -28,15 +28,12 @@ import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTr
|
|||
import im.vector.matrix.android.api.session.crypto.sas.OutgoingSasVerificationRequest
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
class SASVerificationShortCodeFragment : VectorBaseFragment() {
|
||||
class SASVerificationShortCodeFragment @Inject constructor(): VectorBaseFragment() {
|
||||
|
||||
private lateinit var viewModel: SasVerificationViewModel
|
||||
|
||||
companion object {
|
||||
fun newInstance() = SASVerificationShortCodeFragment()
|
||||
}
|
||||
|
||||
@BindView(R.id.sas_decimal_code)
|
||||
lateinit var decimalTextView: TextView
|
||||
|
||||
|
@ -120,7 +117,7 @@ class SASVerificationShortCodeFragment : VectorBaseFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
viewModel.transactionState.observe(this, Observer {
|
||||
viewModel.transactionState.observe(viewLifecycleOwner, Observer {
|
||||
if (viewModel.transaction is IncomingSasVerificationTransaction) {
|
||||
val uxState = (viewModel.transaction as IncomingSasVerificationTransaction).uxState
|
||||
when (uxState) {
|
||||
|
|
|
@ -31,12 +31,9 @@ import im.vector.matrix.android.api.session.crypto.sas.OutgoingSasVerificationRe
|
|||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
class SASVerificationStartFragment : VectorBaseFragment() {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = SASVerificationStartFragment()
|
||||
}
|
||||
class SASVerificationStartFragment @Inject constructor(): VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_sas_verification_start
|
||||
|
||||
|
@ -57,7 +54,7 @@ class SASVerificationStartFragment : VectorBaseFragment() {
|
|||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
viewModel = ViewModelProviders.of(vectorBaseActivity, viewModelFactory).get(SasVerificationViewModel::class.java)
|
||||
viewModel.transactionState.observe(this, Observer {
|
||||
viewModel.transactionState.observe(viewLifecycleOwner, Observer {
|
||||
val uxState = (viewModel.transaction as? OutgoingSasVerificationRequest)?.uxState
|
||||
when (uxState) {
|
||||
OutgoingSasVerificationRequest.UxState.WAIT_FOR_KEY_AGREEMENT -> {
|
||||
|
|
|
@ -20,15 +20,12 @@ import androidx.lifecycle.ViewModelProviders
|
|||
import butterknife.OnClick
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
class SASVerificationVerifiedFragment : VectorBaseFragment() {
|
||||
class SASVerificationVerifiedFragment @Inject constructor() : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_sas_verification_verified
|
||||
|
||||
companion object {
|
||||
fun newInstance() = SASVerificationVerifiedFragment()
|
||||
}
|
||||
|
||||
private lateinit var viewModel: SasVerificationViewModel
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
|
|
|
@ -31,7 +31,6 @@ import im.vector.riotx.R
|
|||
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.hideKeyboard
|
||||
import im.vector.riotx.core.extensions.observeEvent
|
||||
import im.vector.riotx.core.extensions.replaceFragment
|
||||
import im.vector.riotx.core.platform.ToolbarConfigurable
|
||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
|
@ -79,22 +78,21 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
|||
navigationViewModel = ViewModelProviders.of(this).get(HomeNavigationViewModel::class.java)
|
||||
drawerLayout.addDrawerListener(drawerListener)
|
||||
if (isFirstCreation()) {
|
||||
val homeDrawerFragment = HomeDrawerFragment.newInstance()
|
||||
val loadingDetail = LoadingFragment.newInstance()
|
||||
replaceFragment(loadingDetail, R.id.homeDetailFragmentContainer)
|
||||
replaceFragment(homeDrawerFragment, R.id.homeDrawerFragmentContainer)
|
||||
replaceFragment(R.id.homeDetailFragmentContainer, LoadingFragment::class.java)
|
||||
replaceFragment(R.id.homeDrawerFragmentContainer, HomeDrawerFragment::class.java)
|
||||
}
|
||||
|
||||
navigationViewModel.navigateTo.observeEvent(this) { navigation ->
|
||||
when (navigation) {
|
||||
is Navigation.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START)
|
||||
is Navigation.OpenGroup -> {
|
||||
drawerLayout.closeDrawer(GravityCompat.START)
|
||||
val homeDetailFragment = HomeDetailFragment.newInstance()
|
||||
replaceFragment(homeDetailFragment, R.id.homeDetailFragmentContainer)
|
||||
navigationViewModel.observe()
|
||||
.subscribe { navigation ->
|
||||
when (navigation) {
|
||||
is Navigation.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START)
|
||||
is Navigation.OpenGroup -> {
|
||||
drawerLayout.closeDrawer(GravityCompat.START)
|
||||
replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.disposeOnDestroy()
|
||||
|
||||
if (intent.getBooleanExtra(EXTRA_CLEAR_EXISTING_NOTIFICATION, false)) {
|
||||
notificationDrawerManager.clearAllEvents()
|
||||
|
|
|
@ -29,7 +29,7 @@ import im.vector.matrix.android.api.session.Session
|
|||
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
|
||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.addChildFragmentToBackstack
|
||||
import im.vector.riotx.core.platform.ToolbarConfigurable
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.core.ui.views.KeysBackupBanner
|
||||
|
@ -45,25 +45,21 @@ private const val INDEX_CATCHUP = 0
|
|||
private const val INDEX_PEOPLE = 1
|
||||
private const val INDEX_ROOMS = 2
|
||||
|
||||
class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
|
||||
class HomeDetailFragment @Inject constructor(
|
||||
private val session: Session,
|
||||
val homeDetailViewModelFactory: HomeDetailViewModel.Factory,
|
||||
private val avatarRenderer: AvatarRenderer
|
||||
) : VectorBaseFragment(), KeysBackupBanner.Delegate {
|
||||
|
||||
private val unreadCounterBadgeViews = arrayListOf<UnreadCounterBadgeView>()
|
||||
|
||||
private val viewModel: HomeDetailViewModel by fragmentViewModel()
|
||||
private lateinit var navigationViewModel: HomeNavigationViewModel
|
||||
|
||||
@Inject lateinit var session: Session
|
||||
@Inject lateinit var homeDetailViewModelFactory: HomeDetailViewModel.Factory
|
||||
@Inject lateinit var avatarRenderer: AvatarRenderer
|
||||
|
||||
override fun getLayoutResId(): Int {
|
||||
return R.layout.fragment_home_detail
|
||||
}
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
|
@ -99,7 +95,7 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
|
|||
|
||||
model.init(session)
|
||||
|
||||
model.keysBackupState.observe(this, Observer { keysBackupState ->
|
||||
model.keysBackupState.observe(viewLifecycleOwner, Observer { keysBackupState ->
|
||||
when (keysBackupState) {
|
||||
null ->
|
||||
homeKeysBackupBanner.render(KeysBackupBanner.State.Hidden, false)
|
||||
|
@ -133,7 +129,7 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
|
|||
}
|
||||
groupToolbar.title = ""
|
||||
groupToolbarAvatarImageView.setOnClickListener {
|
||||
navigationViewModel.goTo(HomeActivity.Navigation.OpenDrawer)
|
||||
navigationViewModel.post(HomeActivity.Navigation.OpenDrawer)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,14 +168,13 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
|
|||
|
||||
private fun updateSelectedFragment(displayMode: RoomListFragment.DisplayMode) {
|
||||
val fragmentTag = "FRAGMENT_TAG_${displayMode.name}"
|
||||
var fragment = childFragmentManager.findFragmentByTag(fragmentTag)
|
||||
val fragment = childFragmentManager.findFragmentByTag(fragmentTag)
|
||||
if (fragment == null) {
|
||||
fragment = RoomListFragment.newInstance(RoomListParams(displayMode))
|
||||
val params = RoomListParams(displayMode)
|
||||
addChildFragmentToBackstack(R.id.roomListContainer, RoomListFragment::class.java, params, fragmentTag)
|
||||
} else {
|
||||
addChildFragmentToBackstack(R.id.roomListContainer, fragment, fragmentTag)
|
||||
}
|
||||
childFragmentManager.beginTransaction()
|
||||
.replace(R.id.roomListContainer, fragment, fragmentTag)
|
||||
.addToBackStack(fragmentTag)
|
||||
.commit()
|
||||
}
|
||||
|
||||
/* ==========================================================================================
|
||||
|
@ -201,11 +196,4 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
|
|||
unreadCounterBadgeViews[INDEX_ROOMS].render(UnreadCounterBadgeView.State(it.notificationCountRooms, it.notificationHighlightRooms))
|
||||
syncStateView.render(it.syncState)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(): HomeDetailFragment {
|
||||
return HomeDetailFragment()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import im.vector.matrix.rx.rx
|
|||
import im.vector.riotx.core.di.HasScreenInjector
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
import im.vector.riotx.features.home.group.SelectedGroupStore
|
||||
import im.vector.riotx.features.home.group.SelectedGroupDataSource
|
||||
import im.vector.riotx.features.home.room.list.RoomListFragment
|
||||
import im.vector.riotx.features.ui.UiStateRepository
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
@ -38,8 +38,8 @@ import io.reactivex.schedulers.Schedulers
|
|||
class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: HomeDetailViewState,
|
||||
private val session: Session,
|
||||
private val uiStateRepository: UiStateRepository,
|
||||
private val selectedGroupStore: SelectedGroupStore,
|
||||
private val homeRoomListStore: HomeRoomListObservableStore,
|
||||
private val selectedGroupStore: SelectedGroupDataSource,
|
||||
private val homeRoomListStore: HomeRoomListDataSource,
|
||||
private val stringProvider: StringProvider)
|
||||
: VectorViewModel<HomeDetailViewState>(initialState) {
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ package im.vector.riotx.features.home
|
|||
import android.os.Bundle
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.observeK
|
||||
import im.vector.riotx.core.extensions.replaceChildFragment
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
|
@ -27,29 +26,17 @@ import im.vector.riotx.features.home.group.GroupListFragment
|
|||
import kotlinx.android.synthetic.main.fragment_home_drawer.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class HomeDrawerFragment : VectorBaseFragment() {
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(): HomeDrawerFragment {
|
||||
return HomeDrawerFragment()
|
||||
}
|
||||
}
|
||||
|
||||
@Inject lateinit var session: Session
|
||||
@Inject lateinit var avatarRenderer: AvatarRenderer
|
||||
class HomeDrawerFragment @Inject constructor(
|
||||
private val session: Session,
|
||||
private val avatarRenderer: AvatarRenderer
|
||||
) : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_home_drawer
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
if (savedInstanceState == null) {
|
||||
val groupListFragment = GroupListFragment.newInstance()
|
||||
replaceChildFragment(groupListFragment, R.id.homeDrawerGroupListContainer)
|
||||
replaceChildFragment(R.id.homeDrawerGroupListContainer, GroupListFragment::class.java)
|
||||
}
|
||||
session.liveUser(session.myUserId).observeK(this) { optionalUser ->
|
||||
val user = optionalUser?.getOrNull()
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
|
||||
package im.vector.riotx.features.home
|
||||
|
||||
import im.vector.riotx.core.mvrx.NavigationViewModel
|
||||
import javax.inject.Inject
|
||||
import androidx.lifecycle.ViewModel
|
||||
import im.vector.riotx.core.utils.PublishDataSource
|
||||
import im.vector.riotx.core.utils.MutableDataSource
|
||||
|
||||
class HomeNavigationViewModel @Inject constructor() : NavigationViewModel<HomeActivity.Navigation>()
|
||||
class HomeNavigationViewModel(private val source: MutableDataSource<HomeActivity.Navigation> = PublishDataSource())
|
||||
: ViewModel(), MutableDataSource<HomeActivity.Navigation> by source
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
package im.vector.riotx.features.home
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.riotx.core.utils.RxStore
|
||||
import im.vector.riotx.core.utils.BehaviorDataSource
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class HomeRoomListObservableStore @Inject constructor() : RxStore<List<RoomSummary>>()
|
||||
class HomeRoomListDataSource @Inject constructor() : BehaviorDataSource<List<RoomSummary>>()
|
|
@ -22,15 +22,9 @@ import android.view.View
|
|||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import kotlinx.android.synthetic.main.fragment_loading.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class LoadingFragment : VectorBaseFragment() {
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(): LoadingFragment {
|
||||
return LoadingFragment()
|
||||
}
|
||||
}
|
||||
class LoadingFragment @Inject constructor(): VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_loading
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ import im.vector.riotx.core.di.ScreenComponent
|
|||
import im.vector.riotx.core.error.ErrorFormatter
|
||||
import im.vector.riotx.core.extensions.addFragment
|
||||
import im.vector.riotx.core.extensions.addFragmentToBackstack
|
||||
import im.vector.riotx.core.extensions.observeEvent
|
||||
import im.vector.riotx.core.platform.SimpleFragmentActivity
|
||||
import im.vector.riotx.core.platform.WaitingViewData
|
||||
import kotlinx.android.synthetic.main.activity.*
|
||||
|
@ -59,15 +58,17 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
toolbar.visibility = View.GONE
|
||||
navigationViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateDirectRoomNavigationViewModel::class.java)
|
||||
navigationViewModel.navigateTo.observeEvent(this) { navigation ->
|
||||
when (navigation) {
|
||||
is Navigation.UsersDirectory -> addFragmentToBackstack(CreateDirectRoomDirectoryUsersFragment(), R.id.container)
|
||||
Navigation.Close -> finish()
|
||||
Navigation.Previous -> onBackPressed()
|
||||
}
|
||||
}
|
||||
navigationViewModel.observe()
|
||||
.subscribe { navigation ->
|
||||
when (navigation) {
|
||||
is Navigation.UsersDirectory -> addFragmentToBackstack(R.id.container, CreateDirectRoomDirectoryUsersFragment::class.java)
|
||||
Navigation.Close -> finish()
|
||||
Navigation.Previous -> onBackPressed()
|
||||
}
|
||||
}
|
||||
.disposeOnDestroy()
|
||||
if (isFirstCreation()) {
|
||||
addFragment(CreateDirectRoomKnownUsersFragment(), R.id.container)
|
||||
addFragment(R.id.container, CreateDirectRoomKnownUsersFragment::class.java)
|
||||
}
|
||||
viewModel.selectSubscribe(this, CreateDirectRoomViewState::createAndInviteState) {
|
||||
renderCreateAndInviteState(it)
|
||||
|
|
|
@ -25,26 +25,22 @@ import com.airbnb.mvrx.withState
|
|||
import com.jakewharton.rxbinding3.widget.textChanges
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.hideKeyboard
|
||||
import im.vector.riotx.core.extensions.setupAsSearch
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import kotlinx.android.synthetic.main.fragment_create_direct_room_directory_users.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class CreateDirectRoomDirectoryUsersFragment : VectorBaseFragment(), DirectoryUsersController.Callback {
|
||||
class CreateDirectRoomDirectoryUsersFragment @Inject constructor(
|
||||
private val directRoomController: DirectoryUsersController
|
||||
) : VectorBaseFragment(), DirectoryUsersController.Callback {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_create_direct_room_directory_users
|
||||
|
||||
private val viewModel: CreateDirectRoomViewModel by activityViewModel()
|
||||
|
||||
@Inject lateinit var directRoomController: DirectoryUsersController
|
||||
private lateinit var navigationViewModel: CreateDirectRoomNavigationViewModel
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
navigationViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomNavigationViewModel::class.java)
|
||||
|
@ -74,7 +70,7 @@ class CreateDirectRoomDirectoryUsersFragment : VectorBaseFragment(), DirectoryUs
|
|||
|
||||
private fun setupCloseView() {
|
||||
createDirectRoomClose.setOnClickListener {
|
||||
navigationViewModel.goTo(CreateDirectRoomActivity.Navigation.Previous)
|
||||
navigationViewModel.post(CreateDirectRoomActivity.Navigation.Previous)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +81,7 @@ class CreateDirectRoomDirectoryUsersFragment : VectorBaseFragment(), DirectoryUs
|
|||
override fun onItemClick(user: User) {
|
||||
view?.hideKeyboard()
|
||||
viewModel.handle(CreateDirectRoomActions.SelectUser(user))
|
||||
navigationViewModel.goTo(CreateDirectRoomActivity.Navigation.Previous)
|
||||
navigationViewModel.post(CreateDirectRoomActivity.Navigation.Previous)
|
||||
}
|
||||
|
||||
override fun retryDirectoryUsersRequest() {
|
||||
|
|
|
@ -31,33 +31,26 @@ import com.google.android.material.chip.ChipGroup
|
|||
import com.jakewharton.rxbinding3.widget.textChanges
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.hideKeyboard
|
||||
import im.vector.riotx.core.extensions.observeEvent
|
||||
import im.vector.riotx.core.extensions.setupAsSearch
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.core.utils.DimensionConverter
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import kotlinx.android.synthetic.main.fragment_create_direct_room.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class CreateDirectRoomKnownUsersFragment : VectorBaseFragment(), KnownUsersController.Callback {
|
||||
class CreateDirectRoomKnownUsersFragment @Inject constructor(
|
||||
private val knownUsersController: KnownUsersController,
|
||||
private val dimensionConverter: DimensionConverter
|
||||
) : VectorBaseFragment(), KnownUsersController.Callback {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_create_direct_room
|
||||
|
||||
override fun getMenuRes() = R.menu.vector_create_direct_room
|
||||
|
||||
private val viewModel: CreateDirectRoomViewModel by activityViewModel()
|
||||
|
||||
@Inject lateinit var directRoomController: KnownUsersController
|
||||
@Inject lateinit var avatarRenderer: AvatarRenderer
|
||||
@Inject lateinit var dimensionConverter: DimensionConverter
|
||||
private lateinit var navigationViewModel: CreateDirectRoomNavigationViewModel
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
navigationViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomNavigationViewModel::class.java)
|
||||
|
@ -96,7 +89,7 @@ class CreateDirectRoomKnownUsersFragment : VectorBaseFragment(), KnownUsersContr
|
|||
|
||||
private fun setupAddByMatrixIdView() {
|
||||
addByMatrixId.setOnClickListener {
|
||||
navigationViewModel.goTo(CreateDirectRoomActivity.Navigation.UsersDirectory)
|
||||
navigationViewModel.post(CreateDirectRoomActivity.Navigation.UsersDirectory)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,8 +97,8 @@ class CreateDirectRoomKnownUsersFragment : VectorBaseFragment(), KnownUsersContr
|
|||
recyclerView.setHasFixedSize(true)
|
||||
// Don't activate animation as we might have way to much item animation when filtering
|
||||
recyclerView.itemAnimator = null
|
||||
directRoomController.callback = this
|
||||
recyclerView.setController(directRoomController)
|
||||
knownUsersController.callback = this
|
||||
recyclerView.setController(knownUsersController)
|
||||
}
|
||||
|
||||
private fun setupFilterView() {
|
||||
|
@ -134,7 +127,7 @@ class CreateDirectRoomKnownUsersFragment : VectorBaseFragment(), KnownUsersContr
|
|||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) {
|
||||
directRoomController.setData(it)
|
||||
knownUsersController.setData(it)
|
||||
}
|
||||
|
||||
private fun updateChipsView(data: SelectUserAction) {
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
|
||||
package im.vector.riotx.features.home.createdirect
|
||||
|
||||
import im.vector.riotx.core.mvrx.NavigationViewModel
|
||||
import javax.inject.Inject
|
||||
import androidx.lifecycle.ViewModel
|
||||
import im.vector.riotx.core.utils.PublishDataSource
|
||||
import im.vector.riotx.core.utils.MutableDataSource
|
||||
|
||||
class CreateDirectRoomNavigationViewModel @Inject constructor(): NavigationViewModel<CreateDirectRoomActivity.Navigation>()
|
||||
class CreateDirectRoomNavigationViewModel(private val dataSource: MutableDataSource<CreateDirectRoomActivity.Navigation> = PublishDataSource())
|
||||
: ViewModel(), MutableDataSource<CreateDirectRoomActivity.Navigation> by dataSource
|
||||
|
|
|
@ -23,7 +23,6 @@ import com.airbnb.mvrx.Success
|
|||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.observeEvent
|
||||
import im.vector.riotx.core.platform.StateView
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
|
@ -32,26 +31,16 @@ import im.vector.riotx.features.home.HomeNavigationViewModel
|
|||
import kotlinx.android.synthetic.main.fragment_group_list.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback {
|
||||
|
||||
companion object {
|
||||
fun newInstance(): GroupListFragment {
|
||||
return GroupListFragment()
|
||||
}
|
||||
}
|
||||
class GroupListFragment @Inject constructor(
|
||||
val groupListViewModelFactory: GroupListViewModel.Factory,
|
||||
private val groupController: GroupSummaryController
|
||||
) : VectorBaseFragment(), GroupSummaryController.Callback {
|
||||
|
||||
private lateinit var navigationViewModel: HomeNavigationViewModel
|
||||
private val viewModel: GroupListViewModel by fragmentViewModel()
|
||||
|
||||
@Inject lateinit var groupListViewModelFactory: GroupListViewModel.Factory
|
||||
@Inject lateinit var groupController: GroupSummaryController
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_group_list
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
navigationViewModel = ViewModelProviders.of(requireActivity()).get(HomeNavigationViewModel::class.java)
|
||||
|
@ -60,7 +49,7 @@ class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback
|
|||
groupListEpoxyRecyclerView.setController(groupController)
|
||||
viewModel.subscribe { renderState(it) }
|
||||
viewModel.openGroupLiveData.observeEvent(this) {
|
||||
navigationViewModel.goTo(HomeActivity.Navigation.OpenGroup)
|
||||
navigationViewModel.post(HomeActivity.Navigation.OpenGroup)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ import io.reactivex.functions.BiFunction
|
|||
const val ALL_COMMUNITIES_GROUP_ID = "ALL_COMMUNITIES_GROUP_ID"
|
||||
|
||||
class GroupListViewModel @AssistedInject constructor(@Assisted initialState: GroupListViewState,
|
||||
private val selectedGroupStore: SelectedGroupStore,
|
||||
private val selectedGroupStore: SelectedGroupDataSource,
|
||||
private val session: Session,
|
||||
private val stringProvider: StringProvider
|
||||
) : VectorViewModel<GroupListViewState>(initialState) {
|
||||
|
|
|
@ -18,9 +18,9 @@ package im.vector.riotx.features.home.group
|
|||
|
||||
import arrow.core.Option
|
||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.riotx.core.utils.RxStore
|
||||
import im.vector.riotx.core.utils.BehaviorDataSource
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class SelectedGroupStore @Inject constructor() : RxStore<Option<GroupSummary>>(Option.empty())
|
||||
class SelectedGroupDataSource @Inject constructor() : BehaviorDataSource<Option<GroupSummary>>(Option.empty())
|
|
@ -50,7 +50,14 @@ sealed class RoomDetailActions {
|
|||
data class ResendMessage(val eventId: String) : RoomDetailActions()
|
||||
data class RemoveFailedEcho(val eventId: String) : RoomDetailActions()
|
||||
|
||||
data class ReportContent(val eventId: String, val reason: String, val spam: Boolean = false, val inappropriate: Boolean = false) : RoomDetailActions()
|
||||
data class ReportContent(
|
||||
val eventId: String,
|
||||
val senderId: String?,
|
||||
val reason: String,
|
||||
val spam: Boolean = false,
|
||||
val inappropriate: Boolean = false) : RoomDetailActions()
|
||||
|
||||
data class IgnoreUser(val userId: String?) : RoomDetailActions()
|
||||
|
||||
object ClearSendQueue : RoomDetailActions()
|
||||
object ResendAll : RoomDetailActions()
|
||||
|
|
|
@ -38,8 +38,7 @@ class RoomDetailActivity : VectorBaseActivity(), ToolbarConfigurable {
|
|||
if (isFirstCreation()) {
|
||||
val roomDetailArgs: RoomDetailArgs = intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS)
|
||||
?: return
|
||||
val roomDetailFragment = RoomDetailFragment.newInstance(roomDetailArgs)
|
||||
replaceFragment(roomDetailFragment, R.id.roomDetailContainer)
|
||||
replaceFragment(R.id.roomDetailContainer, RoomDetailFragment::class.java, roomDetailArgs)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,6 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
|||
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.dialogs.withColoredButton
|
||||
import im.vector.riotx.core.epoxy.LayoutManagerStateRestorer
|
||||
import im.vector.riotx.core.error.ErrorFormatter
|
||||
|
@ -98,8 +97,8 @@ import im.vector.riotx.features.home.room.detail.composer.TextComposerViewModel
|
|||
import im.vector.riotx.features.home.room.detail.composer.TextComposerViewState
|
||||
import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet
|
||||
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
|
||||
import im.vector.riotx.features.home.room.detail.timeline.action.ActionsHandler
|
||||
import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsBottomSheet
|
||||
import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsDispatcher
|
||||
import im.vector.riotx.features.home.room.detail.timeline.action.SimpleAction
|
||||
import im.vector.riotx.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet
|
||||
import im.vector.riotx.features.home.room.detail.timeline.item.*
|
||||
|
@ -134,7 +133,22 @@ data class RoomDetailArgs(
|
|||
|
||||
private const val REACTION_SELECT_REQUEST_CODE = 0
|
||||
|
||||
class RoomDetailFragment :
|
||||
class RoomDetailFragment @Inject constructor(
|
||||
private val session: Session,
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
private val timelineEventController: TimelineEventController,
|
||||
private val commandAutocompletePolicy: CommandAutocompletePolicy,
|
||||
private val autocompleteCommandPresenter: AutocompleteCommandPresenter,
|
||||
private val autocompleteUserPresenter: AutocompleteUserPresenter,
|
||||
private val permalinkHandler: PermalinkHandler,
|
||||
private val notificationDrawerManager: NotificationDrawerManager,
|
||||
val roomDetailViewModelFactory: RoomDetailViewModel.Factory,
|
||||
val textComposerViewModelFactory: TextComposerViewModel.Factory,
|
||||
private val errorFormatter: ErrorFormatter,
|
||||
private val eventHtmlRenderer: EventHtmlRenderer,
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val readMarkerHelper: ReadMarkerHelper
|
||||
) :
|
||||
VectorBaseFragment(),
|
||||
TimelineEventController.Callback,
|
||||
AutocompleteUserPresenter.Callback,
|
||||
|
@ -145,12 +159,6 @@ class RoomDetailFragment :
|
|||
|
||||
companion object {
|
||||
|
||||
fun newInstance(args: RoomDetailArgs): RoomDetailFragment {
|
||||
return RoomDetailFragment().apply {
|
||||
setArguments(args)
|
||||
}
|
||||
}
|
||||
|
||||
/**x
|
||||
* Sanitize the display name.
|
||||
*
|
||||
|
@ -178,21 +186,6 @@ class RoomDetailFragment :
|
|||
|
||||
private val debouncer = Debouncer(createUIHandler())
|
||||
|
||||
@Inject lateinit var session: Session
|
||||
@Inject lateinit var avatarRenderer: AvatarRenderer
|
||||
@Inject lateinit var timelineEventController: TimelineEventController
|
||||
@Inject lateinit var commandAutocompletePolicy: CommandAutocompletePolicy
|
||||
@Inject lateinit var autocompleteCommandPresenter: AutocompleteCommandPresenter
|
||||
@Inject lateinit var autocompleteUserPresenter: AutocompleteUserPresenter
|
||||
@Inject lateinit var permalinkHandler: PermalinkHandler
|
||||
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager
|
||||
@Inject lateinit var roomDetailViewModelFactory: RoomDetailViewModel.Factory
|
||||
@Inject lateinit var textComposerViewModelFactory: TextComposerViewModel.Factory
|
||||
@Inject lateinit var errorFormatter: ErrorFormatter
|
||||
@Inject lateinit var eventHtmlRenderer: EventHtmlRenderer
|
||||
@Inject lateinit var vectorPreferences: VectorPreferences
|
||||
@Inject lateinit var readMarkerHelper: ReadMarkerHelper
|
||||
|
||||
private lateinit var scrollOnNewMessageCallback: ScrollOnNewMessageCallback
|
||||
private lateinit var scrollOnHighlightedEventCallback: ScrollOnHighlightedEventCallback
|
||||
|
||||
|
@ -200,7 +193,7 @@ class RoomDetailFragment :
|
|||
|
||||
override fun getMenuRes() = R.menu.menu_timeline
|
||||
|
||||
private lateinit var actionViewModel: ActionsHandler
|
||||
private lateinit var messageActionsDispatcher: MessageActionsDispatcher
|
||||
private lateinit var layoutManager: LinearLayoutManager
|
||||
private lateinit var attachmentsHelper: AttachmentsHelper
|
||||
private lateinit var keyboardStateUtils: KeyboardStateUtils
|
||||
|
@ -211,13 +204,9 @@ class RoomDetailFragment :
|
|||
|
||||
private var lockSendButton = false
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
actionViewModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java)
|
||||
messageActionsDispatcher = ViewModelProviders.of(requireActivity()).get(MessageActionsDispatcher::class.java)
|
||||
attachmentsHelper = AttachmentsHelper.create(this, this).register()
|
||||
keyboardStateUtils = KeyboardStateUtils(requireActivity())
|
||||
setupToolbar(roomToolbar)
|
||||
|
@ -235,9 +224,12 @@ class RoomDetailFragment :
|
|||
val message = requireContext().getString(pair.first, *pair.second.toTypedArray())
|
||||
showSnackWithMessage(message, Snackbar.LENGTH_LONG)
|
||||
}
|
||||
actionViewModel.actionCommandEvent.observeEvent(this) {
|
||||
handleActions(it)
|
||||
}
|
||||
messageActionsDispatcher
|
||||
.observe()
|
||||
.subscribe {
|
||||
handleActions(it)
|
||||
}
|
||||
.disposeOnDestroy()
|
||||
|
||||
roomDetailViewModel.navigateToEvent.observeEvent(this) {
|
||||
val scrollPosition = timelineEventController.searchPositionOfEvent(it)
|
||||
|
@ -767,7 +759,7 @@ class RoomDetailFragment :
|
|||
.setView(layout)
|
||||
.setPositiveButton(R.string.report_content_custom_submit) { _, _ ->
|
||||
val reason = input.text.toString()
|
||||
roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, reason))
|
||||
roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, action.senderId, reason))
|
||||
}
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show()
|
||||
|
@ -791,7 +783,9 @@ class RoomDetailFragment :
|
|||
.setTitle(R.string.content_reported_as_spam_title)
|
||||
.setMessage(R.string.content_reported_as_spam_content)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.setNegativeButton(R.string.block_user) { _, _ -> vectorBaseActivity.notImplemented("block user") }
|
||||
.setNegativeButton(R.string.block_user) { _, _ ->
|
||||
roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId))
|
||||
}
|
||||
.show()
|
||||
.withColoredButton(DialogInterface.BUTTON_NEGATIVE)
|
||||
}
|
||||
|
@ -800,7 +794,9 @@ class RoomDetailFragment :
|
|||
.setTitle(R.string.content_reported_as_inappropriate_title)
|
||||
.setMessage(R.string.content_reported_as_inappropriate_content)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.setNegativeButton(R.string.block_user) { _, _ -> vectorBaseActivity.notImplemented("block user") }
|
||||
.setNegativeButton(R.string.block_user) { _, _ ->
|
||||
roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId))
|
||||
}
|
||||
.show()
|
||||
.withColoredButton(DialogInterface.BUTTON_NEGATIVE)
|
||||
}
|
||||
|
@ -809,7 +805,9 @@ class RoomDetailFragment :
|
|||
.setTitle(R.string.content_reported_title)
|
||||
.setMessage(R.string.content_reported_content)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.setNegativeButton(R.string.block_user) { _, _ -> vectorBaseActivity.notImplemented("block user") }
|
||||
.setNegativeButton(R.string.block_user) { _, _ ->
|
||||
roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId))
|
||||
}
|
||||
.show()
|
||||
.withColoredButton(DialogInterface.BUTTON_NEGATIVE)
|
||||
}
|
||||
|
@ -958,6 +956,7 @@ class RoomDetailFragment :
|
|||
val roomId = roomDetailArgs.roomId
|
||||
|
||||
this.view?.hideKeyboard()
|
||||
|
||||
MessageActionsBottomSheet
|
||||
.newInstance(roomId, informationData)
|
||||
.show(requireActivity().supportFragmentManager, "MESSAGE_CONTEXTUAL_ACTIONS")
|
||||
|
@ -1133,10 +1132,12 @@ class RoomDetailFragment :
|
|||
roomDetailViewModel.process(RoomDetailActions.RemoveFailedEcho(action.eventId))
|
||||
}
|
||||
is SimpleAction.ReportContentSpam -> {
|
||||
roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, "This message is spam", spam = true))
|
||||
roomDetailViewModel.process(RoomDetailActions.ReportContent(
|
||||
action.eventId, action.senderId, "This message is spam", spam = true))
|
||||
}
|
||||
is SimpleAction.ReportContentInappropriate -> {
|
||||
roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, "This message is inappropriate", inappropriate = true))
|
||||
roomDetailViewModel.process(RoomDetailActions.ReportContent(
|
||||
action.eventId, action.senderId, "This message is inappropriate", inappropriate = true))
|
||||
}
|
||||
is SimpleAction.ReportContentCustom -> {
|
||||
promptReasonToReportContent(action)
|
||||
|
|
|
@ -157,6 +157,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
|||
is RoomDetailActions.SetReadMarkerAction -> handleSetReadMarkerAction(action)
|
||||
is RoomDetailActions.MarkAllAsRead -> handleMarkAllAsRead()
|
||||
is RoomDetailActions.ReportContent -> handleReportContent(action)
|
||||
is RoomDetailActions.IgnoreUser -> handleIgnoreUser(action)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,6 +713,22 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
|||
})
|
||||
}
|
||||
|
||||
private fun handleIgnoreUser(action: RoomDetailActions.IgnoreUser) {
|
||||
if (action.userId.isNullOrEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
session.ignoreUserIds(listOf(action.userId), object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
_requestLiveData.postValue(LiveEvent(Success(action)))
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
_requestLiveData.postValue(LiveEvent(Fail(failure)))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun observeSyncState() {
|
||||
session.rx()
|
||||
.liveSyncState()
|
||||
|
|
|
@ -47,7 +47,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message
|
|||
|
||||
override val showExpanded = true
|
||||
|
||||
private lateinit var actionHandlerModel: ActionsHandler
|
||||
private lateinit var messageActionsStore: MessageActionsDispatcher
|
||||
|
||||
override fun injectWith(screenComponent: ScreenComponent) {
|
||||
screenComponent.inject(this)
|
||||
|
@ -61,7 +61,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message
|
|||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
actionHandlerModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java)
|
||||
messageActionsStore = ViewModelProviders.of(requireActivity()).get(MessageActionsDispatcher::class.java)
|
||||
recyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
|
||||
recyclerView.adapter = messageActionsEpoxyController.adapter
|
||||
// Disable item animation
|
||||
|
@ -74,7 +74,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message
|
|||
// Toggle report menu
|
||||
viewModel.toggleReportMenu()
|
||||
} else {
|
||||
actionHandlerModel.fireAction(simpleAction)
|
||||
messageActionsStore.post(simpleAction)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,20 +15,13 @@
|
|||
*/
|
||||
package im.vector.riotx.features.home.room.detail.timeline.action
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import im.vector.riotx.core.extensions.postLiveEvent
|
||||
import im.vector.riotx.core.utils.LiveEvent
|
||||
import javax.inject.Inject
|
||||
import im.vector.riotx.core.utils.PublishDataSource
|
||||
import im.vector.riotx.core.utils.MutableDataSource
|
||||
|
||||
/**
|
||||
* Activity shared view model to handle message actions
|
||||
*/
|
||||
class ActionsHandler @Inject constructor() : ViewModel() {
|
||||
|
||||
val actionCommandEvent = MutableLiveData<LiveEvent<SimpleAction>>()
|
||||
|
||||
fun fireAction(action: SimpleAction) {
|
||||
actionCommandEvent.postLiveEvent(action)
|
||||
}
|
||||
}
|
||||
class MessageActionsDispatcher constructor(
|
||||
private val dataSource: MutableDataSource<SimpleAction> = PublishDataSource()
|
||||
) : ViewModel(), MutableDataSource<SimpleAction> by dataSource
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue