forked from GitHub-Mirror/riotX-android
Direct messages: try to handle selecting/deselecting users (WIP)
This commit is contained in:
parent
03974c8bdf
commit
125eacb20b
@ -28,7 +28,7 @@ object MatrixPatterns {
|
|||||||
// regex pattern to find matrix user ids in a string.
|
// regex pattern to find matrix user ids in a string.
|
||||||
// See https://matrix.org/speculator/spec/HEAD/appendices.html#historical-user-ids
|
// See https://matrix.org/speculator/spec/HEAD/appendices.html#historical-user-ids
|
||||||
private const val MATRIX_USER_IDENTIFIER_REGEX = "@[A-Z0-9\\x21-\\x39\\x3B-\\x7F]+$DOMAIN_REGEX"
|
private const val MATRIX_USER_IDENTIFIER_REGEX = "@[A-Z0-9\\x21-\\x39\\x3B-\\x7F]+$DOMAIN_REGEX"
|
||||||
private val PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER = MATRIX_USER_IDENTIFIER_REGEX.toRegex(RegexOption.IGNORE_CASE)
|
val PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER = MATRIX_USER_IDENTIFIER_REGEX.toRegex(RegexOption.IGNORE_CASE)
|
||||||
|
|
||||||
// regex pattern to find room ids in a string.
|
// regex pattern to find room ids in a string.
|
||||||
private const val MATRIX_ROOM_IDENTIFIER_REGEX = "![A-Z0-9]+$DOMAIN_REGEX"
|
private const val MATRIX_ROOM_IDENTIFIER_REGEX = "![A-Z0-9]+$DOMAIN_REGEX"
|
||||||
|
@ -18,6 +18,7 @@ package im.vector.riotx.core.extensions
|
|||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import im.vector.riotx.core.utils.FirstThrottler
|
import im.vector.riotx.core.utils.FirstThrottler
|
||||||
import im.vector.riotx.core.utils.EventObserver
|
import im.vector.riotx.core.utils.EventObserver
|
||||||
@ -44,3 +45,7 @@ inline fun <T> LiveData<LiveEvent<T>>.observeEventFirstThrottle(owner: Lifecycle
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> MutableLiveData<LiveEvent<T>>.postLiveEvent(content: T) {
|
||||||
|
this.postValue(LiveEvent(content))
|
||||||
|
}
|
||||||
|
@ -19,6 +19,7 @@ package im.vector.riotx.core.mvrx
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import im.vector.riotx.core.extensions.postLiveEvent
|
||||||
import im.vector.riotx.core.utils.LiveEvent
|
import im.vector.riotx.core.utils.LiveEvent
|
||||||
|
|
||||||
abstract class NavigationViewModel<NavigationClass> : ViewModel() {
|
abstract class NavigationViewModel<NavigationClass> : ViewModel() {
|
||||||
@ -29,6 +30,6 @@ abstract class NavigationViewModel<NavigationClass> : ViewModel() {
|
|||||||
|
|
||||||
|
|
||||||
fun goTo(navigation: NavigationClass) {
|
fun goTo(navigation: NavigationClass) {
|
||||||
_navigateTo.postValue(LiveEvent(navigation))
|
_navigateTo.postLiveEvent(navigation)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,20 +16,36 @@
|
|||||||
|
|
||||||
package im.vector.riotx.core.platform
|
package im.vector.riotx.core.platform
|
||||||
|
|
||||||
import com.airbnb.mvrx.BaseMvRxViewModel
|
import com.airbnb.mvrx.*
|
||||||
import com.airbnb.mvrx.MvRxState
|
|
||||||
import im.vector.matrix.android.api.util.CancelableBag
|
import im.vector.matrix.android.api.util.CancelableBag
|
||||||
import im.vector.riotx.BuildConfig
|
import im.vector.riotx.BuildConfig
|
||||||
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.Single
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
|
|
||||||
abstract class VectorViewModel<S : MvRxState>(initialState: S)
|
abstract class VectorViewModel<S : MvRxState>(initialState: S)
|
||||||
: BaseMvRxViewModel<S>(initialState, false) {
|
: BaseMvRxViewModel<S>(initialState, false) {
|
||||||
|
|
||||||
protected val cancelableBag = CancelableBag()
|
/**
|
||||||
|
* This method does the same thing as the execute function, but it doesn't subscribe to the stream
|
||||||
override fun onCleared() {
|
* so you can use this in a switchMap or a flatMap
|
||||||
super.onCleared()
|
*/
|
||||||
cancelableBag.cancel()
|
fun <T> Single<T>.toAsync(stateReducer: S.(Async<T>) -> S): Single<Async<T>> {
|
||||||
|
setState { stateReducer(Loading()) }
|
||||||
|
return this.map { Success(it) as Async<T> }
|
||||||
|
.onErrorReturn { Fail(it) }
|
||||||
|
.doOnSuccess { setState { stateReducer(it) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
fun <T> Observable<T>.toAsync(stateReducer: S.(Async<T>) -> S): Observable<Async<T>> {
|
||||||
|
setState { stateReducer(Loading()) }
|
||||||
|
return this.map { Success(it) as Async<T> }
|
||||||
|
.onErrorReturn { Fail(it) }
|
||||||
|
.doOnNext { setState { stateReducer(it) } }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -19,13 +19,9 @@
|
|||||||
package im.vector.riotx.features.home.createdirect
|
package im.vector.riotx.features.home.createdirect
|
||||||
|
|
||||||
import com.airbnb.epoxy.EpoxyController
|
import com.airbnb.epoxy.EpoxyController
|
||||||
import com.airbnb.epoxy.VisibilityState
|
|
||||||
import com.airbnb.mvrx.Fail
|
import com.airbnb.mvrx.Fail
|
||||||
import com.airbnb.mvrx.Incomplete
|
import com.airbnb.mvrx.Incomplete
|
||||||
import com.airbnb.mvrx.Loading
|
|
||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
import com.airbnb.mvrx.Uninitialized
|
|
||||||
import im.vector.matrix.android.api.failure.Failure
|
|
||||||
import im.vector.matrix.android.api.session.user.model.User
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
import im.vector.matrix.android.internal.util.firstLetterOfDisplayName
|
import im.vector.matrix.android.internal.util.firstLetterOfDisplayName
|
||||||
import im.vector.riotx.core.epoxy.errorWithRetryItem
|
import im.vector.riotx.core.epoxy.errorWithRetryItem
|
||||||
@ -60,7 +56,7 @@ class CreateDirectRoomController @Inject constructor(private val avatarRenderer:
|
|||||||
}
|
}
|
||||||
when (asyncUsers) {
|
when (asyncUsers) {
|
||||||
is Incomplete -> renderLoading()
|
is Incomplete -> renderLoading()
|
||||||
is Success -> renderUsers(asyncUsers(), currentState.selectedUsers)
|
is Success -> renderUsers(asyncUsers(), currentState.selectedUsers.map { it.userId })
|
||||||
is Fail -> renderFailure(asyncUsers.error)
|
is Fail -> renderFailure(asyncUsers.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,10 +75,10 @@ class CreateDirectRoomController @Inject constructor(private val avatarRenderer:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderUsers(users: List<User>, selectedUsers: Set<User>) {
|
private fun renderUsers(users: List<User>, selectedUsers: List<String>) {
|
||||||
var lastFirstLetter: String? = null
|
var lastFirstLetter: String? = null
|
||||||
users.forEach { user ->
|
users.forEach { user ->
|
||||||
val isSelected = selectedUsers.contains(user)
|
val isSelected = selectedUsers.contains(user.userId)
|
||||||
val currentFirstLetter = user.displayName.firstLetterOfDisplayName()
|
val currentFirstLetter = user.displayName.firstLetterOfDisplayName()
|
||||||
val showLetter = currentFirstLetter.isNotEmpty() && lastFirstLetter != currentFirstLetter
|
val showLetter = currentFirstLetter.isNotEmpty() && lastFirstLetter != currentFirstLetter
|
||||||
lastFirstLetter = currentFirstLetter
|
lastFirstLetter = currentFirstLetter
|
||||||
|
@ -25,6 +25,7 @@ import com.jakewharton.rxbinding3.widget.textChanges
|
|||||||
import im.vector.matrix.android.api.session.user.model.User
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.di.ScreenComponent
|
import im.vector.riotx.core.di.ScreenComponent
|
||||||
|
import im.vector.riotx.core.extensions.hideKeyboard
|
||||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||||
import kotlinx.android.synthetic.main.fragment_create_direct_room_directory_users.*
|
import kotlinx.android.synthetic.main.fragment_create_direct_room_directory_users.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -82,6 +83,7 @@ class CreateDirectRoomDirectoryUsersFragment : VectorBaseFragment(), CreateDirec
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClick(user: User) {
|
override fun onItemClick(user: User) {
|
||||||
|
view?.hideKeyboard()
|
||||||
viewModel.handle(CreateDirectRoomActions.SelectUser(user))
|
viewModel.handle(CreateDirectRoomActions.SelectUser(user))
|
||||||
navigationViewModel.goTo(CreateDirectRoomActivity.Navigation.Previous)
|
navigationViewModel.goTo(CreateDirectRoomActivity.Navigation.Previous)
|
||||||
}
|
}
|
||||||
|
@ -19,21 +19,24 @@
|
|||||||
package im.vector.riotx.features.home.createdirect
|
package im.vector.riotx.features.home.createdirect
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.text.Spannable
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import com.airbnb.mvrx.Fail
|
|
||||||
import com.airbnb.mvrx.Loading
|
|
||||||
import com.airbnb.mvrx.Success
|
|
||||||
import com.airbnb.mvrx.Uninitialized
|
|
||||||
import com.airbnb.mvrx.activityViewModel
|
import com.airbnb.mvrx.activityViewModel
|
||||||
import com.jakewharton.rxbinding3.appcompat.queryTextChanges
|
import com.airbnb.mvrx.withState
|
||||||
|
import com.jakewharton.rxbinding3.widget.beforeTextChangeEvents
|
||||||
|
import com.jakewharton.rxbinding3.widget.textChanges
|
||||||
|
import im.vector.matrix.android.api.MatrixPatterns
|
||||||
import im.vector.matrix.android.api.session.user.model.User
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.di.ScreenComponent
|
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.glide.GlideApp
|
||||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity
|
import im.vector.riotx.features.home.AvatarRenderer
|
||||||
|
import im.vector.riotx.features.html.PillImageSpan
|
||||||
import kotlinx.android.synthetic.main.fragment_create_direct_room.*
|
import kotlinx.android.synthetic.main.fragment_create_direct_room.*
|
||||||
import kotlinx.android.synthetic.main.fragment_public_rooms.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class CreateDirectRoomFragment : VectorBaseFragment(), CreateDirectRoomController.Callback {
|
class CreateDirectRoomFragment : VectorBaseFragment(), CreateDirectRoomController.Callback {
|
||||||
@ -45,6 +48,7 @@ class CreateDirectRoomFragment : VectorBaseFragment(), CreateDirectRoomControlle
|
|||||||
private val viewModel: CreateDirectRoomViewModel by activityViewModel()
|
private val viewModel: CreateDirectRoomViewModel by activityViewModel()
|
||||||
|
|
||||||
@Inject lateinit var directRoomController: CreateDirectRoomController
|
@Inject lateinit var directRoomController: CreateDirectRoomController
|
||||||
|
@Inject lateinit var avatarRenderer: AvatarRenderer
|
||||||
private lateinit var navigationViewModel: CreateDirectRoomNavigationViewModel
|
private lateinit var navigationViewModel: CreateDirectRoomNavigationViewModel
|
||||||
|
|
||||||
override fun injectWith(injector: ScreenComponent) {
|
override fun injectWith(injector: ScreenComponent) {
|
||||||
@ -59,6 +63,10 @@ class CreateDirectRoomFragment : VectorBaseFragment(), CreateDirectRoomControlle
|
|||||||
setupFilterView()
|
setupFilterView()
|
||||||
setupAddByMatrixIdView()
|
setupAddByMatrixIdView()
|
||||||
setupCloseView()
|
setupCloseView()
|
||||||
|
viewModel.selectUserEvent.observeEvent(this) {
|
||||||
|
updateFilterViewWith(it)
|
||||||
|
|
||||||
|
}
|
||||||
viewModel.subscribe(this) { renderState(it) }
|
viewModel.subscribe(this) { renderState(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,16 +98,43 @@ class CreateDirectRoomFragment : VectorBaseFragment(), CreateDirectRoomControlle
|
|||||||
|
|
||||||
private fun setupFilterView() {
|
private fun setupFilterView() {
|
||||||
createDirectRoomFilter
|
createDirectRoomFilter
|
||||||
.queryTextChanges()
|
.textChanges()
|
||||||
.subscribe {
|
.subscribe { text ->
|
||||||
val action = if (it.isNullOrEmpty()) {
|
val userMatches = MatrixPatterns.PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER.findAll(text)
|
||||||
|
val lastUserMatch = userMatches.lastOrNull()
|
||||||
|
val filterValue = if (lastUserMatch == null) {
|
||||||
|
text
|
||||||
|
} else {
|
||||||
|
text.substring(startIndex = lastUserMatch.range.endInclusive + 1)
|
||||||
|
}.trim()
|
||||||
|
|
||||||
|
val action = if (filterValue.isBlank()) {
|
||||||
CreateDirectRoomActions.ClearFilterKnownUsers
|
CreateDirectRoomActions.ClearFilterKnownUsers
|
||||||
} else {
|
} else {
|
||||||
CreateDirectRoomActions.FilterKnownUsers(it.toString())
|
CreateDirectRoomActions.FilterKnownUsers(filterValue.toString())
|
||||||
}
|
}
|
||||||
viewModel.handle(action)
|
viewModel.handle(action)
|
||||||
}
|
}
|
||||||
.disposeOnDestroy()
|
.disposeOnDestroy()
|
||||||
|
|
||||||
|
createDirectRoomFilter
|
||||||
|
.beforeTextChangeEvents()
|
||||||
|
.subscribe { event ->
|
||||||
|
if (event.after == 0) {
|
||||||
|
val sub = event.text.substring(0, event.start)
|
||||||
|
val startIndexOfUser = sub.lastIndexOf(" ") + 1
|
||||||
|
val user = sub.substring(startIndexOfUser)
|
||||||
|
val selectedUser = withState(viewModel) { state ->
|
||||||
|
state.selectedUsers.find { it.userId == user }
|
||||||
|
}
|
||||||
|
if (selectedUser != null) {
|
||||||
|
viewModel.handle(CreateDirectRoomActions.RemoveSelectedUser(selectedUser))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.disposeOnDestroy()
|
||||||
|
|
||||||
|
createDirectRoomFilter.requestFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupCloseView() {
|
private fun setupCloseView() {
|
||||||
@ -109,11 +144,37 @@ class CreateDirectRoomFragment : VectorBaseFragment(), CreateDirectRoomControlle
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun renderState(state: CreateDirectRoomViewState) {
|
private fun renderState(state: CreateDirectRoomViewState) {
|
||||||
|
|
||||||
directRoomController.setData(state)
|
directRoomController.setData(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateFilterViewWith(data: SelectUserAction) = withState(viewModel) { state ->
|
||||||
|
if (state.selectedUsers.isEmpty()) {
|
||||||
|
createDirectRoomFilter.text = null
|
||||||
|
} else {
|
||||||
|
val editable = createDirectRoomFilter.editableText
|
||||||
|
val user = data.user
|
||||||
|
if (data.isAdded) {
|
||||||
|
val startIndex = editable.lastIndexOf(" ") + 1
|
||||||
|
val endIndex = editable.length
|
||||||
|
editable.replace(startIndex, endIndex, "${user.userId} ")
|
||||||
|
val span = PillImageSpan(GlideApp.with(this), avatarRenderer, requireContext(), user.userId, user)
|
||||||
|
span.bind(createDirectRoomFilter)
|
||||||
|
editable.setSpan(span, startIndex, startIndex + user.userId.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
} else {
|
||||||
|
val startIndex = editable.indexOf(user.userId)
|
||||||
|
if (startIndex != -1) {
|
||||||
|
var endIndex = editable.indexOf(" ", startIndex) + 1
|
||||||
|
if (endIndex == 0) {
|
||||||
|
endIndex = editable.length
|
||||||
|
}
|
||||||
|
editable.replace(startIndex, endIndex, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onItemClick(user: User) {
|
override fun onItemClick(user: User) {
|
||||||
|
view?.hideKeyboard()
|
||||||
viewModel.handle(CreateDirectRoomActions.SelectUser(user))
|
viewModel.handle(CreateDirectRoomActions.SelectUser(user))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -28,9 +28,7 @@ import com.amulyakhare.textdrawable.TextDrawable
|
|||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||||
import im.vector.riotx.core.resources.ColorProvider
|
|
||||||
import im.vector.riotx.features.home.AvatarRenderer
|
import im.vector.riotx.features.home.AvatarRenderer
|
||||||
import im.vector.riotx.features.home.getColorFromUserId
|
|
||||||
|
|
||||||
@EpoxyModelClass(layout = R.layout.item_create_direct_room_user)
|
@EpoxyModelClass(layout = R.layout.item_create_direct_room_user)
|
||||||
abstract class CreateDirectRoomUserItem : VectorEpoxyModel<CreateDirectRoomUserItem.Holder>() {
|
abstract class CreateDirectRoomUserItem : VectorEpoxyModel<CreateDirectRoomUserItem.Holder>() {
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
|
|
||||||
package im.vector.riotx.features.home.createdirect
|
package im.vector.riotx.features.home.createdirect
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import arrow.core.Option
|
import arrow.core.Option
|
||||||
import com.airbnb.mvrx.ActivityViewModelContext
|
import com.airbnb.mvrx.*
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
|
||||||
import com.jakewharton.rxrelay2.BehaviorRelay
|
import com.jakewharton.rxrelay2.BehaviorRelay
|
||||||
import com.squareup.inject.assisted.Assisted
|
import com.squareup.inject.assisted.Assisted
|
||||||
import com.squareup.inject.assisted.AssistedInject
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
@ -29,7 +29,9 @@ import im.vector.matrix.android.api.session.Session
|
|||||||
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
||||||
import im.vector.matrix.android.api.session.user.model.User
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
|
import im.vector.riotx.core.extensions.postLiveEvent
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
|
import im.vector.riotx.core.utils.LiveEvent
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.functions.BiFunction
|
import io.reactivex.functions.BiFunction
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -37,6 +39,11 @@ import java.util.concurrent.TimeUnit
|
|||||||
private typealias KnowUsersFilter = String
|
private typealias KnowUsersFilter = String
|
||||||
private typealias DirectoryUsersSearch = String
|
private typealias DirectoryUsersSearch = String
|
||||||
|
|
||||||
|
data class SelectUserAction(
|
||||||
|
val user: User,
|
||||||
|
val isAdded: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
|
class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
|
||||||
initialState: CreateDirectRoomViewState,
|
initialState: CreateDirectRoomViewState,
|
||||||
private val session: Session)
|
private val session: Session)
|
||||||
@ -50,6 +57,10 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
|
|||||||
private val knownUsersFilter = BehaviorRelay.createDefault<Option<KnowUsersFilter>>(Option.empty())
|
private val knownUsersFilter = BehaviorRelay.createDefault<Option<KnowUsersFilter>>(Option.empty())
|
||||||
private val directoryUsersSearch = BehaviorRelay.create<DirectoryUsersSearch>()
|
private val directoryUsersSearch = BehaviorRelay.create<DirectoryUsersSearch>()
|
||||||
|
|
||||||
|
private val _selectUserEvent = MutableLiveData<LiveEvent<SelectUserAction>>()
|
||||||
|
val selectUserEvent: LiveData<LiveEvent<SelectUserAction>>
|
||||||
|
get() = _selectUserEvent
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<CreateDirectRoomViewModel, CreateDirectRoomViewState> {
|
companion object : MvRxViewModelFactory<CreateDirectRoomViewModel, CreateDirectRoomViewState> {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@ -78,7 +89,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
|
|||||||
private fun createRoomAndInviteSelectedUsers() = withState { currentState ->
|
private fun createRoomAndInviteSelectedUsers() = withState { currentState ->
|
||||||
val isDirect = currentState.selectedUsers.size == 1
|
val isDirect = currentState.selectedUsers.size == 1
|
||||||
val roomParams = CreateRoomParams().apply {
|
val roomParams = CreateRoomParams().apply {
|
||||||
invitedUserIds = ArrayList(currentState.selectedUsers.map { user -> user.userId })
|
invitedUserIds = ArrayList(currentState.selectedUsers.map { it.userId })
|
||||||
if (isDirect) {
|
if (isDirect) {
|
||||||
setDirectMessage()
|
setDirectMessage()
|
||||||
}
|
}
|
||||||
@ -92,33 +103,42 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleRemoveSelectedUser(action: CreateDirectRoomActions.RemoveSelectedUser) = withState {
|
private fun handleRemoveSelectedUser(action: CreateDirectRoomActions.RemoveSelectedUser) = withState {
|
||||||
val selectedUsers = it.selectedUsers.minusElement(action.user)
|
val selectedUsers = it.selectedUsers.minus(action.user)
|
||||||
setState { copy(selectedUsers = selectedUsers) }
|
setState { copy(selectedUsers = selectedUsers) }
|
||||||
|
_selectUserEvent.postLiveEvent(SelectUserAction(action.user, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSelectUser(action: CreateDirectRoomActions.SelectUser) = withState {
|
private fun handleSelectUser(action: CreateDirectRoomActions.SelectUser) = withState {
|
||||||
val selectedUsers = if (it.selectedUsers.contains(action.user)) {
|
//Reset the filter asap
|
||||||
it.selectedUsers.minusElement(action.user)
|
knownUsersFilter.accept(Option.empty())
|
||||||
|
directoryUsersSearch.accept("")
|
||||||
|
|
||||||
|
val isAddOperation: Boolean
|
||||||
|
val selectedUsers: Set<User>
|
||||||
|
if (it.selectedUsers.contains(action.user)) {
|
||||||
|
selectedUsers = it.selectedUsers.minus(action.user)
|
||||||
|
isAddOperation = false
|
||||||
} else {
|
} else {
|
||||||
it.selectedUsers.plus(action.user)
|
selectedUsers = it.selectedUsers.plus(action.user)
|
||||||
|
isAddOperation = true
|
||||||
}
|
}
|
||||||
setState { copy(selectedUsers = selectedUsers) }
|
setState { copy(selectedUsers = selectedUsers) }
|
||||||
|
_selectUserEvent.postLiveEvent(SelectUserAction(action.user, isAddOperation))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeDirectoryUsers() {
|
private fun observeDirectoryUsers() {
|
||||||
directoryUsersSearch
|
directoryUsersSearch
|
||||||
.throttleLast(300, TimeUnit.MILLISECONDS)
|
.throttleLast(500, TimeUnit.MILLISECONDS)
|
||||||
.switchMapSingle { search ->
|
.switchMapSingle { search ->
|
||||||
session.rx()
|
session.rx()
|
||||||
.searchUsersDirectory(search, 50, emptySet())
|
.searchUsersDirectory(search, 50, emptySet())
|
||||||
.map { users ->
|
.map { users ->
|
||||||
users.sortedBy { it.displayName }
|
users.sortedBy { it.displayName }
|
||||||
}
|
}
|
||||||
|
.toAsync { copy(directoryUsers = it) }
|
||||||
}
|
}
|
||||||
.execute { async ->
|
.subscribe()
|
||||||
copy(directoryUsers = async)
|
.disposeOnClear()
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeKnownUsers() {
|
private fun observeKnownUsers() {
|
||||||
|
@ -28,6 +28,7 @@ import im.vector.matrix.android.api.session.Session
|
|||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
|
import im.vector.riotx.core.extensions.postLiveEvent
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
import im.vector.riotx.core.resources.StringProvider
|
import im.vector.riotx.core.resources.StringProvider
|
||||||
import im.vector.riotx.core.utils.LiveEvent
|
import im.vector.riotx.core.utils.LiveEvent
|
||||||
@ -67,7 +68,7 @@ class GroupListViewModel @AssistedInject constructor(@Assisted initialState: Gro
|
|||||||
private fun observeSelectionState() {
|
private fun observeSelectionState() {
|
||||||
selectSubscribe(GroupListViewState::selectedGroup) {
|
selectSubscribe(GroupListViewState::selectedGroup) {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
_openGroupLiveData.postValue(LiveEvent(it))
|
_openGroupLiveData.postLiveEvent(it)
|
||||||
val optionGroup = Option.fromNullable(it)
|
val optionGroup = Option.fromNullable(it)
|
||||||
selectedGroupHolder.post(optionGroup)
|
selectedGroupHolder.post(optionGroup)
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
|||||||
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
|
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
|
||||||
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
|
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
|
import im.vector.riotx.core.extensions.postLiveEvent
|
||||||
import im.vector.riotx.core.intent.getFilenameFromUri
|
import im.vector.riotx.core.intent.getFilenameFromUri
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
import im.vector.riotx.core.resources.UserPreferencesProvider
|
import im.vector.riotx.core.resources.UserPreferencesProvider
|
||||||
@ -168,62 +169,62 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
|||||||
is ParsedCommand.ErrorNotACommand -> {
|
is ParsedCommand.ErrorNotACommand -> {
|
||||||
// Send the text message to the room
|
// Send the text message to the room
|
||||||
room.sendTextMessage(action.text, autoMarkdown = action.autoMarkdown)
|
room.sendTextMessage(action.text, autoMarkdown = action.autoMarkdown)
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.MessageSent))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.MessageSent)
|
||||||
}
|
}
|
||||||
is ParsedCommand.ErrorSyntax -> {
|
is ParsedCommand.ErrorSyntax -> {
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandError(slashCommandResult.command)))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandError(slashCommandResult.command))
|
||||||
}
|
}
|
||||||
is ParsedCommand.ErrorEmptySlashCommand -> {
|
is ParsedCommand.ErrorEmptySlashCommand -> {
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandUnknown("/")))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandUnknown("/"))
|
||||||
}
|
}
|
||||||
is ParsedCommand.ErrorUnknownSlashCommand -> {
|
is ParsedCommand.ErrorUnknownSlashCommand -> {
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandUnknown(slashCommandResult.slashCommand)))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandUnknown(slashCommandResult.slashCommand))
|
||||||
}
|
}
|
||||||
is ParsedCommand.Invite -> {
|
is ParsedCommand.Invite -> {
|
||||||
handleInviteSlashCommand(slashCommandResult)
|
handleInviteSlashCommand(slashCommandResult)
|
||||||
}
|
}
|
||||||
is ParsedCommand.SetUserPowerLevel -> {
|
is ParsedCommand.SetUserPowerLevel -> {
|
||||||
// TODO
|
// TODO
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandNotImplemented)
|
||||||
}
|
}
|
||||||
is ParsedCommand.ClearScalarToken -> {
|
is ParsedCommand.ClearScalarToken -> {
|
||||||
// TODO
|
// TODO
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandNotImplemented)
|
||||||
}
|
}
|
||||||
is ParsedCommand.SetMarkdown -> {
|
is ParsedCommand.SetMarkdown -> {
|
||||||
// TODO
|
// TODO
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandNotImplemented)
|
||||||
}
|
}
|
||||||
is ParsedCommand.UnbanUser -> {
|
is ParsedCommand.UnbanUser -> {
|
||||||
// TODO
|
// TODO
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandNotImplemented)
|
||||||
}
|
}
|
||||||
is ParsedCommand.BanUser -> {
|
is ParsedCommand.BanUser -> {
|
||||||
// TODO
|
// TODO
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandNotImplemented)
|
||||||
}
|
}
|
||||||
is ParsedCommand.KickUser -> {
|
is ParsedCommand.KickUser -> {
|
||||||
// TODO
|
// TODO
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandNotImplemented)
|
||||||
}
|
}
|
||||||
is ParsedCommand.JoinRoom -> {
|
is ParsedCommand.JoinRoom -> {
|
||||||
// TODO
|
// TODO
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandNotImplemented)
|
||||||
}
|
}
|
||||||
is ParsedCommand.PartRoom -> {
|
is ParsedCommand.PartRoom -> {
|
||||||
// TODO
|
// TODO
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandNotImplemented)
|
||||||
}
|
}
|
||||||
is ParsedCommand.SendEmote -> {
|
is ParsedCommand.SendEmote -> {
|
||||||
room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE)
|
room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE)
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandHandled))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandHandled)
|
||||||
}
|
}
|
||||||
is ParsedCommand.ChangeTopic -> {
|
is ParsedCommand.ChangeTopic -> {
|
||||||
handleChangeTopicSlashCommand(slashCommandResult)
|
handleChangeTopicSlashCommand(slashCommandResult)
|
||||||
}
|
}
|
||||||
is ParsedCommand.ChangeDisplayName -> {
|
is ParsedCommand.ChangeDisplayName -> {
|
||||||
// TODO
|
// TODO
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandNotImplemented)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,7 +256,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
|||||||
sendMode = SendMode.REGULAR
|
sendMode = SendMode.REGULAR
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.MessageSent))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.MessageSent)
|
||||||
}
|
}
|
||||||
is SendMode.QUOTE -> {
|
is SendMode.QUOTE -> {
|
||||||
val messageContent: MessageContent? =
|
val messageContent: MessageContent? =
|
||||||
@ -280,7 +281,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
|||||||
sendMode = SendMode.REGULAR
|
sendMode = SendMode.REGULAR
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.MessageSent))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.MessageSent)
|
||||||
}
|
}
|
||||||
is SendMode.REPLY -> {
|
is SendMode.REPLY -> {
|
||||||
state.sendMode.timelineEvent.let {
|
state.sendMode.timelineEvent.let {
|
||||||
@ -290,7 +291,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
|||||||
sendMode = SendMode.REGULAR
|
sendMode = SendMode.REGULAR
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.MessageSent))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.MessageSent)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -319,29 +320,29 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleChangeTopicSlashCommand(changeTopic: ParsedCommand.ChangeTopic) {
|
private fun handleChangeTopicSlashCommand(changeTopic: ParsedCommand.ChangeTopic) {
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandHandled))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandHandled)
|
||||||
|
|
||||||
room.updateTopic(changeTopic.topic, object : MatrixCallback<Unit> {
|
room.updateTopic(changeTopic.topic, object : MatrixCallback<Unit> {
|
||||||
override fun onSuccess(data: Unit) {
|
override fun onSuccess(data: Unit) {
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandResultOk))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandResultOk)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandResultError(failure)))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandResultError(failure))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) {
|
private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) {
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandHandled))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandHandled)
|
||||||
|
|
||||||
room.invite(invite.userId, object : MatrixCallback<Unit> {
|
room.invite(invite.userId, object : MatrixCallback<Unit> {
|
||||||
override fun onSuccess(data: Unit) {
|
override fun onSuccess(data: Unit) {
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandResultOk))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandResultOk)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandResultError(failure)))
|
_sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandResultError(failure))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -453,19 +454,19 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
|||||||
action.messageFileContent.encryptedFileInfo?.toElementToDecrypt(),
|
action.messageFileContent.encryptedFileInfo?.toElementToDecrypt(),
|
||||||
object : MatrixCallback<File> {
|
object : MatrixCallback<File> {
|
||||||
override fun onSuccess(data: File) {
|
override fun onSuccess(data: File) {
|
||||||
_downloadedFileEvent.postValue(LiveEvent(DownloadFileState(
|
_downloadedFileEvent.postLiveEvent(DownloadFileState(
|
||||||
action.messageFileContent.getMimeType(),
|
action.messageFileContent.getMimeType(),
|
||||||
data,
|
data,
|
||||||
null
|
null
|
||||||
)))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
_downloadedFileEvent.postValue(LiveEvent(DownloadFileState(
|
_downloadedFileEvent.postLiveEvent(DownloadFileState(
|
||||||
action.messageFileContent.getMimeType(),
|
action.messageFileContent.getMimeType(),
|
||||||
null,
|
null,
|
||||||
failure
|
failure
|
||||||
)))
|
))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -494,7 +495,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_navigateToEvent.postValue(LiveEvent(targetEventId))
|
_navigateToEvent.postLiveEvent(targetEventId)
|
||||||
} else {
|
} else {
|
||||||
// change timeline
|
// change timeline
|
||||||
timeline.dispose()
|
timeline.dispose()
|
||||||
@ -519,7 +520,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_navigateToEvent.postValue(LiveEvent(targetEventId))
|
_navigateToEvent.postLiveEvent(targetEventId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import im.vector.matrix.android.api.session.Session
|
|||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.matrix.android.api.session.room.model.tag.RoomTag
|
import im.vector.matrix.android.api.session.room.model.tag.RoomTag
|
||||||
|
import im.vector.riotx.core.extensions.postLiveEvent
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
import im.vector.riotx.core.utils.LiveEvent
|
import im.vector.riotx.core.utils.LiveEvent
|
||||||
import im.vector.riotx.features.home.HomeRoomListObservableStore
|
import im.vector.riotx.features.home.HomeRoomListObservableStore
|
||||||
@ -142,7 +143,7 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
|
|||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
// Notify the user
|
// Notify the user
|
||||||
_invitationAnswerErrorLiveData.postValue(LiveEvent(failure))
|
_invitationAnswerErrorLiveData.postLiveEvent(failure)
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
@ -178,7 +179,7 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
|
|||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
// Notify the user
|
// Notify the user
|
||||||
_invitationAnswerErrorLiveData.postValue(LiveEvent(failure))
|
_invitationAnswerErrorLiveData.postLiveEvent(failure)
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
|
@ -31,6 +31,7 @@ import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRooms
|
|||||||
import im.vector.matrix.android.api.session.room.model.thirdparty.RoomDirectoryData
|
import im.vector.matrix.android.api.session.room.model.thirdparty.RoomDirectoryData
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
|
import im.vector.riotx.core.extensions.postLiveEvent
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
import im.vector.riotx.core.utils.LiveEvent
|
import im.vector.riotx.core.utils.LiveEvent
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -207,7 +208,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState:
|
|||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
// Notify the user
|
// Notify the user
|
||||||
_joinRoomErrorLiveData.postValue(LiveEvent(failure))
|
_joinRoomErrorLiveData.postLiveEvent(failure)
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
|
@ -71,16 +71,13 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/createDirectRoomToolbar">
|
app:layout_constraintTop_toBottomOf="@+id/createDirectRoomToolbar">
|
||||||
|
|
||||||
<androidx.appcompat.widget.SearchView
|
<EditText
|
||||||
android:id="@+id/createDirectRoomFilter"
|
android:id="@+id/createDirectRoomFilter"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="text|textMultiLine"
|
android:maxHeight="80dp"
|
||||||
app:closeIcon="@drawable/ic_x_green"
|
android:importantForAutofill="no"
|
||||||
app:iconifiedByDefault="false"
|
android:hint="@string/room_directory_search_hint"/>
|
||||||
app:queryBackground="@android:color/transparent"
|
|
||||||
app:queryHint="@string/room_directory_search_hint"
|
|
||||||
app:searchIcon="@drawable/ic_filter" />
|
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user