forked from GitHub-Mirror/riotX-android
Home: change some UI in room list
This commit is contained in:
parent
1691537a1e
commit
9f9f4c0755
@ -1,66 +1,68 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* * 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.
|
||||
* 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
|
||||
package im.vector.riotredesign.features.home
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import androidx.core.view.forEachIndexed
|
||||
import com.airbnb.mvrx.args
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationItemView
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationMenuView
|
||||
import im.vector.riotredesign.R
|
||||
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 im.vector.riotredesign.features.home.room.list.UnreadCounterBadgeView
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.fragment_selected_group.*
|
||||
import kotlinx.android.synthetic.main.fragment_home_detail.*
|
||||
|
||||
|
||||
@Parcelize
|
||||
data class SelectedGroupParams(
|
||||
data class HomeDetailParams(
|
||||
val groupId: String,
|
||||
val groupName: String,
|
||||
val groupAvatar: String
|
||||
) : Parcelable
|
||||
|
||||
|
||||
private const val CURRENT_DISPLAY_MODE = "CURRENT_DISPLAY_MODE"
|
||||
|
||||
class SelectedGroupFragment : VectorBaseFragment() {
|
||||
class HomeDetailFragment : VectorBaseFragment() {
|
||||
|
||||
private val selectedGroupParams: SelectedGroupParams by args()
|
||||
private val params: HomeDetailParams by args()
|
||||
private val unreadCounterBadgeViews = arrayListOf<UnreadCounterBadgeView>()
|
||||
private lateinit var currentDisplayMode: RoomListFragment.DisplayMode
|
||||
|
||||
override fun getLayoutResId(): Int {
|
||||
return R.layout.fragment_selected_group
|
||||
return R.layout.fragment_home_detail
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
if (savedInstanceState == null) {
|
||||
currentDisplayMode = RoomListFragment.DisplayMode.HOME
|
||||
} else {
|
||||
currentDisplayMode = savedInstanceState.getSerializable(CURRENT_DISPLAY_MODE) as? RoomListFragment.DisplayMode
|
||||
currentDisplayMode = savedInstanceState?.getSerializable(CURRENT_DISPLAY_MODE) as? RoomListFragment.DisplayMode
|
||||
?: RoomListFragment.DisplayMode.HOME
|
||||
}
|
||||
renderState(currentDisplayMode)
|
||||
switchDisplayMode(currentDisplayMode)
|
||||
setupBottomNavigationView()
|
||||
setupToolbar()
|
||||
}
|
||||
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
outState.putSerializable(CURRENT_DISPLAY_MODE, currentDisplayMode)
|
||||
super.onSaveInstanceState(outState)
|
||||
@ -73,9 +75,9 @@ class SelectedGroupFragment : VectorBaseFragment() {
|
||||
}
|
||||
groupToolbar.title = ""
|
||||
AvatarRenderer.render(
|
||||
selectedGroupParams.groupAvatar,
|
||||
selectedGroupParams.groupId,
|
||||
selectedGroupParams.groupName,
|
||||
params.groupAvatar,
|
||||
params.groupId,
|
||||
params.groupName,
|
||||
groupToolbarAvatarImageView
|
||||
)
|
||||
groupToolbarAvatarImageView.setOnClickListener {
|
||||
@ -92,13 +94,21 @@ class SelectedGroupFragment : VectorBaseFragment() {
|
||||
}
|
||||
if (currentDisplayMode != displayMode) {
|
||||
currentDisplayMode = displayMode
|
||||
renderState(displayMode)
|
||||
switchDisplayMode(displayMode)
|
||||
}
|
||||
true
|
||||
}
|
||||
val menuView = bottomNavigationView.getChildAt(0) as BottomNavigationMenuView
|
||||
menuView.forEachIndexed { index, view ->
|
||||
val itemView = view as BottomNavigationItemView
|
||||
val badgeLayout = LayoutInflater.from(requireContext()).inflate(R.layout.vector_unread_layout, menuView, false)
|
||||
val unreadCounterBadgeView: UnreadCounterBadgeView = badgeLayout.findViewById(R.id.actionUnreadCounterBadgeView)
|
||||
itemView.addView(badgeLayout)
|
||||
unreadCounterBadgeViews.add(index, unreadCounterBadgeView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderState(displayMode: RoomListFragment.DisplayMode) {
|
||||
private fun switchDisplayMode(displayMode: RoomListFragment.DisplayMode) {
|
||||
groupToolbarTitleView.setText(displayMode.titleRes)
|
||||
updateSelectedFragment(displayMode)
|
||||
}
|
||||
@ -117,8 +127,8 @@ class SelectedGroupFragment : VectorBaseFragment() {
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(args: SelectedGroupParams): SelectedGroupFragment {
|
||||
return SelectedGroupFragment().apply {
|
||||
fun newInstance(args: HomeDetailParams): HomeDetailFragment {
|
||||
return HomeDetailFragment().apply {
|
||||
setArguments(args)
|
||||
}
|
||||
}
|
@ -21,8 +21,6 @@ import androidx.fragment.app.FragmentManager
|
||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.riotredesign.R
|
||||
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 kotlinx.android.synthetic.main.activity_home.*
|
||||
@ -37,10 +35,10 @@ class HomeNavigator {
|
||||
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)
|
||||
val args = HomeDetailParams(groupSummary.groupId, groupSummary.displayName, groupSummary.avatarUrl)
|
||||
val homeDetailFragment = HomeDetailFragment.newInstance(args)
|
||||
it.drawerLayout?.closeDrawer(GravityCompat.START)
|
||||
it.replaceFragment(selectedGroupFragment, R.id.homeDetailFragmentContainer)
|
||||
it.replaceFragment(homeDetailFragment, R.id.homeDetailFragmentContainer)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,5 +18,18 @@ package im.vector.riotredesign.features.home
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.riotredesign.core.utils.RxStore
|
||||
import im.vector.riotredesign.features.home.room.list.RoomListDisplayModeFilter
|
||||
import im.vector.riotredesign.features.home.room.list.RoomListFragment
|
||||
import io.reactivex.Observable
|
||||
|
||||
class HomeRoomListObservableStore : RxStore<List<RoomSummary>>(emptyList())
|
||||
class HomeRoomListObservableStore : RxStore<List<RoomSummary>>() {
|
||||
|
||||
fun observeFilteredBy(displayMode: RoomListFragment.DisplayMode): Observable<List<RoomSummary>> {
|
||||
return observe()
|
||||
.flatMapSingle {
|
||||
Observable.fromIterable(it).filter(RoomListDisplayModeFilter(displayMode)).toList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -389,15 +389,15 @@ class RoomDetailFragment :
|
||||
private fun renderState(state: RoomDetailViewState) {
|
||||
renderRoomSummary(state)
|
||||
val summary = state.asyncRoomSummary()
|
||||
val inviter = state.inviter()
|
||||
val inviter = state.asyncInviter()
|
||||
if (summary?.membership == Membership.JOIN) {
|
||||
timelineEventController.setTimeline(state.timeline)
|
||||
inviteView.visibility = View.GONE
|
||||
} else if (summary?.membership == Membership.INVITE && inviter != null) {
|
||||
inviteView.visibility = View.VISIBLE
|
||||
inviteView.render(inviter, VectorInviteView.Mode.LARGE)
|
||||
} else {
|
||||
//TODO : close the screen
|
||||
} else if (state.asyncInviter.complete) {
|
||||
vectorBaseActivity.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,7 +292,7 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
summary.lastMessage?.sender?.let { senderId ->
|
||||
session.getUser(senderId)
|
||||
}?.also {
|
||||
setState { copy(inviter = Success(it)) }
|
||||
setState { copy(asyncInviter = Success(it)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ data class RoomDetailViewState(
|
||||
val roomId: String,
|
||||
val eventId: String?,
|
||||
val timeline: Timeline? = null,
|
||||
val inviter: Async<User> = Uninitialized,
|
||||
val asyncInviter: Async<User> = Uninitialized,
|
||||
val asyncRoomSummary: Async<RoomSummary> = Uninitialized,
|
||||
val asyncTimelineData: Async<TimelineData> = Uninitialized
|
||||
) : MvRxState {
|
||||
|
@ -41,7 +41,7 @@ abstract class RoomCategoryItem : VectorEpoxyModel<RoomCategoryItem.Holder>() {
|
||||
val expandedArrowDrawable = ContextCompat.getDrawable(holder.rootView.context, expandedArrowDrawableRes)?.also {
|
||||
DrawableCompat.setTint(it, tintColor)
|
||||
}
|
||||
holder.unreadCounterBadgeView.render(unreadCount, showHighlighted)
|
||||
holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadCount, showHighlighted))
|
||||
holder.titleView.setCompoundDrawablesWithIntrinsicBounds(expandedArrowDrawable, null, null, null)
|
||||
holder.titleView.text = title
|
||||
holder.rootView.setOnClickListener { listener?.invoke() }
|
||||
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.list
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import io.reactivex.functions.Predicate
|
||||
|
||||
class RoomListDisplayModeFilter(private val displayMode: RoomListFragment.DisplayMode) : Predicate<RoomSummary> {
|
||||
|
||||
override fun test(roomSummary: RoomSummary): Boolean {
|
||||
return when (displayMode) {
|
||||
RoomListFragment.DisplayMode.HOME -> roomSummary.notificationCount > 0 || roomSummary.membership == Membership.INVITE
|
||||
RoomListFragment.DisplayMode.PEOPLE -> roomSummary.isDirect && roomSummary.membership == Membership.JOIN
|
||||
RoomListFragment.DisplayMode.ROOMS -> !roomSummary.isDirect && roomSummary.membership == Membership.JOIN
|
||||
}
|
||||
}
|
||||
}
|
@ -29,7 +29,6 @@ import im.vector.matrix.android.api.session.room.model.tag.RoomTag
|
||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||
import im.vector.riotredesign.core.utils.LiveEvent
|
||||
import im.vector.riotredesign.features.home.HomeRoomListObservableStore
|
||||
import io.reactivex.Observable
|
||||
import org.koin.android.ext.android.get
|
||||
|
||||
typealias RoomListFilterName = CharSequence
|
||||
@ -54,6 +53,7 @@ class RoomListViewModel(initialState: RoomListViewState,
|
||||
}
|
||||
|
||||
private val displayMode = initialState.displayMode
|
||||
private val roomListDisplayModeFilter = RoomListDisplayModeFilter(displayMode)
|
||||
private val roomListFilter = BehaviorRelay.createDefault<Option<RoomListFilterName>>(Option.empty())
|
||||
|
||||
private val _openRoomLiveData = MutableLiveData<LiveEvent<String>>()
|
||||
@ -95,27 +95,13 @@ class RoomListViewModel(initialState: RoomListViewState,
|
||||
copy(asyncRooms = asyncRooms)
|
||||
}
|
||||
|
||||
homeRoomListObservableSource
|
||||
.observe()
|
||||
.flatMapSingle {
|
||||
Observable.fromIterable(it)
|
||||
.filter(filterByDisplayMode(displayMode))
|
||||
.toList()
|
||||
}
|
||||
homeRoomListObservableSource.observeFilteredBy(displayMode)
|
||||
.map { buildRoomSummaries(it) }
|
||||
.execute { async ->
|
||||
copy(asyncFilteredRooms = async)
|
||||
}
|
||||
}
|
||||
|
||||
private fun filterByDisplayMode(displayMode: RoomListFragment.DisplayMode) = { roomSummary: RoomSummary ->
|
||||
when (displayMode) {
|
||||
RoomListFragment.DisplayMode.HOME -> roomSummary.notificationCount > 0
|
||||
RoomListFragment.DisplayMode.PEOPLE -> roomSummary.isDirect
|
||||
RoomListFragment.DisplayMode.ROOMS -> !roomSummary.isDirect
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildRoomSummaries(rooms: List<RoomSummary>): RoomSummaries {
|
||||
val invites = ArrayList<RoomSummary>()
|
||||
val favourites = ArrayList<RoomSummary>()
|
||||
|
@ -17,12 +17,16 @@
|
||||
package im.vector.riotredesign.features.home.room.list
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.MvRxState
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.riotredesign.R
|
||||
|
||||
data class RoomListViewState(
|
||||
val displayMode: RoomListFragment.DisplayMode,
|
||||
val asyncRooms: Async<List<RoomSummary>> = Uninitialized,
|
||||
val asyncFilteredRooms: Async<RoomSummaries> = Uninitialized,
|
||||
val isInviteExpanded: Boolean = true,
|
||||
val isFavouriteRoomsExpanded: Boolean = true,
|
||||
val isDirectRoomsExpanded: Boolean = true,
|
||||
|
@ -46,7 +46,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
||||
holder.titleView.text = roomName
|
||||
holder.lastEventTimeView.text = lastEventTime
|
||||
holder.lastEventView.text = lastFormattedEvent
|
||||
holder.unreadCounterBadgeView.render(unreadCount, showHighlighted)
|
||||
holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadCount, showHighlighted))
|
||||
AvatarRenderer.render(avatarUrl, roomId, roomName.toString(), holder.avatarImageView)
|
||||
}
|
||||
|
||||
|
@ -29,24 +29,24 @@ class UnreadCounterBadgeView : AppCompatTextView {
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||
|
||||
fun render(count: Int, highlighted: Boolean) {
|
||||
if (count == 0) {
|
||||
fun render(state: State) {
|
||||
if (state.count == 0) {
|
||||
visibility = View.INVISIBLE
|
||||
} else {
|
||||
visibility = View.VISIBLE
|
||||
val bgRes = if (highlighted) {
|
||||
val bgRes = if (state.highlighted) {
|
||||
R.drawable.bg_unread_highlight
|
||||
} else {
|
||||
R.drawable.bg_unread_notification
|
||||
}
|
||||
setBackgroundResource(bgRes)
|
||||
text = RoomSummaryFormatter.formatUnreadMessagesCounter(count)
|
||||
text = RoomSummaryFormatter.formatUnreadMessagesCounter(state.count)
|
||||
}
|
||||
}
|
||||
|
||||
enum class Status {
|
||||
NOTIFICATION,
|
||||
HIGHLIGHT
|
||||
}
|
||||
data class State(
|
||||
val count: Int,
|
||||
val highlighted: Boolean
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -57,6 +57,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:labelVisibilityMode="unlabeled"
|
||||
app:itemIconTint="@android:color/white"
|
||||
app:itemTextColor="@color/home_bottom_nav_view_tint"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
@ -10,11 +10,7 @@
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="8dp">
|
||||
android:paddingLeft="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomAvatarImageView"
|
||||
@ -22,7 +18,7 @@
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
@ -32,7 +28,10 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:duplicateParentState="true"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
@ -43,14 +42,14 @@
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toEndOf="@id/roomAvatarImageView"
|
||||
app:layout_constraintTop_toTopOf="@+id/roomAvatarImageView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
|
||||
|
||||
<im.vector.riotredesign.features.home.room.list.UnreadCounterBadgeView
|
||||
android:id="@+id/roomUnreadCounterBadgeView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:gravity="center"
|
||||
android:minWidth="16dp"
|
||||
@ -59,9 +58,10 @@
|
||||
android:paddingRight="4dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="10sp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/roomNameView"
|
||||
app:layout_constraintEnd_toStartOf="@+id/roomLastEventTimeView"
|
||||
app:layout_constraintStart_toEndOf="@+id/roomNameView"
|
||||
app:layout_constraintTop_toTopOf="@+id/roomAvatarImageView"
|
||||
app:layout_constraintTop_toTopOf="@+id/roomNameView"
|
||||
tools:background="@drawable/bg_unread_highlight"
|
||||
tools:text="4" />
|
||||
|
||||
@ -69,20 +69,21 @@
|
||||
android:id="@+id/roomLastEventTimeView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:textColor="@color/black_38"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintBaseline_toBaselineOf="@id/messageMemberNameView"
|
||||
app:layout_constraintTop_toTopOf="@+id/roomAvatarImageView"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/roomNameView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/roomNameView"
|
||||
tools:text="@tools:sample/date/hhmm" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomLastEventView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="34dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textColor="@color/black_38"
|
||||
@ -92,5 +93,14 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/roomNameView"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<View
|
||||
android:id="@+id/roomDividerView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:background="#1e000000"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/roomLastEventView"
|
||||
app:layout_constraintStart_toStartOf="@+id/roomNameView" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
26
vector/src/main/res/layout/vector_unread_layout.xml
Normal file
26
vector/src/main/res/layout/vector_unread_layout.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<im.vector.riotredesign.features.home.room.list.UnreadCounterBadgeView
|
||||
android:id="@+id/actionUnreadCounterBadgeView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|center_horizontal"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center"
|
||||
android:minWidth="8dp"
|
||||
android:minHeight="8dp"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingRight="4dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="10sp"
|
||||
tools:background="@drawable/bg_unread_highlight"
|
||||
tools:text="4" />
|
||||
|
||||
</FrameLayout>
|
Loading…
Reference in New Issue
Block a user