forked from GitHub-Mirror/riotX-android
Create direct room: start creating all the required stuff
This commit is contained in:
parent
bb3b5788ba
commit
838003b68a
@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.group.model.GroupSummary
|
|||||||
import im.vector.matrix.android.api.session.pushers.Pusher
|
import im.vector.matrix.android.api.session.pushers.Pusher
|
||||||
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.sync.SyncState
|
import im.vector.matrix.android.api.session.sync.SyncState
|
||||||
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
|
||||||
@ -42,6 +43,10 @@ class RxSession(private val session: Session) {
|
|||||||
return session.livePushers().asObservable().observeOn(Schedulers.computation())
|
return session.livePushers().asObservable().observeOn(Schedulers.computation())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun liveUsers(): Observable<List<User>> {
|
||||||
|
return session.liveUsers().asObservable().observeOn(Schedulers.computation())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Session.rx(): RxSession {
|
fun Session.rx(): RxSession {
|
||||||
|
@ -36,6 +36,12 @@ interface UserService {
|
|||||||
* @param userId the userId to look for.
|
* @param userId the userId to look for.
|
||||||
* @return a Livedata of user with userId
|
* @return a Livedata of user with userId
|
||||||
*/
|
*/
|
||||||
fun observeUser(userId: String): LiveData<User?>
|
fun liveUser(userId: String): LiveData<User?>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Observe a live list of users sorted alphabetically
|
||||||
|
* @return a Livedata of users
|
||||||
|
*/
|
||||||
|
fun liveUsers(): LiveData<List<User>>
|
||||||
|
|
||||||
}
|
}
|
@ -24,6 +24,7 @@ import im.vector.matrix.android.api.session.user.model.User
|
|||||||
import im.vector.matrix.android.internal.database.RealmLiveData
|
import im.vector.matrix.android.internal.database.RealmLiveData
|
||||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||||
import im.vector.matrix.android.internal.database.model.UserEntity
|
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.database.query.where
|
||||||
import im.vector.matrix.android.internal.session.SessionScope
|
import im.vector.matrix.android.internal.session.SessionScope
|
||||||
import im.vector.matrix.android.internal.util.fetchCopied
|
import im.vector.matrix.android.internal.util.fetchCopied
|
||||||
@ -33,12 +34,12 @@ internal class DefaultUserService @Inject constructor(private val monarchy: Mona
|
|||||||
|
|
||||||
override fun getUser(userId: String): User? {
|
override fun getUser(userId: String): User? {
|
||||||
val userEntity = monarchy.fetchCopied { UserEntity.where(it, userId).findFirst() }
|
val userEntity = monarchy.fetchCopied { UserEntity.where(it, userId).findFirst() }
|
||||||
?: return null
|
?: return null
|
||||||
|
|
||||||
return userEntity.asDomain()
|
return userEntity.asDomain()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun observeUser(userId: String): LiveData<User?> {
|
override fun liveUser(userId: String): LiveData<User?> {
|
||||||
val liveRealmData = RealmLiveData(monarchy.realmConfiguration) { realm ->
|
val liveRealmData = RealmLiveData(monarchy.realmConfiguration) { realm ->
|
||||||
UserEntity.where(realm, userId)
|
UserEntity.where(realm, userId)
|
||||||
}
|
}
|
||||||
@ -48,4 +49,13 @@ internal class DefaultUserService @Inject constructor(private val monarchy: Mona
|
|||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun liveUsers(): LiveData<List<User>> {
|
||||||
|
val liveRealmData = RealmLiveData(monarchy.realmConfiguration) { realm ->
|
||||||
|
realm.where(UserEntity::class.java).sort(UserEntityFields.DISPLAY_NAME)
|
||||||
|
}
|
||||||
|
return Transformations.map(liveRealmData) { results ->
|
||||||
|
results.map { it.asDomain() }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.internal.util
|
package im.vector.matrix.android.internal.util
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.MatrixPatterns
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,3 +50,10 @@ fun convertFromUTF8(s: String): String? {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun String?.firstLetterOfDisplayName(): String {
|
||||||
|
if (this.isNullOrEmpty()) return ""
|
||||||
|
val isUserId = MatrixPatterns.isUserId(this)
|
||||||
|
val firstLetterIndex = if (isUserId) 1 else 0
|
||||||
|
return this[firstLetterIndex].toString().toUpperCase()
|
||||||
|
}
|
@ -64,6 +64,7 @@
|
|||||||
<activity android:name=".features.home.room.filtered.FilteredRoomsActivity" />
|
<activity android:name=".features.home.room.filtered.FilteredRoomsActivity" />
|
||||||
<activity android:name=".features.home.room.detail.RoomDetailActivity" />
|
<activity android:name=".features.home.room.detail.RoomDetailActivity" />
|
||||||
<activity android:name=".features.debug.DebugMenuActivity" />
|
<activity android:name=".features.debug.DebugMenuActivity" />
|
||||||
|
<activity android:name=".features.home.createdirect.CreateDirectRoomActivity" />
|
||||||
|
|
||||||
<!-- Services -->
|
<!-- Services -->
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ import im.vector.riotx.features.home.HomeActivity
|
|||||||
import im.vector.riotx.features.home.HomeDetailFragment
|
import im.vector.riotx.features.home.HomeDetailFragment
|
||||||
import im.vector.riotx.features.home.HomeDrawerFragment
|
import im.vector.riotx.features.home.HomeDrawerFragment
|
||||||
import im.vector.riotx.features.home.HomeModule
|
import im.vector.riotx.features.home.HomeModule
|
||||||
|
import im.vector.riotx.features.home.createdirect.CreateDirectRoomFragment
|
||||||
import im.vector.riotx.features.home.group.GroupListFragment
|
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.RoomDetailFragment
|
||||||
import im.vector.riotx.features.home.room.detail.timeline.action.*
|
import im.vector.riotx.features.home.room.detail.timeline.action.*
|
||||||
@ -153,6 +154,8 @@ interface ScreenComponent {
|
|||||||
|
|
||||||
fun inject(pushGatewaysFragment: PushGatewaysFragment)
|
fun inject(pushGatewaysFragment: PushGatewaysFragment)
|
||||||
|
|
||||||
|
fun inject(createDirectRoomFragment: CreateDirectRoomFragment)
|
||||||
|
|
||||||
@Component.Factory
|
@Component.Factory
|
||||||
interface Factory {
|
interface Factory {
|
||||||
fun create(vectorComponent: VectorComponent,
|
fun create(vectorComponent: VectorComponent,
|
||||||
|
@ -30,6 +30,8 @@ import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupSettingsVie
|
|||||||
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupSharedViewModel
|
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupSharedViewModel
|
||||||
import im.vector.riotx.features.crypto.verification.SasVerificationViewModel
|
import im.vector.riotx.features.crypto.verification.SasVerificationViewModel
|
||||||
import im.vector.riotx.features.home.*
|
import im.vector.riotx.features.home.*
|
||||||
|
import im.vector.riotx.features.home.createdirect.CreateDirectRoomViewModel
|
||||||
|
import im.vector.riotx.features.home.createdirect.CreateDirectRoomViewModel_AssistedFactory
|
||||||
import im.vector.riotx.features.home.group.GroupListViewModel
|
import im.vector.riotx.features.home.group.GroupListViewModel
|
||||||
import im.vector.riotx.features.home.group.GroupListViewModel_AssistedFactory
|
import im.vector.riotx.features.home.group.GroupListViewModel_AssistedFactory
|
||||||
import im.vector.riotx.features.home.room.detail.RoomDetailViewModel
|
import im.vector.riotx.features.home.room.detail.RoomDetailViewModel
|
||||||
@ -158,6 +160,9 @@ interface ViewModelModule {
|
|||||||
@Binds
|
@Binds
|
||||||
fun bindCreateRoomViewModelFactory(factory: CreateRoomViewModel_AssistedFactory): CreateRoomViewModel.Factory
|
fun bindCreateRoomViewModelFactory(factory: CreateRoomViewModel_AssistedFactory): CreateRoomViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bindCreateDirectRoomViewModelFactory(factory: CreateDirectRoomViewModel_AssistedFactory): CreateDirectRoomViewModel.Factory
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
fun bindPushGatewaysViewModelFactory(factory: PushGatewaysViewModel_AssistedFactory): PushGatewaysViewModel.Factory
|
fun bindPushGatewaysViewModelFactory(factory: PushGatewaysViewModel_AssistedFactory): PushGatewaysViewModel.Factory
|
||||||
|
|
||||||
|
@ -26,10 +26,10 @@ import com.amulyakhare.textdrawable.TextDrawable
|
|||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import com.bumptech.glide.request.target.DrawableImageViewTarget
|
import com.bumptech.glide.request.target.DrawableImageViewTarget
|
||||||
import com.bumptech.glide.request.target.Target
|
import com.bumptech.glide.request.target.Target
|
||||||
import im.vector.matrix.android.api.MatrixPatterns
|
|
||||||
import im.vector.matrix.android.api.session.content.ContentUrlResolver
|
import im.vector.matrix.android.api.session.content.ContentUrlResolver
|
||||||
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.user.model.User
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
|
import im.vector.matrix.android.internal.util.firstLetterOfDisplayName
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||||
import im.vector.riotx.core.glide.GlideApp
|
import im.vector.riotx.core.glide.GlideApp
|
||||||
@ -41,7 +41,7 @@ import javax.inject.Inject
|
|||||||
* This helper centralise ways to retrieve avatar into ImageView or even generic Target<Drawable>
|
* This helper centralise ways to retrieve avatar into ImageView or even generic Target<Drawable>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class AvatarRenderer @Inject constructor(private val activeSessionHolder: ActiveSessionHolder){
|
class AvatarRenderer @Inject constructor(private val activeSessionHolder: ActiveSessionHolder) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val THUMBNAIL_SIZE = 250
|
private const val THUMBNAIL_SIZE = 250
|
||||||
@ -92,9 +92,7 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active
|
|||||||
return if (text.isEmpty()) {
|
return if (text.isEmpty()) {
|
||||||
TextDrawable.builder().buildRound("", avatarColor)
|
TextDrawable.builder().buildRound("", avatarColor)
|
||||||
} else {
|
} else {
|
||||||
val isUserId = MatrixPatterns.isUserId(text)
|
val firstLetter = text.firstLetterOfDisplayName()
|
||||||
val firstLetterIndex = if (isUserId) 1 else 0
|
|
||||||
val firstLetter = text[firstLetterIndex].toString().toUpperCase()
|
|
||||||
TextDrawable.builder()
|
TextDrawable.builder()
|
||||||
.beginConfig()
|
.beginConfig()
|
||||||
.bold()
|
.bold()
|
||||||
|
@ -73,21 +73,21 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
|
|||||||
.subscribe { list ->
|
.subscribe { list ->
|
||||||
list.let { summaries ->
|
list.let { summaries ->
|
||||||
val peopleNotifications = summaries
|
val peopleNotifications = summaries
|
||||||
.filter { it.isDirect }
|
.filter { it.isDirect }
|
||||||
.map { it.notificationCount }
|
.map { it.notificationCount }
|
||||||
.takeIf { it.isNotEmpty() }
|
.takeIf { it.isNotEmpty() }
|
||||||
?.sumBy { i -> i }
|
?.sumBy { i -> i }
|
||||||
?: 0
|
?: 0
|
||||||
val peopleHasHighlight = summaries
|
val peopleHasHighlight = summaries
|
||||||
.filter { it.isDirect }
|
.filter { it.isDirect }
|
||||||
.any { it.highlightCount > 0 }
|
.any { it.highlightCount > 0 }
|
||||||
|
|
||||||
val roomsNotifications = summaries
|
val roomsNotifications = summaries
|
||||||
.filter { !it.isDirect }
|
.filter { !it.isDirect }
|
||||||
.map { it.notificationCount }
|
.map { it.notificationCount }
|
||||||
.takeIf { it.isNotEmpty() }
|
.takeIf { it.isNotEmpty() }
|
||||||
?.sumBy { i -> i }
|
?.sumBy { i -> i }
|
||||||
?: 0
|
?: 0
|
||||||
val roomsHasHighlight = summaries
|
val roomsHasHighlight = summaries
|
||||||
.filter { !it.isDirect }
|
.filter { !it.isDirect }
|
||||||
.any { it.highlightCount > 0 }
|
.any { it.highlightCount > 0 }
|
||||||
|
@ -52,7 +52,7 @@ class HomeDrawerFragment : VectorBaseFragment() {
|
|||||||
replaceChildFragment(groupListFragment, R.id.homeDrawerGroupListContainer)
|
replaceChildFragment(groupListFragment, R.id.homeDrawerGroupListContainer)
|
||||||
}
|
}
|
||||||
|
|
||||||
session.observeUser(session.sessionParams.credentials.userId).observeK(this) { user ->
|
session.liveUser(session.sessionParams.credentials.userId).observeK(this) { user ->
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
avatarRenderer.render(user.avatarUrl, user.userId, user.displayName, homeDrawerHeaderAvatarView)
|
avatarRenderer.render(user.avatarUrl, user.userId, user.displayName, homeDrawerHeaderAvatarView)
|
||||||
homeDrawerUsernameView.text = user.displayName
|
homeDrawerUsernameView.text = user.displayName
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * 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.home.createdirect
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import im.vector.riotx.R
|
||||||
|
import im.vector.riotx.core.extensions.addFragment
|
||||||
|
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||||
|
|
||||||
|
class CreateDirectRoomActivity : VectorBaseActivity() {
|
||||||
|
|
||||||
|
override fun getLayoutRes() = R.layout.activity_simple
|
||||||
|
|
||||||
|
override fun initUiAndData() {
|
||||||
|
if (isFirstCreation()) {
|
||||||
|
addFragment(CreateDirectRoomFragment(), R.id.simpleFragmentContainer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getIntent(context: Context): Intent {
|
||||||
|
return Intent(context, CreateDirectRoomActivity::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * 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.home.createdirect
|
||||||
|
|
||||||
|
import com.airbnb.epoxy.EpoxyController
|
||||||
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
|
import im.vector.matrix.android.internal.util.firstLetterOfDisplayName
|
||||||
|
import im.vector.riotx.features.home.AvatarRenderer
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class CreateDirectRoomController @Inject constructor(private val avatarRenderer: AvatarRenderer) : EpoxyController() {
|
||||||
|
|
||||||
|
private var state: CreateDirectRoomViewState? = null
|
||||||
|
var callback: Callback? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
requestModelBuild()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setData(state: CreateDirectRoomViewState) {
|
||||||
|
this.state = state
|
||||||
|
requestModelBuild()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun buildModels() {
|
||||||
|
val currentState = state ?: return
|
||||||
|
val knownUsers = currentState.knownUsers() ?: return
|
||||||
|
|
||||||
|
var lastFirstLetter: String? = null
|
||||||
|
knownUsers.forEach { user ->
|
||||||
|
val currentFirstLetter = user.displayName.firstLetterOfDisplayName()
|
||||||
|
val showLetter = lastFirstLetter != currentFirstLetter
|
||||||
|
lastFirstLetter = currentFirstLetter
|
||||||
|
createDirectRoomUserItem {
|
||||||
|
id(user.userId)
|
||||||
|
userId(user.userId)
|
||||||
|
showLetter(showLetter)
|
||||||
|
firstLetter(currentFirstLetter)
|
||||||
|
name(user.displayName)
|
||||||
|
avatarUrl(user.avatarUrl)
|
||||||
|
avatarRenderer(avatarRenderer)
|
||||||
|
clickListener { _ ->
|
||||||
|
callback?.onItemClick(user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Callback {
|
||||||
|
fun onItemClick(user: User)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * 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.home.createdirect
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
|
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.platform.VectorBaseFragment
|
||||||
|
import kotlinx.android.synthetic.main.fragment_create_direct_room.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class CreateDirectRoomFragment : VectorBaseFragment(), CreateDirectRoomController.Callback {
|
||||||
|
|
||||||
|
override fun getLayoutResId() = R.layout.fragment_create_direct_room
|
||||||
|
|
||||||
|
private val viewModel: CreateDirectRoomViewModel by fragmentViewModel()
|
||||||
|
|
||||||
|
@Inject lateinit var createDirectRoomViewModelFactory: CreateDirectRoomViewModel.Factory
|
||||||
|
@Inject lateinit var directRoomController: CreateDirectRoomController
|
||||||
|
|
||||||
|
override fun injectWith(injector: ScreenComponent) {
|
||||||
|
injector.inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
setupRecyclerView()
|
||||||
|
viewModel.subscribe(this) { renderState(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupRecyclerView() {
|
||||||
|
recyclerView.setHasFixedSize(true)
|
||||||
|
directRoomController.callback = this
|
||||||
|
recyclerView.setController(directRoomController)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderState(state: CreateDirectRoomViewState) {
|
||||||
|
directRoomController.setData(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemClick(user: User) {
|
||||||
|
vectorBaseActivity.notImplemented("IMPLEMENT ON USER CLICKED")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * 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.home.createdirect
|
||||||
|
|
||||||
|
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.features.home.AvatarRenderer
|
||||||
|
|
||||||
|
@EpoxyModelClass(layout = R.layout.item_create_direct_room_user)
|
||||||
|
abstract class CreateDirectRoomUserItem : VectorEpoxyModel<CreateDirectRoomUserItem.Holder>() {
|
||||||
|
|
||||||
|
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||||
|
@EpoxyAttribute var showLetter: Boolean = false
|
||||||
|
@EpoxyAttribute var firstLetter: String = ""
|
||||||
|
@EpoxyAttribute var name: String? = null
|
||||||
|
@EpoxyAttribute var userId: String = ""
|
||||||
|
@EpoxyAttribute var avatarUrl: String? = null
|
||||||
|
@EpoxyAttribute var clickListener: View.OnClickListener? = null
|
||||||
|
|
||||||
|
override fun bind(holder: Holder) {
|
||||||
|
holder.view.setOnClickListener(clickListener)
|
||||||
|
holder.nameView.text = name
|
||||||
|
holder.letterView.visibility = if (showLetter) View.VISIBLE else View.INVISIBLE
|
||||||
|
holder.letterView.text = firstLetter
|
||||||
|
avatarRenderer.render(avatarUrl, userId, name, holder.avatarImageView)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Holder : VectorEpoxyHolder() {
|
||||||
|
val letterView by bind<TextView>(R.id.createDirectRoomUserLetter)
|
||||||
|
val nameView by bind<TextView>(R.id.createDirectRoomUserName)
|
||||||
|
val avatarImageView by bind<ImageView>(R.id.createDirectRoomUserAvatar)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * 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.home.createdirect
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.matrix.rx.rx
|
||||||
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
|
|
||||||
|
class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
|
||||||
|
initialState: CreateDirectRoomViewState,
|
||||||
|
private val session: Session)
|
||||||
|
: VectorViewModel<CreateDirectRoomViewState>(initialState) {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: CreateDirectRoomViewState): CreateDirectRoomViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : MvRxViewModelFactory<CreateDirectRoomViewModel, CreateDirectRoomViewState> {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
override fun create(viewModelContext: ViewModelContext, state: CreateDirectRoomViewState): CreateDirectRoomViewModel? {
|
||||||
|
val fragment: CreateDirectRoomFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
|
return fragment.createDirectRoomViewModelFactory.create(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
observeKnownUsers()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun observeKnownUsers() {
|
||||||
|
session.rx().liveUsers().execute {
|
||||||
|
this.copy(knownUsers = it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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.riotx.features.home.createdirect
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.Async
|
||||||
|
import com.airbnb.mvrx.MvRxState
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
|
|
||||||
|
data class CreateDirectRoomViewState(
|
||||||
|
val knownUsers: Async<List<User>> = Uninitialized
|
||||||
|
) : MvRxState
|
@ -144,7 +144,7 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun createDirectChat() {
|
override fun createDirectChat() {
|
||||||
vectorBaseActivity.notImplemented("creating direct chat")
|
navigator.openCreateDirectRoom(requireActivity())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
@ -248,7 +248,7 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O
|
|||||||
return super.onBackPressed()
|
return super.onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
// RoomSummaryController.Callback **************************************************************
|
// RoomSummaryController.Callback **************************************************************
|
||||||
|
|
||||||
override fun onRoomSelected(room: RoomSummary) {
|
override fun onRoomSelected(room: RoomSummary) {
|
||||||
roomListViewModel.accept(RoomListActions.SelectRoom(room))
|
roomListViewModel.accept(RoomListActions.SelectRoom(room))
|
||||||
|
@ -25,6 +25,8 @@ import im.vector.riotx.core.utils.toast
|
|||||||
import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActivity
|
import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActivity
|
||||||
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupActivity
|
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupActivity
|
||||||
import im.vector.riotx.features.debug.DebugMenuActivity
|
import im.vector.riotx.features.debug.DebugMenuActivity
|
||||||
|
import im.vector.riotx.features.home.createdirect.CreateDirectRoomActivity
|
||||||
|
import im.vector.riotx.features.home.createdirect.CreateDirectRoomFragment
|
||||||
import im.vector.riotx.features.home.room.detail.RoomDetailActivity
|
import im.vector.riotx.features.home.room.detail.RoomDetailActivity
|
||||||
import im.vector.riotx.features.home.room.detail.RoomDetailArgs
|
import im.vector.riotx.features.home.room.detail.RoomDetailArgs
|
||||||
import im.vector.riotx.features.home.room.filtered.FilteredRoomsActivity
|
import im.vector.riotx.features.home.room.filtered.FilteredRoomsActivity
|
||||||
@ -68,6 +70,11 @@ class DefaultNavigator @Inject constructor() : Navigator {
|
|||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun openCreateDirectRoom(context: Context) {
|
||||||
|
val intent = CreateDirectRoomActivity.getIntent(context)
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
override fun openRoomsFiltering(context: Context) {
|
override fun openRoomsFiltering(context: Context) {
|
||||||
val intent = FilteredRoomsActivity.newIntent(context)
|
val intent = FilteredRoomsActivity.newIntent(context)
|
||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
|
@ -29,6 +29,8 @@ interface Navigator {
|
|||||||
|
|
||||||
fun openCreateRoom(context: Context)
|
fun openCreateRoom(context: Context)
|
||||||
|
|
||||||
|
fun openCreateDirectRoom(context: Context)
|
||||||
|
|
||||||
fun openRoomDirectory(context: Context)
|
fun openRoomDirectory(context: Context)
|
||||||
|
|
||||||
fun openRoomsFiltering(context: Context)
|
fun openRoomsFiltering(context: Context)
|
||||||
|
14
vector/src/main/res/layout/fragment_create_direct_room.xml
Normal file
14
vector/src/main/res/layout/fragment_create_direct_room.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<im.vector.riotx.core.platform.StateView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/stateView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.airbnb.epoxy.EpoxyRecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:listitem="@layout/item_create_direct_room_user" />
|
||||||
|
|
||||||
|
</im.vector.riotx.core.platform.StateView>
|
43
vector/src/main/res/layout/item_create_direct_room_user.xml
Normal file
43
vector/src/main/res/layout/item_create_direct_room_user.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?riotx_background"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/createDirectRoomUserLetter"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="sans-serif-medium"
|
||||||
|
android:textColor="#7e899c"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="normal"
|
||||||
|
tools:text="C" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/createDirectRoomUserAvatar"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_marginStart="48dp"
|
||||||
|
tools:src="@tools:sample/avatars" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/createDirectRoomUserName"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="?riotx_text_primary"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="@tools:sample/full_names" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
Loading…
Reference in New Issue
Block a user