mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 10:25:35 +03:00
Display ignored users list
This commit is contained in:
parent
fbae3d27c2
commit
9c952b6bc8
18 changed files with 394 additions and 177 deletions
|
@ -125,7 +125,9 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc
|
|||
}
|
||||
|
||||
private fun handleIgnoredUsers(userAccountDataIgnoredUsers: UserAccountDataIgnoredUsers) {
|
||||
saveIgnoredUsersTask.configureWith(userAccountDataIgnoredUsers).executeBy(taskExecutor)
|
||||
saveIgnoredUsersTask
|
||||
.configureWith(SaveIgnoredUsersTask.Params(userAccountDataIgnoredUsers.content.ignoredUsers.keys.toList()))
|
||||
.executeBy(taskExecutor)
|
||||
// TODO If not initial sync, we should execute a init sync
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ 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(
|
||||
|
@ -26,4 +27,13 @@ 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 }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,24 +18,9 @@ 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.emptyJsonDict
|
||||
|
||||
@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() {
|
||||
|
||||
|
||||
companion object {
|
||||
fun createWithUserIds(userIds: List<String>): UserAccountDataIgnoredUsers {
|
||||
return UserAccountDataIgnoredUsers(
|
||||
content = IgnoredUsersContent(
|
||||
ignoredUsers = userIds.associateWith { emptyJsonDict }
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
) : UserAccountData()
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
package im.vector.matrix.android.internal.session.user.accountdata
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse
|
||||
import im.vector.matrix.android.internal.database.model.IgnoredUserEntity
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import im.vector.matrix.android.internal.util.awaitTransaction
|
||||
import javax.inject.Inject
|
||||
|
@ -26,20 +24,23 @@ import javax.inject.Inject
|
|||
/**
|
||||
* Save the ignored users list in DB
|
||||
*/
|
||||
internal interface SaveIgnoredUsersTask : Task<UserAccountDataIgnoredUsers, Unit> {
|
||||
data class Params(val pa: GetPushRulesResponse)
|
||||
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: UserAccountDataIgnoredUsers) {
|
||||
override suspend fun execute(params: SaveIgnoredUsersTask.Params) {
|
||||
monarchy.awaitTransaction { realm ->
|
||||
// clear current ignored users
|
||||
realm.where(IgnoredUserEntity::class.java)
|
||||
.findAll()
|
||||
.deleteAllFromRealm()
|
||||
|
||||
params.content.ignoredUsers.keys.forEach { realm.createObject(IgnoredUserEntity::class.java, it) }
|
||||
// And save the new received list
|
||||
params.userIds.forEach { realm.createObject(IgnoredUserEntity::class.java).apply { userId = it } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ 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.session.sync.model.accountdata.UserAccountDataIgnoredUsers
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -36,6 +36,7 @@ internal interface UpdateIgnoredUserIdsTask : Task<UpdateIgnoredUserIdsTask.Para
|
|||
|
||||
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) {
|
||||
|
@ -43,22 +44,26 @@ internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor(private val a
|
|||
val ignoredUserIds = monarchy.fetchAllMappedSync(
|
||||
{ realm -> realm.where(IgnoredUserEntity::class.java) },
|
||||
{ it.userId }
|
||||
)
|
||||
).toMutableSet()
|
||||
|
||||
val original = ignoredUserIds.toList()
|
||||
|
||||
ignoredUserIds -= params.userIdsToUnIgnore
|
||||
ignoredUserIds += params.userIdsToIgnore
|
||||
ignoredUserIds.removeAll { it in params.userIdsToUnIgnore }
|
||||
ignoredUserIds.addAll(params.userIdsToIgnore)
|
||||
|
||||
if (original == ignoredUserIds) {
|
||||
// No change
|
||||
return
|
||||
}
|
||||
|
||||
val body = UserAccountDataIgnoredUsers.createWithUserIds(ignoredUserIds)
|
||||
val list = ignoredUserIds.toList()
|
||||
val body = IgnoredUsersContent.createWithUserIds(list)
|
||||
|
||||
return executeRequest {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,13 +16,22 @@
|
|||
|
||||
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
|
||||
|
|
|
@ -55,8 +55,6 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||
const val SETTINGS_CONTACT_PREFERENCE_KEYS = "SETTINGS_CONTACT_PREFERENCE_KEYS"
|
||||
const val SETTINGS_NOTIFICATIONS_TARGETS_PREFERENCE_KEY = "SETTINGS_NOTIFICATIONS_TARGETS_PREFERENCE_KEY"
|
||||
const val SETTINGS_NOTIFICATIONS_TARGET_DIVIDER_PREFERENCE_KEY = "SETTINGS_NOTIFICATIONS_TARGET_DIVIDER_PREFERENCE_KEY"
|
||||
const val SETTINGS_IGNORED_USERS_PREFERENCE_KEY = "SETTINGS_IGNORED_USERS_PREFERENCE_KEY"
|
||||
const val SETTINGS_IGNORE_USERS_DIVIDER_PREFERENCE_KEY = "SETTINGS_IGNORE_USERS_DIVIDER_PREFERENCE_KEY"
|
||||
const val SETTINGS_BACKGROUND_SYNC_PREFERENCE_KEY = "SETTINGS_BACKGROUND_SYNC_PREFERENCE_KEY"
|
||||
const val SETTINGS_BACKGROUND_SYNC_DIVIDER_PREFERENCE_KEY = "SETTINGS_BACKGROUND_SYNC_DIVIDER_PREFERENCE_KEY"
|
||||
const val SETTINGS_LABS_PREFERENCE_KEY = "SETTINGS_LABS_PREFERENCE_KEY"
|
||||
|
@ -544,7 +542,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||
MEDIA_SAVING_1_WEEK -> System.currentTimeMillis() / 1000 - 7 * 24 * 60 * 60
|
||||
MEDIA_SAVING_1_MONTH -> System.currentTimeMillis() / 1000 - 30 * 24 * 60 * 60
|
||||
MEDIA_SAVING_FOREVER -> 0
|
||||
else -> 0
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -559,7 +557,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||
MEDIA_SAVING_1_WEEK -> context.getString(R.string.media_saving_period_1_week)
|
||||
MEDIA_SAVING_1_MONTH -> context.getString(R.string.media_saving_period_1_month)
|
||||
MEDIA_SAVING_FOREVER -> context.getString(R.string.media_saving_period_forever)
|
||||
else -> "?"
|
||||
else -> "?"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,121 +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.features.settings
|
||||
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceCategory
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.preference.VectorPreference
|
||||
import java.util.ArrayList
|
||||
import kotlin.Comparator
|
||||
|
||||
class VectorSettingsIgnoredUsersFragment : VectorSettingsBaseFragment() {
|
||||
|
||||
override var titleRes = R.string.settings_ignored_users
|
||||
override val preferenceXmlRes = R.xml.vector_settings_ignored_users
|
||||
|
||||
// displayed the ignored users list
|
||||
private val mIgnoredUserSettingsCategoryDivider by lazy {
|
||||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_IGNORE_USERS_DIVIDER_PREFERENCE_KEY)!!
|
||||
}
|
||||
private val mIgnoredUserSettingsCategory by lazy {
|
||||
findPreference<PreferenceCategory>(VectorPreferences.SETTINGS_IGNORED_USERS_PREFERENCE_KEY)!!
|
||||
}
|
||||
|
||||
override fun bindPref() {
|
||||
// Ignore users
|
||||
refreshIgnoredUsersList()
|
||||
}
|
||||
|
||||
// ==============================================================================================================
|
||||
// ignored users list management
|
||||
// ==============================================================================================================
|
||||
|
||||
/**
|
||||
* Refresh the ignored users list
|
||||
*/
|
||||
private fun refreshIgnoredUsersList() {
|
||||
val ignoredUsersList = mutableListOf<String>() // TODO session.dataHandler.ignoredUserIds
|
||||
|
||||
ignoredUsersList.sortWith(Comparator { u1, u2 ->
|
||||
u1.toLowerCase(VectorLocale.applicationLocale).compareTo(u2.toLowerCase(VectorLocale.applicationLocale))
|
||||
})
|
||||
|
||||
val preferenceScreen = preferenceScreen
|
||||
|
||||
preferenceScreen.removePreference(mIgnoredUserSettingsCategory)
|
||||
preferenceScreen.removePreference(mIgnoredUserSettingsCategoryDivider)
|
||||
mIgnoredUserSettingsCategory.removeAll()
|
||||
|
||||
if (ignoredUsersList.size > 0) {
|
||||
preferenceScreen.addPreference(mIgnoredUserSettingsCategoryDivider)
|
||||
preferenceScreen.addPreference(mIgnoredUserSettingsCategory)
|
||||
|
||||
for (userId in ignoredUsersList) {
|
||||
val preference = Preference(activity)
|
||||
|
||||
preference.title = userId
|
||||
preference.key = IGNORED_USER_KEY_BASE + userId
|
||||
|
||||
preference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
activity?.let {
|
||||
AlertDialog.Builder(it)
|
||||
.setMessage(getString(R.string.settings_unignore_user, userId))
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
displayLoadingView()
|
||||
|
||||
val idsList = ArrayList<String>()
|
||||
idsList.add(userId)
|
||||
|
||||
notImplemented()
|
||||
/* TODO
|
||||
session.unIgnoreUsers(idsList, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(info: Void?) {
|
||||
onCommonDone(null)
|
||||
}
|
||||
|
||||
override fun onNetworkError(e: Exception) {
|
||||
onCommonDone(e.localizedMessage)
|
||||
}
|
||||
|
||||
override fun onMatrixError(e: MatrixError) {
|
||||
onCommonDone(e.localizedMessage)
|
||||
}
|
||||
|
||||
override fun onUnexpectedError(e: Exception) {
|
||||
onCommonDone(e.localizedMessage)
|
||||
}
|
||||
})
|
||||
*/
|
||||
}
|
||||
.setNegativeButton(R.string.no, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
mIgnoredUserSettingsCategory.addPreference(preference)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val IGNORED_USER_KEY_BASE = "IGNORED_USER_KEY_BASE"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.features.settings.ignored
|
||||
|
||||
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
|
||||
|
||||
/**
|
||||
* A list item for ignored user.
|
||||
*/
|
||||
@EpoxyModelClass(layout = R.layout.item_ignored_user)
|
||||
abstract class IgnoredUserItem : VectorEpoxyModel<IgnoredUserItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var userId: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var itemClickAction: (() -> Unit)? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
holder.userIdText.setTextOrHide(userId)
|
||||
|
||||
holder.userIdText.setOnClickListener { itemClickAction?.invoke() }
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
val userIdText by bind<TextView>(R.id.itemIgnoredUserId)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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.features.settings.ignored
|
||||
|
||||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.noResultItem
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
import javax.inject.Inject
|
||||
|
||||
class IgnoredUsersController @Inject constructor(private val stringProvider: StringProvider) : EpoxyController() {
|
||||
|
||||
var callback: Callback? = null
|
||||
private var viewState: IgnoredUsersViewState? = null
|
||||
|
||||
init {
|
||||
requestModelBuild()
|
||||
}
|
||||
|
||||
fun update(viewState: IgnoredUsersViewState) {
|
||||
this.viewState = viewState
|
||||
requestModelBuild()
|
||||
}
|
||||
|
||||
override fun buildModels() {
|
||||
val nonNullViewState = viewState ?: return
|
||||
buildIgnoredUserModels(nonNullViewState.ignoredUserIds)
|
||||
}
|
||||
|
||||
private fun buildIgnoredUserModels(userIds: List<String>) {
|
||||
if (userIds.isEmpty()) {
|
||||
noResultItem {
|
||||
id("empty")
|
||||
text(stringProvider.getString(R.string.no_ignored_users))
|
||||
}
|
||||
} else {
|
||||
userIds.forEach { userId ->
|
||||
ignoredUserItem {
|
||||
id(userId)
|
||||
userId(userId)
|
||||
itemClickAction { callback?.onUserIdClicked(userId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
fun onUserIdClicked(userId: String)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* 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.features.settings.ignored
|
||||
|
||||
import com.airbnb.mvrx.*
|
||||
import com.squareup.inject.assisted.Assisted
|
||||
import com.squareup.inject.assisted.AssistedInject
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.rx.rx
|
||||
import im.vector.riotx.core.extensions.postLiveEvent
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
|
||||
data class IgnoredUsersViewState(
|
||||
val ignoredUserIds: List<String> = emptyList(),
|
||||
val unIgnoreRequest: Async<Unit> = Uninitialized
|
||||
) : MvRxState
|
||||
|
||||
|
||||
sealed class IgnoredUsersAction {
|
||||
data class UnIgnore(val userId: String) : IgnoredUsersAction()
|
||||
}
|
||||
|
||||
class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: IgnoredUsersViewState,
|
||||
private val session: Session) : VectorViewModel<IgnoredUsersViewState>(initialState) {
|
||||
|
||||
@AssistedInject.Factory
|
||||
interface Factory {
|
||||
fun create(initialState: IgnoredUsersViewState): IgnoredUsersViewModel
|
||||
}
|
||||
|
||||
companion object : MvRxViewModelFactory<IgnoredUsersViewModel, IgnoredUsersViewState> {
|
||||
|
||||
@JvmStatic
|
||||
override fun create(viewModelContext: ViewModelContext, state: IgnoredUsersViewState): IgnoredUsersViewModel? {
|
||||
val ignoredUsersFragment: VectorSettingsIgnoredUsersFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
return ignoredUsersFragment.ignoredUsersViewModelFactory.create(state)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
observeIgnoredUsers()
|
||||
}
|
||||
|
||||
private fun observeIgnoredUsers() {
|
||||
session.rx()
|
||||
.liveIgnoredUserIds()
|
||||
.execute { async ->
|
||||
copy(
|
||||
ignoredUserIds = async.invoke().orEmpty()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun handle(action: IgnoredUsersAction) {
|
||||
when (action) {
|
||||
is IgnoredUsersAction.UnIgnore -> handleUnIgnore(action)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleUnIgnore(action: IgnoredUsersAction.UnIgnore) {
|
||||
setState {
|
||||
copy(
|
||||
unIgnoreRequest = Loading()
|
||||
)
|
||||
}
|
||||
|
||||
session.unIgnoreUserIds(listOf(action.userId), object : MatrixCallback<Unit> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
setState {
|
||||
copy(
|
||||
unIgnoreRequest = Fail(failure)
|
||||
)
|
||||
}
|
||||
|
||||
_requestErrorLiveData.postLiveEvent(failure)
|
||||
}
|
||||
|
||||
override fun onSuccess(data: Unit) {
|
||||
setState {
|
||||
copy(
|
||||
unIgnoreRequest = Success(data)
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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.features.settings.ignored
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.Loading
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.error.ErrorFormatter
|
||||
import im.vector.riotx.core.extensions.observeEvent
|
||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import kotlinx.android.synthetic.main.fragment_generic_recycler_epoxy.*
|
||||
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class VectorSettingsIgnoredUsersFragment @Inject constructor(
|
||||
val ignoredUsersViewModelFactory: IgnoredUsersViewModel.Factory,
|
||||
private val ignoredUsersController: IgnoredUsersController,
|
||||
private val errorFormatter: ErrorFormatter
|
||||
) : VectorBaseFragment(), IgnoredUsersController.Callback {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_generic_recycler_epoxy
|
||||
|
||||
private val ignoredUsersViewModel: IgnoredUsersViewModel by fragmentViewModel()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
waiting_view_status_text.setText(R.string.please_wait)
|
||||
waiting_view_status_text.isVisible = true
|
||||
ignoredUsersController.callback = this
|
||||
epoxyRecyclerView.setController(ignoredUsersController)
|
||||
ignoredUsersViewModel.requestErrorLiveData.observeEvent(this) {
|
||||
displayErrorDialog(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
(activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_ignored_users)
|
||||
}
|
||||
|
||||
override fun onUserIdClicked(userId: String) {
|
||||
AlertDialog.Builder(requireActivity())
|
||||
.setMessage(getString(R.string.settings_unignore_user, userId))
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
ignoredUsersViewModel.handle(IgnoredUsersAction.UnIgnore(userId))
|
||||
}
|
||||
.setNegativeButton(R.string.no, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun displayErrorDialog(throwable: Throwable) {
|
||||
AlertDialog.Builder(requireActivity())
|
||||
.setTitle(R.string.dialog_title_error)
|
||||
.setMessage(errorFormatter.toHumanReadable(throwable))
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
// ==============================================================================================================
|
||||
// ignored users list management
|
||||
// ==============================================================================================================
|
||||
|
||||
override fun invalidate() = withState(ignoredUsersViewModel) { state ->
|
||||
ignoredUsersController.update(state)
|
||||
|
||||
handleUnIgnoreRequestStatus(state.unIgnoreRequest)
|
||||
}
|
||||
|
||||
private fun handleUnIgnoreRequestStatus(unIgnoreRequest: Async<Unit>) {
|
||||
when (unIgnoreRequest) {
|
||||
is Loading -> waiting_view.isVisible = true
|
||||
else -> waiting_view.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.airbnb.epoxy.EpoxyRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/epoxyRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:itemSpacing="1dp"
|
||||
tools:listitem="@layout/item_pushgateway" />
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.airbnb.epoxy.EpoxyRecyclerView
|
||||
android:id="@+id/epoxyRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:itemSpacing="1dp"
|
||||
tools:listitem="@layout/item_pushgateway" />
|
||||
|
||||
<include layout="@layout/merge_overlay_waiting_view" />
|
||||
|
||||
</FrameLayout>
|
||||
|
|
21
vector/src/main/res/layout/item_ignored_user.xml
Normal file
21
vector/src/main/res/layout/item_ignored_user.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/itemIgnoredUserId"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?riotx_background"
|
||||
android:clickable="true"
|
||||
android:ellipsize="end"
|
||||
android:focusable="true"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:lines="2"
|
||||
android:maxLines="2"
|
||||
android:minHeight="?listPreferredItemHeight"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="16sp"
|
||||
tools:text="@sample/matrix.json/data/mxid" />
|
||||
|
|
@ -3,8 +3,7 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/waiting_view"
|
||||
|
|
|
@ -4,4 +4,6 @@
|
|||
<!-- Strings not defined in Riot -->
|
||||
<string name="notice_member_no_changes">"%1$s made no changes"</string>
|
||||
|
||||
<string name="no_ignored_users">You are not ignoring any users</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreferenceCategory
|
||||
android:key="SETTINGS_IGNORED_USERS_PREFERENCE_KEY"
|
||||
android:title="@string/settings_ignored_users" />
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreferenceDivider android:key="SETTINGS_IGNORE_USERS_DIVIDER_PREFERENCE_KEY" />
|
||||
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
|
@ -37,10 +37,9 @@
|
|||
|
||||
<im.vector.riotx.core.preference.VectorPreference
|
||||
android:layout_width="match_parent"
|
||||
android:enabled="@bool/false_not_implemented"
|
||||
android:icon="@drawable/ic_settings_root_ignored_users"
|
||||
android:title="@string/settings_ignored_users"
|
||||
app:fragment="im.vector.riotx.features.settings.VectorSettingsIgnoredUsersFragment" />
|
||||
app:fragment="im.vector.riotx.features.settings.ignored.VectorSettingsIgnoredUsersFragment" />
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreference
|
||||
android:layout_width="match_parent"
|
||||
|
|
Loading…
Reference in a new issue