Home: start reworking room list.
This commit is contained in:
parent
275521db70
commit
c0fd06fd2d
|
@ -23,6 +23,7 @@ import im.vector.riotredesign.core.error.ErrorFormatter
|
|||
import im.vector.riotredesign.core.resources.LocaleProvider
|
||||
import im.vector.riotredesign.core.resources.StringArrayProvider
|
||||
import im.vector.riotredesign.core.resources.StringProvider
|
||||
import im.vector.riotredesign.features.home.HomeRoomListObservableStore
|
||||
import im.vector.riotredesign.features.home.group.SelectedGroupStore
|
||||
import im.vector.riotredesign.features.home.room.list.RoomSummaryComparator
|
||||
import im.vector.riotredesign.features.notifications.NotificationDrawerManager
|
||||
|
@ -52,6 +53,10 @@ class AppModule(private val context: Context) {
|
|||
SelectedGroupStore()
|
||||
}
|
||||
|
||||
single {
|
||||
HomeRoomListObservableStore()
|
||||
}
|
||||
|
||||
single {
|
||||
RoomSummaryComparator()
|
||||
}
|
||||
|
|
|
@ -29,4 +29,9 @@ object DateProvider {
|
|||
return LocalDateTime.ofInstant(instant, zoneId)
|
||||
}
|
||||
|
||||
fun currentLocalDateTime(): LocalDateTime {
|
||||
val instant = Instant.now()
|
||||
return LocalDateTime.ofInstant(instant, zoneId)
|
||||
}
|
||||
|
||||
}
|
|
@ -25,14 +25,7 @@ import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserControl
|
|||
import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserPresenter
|
||||
import im.vector.riotredesign.features.home.group.GroupSummaryController
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.CallItemFactory
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.DefaultItemFactory
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.MessageItemFactory
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.RoomHistoryVisibilityItemFactory
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.RoomMemberItemFactory
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.RoomNameItemFactory
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.RoomTopicItemFactory
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.TimelineItemFactory
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.*
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
||||
import im.vector.riotredesign.features.home.room.list.RoomSummaryController
|
||||
|
@ -56,36 +49,36 @@ class HomeModule {
|
|||
HomeNavigator()
|
||||
}
|
||||
|
||||
scope(HOME_SCOPE) {
|
||||
HomeRoomListObservableStore()
|
||||
}
|
||||
|
||||
scope(HOME_SCOPE) {
|
||||
HomePermalinkHandler(get())
|
||||
}
|
||||
|
||||
// Fragment scopes
|
||||
|
||||
factory {
|
||||
TimelineDateFormatter(get())
|
||||
}
|
||||
|
||||
factory { (fragment: Fragment) ->
|
||||
val eventHtmlRenderer = EventHtmlRenderer(GlideApp.with(fragment), fragment.requireContext(), get())
|
||||
val timelineDateFormatter = TimelineDateFormatter(get())
|
||||
val timelineMediaSizeProvider = TimelineMediaSizeProvider()
|
||||
val colorProvider = ColorProvider(fragment.requireContext())
|
||||
val timelineDateFormatter = get<TimelineDateFormatter>()
|
||||
val messageItemFactory = MessageItemFactory(colorProvider, timelineMediaSizeProvider, timelineDateFormatter, eventHtmlRenderer)
|
||||
|
||||
val timelineItemFactory = TimelineItemFactory(messageItemFactory = messageItemFactory,
|
||||
roomNameItemFactory = RoomNameItemFactory(get()),
|
||||
roomTopicItemFactory = RoomTopicItemFactory(get()),
|
||||
roomMemberItemFactory = RoomMemberItemFactory(get()),
|
||||
roomHistoryVisibilityItemFactory = RoomHistoryVisibilityItemFactory(get()),
|
||||
callItemFactory = CallItemFactory(get()),
|
||||
defaultItemFactory = DefaultItemFactory()
|
||||
roomNameItemFactory = RoomNameItemFactory(get()),
|
||||
roomTopicItemFactory = RoomTopicItemFactory(get()),
|
||||
roomMemberItemFactory = RoomMemberItemFactory(get()),
|
||||
roomHistoryVisibilityItemFactory = RoomHistoryVisibilityItemFactory(get()),
|
||||
callItemFactory = CallItemFactory(get()),
|
||||
defaultItemFactory = DefaultItemFactory()
|
||||
)
|
||||
TimelineEventController(timelineDateFormatter, timelineItemFactory, timelineMediaSizeProvider)
|
||||
}
|
||||
|
||||
factory {
|
||||
RoomSummaryController(get())
|
||||
RoomSummaryController(get(), get())
|
||||
}
|
||||
|
||||
factory {
|
||||
|
|
|
@ -29,6 +29,7 @@ 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
|
||||
|
@ -50,7 +51,7 @@ class RoomListViewModel(initialState: RoomListViewState,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private val displayMode = initialState.displayMode
|
||||
private val roomListFilter = BehaviorRelay.createDefault<Option<RoomListFilterName>>(Option.empty())
|
||||
|
||||
private val _openRoomLiveData = MutableLiveData<LiveEvent<String>>()
|
||||
|
@ -86,15 +87,27 @@ class RoomListViewModel(initialState: RoomListViewState,
|
|||
|
||||
|
||||
private fun observeRoomSummaries() {
|
||||
homeRoomListObservableSource.observe()
|
||||
homeRoomListObservableSource
|
||||
.observe()
|
||||
.flatMapSingle {
|
||||
Observable.fromIterable(it)
|
||||
.filter(filterByDisplayMode(displayMode))
|
||||
.toList()
|
||||
}
|
||||
.map { buildRoomSummaries(it) }
|
||||
.execute { async ->
|
||||
copy(
|
||||
asyncRooms = async
|
||||
)
|
||||
copy(asyncRooms = 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>()
|
||||
|
|
|
@ -24,6 +24,7 @@ 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<RoomSummaries> = Uninitialized,
|
||||
val isInviteExpanded: Boolean = true,
|
||||
val isFavouriteRoomsExpanded: Boolean = true,
|
||||
|
@ -33,6 +34,8 @@ data class RoomListViewState(
|
|||
val isServerNoticeRoomsExpanded: Boolean = true
|
||||
) : MvRxState {
|
||||
|
||||
constructor(args: RoomListParams) : this(displayMode = args.displayMode)
|
||||
|
||||
fun isCategoryExpanded(roomCategory: RoomCategory): Boolean {
|
||||
return when (roomCategory) {
|
||||
RoomCategory.INVITE -> isInviteExpanded
|
||||
|
|
|
@ -19,9 +19,13 @@ package im.vector.riotredesign.features.home.room.list
|
|||
import androidx.annotation.StringRes
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.riotredesign.core.extensions.localDateTime
|
||||
import im.vector.riotredesign.core.resources.DateProvider
|
||||
import im.vector.riotredesign.core.resources.StringProvider
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||
|
||||
class RoomSummaryController(private val stringProvider: StringProvider
|
||||
class RoomSummaryController(private val stringProvider: StringProvider,
|
||||
private val timelineDateFormatter: TimelineDateFormatter
|
||||
) : TypedEpoxyController<RoomListViewState>() {
|
||||
|
||||
var callback: Callback? = null
|
||||
|
@ -76,9 +80,29 @@ class RoomSummaryController(private val stringProvider: StringProvider
|
|||
val unreadCount = roomSummary.notificationCount
|
||||
val showHighlighted = roomSummary.highlightCount > 0
|
||||
|
||||
var lastMessageFormatted: CharSequence = ""
|
||||
var lastMessageTime: CharSequence = ""
|
||||
val lastMessage = roomSummary.lastMessage
|
||||
if (lastMessage != null) {
|
||||
val date = lastMessage.localDateTime()
|
||||
val currentData = DateProvider.currentLocalDateTime()
|
||||
val isSameDay = date.toLocalDate() == currentData.toLocalDate()
|
||||
//TODO: get formatted
|
||||
lastMessageFormatted = lastMessage.content?.toString() ?: ""
|
||||
lastMessageTime = if (isSameDay) {
|
||||
timelineDateFormatter.formatMessageHour(date)
|
||||
} else {
|
||||
//TODO: change this
|
||||
timelineDateFormatter.formatMessageDay(date)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
roomSummaryItem {
|
||||
id(roomSummary.roomId)
|
||||
roomId(roomSummary.roomId)
|
||||
lastEventTime(lastMessageTime)
|
||||
lastFormattedEvent(lastMessageFormatted)
|
||||
roomName(roomSummary.displayName)
|
||||
avatarUrl(roomSummary.avatarUrl)
|
||||
showHighlighted(showHighlighted)
|
||||
|
|
|
@ -32,6 +32,8 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
|||
|
||||
@EpoxyAttribute lateinit var roomName: CharSequence
|
||||
@EpoxyAttribute lateinit var roomId: String
|
||||
@EpoxyAttribute lateinit var lastFormattedEvent: CharSequence
|
||||
@EpoxyAttribute lateinit var lastEventTime: CharSequence
|
||||
@EpoxyAttribute var avatarUrl: String? = null
|
||||
@EpoxyAttribute var unreadCount: Int = 0
|
||||
@EpoxyAttribute var showHighlighted: Boolean = false
|
||||
|
@ -40,15 +42,17 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
|||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.unreadCounterBadgeView.render(unreadCount, showHighlighted)
|
||||
holder.rootView.setOnClickListener { listener?.invoke() }
|
||||
holder.titleView.text = roomName
|
||||
holder.lastEventTimeView.text = lastEventTime
|
||||
holder.lastEventView.text = lastFormattedEvent
|
||||
AvatarRenderer.render(avatarUrl, roomId, roomName.toString(), holder.avatarImageView)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
val unreadCounterBadgeView by bind<UnreadCounterBadgeView>(R.id.roomUnreadCounterBadgeView)
|
||||
val titleView by bind<TextView>(R.id.roomNameView)
|
||||
val lastEventView by bind<TextView>(R.id.roomLastEventView)
|
||||
val lastEventTimeView by bind<TextView>(R.id.roomLastEventTimeView)
|
||||
val avatarImageView by bind<ImageView>(R.id.roomAvatarImageView)
|
||||
val rootView by bind<ViewGroup>(R.id.itemRoomLayout)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:minHeight="48dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingEnd="16dp"
|
||||
|
@ -17,8 +18,8 @@
|
|||
|
||||
<ImageView
|
||||
android:id="@+id/roomAvatarImageView"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
@ -33,30 +34,38 @@
|
|||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:duplicateParentState="true"
|
||||
android:textColor="@color/color_room_title"
|
||||
android:textColor="@color/black_87"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/roomUnreadCounterBadgeView"
|
||||
app:layout_constraintEnd_toStartOf="@+id/roomLastEventTimeView"
|
||||
app:layout_constraintStart_toEndOf="@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"
|
||||
<TextView
|
||||
android:id="@+id/roomLastEventView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black_38"
|
||||
android:textSize="14sp"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/roomNameView"
|
||||
app:layout_constraintTop_toBottomOf="@+id/roomNameView"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomLastEventTimeView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:minWidth="24dp"
|
||||
android:minHeight="24dp"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingRight="4dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:textColor="@color/black_38"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintBaseline_toBaselineOf="@id/messageMemberNameView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:background="@drawable/bg_unread_highlight"
|
||||
tools:text="115" />
|
||||
app:layout_constraintStart_toEndOf="@id/messageMemberNameView"
|
||||
tools:text="@tools:sample/date/hhmm" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
<color name="pale_grey_two">#ebedf8</color>
|
||||
<color name="brown_grey">#a5a5a5</color>
|
||||
<color name="grey_lynch">#61708B</color>
|
||||
<color name="black_87">#de000000</color>
|
||||
<color name="black_38">#61000000</color>
|
||||
<color name="black_37">#5d000000</color>
|
||||
|
||||
<color name="black">#000000</color>
|
||||
<color name="black_87">#de000000</color>
|
||||
|
|
Loading…
Reference in New Issue