Home: start reworking UX [WIP]
This commit is contained in:
parent
0feb10315b
commit
268730e71b
|
@ -44,6 +44,7 @@
|
||||||
android:label="@string/title_activity_emoji_reaction_picker" />
|
android:label="@string/title_activity_emoji_reaction_picker" />
|
||||||
|
|
||||||
<activity android:name=".features.roomdirectory.RoomDirectoryActivity" />
|
<activity android:name=".features.roomdirectory.RoomDirectoryActivity" />
|
||||||
|
<activity android:name=".features.home.room.detail.RoomDetailActivity" />
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".core.services.CallService"
|
android:name=".core.services.CallService"
|
||||||
|
|
|
@ -21,7 +21,6 @@ import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.view.GravityCompat
|
import androidx.core.view.GravityCompat
|
||||||
|
@ -32,12 +31,10 @@ import com.airbnb.mvrx.viewModel
|
||||||
import im.vector.matrix.android.api.Matrix
|
import im.vector.matrix.android.api.Matrix
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.extensions.hideKeyboard
|
import im.vector.riotredesign.core.extensions.hideKeyboard
|
||||||
import im.vector.riotredesign.core.extensions.observeEvent
|
|
||||||
import im.vector.riotredesign.core.extensions.replaceFragment
|
import im.vector.riotredesign.core.extensions.replaceFragment
|
||||||
import im.vector.riotredesign.core.platform.OnBackPressed
|
import im.vector.riotredesign.core.platform.OnBackPressed
|
||||||
import im.vector.riotredesign.core.platform.ToolbarConfigurable
|
import im.vector.riotredesign.core.platform.ToolbarConfigurable
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseActivity
|
import im.vector.riotredesign.core.platform.VectorBaseActivity
|
||||||
import im.vector.riotredesign.features.home.room.detail.LoadingRoomDetailFragment
|
|
||||||
import im.vector.riotredesign.features.rageshake.BugReporter
|
import im.vector.riotredesign.features.rageshake.BugReporter
|
||||||
import im.vector.riotredesign.features.rageshake.VectorUncaughtExceptionHandler
|
import im.vector.riotredesign.features.rageshake.VectorUncaughtExceptionHandler
|
||||||
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryActivity
|
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryActivity
|
||||||
|
@ -71,13 +68,11 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||||
drawerLayout.addDrawerListener(drawerListener)
|
drawerLayout.addDrawerListener(drawerListener)
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
val homeDrawerFragment = HomeDrawerFragment.newInstance()
|
val homeDrawerFragment = HomeDrawerFragment.newInstance()
|
||||||
val loadingDetail = LoadingRoomDetailFragment.newInstance()
|
val loadingDetail = LoadingFragment.newInstance()
|
||||||
replaceFragment(loadingDetail, R.id.homeDetailFragmentContainer)
|
replaceFragment(loadingDetail, R.id.homeDetailFragmentContainer)
|
||||||
replaceFragment(homeDrawerFragment, R.id.homeDrawerFragmentContainer)
|
replaceFragment(homeDrawerFragment, R.id.homeDrawerFragmentContainer)
|
||||||
}
|
}
|
||||||
homeActivityViewModel.openRoomLiveData.observeEvent(this) {
|
|
||||||
homeNavigator.openRoomDetail(it, null)
|
|
||||||
}
|
|
||||||
homeActivityViewModel.isLoading.observe(this, Observer<Boolean> {
|
homeActivityViewModel.isLoading.observe(this, Observer<Boolean> {
|
||||||
// TODO better UI
|
// TODO better UI
|
||||||
if (it) {
|
if (it) {
|
||||||
|
@ -115,30 +110,27 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||||
override fun configure(toolbar: Toolbar) {
|
override fun configure(toolbar: Toolbar) {
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
supportActionBar?.setHomeButtonEnabled(true)
|
supportActionBar?.setHomeButtonEnabled(true)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayUseLogoEnabled(true)
|
||||||
val drawerToggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, 0, 0)
|
|
||||||
drawerLayout.addDrawerListener(drawerToggle)
|
|
||||||
drawerToggle.syncState()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMenuRes() = R.menu.home
|
override fun getMenuRes() = R.menu.home
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
android.R.id.home -> {
|
android.R.id.home -> {
|
||||||
drawerLayout.openDrawer(GravityCompat.START)
|
drawerLayout.openDrawer(GravityCompat.START)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.sliding_menu_settings -> {
|
R.id.sliding_menu_settings -> {
|
||||||
startActivity(VectorSettingsActivity.getIntent(this, "TODO"))
|
startActivity(VectorSettingsActivity.getIntent(this, "TODO"))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.sliding_menu_sign_out -> {
|
R.id.sliding_menu_sign_out -> {
|
||||||
SignOutUiWorker(this).perform(Matrix.getInstance().currentSession!!)
|
SignOutUiWorker(this).perform(Matrix.getInstance().currentSession!!)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// TODO Temporary code here to create a room
|
// TODO Temporary code here to create a room
|
||||||
R.id.tmp_menu_create_room -> {
|
R.id.tmp_menu_create_room -> {
|
||||||
// Start Activity for now
|
// Start Activity for now
|
||||||
startActivity(Intent(this, RoomDirectoryActivity::class.java))
|
startActivity(Intent(this, RoomDirectoryActivity::class.java))
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -17,11 +17,12 @@
|
||||||
package im.vector.riotredesign.features.home
|
package im.vector.riotredesign.features.home
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import im.vector.matrix.android.api.Matrix
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.extensions.replaceChildFragment
|
import im.vector.riotredesign.core.extensions.replaceChildFragment
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.features.home.group.GroupListFragment
|
import im.vector.riotredesign.features.home.group.GroupListFragment
|
||||||
import im.vector.riotredesign.features.home.room.list.RoomListFragment
|
import kotlinx.android.synthetic.main.fragment_home_drawer.*
|
||||||
|
|
||||||
class HomeDrawerFragment : VectorBaseFragment() {
|
class HomeDrawerFragment : VectorBaseFragment() {
|
||||||
|
|
||||||
|
@ -38,9 +39,14 @@ class HomeDrawerFragment : VectorBaseFragment() {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
val groupListFragment = GroupListFragment.newInstance()
|
val groupListFragment = GroupListFragment.newInstance()
|
||||||
replaceChildFragment(groupListFragment, R.id.groupListFragmentContainer)
|
replaceChildFragment(groupListFragment, R.id.homeDrawerGroupListContainer)
|
||||||
val roomListFragment = RoomListFragment.newInstance()
|
}
|
||||||
replaceChildFragment(roomListFragment, R.id.roomListFragmentContainer)
|
val session = Matrix.getInstance().currentSession ?: return
|
||||||
|
val user = session.getUser(session.sessionParams.credentials.userId)
|
||||||
|
if (user != null) {
|
||||||
|
AvatarRenderer.render(user.avatarUrl, user.userId, user.displayName, homeDrawerHeaderAvatarView)
|
||||||
|
homeDrawerUsernameView.text = user.displayName
|
||||||
|
homeDrawerUserIdView.text = user.userId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,13 @@ package im.vector.riotredesign.features.home
|
||||||
|
|
||||||
import androidx.core.view.GravityCompat
|
import androidx.core.view.GravityCompat
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.extensions.addFragmentToBackstack
|
|
||||||
import im.vector.riotredesign.core.extensions.replaceFragment
|
import im.vector.riotredesign.core.extensions.replaceFragment
|
||||||
|
import im.vector.riotredesign.features.home.group.SelectedGroupFragment
|
||||||
|
import im.vector.riotredesign.features.home.group.SelectedGroupParams
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.RoomDetailActivity
|
||||||
import im.vector.riotredesign.features.home.room.detail.RoomDetailArgs
|
import im.vector.riotredesign.features.home.room.detail.RoomDetailArgs
|
||||||
import im.vector.riotredesign.features.home.room.detail.RoomDetailFragment
|
|
||||||
import kotlinx.android.synthetic.main.activity_home.*
|
import kotlinx.android.synthetic.main.activity_home.*
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
|
@ -32,22 +34,25 @@ class HomeNavigator {
|
||||||
|
|
||||||
private var rootRoomId: String? = null
|
private var rootRoomId: String? = null
|
||||||
|
|
||||||
|
fun openSelectedGroup(groupSummary: GroupSummary) {
|
||||||
|
Timber.v("Open selected group ${groupSummary.groupId}")
|
||||||
|
activity?.let {
|
||||||
|
val args = SelectedGroupParams(groupSummary.groupId, groupSummary.displayName, groupSummary.avatarUrl)
|
||||||
|
val selectedGroupFragment = SelectedGroupFragment.newInstance(args)
|
||||||
|
it.drawerLayout?.closeDrawer(GravityCompat.START)
|
||||||
|
it.replaceFragment(selectedGroupFragment, R.id.homeDetailFragmentContainer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun openRoomDetail(roomId: String,
|
fun openRoomDetail(roomId: String,
|
||||||
eventId: String?,
|
eventId: String?) {
|
||||||
addToBackstack: Boolean = false) {
|
Timber.v("Open room detail $roomId - $eventId")
|
||||||
Timber.v("Open room detail $roomId - $eventId - $addToBackstack")
|
|
||||||
activity?.let {
|
activity?.let {
|
||||||
//TODO enable eventId permalink. It doesn't work enough at the moment.
|
//TODO enable eventId permalink. It doesn't work enough at the moment.
|
||||||
val args = RoomDetailArgs(roomId)
|
|
||||||
val roomDetailFragment = RoomDetailFragment.newInstance(args)
|
|
||||||
it.drawerLayout?.closeDrawer(GravityCompat.START)
|
it.drawerLayout?.closeDrawer(GravityCompat.START)
|
||||||
if (addToBackstack) {
|
val args = RoomDetailArgs(roomId)
|
||||||
it.addFragmentToBackstack(roomDetailFragment, R.id.homeDetailFragmentContainer, roomId)
|
val roomDetailIntent = RoomDetailActivity.newIntent(it, args)
|
||||||
} else {
|
it.startActivity(roomDetailIntent)
|
||||||
rootRoomId = roomId
|
|
||||||
clearBackStack(it.supportFragmentManager)
|
|
||||||
it.replaceFragment(roomDetailFragment, R.id.homeDetailFragmentContainer)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,10 @@ class HomePermalinkHandler(private val navigator: HomeNavigator) {
|
||||||
val permalinkData = PermalinkParser.parse(deepLink)
|
val permalinkData = PermalinkParser.parse(deepLink)
|
||||||
when (permalinkData) {
|
when (permalinkData) {
|
||||||
is PermalinkData.EventLink -> {
|
is PermalinkData.EventLink -> {
|
||||||
navigator.openRoomDetail(permalinkData.roomIdOrAlias, permalinkData.eventId, true)
|
navigator.openRoomDetail(permalinkData.roomIdOrAlias, permalinkData.eventId)
|
||||||
}
|
}
|
||||||
is PermalinkData.RoomLink -> {
|
is PermalinkData.RoomLink -> {
|
||||||
navigator.openRoomDetail(permalinkData.roomIdOrAlias, null, true)
|
navigator.openRoomDetail(permalinkData.roomIdOrAlias, null)
|
||||||
}
|
}
|
||||||
is PermalinkData.GroupLink -> {
|
is PermalinkData.GroupLink -> {
|
||||||
navigator.openGroupDetail(permalinkData.groupId)
|
navigator.openGroupDetail(permalinkData.groupId)
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* * 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.riotredesign.features.home
|
||||||
|
|
||||||
|
import android.graphics.drawable.AnimationDrawable
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
|
import kotlinx.android.synthetic.main.fragment_loading.*
|
||||||
|
|
||||||
|
class LoadingFragment : VectorBaseFragment() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun newInstance(): LoadingFragment {
|
||||||
|
return LoadingFragment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLayoutResId() = R.layout.fragment_loading
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
val background = animatedLogoImageView.background
|
||||||
|
if (background is AnimationDrawable) {
|
||||||
|
background.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -22,9 +22,11 @@ import com.airbnb.mvrx.Success
|
||||||
import com.airbnb.mvrx.fragmentViewModel
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.extensions.observeEvent
|
||||||
import im.vector.riotredesign.core.platform.StateView
|
import im.vector.riotredesign.core.platform.StateView
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.features.home.HomeModule
|
import im.vector.riotredesign.features.home.HomeModule
|
||||||
|
import im.vector.riotredesign.features.home.HomeNavigator
|
||||||
import kotlinx.android.synthetic.main.fragment_group_list.*
|
import kotlinx.android.synthetic.main.fragment_group_list.*
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.koin.android.scope.ext.android.bindScope
|
import org.koin.android.scope.ext.android.bindScope
|
||||||
|
@ -39,6 +41,7 @@ class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback
|
||||||
}
|
}
|
||||||
|
|
||||||
private val viewModel: GroupListViewModel by fragmentViewModel()
|
private val viewModel: GroupListViewModel by fragmentViewModel()
|
||||||
|
private val homeNavigator by inject<HomeNavigator>()
|
||||||
private val groupController by inject<GroupSummaryController>()
|
private val groupController by inject<GroupSummaryController>()
|
||||||
|
|
||||||
override fun getLayoutResId() = R.layout.fragment_group_list
|
override fun getLayoutResId() = R.layout.fragment_group_list
|
||||||
|
@ -50,6 +53,9 @@ class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback
|
||||||
stateView.contentView = epoxyRecyclerView
|
stateView.contentView = epoxyRecyclerView
|
||||||
epoxyRecyclerView.setController(groupController)
|
epoxyRecyclerView.setController(groupController)
|
||||||
viewModel.subscribe { renderState(it) }
|
viewModel.subscribe { renderState(it) }
|
||||||
|
viewModel.openGroupLiveData.observeEvent(this) {
|
||||||
|
homeNavigator.openSelectedGroup(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderState(state: GroupListViewState) {
|
private fun renderState(state: GroupListViewState) {
|
||||||
|
|
|
@ -16,17 +16,25 @@
|
||||||
|
|
||||||
package im.vector.riotredesign.features.home.group
|
package im.vector.riotredesign.features.home.group
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import arrow.core.Option
|
import arrow.core.Option
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
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.riotredesign.core.platform.VectorViewModel
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
|
import im.vector.riotredesign.core.resources.StringProvider
|
||||||
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
import org.koin.android.ext.android.get
|
import org.koin.android.ext.android.get
|
||||||
|
|
||||||
|
const val ALL_COMMUNITIES_GROUP_ID = "ALL_COMMUNITIES_GROUP_ID"
|
||||||
|
|
||||||
class GroupListViewModel(initialState: GroupListViewState,
|
class GroupListViewModel(initialState: GroupListViewState,
|
||||||
private val selectedGroupHolder: SelectedGroupStore,
|
private val selectedGroupHolder: SelectedGroupStore,
|
||||||
private val session: Session
|
private val session: Session,
|
||||||
|
private val stringProvider: StringProvider
|
||||||
) : VectorViewModel<GroupListViewState>(initialState) {
|
) : VectorViewModel<GroupListViewState>(initialState) {
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<GroupListViewModel, GroupListViewState> {
|
companion object : MvRxViewModelFactory<GroupListViewModel, GroupListViewState> {
|
||||||
|
@ -35,10 +43,15 @@ class GroupListViewModel(initialState: GroupListViewState,
|
||||||
override fun create(viewModelContext: ViewModelContext, state: GroupListViewState): GroupListViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: GroupListViewState): GroupListViewModel? {
|
||||||
val currentSession = viewModelContext.activity.get<Session>()
|
val currentSession = viewModelContext.activity.get<Session>()
|
||||||
val selectedGroupHolder = viewModelContext.activity.get<SelectedGroupStore>()
|
val selectedGroupHolder = viewModelContext.activity.get<SelectedGroupStore>()
|
||||||
return GroupListViewModel(state, selectedGroupHolder, currentSession)
|
val stringProvider = viewModelContext.activity.get<StringProvider>()
|
||||||
|
return GroupListViewModel(state, selectedGroupHolder, currentSession, stringProvider)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val _openGroupLiveData = MutableLiveData<LiveEvent<GroupSummary>>()
|
||||||
|
val openGroupLiveData: LiveData<LiveEvent<GroupSummary>>
|
||||||
|
get() = _openGroupLiveData
|
||||||
|
|
||||||
init {
|
init {
|
||||||
observeGroupSummaries()
|
observeGroupSummaries()
|
||||||
observeState()
|
observeState()
|
||||||
|
@ -46,8 +59,8 @@ class GroupListViewModel(initialState: GroupListViewState,
|
||||||
|
|
||||||
private fun observeState() {
|
private fun observeState() {
|
||||||
subscribe {
|
subscribe {
|
||||||
val selectedGroup = Option.fromNullable(it.selectedGroup)
|
val optionGroup = Option.fromNullable(it.selectedGroup)
|
||||||
selectedGroupHolder.post(selectedGroup)
|
selectedGroupHolder.post(optionGroup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,15 +75,21 @@ class GroupListViewModel(initialState: GroupListViewState,
|
||||||
private fun handleSelectGroup(action: GroupListActions.SelectGroup) = withState { state ->
|
private fun handleSelectGroup(action: GroupListActions.SelectGroup) = withState { state ->
|
||||||
if (state.selectedGroup?.groupId != action.groupSummary.groupId) {
|
if (state.selectedGroup?.groupId != action.groupSummary.groupId) {
|
||||||
setState { copy(selectedGroup = action.groupSummary) }
|
setState { copy(selectedGroup = action.groupSummary) }
|
||||||
} else {
|
_openGroupLiveData.postValue(LiveEvent(action.groupSummary))
|
||||||
setState { copy(selectedGroup = null) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun observeGroupSummaries() {
|
private fun observeGroupSummaries() {
|
||||||
session
|
session
|
||||||
.rx().liveGroupSummaries()
|
.rx().liveGroupSummaries()
|
||||||
|
.map {
|
||||||
|
val myUser = session.getUser(session.sessionParams.credentials.userId)
|
||||||
|
val allCommunityGroup = GroupSummary(
|
||||||
|
groupId = ALL_COMMUNITIES_GROUP_ID,
|
||||||
|
displayName = "All Communities",
|
||||||
|
avatarUrl = myUser?.avatarUrl ?: "")
|
||||||
|
listOf(allCommunityGroup) + it
|
||||||
|
}
|
||||||
.execute { async ->
|
.execute { async ->
|
||||||
copy(asyncGroups = async)
|
copy(asyncGroups = async)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,14 @@
|
||||||
|
|
||||||
package im.vector.riotredesign.features.home.group
|
package im.vector.riotredesign.features.home.group
|
||||||
|
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
import com.airbnb.epoxy.EpoxyAttribute
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
import com.airbnb.epoxy.EpoxyModelClass
|
import com.airbnb.epoxy.EpoxyModelClass
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder
|
import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder
|
||||||
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
||||||
import im.vector.riotredesign.core.platform.CheckableFrameLayout
|
|
||||||
import im.vector.riotredesign.features.home.AvatarRenderer
|
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||||
|
|
||||||
@EpoxyModelClass(layout = R.layout.item_group)
|
@EpoxyModelClass(layout = R.layout.item_group)
|
||||||
|
@ -36,14 +37,15 @@ abstract class GroupSummaryItem : VectorEpoxyModel<GroupSummaryItem.Holder>() {
|
||||||
|
|
||||||
override fun bind(holder: Holder) {
|
override fun bind(holder: Holder) {
|
||||||
super.bind(holder)
|
super.bind(holder)
|
||||||
holder.rootView.isSelected = selected
|
|
||||||
holder.rootView.setOnClickListener { listener?.invoke() }
|
holder.rootView.setOnClickListener { listener?.invoke() }
|
||||||
|
holder.groupNameView.text = groupName
|
||||||
AvatarRenderer.render(avatarUrl, groupId, groupName.toString(), holder.avatarImageView)
|
AvatarRenderer.render(avatarUrl, groupId, groupName.toString(), holder.avatarImageView)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Holder : VectorEpoxyHolder() {
|
class Holder : VectorEpoxyHolder() {
|
||||||
val avatarImageView by bind<ImageView>(R.id.groupAvatarImageView)
|
val avatarImageView by bind<ImageView>(R.id.groupAvatarImageView)
|
||||||
val rootView by bind<CheckableFrameLayout>(R.id.itemGroupLayout)
|
val groupNameView by bind<TextView>(R.id.groupNameView)
|
||||||
|
val rootView by bind<ViewGroup>(R.id.itemGroupLayout)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* * 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.riotredesign.features.home.group
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Parcelable
|
||||||
|
import com.airbnb.mvrx.args
|
||||||
|
import com.bumptech.glide.request.target.SimpleTarget
|
||||||
|
import com.bumptech.glide.request.transition.Transition
|
||||||
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.extensions.replaceChildFragment
|
||||||
|
import im.vector.riotredesign.core.glide.GlideApp
|
||||||
|
import im.vector.riotredesign.core.platform.ToolbarConfigurable
|
||||||
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
|
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||||
|
import im.vector.riotredesign.features.home.room.list.RoomListFragment
|
||||||
|
import im.vector.riotredesign.features.home.room.list.RoomListParams
|
||||||
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
import kotlinx.android.synthetic.main.fragment_selected_group.*
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data class SelectedGroupParams(
|
||||||
|
val groupId: String,
|
||||||
|
val groupName: String,
|
||||||
|
val groupAvatar: String
|
||||||
|
) : Parcelable
|
||||||
|
|
||||||
|
class SelectedGroupFragment : VectorBaseFragment() {
|
||||||
|
|
||||||
|
private val selectedGroupParams: SelectedGroupParams by args()
|
||||||
|
|
||||||
|
override fun getLayoutResId(): Int {
|
||||||
|
return R.layout.fragment_selected_group
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
updateSelectedFragment(RoomListFragment.DisplayMode.HOME)
|
||||||
|
toolbar.setTitle(RoomListFragment.DisplayMode.HOME.titleRes)
|
||||||
|
}
|
||||||
|
setupBottomNavigationView()
|
||||||
|
setupToolbar()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupToolbar() {
|
||||||
|
val parentActivity = vectorBaseActivity
|
||||||
|
if (parentActivity is ToolbarConfigurable) {
|
||||||
|
parentActivity.configure(toolbar)
|
||||||
|
}
|
||||||
|
val toolbarLogoTarget = object : SimpleTarget<Drawable>() {
|
||||||
|
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
|
||||||
|
toolbar.logo = resource
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AvatarRenderer.render(
|
||||||
|
requireContext(),
|
||||||
|
GlideApp.with(this),
|
||||||
|
selectedGroupParams.groupAvatar,
|
||||||
|
selectedGroupParams.groupId,
|
||||||
|
selectedGroupParams.groupName,
|
||||||
|
toolbarLogoTarget
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupBottomNavigationView() {
|
||||||
|
bottomNavigationView.setOnNavigationItemSelectedListener {
|
||||||
|
val displayMode = when {
|
||||||
|
it.itemId == R.id.bottom_action_people -> RoomListFragment.DisplayMode.PEOPLE
|
||||||
|
it.itemId == R.id.bottom_action_rooms -> RoomListFragment.DisplayMode.ROOMS
|
||||||
|
else -> RoomListFragment.DisplayMode.HOME
|
||||||
|
}
|
||||||
|
updateSelectedFragment(displayMode)
|
||||||
|
toolbar.setTitle(displayMode.titleRes)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateSelectedFragment(displayMode: RoomListFragment.DisplayMode) {
|
||||||
|
val roomListParams = RoomListParams(displayMode)
|
||||||
|
val roomListFragment = RoomListFragment.newInstance(roomListParams)
|
||||||
|
replaceChildFragment(roomListFragment, R.id.roomListContainer)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun newInstance(args: SelectedGroupParams): SelectedGroupFragment {
|
||||||
|
return SelectedGroupFragment().apply {
|
||||||
|
setArguments(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2019 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package im.vector.riotredesign.features.home.room.detail
|
|
||||||
|
|
||||||
import android.graphics.drawable.AnimationDrawable
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
|
||||||
import im.vector.riotredesign.R
|
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
|
||||||
import kotlinx.android.synthetic.main.fragment_loading_room_detail.*
|
|
||||||
|
|
||||||
class LoadingRoomDetailFragment : VectorBaseFragment() {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
fun newInstance(): LoadingRoomDetailFragment {
|
|
||||||
return LoadingRoomDetailFragment()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getLayoutResId() = R.layout.fragment_loading_room_detail
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
val background = animatedLogoImageView.background
|
|
||||||
if (background is AnimationDrawable) {
|
|
||||||
background.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* * Copyright 2019 New Vector Ltd
|
||||||
|
* *
|
||||||
|
* * Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* * you may not use this file except in compliance with the License.
|
||||||
|
* * You may obtain a copy of the License at
|
||||||
|
* *
|
||||||
|
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* *
|
||||||
|
* * Unless required by applicable law or agreed to in writing, software
|
||||||
|
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* * See the License for the specific language governing permissions and
|
||||||
|
* * limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.riotredesign.features.home.room.detail
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.extensions.replaceFragment
|
||||||
|
import im.vector.riotredesign.core.platform.VectorBaseActivity
|
||||||
|
|
||||||
|
class RoomDetailActivity : VectorBaseActivity() {
|
||||||
|
|
||||||
|
override fun getLayoutRes(): Int {
|
||||||
|
return R.layout.activity_room_detail
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
val roomDetailArgs: RoomDetailArgs = intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS)
|
||||||
|
?: return
|
||||||
|
val roomDetailFragment = RoomDetailFragment.newInstance(roomDetailArgs)
|
||||||
|
replaceFragment(roomDetailFragment, R.id.roomDetailContainer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private const val EXTRA_ROOM_DETAIL_ARGS = "EXTRA_ROOM_DETAIL_ARGS"
|
||||||
|
|
||||||
|
fun newIntent(context: Context, roomDetailArgs: RoomDetailArgs): Intent {
|
||||||
|
return Intent(context, RoomDetailActivity::class.java).apply {
|
||||||
|
putExtra(EXTRA_ROOM_DETAIL_ARGS, roomDetailArgs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -64,7 +64,6 @@ import im.vector.riotredesign.core.epoxy.LayoutManagerStateRestorer
|
||||||
import im.vector.riotredesign.core.extensions.hideKeyboard
|
import im.vector.riotredesign.core.extensions.hideKeyboard
|
||||||
import im.vector.riotredesign.core.extensions.observeEvent
|
import im.vector.riotredesign.core.extensions.observeEvent
|
||||||
import im.vector.riotredesign.core.glide.GlideApp
|
import im.vector.riotredesign.core.glide.GlideApp
|
||||||
import im.vector.riotredesign.core.platform.ToolbarConfigurable
|
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.core.utils.*
|
import im.vector.riotredesign.core.utils.*
|
||||||
import im.vector.riotredesign.features.autocomplete.command.AutocompleteCommandPresenter
|
import im.vector.riotredesign.features.autocomplete.command.AutocompleteCommandPresenter
|
||||||
|
@ -170,7 +169,6 @@ class RoomDetailFragment :
|
||||||
actionViewModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java)
|
actionViewModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java)
|
||||||
bindScope(getOrCreateScope(HomeModule.ROOM_DETAIL_SCOPE))
|
bindScope(getOrCreateScope(HomeModule.ROOM_DETAIL_SCOPE))
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
setupToolbar()
|
|
||||||
setupComposer()
|
setupComposer()
|
||||||
setupAttachmentButton()
|
setupAttachmentButton()
|
||||||
setupInviteView()
|
setupInviteView()
|
||||||
|
@ -194,7 +192,7 @@ class RoomDetailFragment :
|
||||||
if (resultCode == RESULT_OK && data != null) {
|
if (resultCode == RESULT_OK && data != null) {
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
REQUEST_FILES_REQUEST_CODE, TAKE_IMAGE_REQUEST_CODE -> handleMediaIntent(data)
|
REQUEST_FILES_REQUEST_CODE, TAKE_IMAGE_REQUEST_CODE -> handleMediaIntent(data)
|
||||||
REACTION_SELECT_REQUEST_CODE -> {
|
REACTION_SELECT_REQUEST_CODE -> {
|
||||||
val eventId = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_EVENT_ID)
|
val eventId = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_EVENT_ID)
|
||||||
?: return
|
?: return
|
||||||
val reaction = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_REACTION_RESULT)
|
val reaction = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_REACTION_RESULT)
|
||||||
|
@ -213,13 +211,6 @@ class RoomDetailFragment :
|
||||||
|
|
||||||
// PRIVATE METHODS *****************************************************************************
|
// PRIVATE METHODS *****************************************************************************
|
||||||
|
|
||||||
private fun setupToolbar() {
|
|
||||||
val parentActivity = vectorBaseActivity
|
|
||||||
if (parentActivity is ToolbarConfigurable) {
|
|
||||||
parentActivity.configure(toolbar)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
val epoxyVisibilityTracker = EpoxyVisibilityTracker()
|
val epoxyVisibilityTracker = EpoxyVisibilityTracker()
|
||||||
epoxyVisibilityTracker.attach(recyclerView)
|
epoxyVisibilityTracker.attach(recyclerView)
|
||||||
|
@ -362,24 +353,24 @@ class RoomDetailFragment :
|
||||||
private fun onSendChoiceClicked(dialogListItem: DialogListItem) {
|
private fun onSendChoiceClicked(dialogListItem: DialogListItem) {
|
||||||
Timber.v("On send choice clicked: $dialogListItem")
|
Timber.v("On send choice clicked: $dialogListItem")
|
||||||
when (dialogListItem) {
|
when (dialogListItem) {
|
||||||
is DialogListItem.SendFile -> {
|
is DialogListItem.SendFile -> {
|
||||||
// launchFileIntent
|
// launchFileIntent
|
||||||
}
|
}
|
||||||
is DialogListItem.SendVoice -> {
|
is DialogListItem.SendVoice -> {
|
||||||
//launchAudioRecorderIntent()
|
//launchAudioRecorderIntent()
|
||||||
}
|
}
|
||||||
is DialogListItem.SendSticker -> {
|
is DialogListItem.SendSticker -> {
|
||||||
//startStickerPickerActivity()
|
//startStickerPickerActivity()
|
||||||
}
|
}
|
||||||
is DialogListItem.TakePhotoVideo ->
|
is DialogListItem.TakePhotoVideo ->
|
||||||
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_CAMERA)) {
|
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_CAMERA)) {
|
||||||
// launchCamera()
|
// launchCamera()
|
||||||
}
|
}
|
||||||
is DialogListItem.TakePhoto ->
|
is DialogListItem.TakePhoto ->
|
||||||
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_CAMERA)) {
|
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_CAMERA)) {
|
||||||
openCamera(requireActivity(), CAMERA_VALUE_TITLE, TAKE_IMAGE_REQUEST_CODE)
|
openCamera(requireActivity(), CAMERA_VALUE_TITLE, TAKE_IMAGE_REQUEST_CODE)
|
||||||
}
|
}
|
||||||
is DialogListItem.TakeVideo ->
|
is DialogListItem.TakeVideo ->
|
||||||
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_VIDEO_CAMERA)) {
|
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_VIDEO_CAMERA)) {
|
||||||
// launchNativeVideoRecorder()
|
// launchNativeVideoRecorder()
|
||||||
}
|
}
|
||||||
|
@ -426,20 +417,20 @@ class RoomDetailFragment :
|
||||||
private fun renderSendMessageResult(sendMessageResult: SendMessageResult) {
|
private fun renderSendMessageResult(sendMessageResult: SendMessageResult) {
|
||||||
when (sendMessageResult) {
|
when (sendMessageResult) {
|
||||||
is SendMessageResult.MessageSent,
|
is SendMessageResult.MessageSent,
|
||||||
is SendMessageResult.SlashCommandHandled -> {
|
is SendMessageResult.SlashCommandHandled -> {
|
||||||
// Clear composer
|
// Clear composer
|
||||||
composerEditText.text = null
|
composerEditText.text = null
|
||||||
}
|
}
|
||||||
is SendMessageResult.SlashCommandError -> {
|
is SendMessageResult.SlashCommandError -> {
|
||||||
displayCommandError(getString(R.string.command_problem_with_parameters, sendMessageResult.command.command))
|
displayCommandError(getString(R.string.command_problem_with_parameters, sendMessageResult.command.command))
|
||||||
}
|
}
|
||||||
is SendMessageResult.SlashCommandUnknown -> {
|
is SendMessageResult.SlashCommandUnknown -> {
|
||||||
displayCommandError(getString(R.string.unrecognized_command, sendMessageResult.command))
|
displayCommandError(getString(R.string.unrecognized_command, sendMessageResult.command))
|
||||||
}
|
}
|
||||||
is SendMessageResult.SlashCommandResultOk -> {
|
is SendMessageResult.SlashCommandResultOk -> {
|
||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
is SendMessageResult.SlashCommandResultError -> {
|
is SendMessageResult.SlashCommandResultError -> {
|
||||||
displayCommandError(sendMessageResult.throwable.localizedMessage)
|
displayCommandError(sendMessageResult.throwable.localizedMessage)
|
||||||
}
|
}
|
||||||
is SendMessageResult.SlashCommandNotImplemented -> {
|
is SendMessageResult.SlashCommandNotImplemented -> {
|
||||||
|
@ -537,22 +528,22 @@ class RoomDetailFragment :
|
||||||
it?.getContentIfNotHandled()?.let { actionData ->
|
it?.getContentIfNotHandled()?.let { actionData ->
|
||||||
|
|
||||||
when (actionData.actionId) {
|
when (actionData.actionId) {
|
||||||
MessageMenuViewModel.ACTION_ADD_REACTION -> {
|
MessageMenuViewModel.ACTION_ADD_REACTION -> {
|
||||||
val eventId = actionData.data?.toString() ?: return
|
val eventId = actionData.data?.toString() ?: return
|
||||||
startActivityForResult(EmojiReactionPickerActivity.intent(requireContext(), eventId), REACTION_SELECT_REQUEST_CODE)
|
startActivityForResult(EmojiReactionPickerActivity.intent(requireContext(), eventId), REACTION_SELECT_REQUEST_CODE)
|
||||||
}
|
}
|
||||||
MessageMenuViewModel.ACTION_COPY -> {
|
MessageMenuViewModel.ACTION_COPY -> {
|
||||||
//I need info about the current selected message :/
|
//I need info about the current selected message :/
|
||||||
copyToClipboard(requireContext(), actionData.data?.toString() ?: "", false)
|
copyToClipboard(requireContext(), actionData.data?.toString() ?: "", false)
|
||||||
val snack = Snackbar.make(view!!, requireContext().getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT)
|
val snack = Snackbar.make(view!!, requireContext().getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT)
|
||||||
snack.view.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.notification_accent_color))
|
snack.view.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.notification_accent_color))
|
||||||
snack.show()
|
snack.show()
|
||||||
}
|
}
|
||||||
MessageMenuViewModel.ACTION_DELETE -> {
|
MessageMenuViewModel.ACTION_DELETE -> {
|
||||||
val eventId = actionData.data?.toString() ?: return
|
val eventId = actionData.data?.toString() ?: return
|
||||||
roomDetailViewModel.process(RoomDetailActions.RedactAction(eventId, context?.getString(R.string.event_redacted_by_user_reason)))
|
roomDetailViewModel.process(RoomDetailActions.RedactAction(eventId, context?.getString(R.string.event_redacted_by_user_reason)))
|
||||||
}
|
}
|
||||||
MessageMenuViewModel.ACTION_SHARE -> {
|
MessageMenuViewModel.ACTION_SHARE -> {
|
||||||
//TODO current data communication is too limited
|
//TODO current data communication is too limited
|
||||||
//Need to now the media type
|
//Need to now the media type
|
||||||
actionData.data?.toString()?.let {
|
actionData.data?.toString()?.let {
|
||||||
|
@ -595,13 +586,13 @@ class RoomDetailFragment :
|
||||||
.setPositiveButton(R.string.ok) { dialog, id -> dialog.cancel() }
|
.setPositiveButton(R.string.ok) { dialog, id -> dialog.cancel() }
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
MessageMenuViewModel.ACTION_QUICK_REACT -> {
|
MessageMenuViewModel.ACTION_QUICK_REACT -> {
|
||||||
//eventId,ClickedOn,Opposite
|
//eventId,ClickedOn,Opposite
|
||||||
(actionData.data as? Triple<String, String, String>)?.let { (eventId, clickedOn, opposite) ->
|
(actionData.data as? Triple<String, String, String>)?.let { (eventId, clickedOn, opposite) ->
|
||||||
roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(eventId, clickedOn, opposite))
|
roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(eventId, clickedOn, opposite))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
Toast.makeText(context, "Action ${actionData.actionId} not implemented", Toast.LENGTH_LONG).show()
|
Toast.makeText(context, "Action ${actionData.actionId} not implemented", Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
package im.vector.riotredesign.features.home.room.list
|
package im.vector.riotredesign.features.home.room.list
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.os.Parcelable
|
||||||
import android.text.TextWatcher
|
import androidx.annotation.StringRes
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.airbnb.mvrx.Fail
|
import com.airbnb.mvrx.Fail
|
||||||
import com.airbnb.mvrx.Incomplete
|
import com.airbnb.mvrx.Incomplete
|
||||||
|
@ -29,21 +29,35 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.epoxy.LayoutManagerStateRestorer
|
import im.vector.riotredesign.core.epoxy.LayoutManagerStateRestorer
|
||||||
import im.vector.riotredesign.core.extensions.observeEvent
|
import im.vector.riotredesign.core.extensions.observeEvent
|
||||||
import im.vector.riotredesign.core.extensions.setupAsSearch
|
|
||||||
import im.vector.riotredesign.core.platform.StateView
|
import im.vector.riotredesign.core.platform.StateView
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.features.home.HomeModule
|
import im.vector.riotredesign.features.home.HomeModule
|
||||||
import im.vector.riotredesign.features.home.HomeNavigator
|
import im.vector.riotredesign.features.home.HomeNavigator
|
||||||
|
import kotlinx.android.parcel.Parcelize
|
||||||
import kotlinx.android.synthetic.main.fragment_room_list.*
|
import kotlinx.android.synthetic.main.fragment_room_list.*
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.koin.android.scope.ext.android.bindScope
|
import org.koin.android.scope.ext.android.bindScope
|
||||||
import org.koin.android.scope.ext.android.getOrCreateScope
|
import org.koin.android.scope.ext.android.getOrCreateScope
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data class RoomListParams(
|
||||||
|
val displayMode: RoomListFragment.DisplayMode
|
||||||
|
) : Parcelable
|
||||||
|
|
||||||
|
|
||||||
class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback {
|
class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback {
|
||||||
|
|
||||||
|
enum class DisplayMode(@StringRes val titleRes: Int) {
|
||||||
|
HOME(R.string.bottom_action_home),
|
||||||
|
PEOPLE(R.string.bottom_action_people),
|
||||||
|
ROOMS(R.string.bottom_action_rooms)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance(): RoomListFragment {
|
fun newInstance(roomListParams: RoomListParams): RoomListFragment {
|
||||||
return RoomListFragment()
|
return RoomListFragment().apply {
|
||||||
|
setArguments(roomListParams)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +71,6 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
bindScope(getOrCreateScope(HomeModule.ROOM_LIST_SCOPE))
|
bindScope(getOrCreateScope(HomeModule.ROOM_LIST_SCOPE))
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
setupFilterView()
|
|
||||||
roomListViewModel.subscribe { renderState(it) }
|
roomListViewModel.subscribe { renderState(it) }
|
||||||
roomListViewModel.openRoomLiveData.observeEvent(this) {
|
roomListViewModel.openRoomLiveData.observeEvent(this) {
|
||||||
homeNavigator.openRoomDetail(it, null)
|
homeNavigator.openRoomDetail(it, null)
|
||||||
|
@ -74,19 +87,6 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback {
|
||||||
epoxyRecyclerView.setController(roomController)
|
epoxyRecyclerView.setController(roomController)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupFilterView() {
|
|
||||||
filterRoomView.setupAsSearch()
|
|
||||||
filterRoomView.addTextChangedListener(object : TextWatcher {
|
|
||||||
override fun afterTextChanged(s: Editable?) = Unit
|
|
||||||
|
|
||||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
|
|
||||||
|
|
||||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
|
||||||
roomListViewModel.accept(RoomListActions.FilterRooms(s))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun renderState(state: RoomListViewState) {
|
private fun renderState(state: RoomListViewState) {
|
||||||
when (state.asyncRooms) {
|
when (state.asyncRooms) {
|
||||||
is Incomplete -> renderLoading()
|
is Incomplete -> renderLoading()
|
||||||
|
|
|
@ -30,6 +30,7 @@ import im.vector.matrix.android.api.session.room.model.tag.RoomTag
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
|
import im.vector.riotredesign.features.home.group.ALL_COMMUNITIES_GROUP_ID
|
||||||
import im.vector.riotredesign.features.home.group.SelectedGroupStore
|
import im.vector.riotredesign.features.home.group.SelectedGroupStore
|
||||||
import im.vector.riotredesign.features.home.room.VisibleRoomStore
|
import im.vector.riotredesign.features.home.room.VisibleRoomStore
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
@ -118,7 +119,7 @@ class RoomListViewModel(initialState: RoomListViewState,
|
||||||
val filteredDirectRooms = filteredRooms
|
val filteredDirectRooms = filteredRooms
|
||||||
.filter { it.isDirect }
|
.filter { it.isDirect }
|
||||||
.filter {
|
.filter {
|
||||||
if (selectedGroup == null) {
|
if (selectedGroup == null || selectedGroup.groupId == ALL_COMMUNITIES_GROUP_ID) {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
it.otherMemberIds
|
it.otherMemberIds
|
||||||
|
@ -130,7 +131,8 @@ class RoomListViewModel(initialState: RoomListViewState,
|
||||||
val filteredGroupRooms = filteredRooms
|
val filteredGroupRooms = filteredRooms
|
||||||
.filter { !it.isDirect }
|
.filter { !it.isDirect }
|
||||||
.filter {
|
.filter {
|
||||||
selectedGroup?.roomIds?.contains(it.roomId) ?: true
|
selectedGroup?.groupId == ALL_COMMUNITIES_GROUP_ID
|
||||||
|
|| selectedGroup?.roomIds?.contains(it.roomId) ?: true
|
||||||
}
|
}
|
||||||
buildRoomSummaries(filteredDirectRooms + filteredGroupRooms)
|
buildRoomSummaries(filteredDirectRooms + filteredGroupRooms)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/roomDetailContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</FrameLayout>
|
|
@ -4,8 +4,7 @@
|
||||||
<im.vector.riotredesign.core.platform.StateView xmlns:android="http://schemas.android.com/apk/res/android"
|
<im.vector.riotredesign.core.platform.StateView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/stateView"
|
android:id="@+id/stateView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:background="@color/dark">
|
|
||||||
|
|
||||||
<com.airbnb.epoxy.EpoxyRecyclerView
|
<com.airbnb.epoxy.EpoxyRecyclerView
|
||||||
android:id="@+id/epoxyRecyclerView"
|
android:id="@+id/epoxyRecyclerView"
|
||||||
|
|
|
@ -1,23 +1,68 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/stateView"
|
android:id="@+id/stateView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<FrameLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/groupListFragmentContainer"
|
android:id="@+id/homeDrawerHeader"
|
||||||
android:layout_width="64dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
android:background="?attr/colorPrimary"
|
||||||
|
android:padding="16dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/homeDrawerHeaderAvatarView"
|
||||||
|
android:layout_width="64dp"
|
||||||
|
android:layout_height="64dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:src="@tools:sample/avatars" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/homeDrawerUsernameView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/homeDrawerHeaderAvatarView"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/homeDrawerHeaderAvatarView"
|
||||||
|
tools:text="@tools:sample/full_names" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/homeDrawerUserIdView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/homeDrawerUsernameView"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/homeDrawerUsernameView"
|
||||||
|
tools:text="@tools:sample/full_names" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/homeDrawerHeaderSettingsView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/homeDrawerUserIdView" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/roomListFragmentContainer"
|
android:id="@+id/homeDrawerGroupListContainer"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
android:background="@android:color/white"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/groupListFragmentContainer"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toBottomOf="@+id/homeDrawerHeader" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,53 +1,15 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<im.vector.riotredesign.core.platform.StateView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
android:id="@+id/stateView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/pale_grey">
|
android:background="@color/pale_grey">
|
||||||
|
|
||||||
<EditText
|
<com.airbnb.epoxy.EpoxyRecyclerView
|
||||||
android:id="@+id/filterRoomView"
|
android:id="@+id/epoxyRecyclerView"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="32dp"
|
android:layout_height="match_parent" />
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:background="@drawable/bg_search_edit_text"
|
|
||||||
android:drawableStart="@drawable/ic_search_white"
|
|
||||||
android:drawableLeft="@drawable/ic_search_white"
|
|
||||||
android:drawablePadding="8dp"
|
|
||||||
android:drawableTint="#9fa9ba"
|
|
||||||
android:hint="@string/home_filter_placeholder_rooms"
|
|
||||||
android:lines="1"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/stateView"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<im.vector.riotredesign.core.platform.StateView
|
</im.vector.riotredesign.core.platform.StateView>
|
||||||
android:id="@+id/stateView"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginEnd="0dp"
|
|
||||||
android:layout_marginRight="0dp"
|
|
||||||
android:layout_marginBottom="0dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/filterRoomView">
|
|
||||||
|
|
||||||
<com.airbnb.epoxy.EpoxyRecyclerView
|
|
||||||
android:id="@+id/epoxyRecyclerView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
</im.vector.riotredesign.core.platform.StateView>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
style="@style/VectorToolbarStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:contentInsetStartWithNavigation="0dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
||||||
|
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/roomListContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/toolbar" />
|
||||||
|
|
||||||
|
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
|
android:id="@+id/bottomNavigationView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/colorPrimary"
|
||||||
|
app:itemIconTint="@android:color/white"
|
||||||
|
app:itemTextColor="@color/home_bottom_nav_view_tint"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:menu='@menu/selected_group_navigation' />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,22 +1,48 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<im.vector.riotredesign.core.platform.CheckableFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/itemGroupLayout"
|
android:id="@+id/itemGroupLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="56dp"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:padding="8dp">
|
android:padding="16dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/groupAvatarImageView"
|
android:id="@+id/groupAvatarImageView"
|
||||||
android:layout_width="48dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="24dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:duplicateParentState="true"
|
android:duplicateParentState="true"
|
||||||
android:foreground="@drawable/fg_group_item"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:src="@tools:sample/avatars" />
|
tools:src="@tools:sample/avatars" />
|
||||||
|
|
||||||
</im.vector.riotredesign.core.platform.CheckableFrameLayout>
|
<TextView
|
||||||
|
android:id="@+id/groupNameView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="32dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/groupAvatarImageView"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/groupAvatarChevron"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/groupAvatarImageView"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/groupAvatarImageView"
|
||||||
|
tools:text="@tools:sample/lorem/random" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/groupAvatarChevron"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_material_chevron_right_black"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/bottom_action_home"
|
||||||
|
android:contentDescription="@string/bottom_action_home"
|
||||||
|
android:enabled="true"
|
||||||
|
android:icon="@drawable/ic_home_black_24dp"
|
||||||
|
android:title="" />
|
||||||
|
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/bottom_action_people"
|
||||||
|
android:contentDescription="@string/bottom_action_people"
|
||||||
|
android:enabled="true"
|
||||||
|
android:icon="@drawable/ic_person_black_24dp"
|
||||||
|
android:title="" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/bottom_action_rooms"
|
||||||
|
android:contentDescription="@string/bottom_action_rooms"
|
||||||
|
android:enabled="true"
|
||||||
|
android:icon="@drawable/riot_tab_rooms"
|
||||||
|
android:title="" />
|
||||||
|
|
||||||
|
</menu>
|
Loading…
Reference in New Issue