Create direct room: start creating all the required stuff

This commit is contained in:
ganfra 2019-07-17 18:30:14 +02:00
parent bb3b5788ba
commit 838003b68a
21 changed files with 442 additions and 21 deletions

View File

@ -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 {

View File

@ -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>>
} }

View File

@ -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() }
}
}
} }

View File

@ -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()
}

View File

@ -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 -->

View File

@ -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,

View File

@ -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

View File

@ -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()

View File

@ -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 }

View File

@ -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

View File

@ -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)
}
}
}

View File

@ -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)
}
}

View File

@ -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")
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}
}

View File

@ -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

View File

@ -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))

View File

@ -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)

View File

@ -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)

View 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>

View 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>