mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-17 04:20:00 +03:00
Handle chunks merging with thread summary
Add animation to fragment transition with offset for recyclerview initialization Support threads on deleted events
This commit is contained in:
parent
afc69c77bd
commit
c4967a2871
17 changed files with 80 additions and 110 deletions
|
@ -34,6 +34,7 @@ import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.query.find
|
import org.matrix.android.sdk.internal.database.query.find
|
||||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
|
import org.matrix.android.sdk.internal.database.query.whereRoomId
|
||||||
import org.matrix.android.sdk.internal.extensions.assertIsManaged
|
import org.matrix.android.sdk.internal.extensions.assertIsManaged
|
||||||
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
|
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
@ -157,9 +158,21 @@ private fun ChunkEntity.addTimelineEventFromMerge(realm: Realm, timelineEventEnt
|
||||||
this.senderName = timelineEventEntity.senderName
|
this.senderName = timelineEventEntity.senderName
|
||||||
this.isUniqueDisplayName = timelineEventEntity.isUniqueDisplayName
|
this.isUniqueDisplayName = timelineEventEntity.isUniqueDisplayName
|
||||||
}
|
}
|
||||||
|
handleThreadSummary(realm, eventId, copied)
|
||||||
timelineEvents.add(copied)
|
timelineEvents.add(copied)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upon copy of the timeline events we should update the latestMessage TimelineEventEntity with the new one
|
||||||
|
*/
|
||||||
|
private fun handleThreadSummary(realm: Realm, oldEventId: String, newTimelineEventEntity: TimelineEventEntity) {
|
||||||
|
EventEntity
|
||||||
|
.whereRoomId(realm, newTimelineEventEntity.roomId)
|
||||||
|
.equalTo(EventEntityFields.IS_ROOT_THREAD, true)
|
||||||
|
.equalTo(EventEntityFields.THREAD_SUMMARY_LATEST_MESSAGE.EVENT_ID, oldEventId)
|
||||||
|
.findFirst()?.threadSummaryLatestMessage = newTimelineEventEntity
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleReadReceipts(realm: Realm, roomId: String, eventEntity: EventEntity, senderId: String): ReadReceiptsSummaryEntity {
|
private fun handleReadReceipts(realm: Realm, roomId: String, eventEntity: EventEntity, senderId: String): ReadReceiptsSummaryEntity {
|
||||||
val readReceiptsSummaryEntity = ReadReceiptsSummaryEntity.where(realm, eventEntity.eventId).findFirst()
|
val readReceiptsSummaryEntity = ReadReceiptsSummaryEntity.where(realm, eventEntity.eventId).findFirst()
|
||||||
?: realm.createObject<ReadReceiptsSummaryEntity>(eventEntity.eventId).apply {
|
?: realm.createObject<ReadReceiptsSummaryEntity>(eventEntity.eventId).apply {
|
||||||
|
|
|
@ -49,6 +49,13 @@ internal fun EventEntity.Companion.where(realm: Realm, eventId: String): RealmQu
|
||||||
.equalTo(EventEntityFields.EVENT_ID, eventId)
|
.equalTo(EventEntityFields.EVENT_ID, eventId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal fun EventEntity.Companion.whereRoomId(realm: Realm, roomId: String): RealmQuery<EventEntity> {
|
||||||
|
return realm.where<EventEntity>()
|
||||||
|
.equalTo(EventEntityFields.ROOM_ID, roomId)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
internal fun EventEntity.Companion.where(realm: Realm, eventIds: List<String>): RealmQuery<EventEntity> {
|
internal fun EventEntity.Companion.where(realm: Realm, eventIds: List<String>): RealmQuery<EventEntity> {
|
||||||
return realm.where<EventEntity>()
|
return realm.where<EventEntity>()
|
||||||
.`in`(EventEntityFields.EVENT_ID, eventIds.toTypedArray())
|
.`in`(EventEntityFields.EVENT_ID, eventIds.toTypedArray())
|
||||||
|
|
|
@ -270,53 +270,4 @@ internal class TokenChunkEventPersistor @Inject constructor(@SessionDatabase pri
|
||||||
optimizedThreadSummaryMap.updateThreadSummaryIfNeeded()
|
optimizedThreadSummaryMap.updateThreadSummaryIfNeeded()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Mark or update the thread root event accordingly. If the Threading is disabled
|
|
||||||
// * no action is done
|
|
||||||
// */
|
|
||||||
// private fun updateRootThreadEventIfNeeded(realm: Realm, eventEntity: EventEntity) {
|
|
||||||
//
|
|
||||||
// if (!BuildConfig.THREADING_ENABLED) return
|
|
||||||
//
|
|
||||||
// val rootThreadEventId = eventEntity.rootThreadEventId
|
|
||||||
//
|
|
||||||
// if (eventEntity.isThread && rootThreadEventId != null) {
|
|
||||||
// markEventAsRootEvent(realm, rootThreadEventId)
|
|
||||||
// } else {
|
|
||||||
// markAsRootEventIfNeeded(realm, eventEntity.eventId)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Finds the event with rootThreadEventId and marks it as a root thread
|
|
||||||
// */
|
|
||||||
// private fun markEventAsRootEvent(realm: Realm, rootThreadEventId: String) {
|
|
||||||
// val rootThreadEvent = EventEntity
|
|
||||||
// .where(realm, rootThreadEventId)
|
|
||||||
// .equalTo(EventEntityFields.IS_THREAD, false).findFirst() ?: return
|
|
||||||
// rootThreadEvent.isThread = true
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Also check if there is at least one thread message for that rootThreadEventId,
|
|
||||||
// * that means it is a root thread so it should be updated accordingly
|
|
||||||
// */
|
|
||||||
// private fun markAsRootEventIfNeeded(realm: Realm, candidateIdRootThread: String) {
|
|
||||||
// EventEntity
|
|
||||||
// .whereRootThreadEventId(realm, candidateIdRootThread)
|
|
||||||
// .findFirst() ?: return
|
|
||||||
//
|
|
||||||
// markEventAsRootEvent(realm, candidateIdRootThread)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Returns the chunk for the current room if exists, otherwise it creates a new ChunkEntity
|
|
||||||
// */
|
|
||||||
// private fun getOrCreateThreadChunk(realm: Realm, roomId: String, rootThreadEventId: String): ChunkEntity {
|
|
||||||
// return ChunkEntity.findThreadChunkOfRoom(realm, roomId, rootThreadEventId)
|
|
||||||
// ?: realm.createObject<ChunkEntity>().apply {
|
|
||||||
// this.rootThreadEventId = rootThreadEventId
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,19 +125,19 @@ class MessageItemFactory @Inject constructor(
|
||||||
pillsPostProcessorFactory.create(roomId)
|
pillsPostProcessorFactory.create(roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun create(params: TimelineItemFactoryParams): VectorEpoxyModel<*>? {
|
fun create(params: TimelineItemFactoryParams): VectorEpoxyModel<*>? {
|
||||||
|
|
||||||
val event = params.event
|
val event = params.event
|
||||||
val highlight = params.isHighlighted
|
val highlight = params.isHighlighted
|
||||||
val callback = params.callback
|
val callback = params.callback
|
||||||
event.root.eventId ?: return null
|
event.root.eventId ?: return null
|
||||||
roomId = event.roomId
|
roomId = event.roomId
|
||||||
val informationData = messageInformationDataFactory.create(params)
|
val informationData = messageInformationDataFactory.create(params)
|
||||||
|
val threadDetails = if (params.isFromThreadTimeline()) null else event.root.threadDetails
|
||||||
|
|
||||||
if (event.root.isRedacted()) {
|
if (event.root.isRedacted()) {
|
||||||
// message is redacted
|
// message is redacted
|
||||||
val attributes = messageItemAttributesFactory.create(null, informationData, callback)
|
val attributes = messageItemAttributesFactory.create(null, informationData, callback, threadDetails)
|
||||||
return buildRedactedItem(attributes, highlight)
|
return buildRedactedItem(attributes, highlight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +154,6 @@ class MessageItemFactory @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
// always hide summary when we are on thread timeline
|
// always hide summary when we are on thread timeline
|
||||||
val threadDetails = if(params.isFromThreadTimeline()) null else event.root.threadDetails
|
|
||||||
val attributes = messageItemAttributesFactory.create(messageContent, informationData, callback, threadDetails)
|
val attributes = messageItemAttributesFactory.create(messageContent, informationData, callback, threadDetails)
|
||||||
|
|
||||||
// val all = event.root.toContent()
|
// val all = event.root.toContent()
|
||||||
|
@ -180,9 +179,10 @@ class MessageItemFactory @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isFromThreadTimeline(params: TimelineItemFactoryParams){
|
private fun isFromThreadTimeline(params: TimelineItemFactoryParams) {
|
||||||
params.rootThreadEventId
|
params.rootThreadEventId
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildOptionsMessageItem(messageContent: MessageOptionsContent,
|
private fun buildOptionsMessageItem(messageContent: MessageOptionsContent,
|
||||||
informationData: MessageInformationData,
|
informationData: MessageInformationData,
|
||||||
highlight: Boolean,
|
highlight: Boolean,
|
||||||
|
|
|
@ -72,6 +72,7 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : AbsBaseMessageItem<H>
|
||||||
attributes.threadCallback?.onThreadSummaryClicked(attributes.informationData.eventId, attributes.threadDetails?.isRootThread ?: false)
|
attributes.threadCallback?.onThreadSummaryClicked(attributes.informationData.eventId, attributes.threadDetails?.isRootThread ?: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bind(holder: H) {
|
override fun bind(holder: H) {
|
||||||
super.bind(holder)
|
super.bind(holder)
|
||||||
if (attributes.informationData.showInformation) {
|
if (attributes.informationData.showInformation) {
|
||||||
|
@ -111,26 +112,28 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : AbsBaseMessageItem<H>
|
||||||
holder.eventSendingIndicator.isVisible = attributes.informationData.sendStateDecoration == SendStateDecoration.SENDING_MEDIA
|
holder.eventSendingIndicator.isVisible = attributes.informationData.sendStateDecoration == SendStateDecoration.SENDING_MEDIA
|
||||||
|
|
||||||
// Threads
|
// Threads
|
||||||
if(BuildConfig.THREADING_ENABLED) {
|
if (BuildConfig.THREADING_ENABLED) {
|
||||||
holder.threadSummaryConstraintLayout.onClick(_threadClickListener)
|
holder.threadSummaryConstraintLayout.onClick(_threadClickListener)
|
||||||
attributes.threadDetails?.let { threadDetails ->
|
attributes.threadDetails?.let { threadDetails ->
|
||||||
holder.threadSummaryConstraintLayout.isVisible = threadDetails.isRootThread
|
holder.threadSummaryConstraintLayout.isVisible = threadDetails.isRootThread
|
||||||
holder.threadSummaryCounterTextView.text = threadDetails.numberOfThreads.toString()
|
holder.threadSummaryCounterTextView.text = threadDetails.numberOfThreads.toString()
|
||||||
holder.threadSummaryInfoTextView.text = threadDetails.threadSummaryLatestTextMessage
|
holder.threadSummaryInfoTextView.text = threadDetails.threadSummaryLatestTextMessage
|
||||||
threadDetails.threadSummarySenderInfo?.let { senderInfo ->
|
|
||||||
attributes.avatarRenderer.render(MatrixItem.UserItem(senderInfo.userId, senderInfo.displayName, senderInfo.avatarUrl), holder.threadSummaryAvatarImageView)
|
val userId = threadDetails.threadSummarySenderInfo?.userId ?: return@let
|
||||||
}
|
val displayName = threadDetails.threadSummarySenderInfo?.displayName
|
||||||
} ?: run{holder.threadSummaryConstraintLayout.isVisible = false}
|
val avatarUrl = threadDetails.threadSummarySenderInfo?.avatarUrl
|
||||||
|
attributes.avatarRenderer.render(MatrixItem.UserItem(userId, displayName, avatarUrl), holder.threadSummaryAvatarImageView)
|
||||||
|
} ?: run { holder.threadSummaryConstraintLayout.isVisible = false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun unbind(holder: H) {
|
override fun unbind(holder: H) {
|
||||||
attributes.avatarRenderer.clear(holder.avatarImageView)
|
attributes.avatarRenderer.clear(holder.avatarImageView)
|
||||||
holder.avatarImageView.setOnClickListener(null)
|
holder.avatarImageView.setOnClickListener(null)
|
||||||
holder.avatarImageView.setOnLongClickListener(null)
|
holder.avatarImageView.setOnLongClickListener(null)
|
||||||
holder.memberNameView.setOnClickListener(null)
|
holder.memberNameView.setOnClickListener(null)
|
||||||
holder.memberNameView.setOnLongClickListener(null)
|
holder.memberNameView.setOnLongClickListener(null)
|
||||||
|
attributes.avatarRenderer.clear(holder.threadSummaryAvatarImageView)
|
||||||
holder.threadSummaryConstraintLayout.setOnClickListener(null)
|
holder.threadSummaryConstraintLayout.setOnClickListener(null)
|
||||||
super.unbind(holder)
|
super.unbind(holder)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package im.vector.app.features.home.room.threads.list.model
|
package im.vector.app.features.home.room.threads.list.model
|
||||||
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
@ -31,8 +30,8 @@ import im.vector.app.features.displayname.getBestName
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
import org.matrix.android.sdk.api.util.MatrixItem
|
import org.matrix.android.sdk.api.util.MatrixItem
|
||||||
|
|
||||||
@EpoxyModelClass(layout = R.layout.item_thread_summary)
|
@EpoxyModelClass(layout = R.layout.item_thread_list)
|
||||||
abstract class ThreadSummaryModel : VectorEpoxyModel<ThreadSummaryModel.Holder>() {
|
abstract class ThreadListModel : VectorEpoxyModel<ThreadListModel.Holder>() {
|
||||||
|
|
||||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
|
@ -20,21 +20,21 @@ import com.airbnb.epoxy.EpoxyController
|
||||||
import im.vector.app.core.date.DateFormatKind
|
import im.vector.app.core.date.DateFormatKind
|
||||||
import im.vector.app.core.date.VectorDateFormatter
|
import im.vector.app.core.date.VectorDateFormatter
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.home.room.threads.list.model.threadSummary
|
import im.vector.app.features.home.room.threads.list.model.threadList
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ThreadSummaryController @Inject constructor(
|
class ThreadListController @Inject constructor(
|
||||||
private val avatarRenderer: AvatarRenderer,
|
private val avatarRenderer: AvatarRenderer,
|
||||||
private val dateFormatter: VectorDateFormatter
|
private val dateFormatter: VectorDateFormatter
|
||||||
) : EpoxyController() {
|
) : EpoxyController() {
|
||||||
|
|
||||||
var listener: Listener? = null
|
var listener: Listener? = null
|
||||||
|
|
||||||
private var viewState: ThreadSummaryViewState? = null
|
private var viewState: ThreadListViewState? = null
|
||||||
|
|
||||||
fun update(viewState: ThreadSummaryViewState) {
|
fun update(viewState: ThreadListViewState) {
|
||||||
this.viewState = viewState
|
this.viewState = viewState
|
||||||
requestModelBuild()
|
requestModelBuild()
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ class ThreadSummaryController @Inject constructor(
|
||||||
safeViewState.rootThreadEventList.invoke()
|
safeViewState.rootThreadEventList.invoke()
|
||||||
?.forEach { timelineEvent ->
|
?.forEach { timelineEvent ->
|
||||||
val date = dateFormatter.format(timelineEvent.root.originServerTs, DateFormatKind.ROOM_LIST)
|
val date = dateFormatter.format(timelineEvent.root.originServerTs, DateFormatKind.ROOM_LIST)
|
||||||
threadSummary {
|
threadList {
|
||||||
id(timelineEvent.eventId)
|
id(timelineEvent.eventId)
|
||||||
avatarRenderer(host.avatarRenderer)
|
avatarRenderer(host.avatarRenderer)
|
||||||
matrixItem(timelineEvent.senderInfo.toMatrixItem())
|
matrixItem(timelineEvent.senderInfo.toMatrixItem())
|
|
@ -31,23 +31,23 @@ import kotlinx.coroutines.flow.map
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.flow.flow
|
import org.matrix.android.sdk.flow.flow
|
||||||
|
|
||||||
class ThreadSummaryViewModel @AssistedInject constructor(@Assisted val initialState: ThreadSummaryViewState,
|
class ThreadListViewModel @AssistedInject constructor(@Assisted val initialState: ThreadListViewState,
|
||||||
private val session: Session) :
|
private val session: Session) :
|
||||||
VectorViewModel<ThreadSummaryViewState, EmptyAction, EmptyViewEvents>(initialState) {
|
VectorViewModel<ThreadListViewState, EmptyAction, EmptyViewEvents>(initialState) {
|
||||||
|
|
||||||
private val room = session.getRoom(initialState.roomId)
|
private val room = session.getRoom(initialState.roomId)
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
interface Factory {
|
||||||
fun create(initialState: ThreadSummaryViewState): ThreadSummaryViewModel
|
fun create(initialState: ThreadListViewState): ThreadListViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : MavericksViewModelFactory<ThreadSummaryViewModel, ThreadSummaryViewState> {
|
companion object : MavericksViewModelFactory<ThreadListViewModel, ThreadListViewState> {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
override fun create(viewModelContext: ViewModelContext, state: ThreadSummaryViewState): ThreadSummaryViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: ThreadListViewState): ThreadListViewModel? {
|
||||||
val fragment: ThreadListFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
val fragment: ThreadListFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
return fragment.threadSummaryViewModelFactory.create(state)
|
return fragment.threadListViewModelFactory.create(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import com.airbnb.mvrx.Uninitialized
|
||||||
import im.vector.app.features.home.room.threads.arguments.ThreadListArgs
|
import im.vector.app.features.home.room.threads.arguments.ThreadListArgs
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
|
|
||||||
data class ThreadSummaryViewState(
|
data class ThreadListViewState(
|
||||||
val rootThreadEventList: Async<List<TimelineEvent>> = Uninitialized,
|
val rootThreadEventList: Async<List<TimelineEvent>> = Uninitialized,
|
||||||
val shouldFilterThreads: Boolean = false,
|
val shouldFilterThreads: Boolean = false,
|
||||||
val roomId: String
|
val roomId: String
|
|
@ -20,14 +20,13 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.content.res.AppCompatResources.getDrawable
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.airbnb.mvrx.parentFragmentViewModel
|
import com.airbnb.mvrx.parentFragmentViewModel
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||||
import im.vector.app.databinding.BottomSheetThreadListBinding
|
import im.vector.app.databinding.BottomSheetThreadListBinding
|
||||||
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadSummaryViewModel
|
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadListViewModel
|
||||||
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadSummaryViewState
|
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadListViewState
|
||||||
|
|
||||||
class ThreadListBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetThreadListBinding>() {
|
class ThreadListBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetThreadListBinding>() {
|
||||||
|
|
||||||
|
@ -35,13 +34,12 @@ class ThreadListBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetThr
|
||||||
return BottomSheetThreadListBinding.inflate(inflater, container, false)
|
return BottomSheetThreadListBinding.inflate(inflater, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val threadListViewModel: ThreadListViewModel by parentFragmentViewModel()
|
||||||
private val threadListViewModel: ThreadSummaryViewModel by parentFragmentViewModel()
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
threadListViewModel.subscribe(this){
|
threadListViewModel.subscribe(this) {
|
||||||
renderState(it)
|
renderState(it)
|
||||||
}
|
}
|
||||||
views.threadListModalAllThreads.views.bottomSheetActionClickableZone.debouncedClicks {
|
views.threadListModalAllThreads.views.bottomSheetActionClickableZone.debouncedClicks {
|
||||||
|
@ -52,18 +50,11 @@ class ThreadListBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetThr
|
||||||
threadListViewModel.applyFiltering(true)
|
threadListViewModel.applyFiltering(true)
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderState(state: ThreadSummaryViewState) {
|
private fun renderState(state: ThreadListViewState) {
|
||||||
|
val tickDrawable = ContextCompat.getDrawable(requireContext(), R.drawable.ic_tick)
|
||||||
if(state.shouldFilterThreads){
|
views.threadListModalAllThreads.rightIcon = if (state.shouldFilterThreads) null else tickDrawable
|
||||||
views.threadListModalAllThreads.rightIcon = null
|
views.threadListModalMyThreads.rightIcon = if (state.shouldFilterThreads) tickDrawable else null
|
||||||
views.threadListModalMyThreads.rightIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_tick)
|
|
||||||
}else{
|
|
||||||
views.threadListModalAllThreads.rightIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_tick)
|
|
||||||
views.threadListModalMyThreads.rightIcon = null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,20 +34,20 @@ import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.home.room.detail.timeline.animation.TimelineItemAnimator
|
import im.vector.app.features.home.room.detail.timeline.animation.TimelineItemAnimator
|
||||||
import im.vector.app.features.home.room.threads.ThreadsActivity
|
import im.vector.app.features.home.room.threads.ThreadsActivity
|
||||||
import im.vector.app.features.home.room.threads.arguments.ThreadListArgs
|
import im.vector.app.features.home.room.threads.arguments.ThreadListArgs
|
||||||
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadSummaryController
|
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadListController
|
||||||
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadSummaryViewModel
|
import im.vector.app.features.home.room.threads.list.viewmodel.ThreadListViewModel
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import org.matrix.android.sdk.api.util.MatrixItem
|
import org.matrix.android.sdk.api.util.MatrixItem
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ThreadListFragment @Inject constructor(
|
class ThreadListFragment @Inject constructor(
|
||||||
private val avatarRenderer: AvatarRenderer,
|
private val avatarRenderer: AvatarRenderer,
|
||||||
private val threadSummaryController: ThreadSummaryController,
|
private val threadListController: ThreadListController,
|
||||||
val threadSummaryViewModelFactory: ThreadSummaryViewModel.Factory
|
val threadListViewModelFactory: ThreadListViewModel.Factory
|
||||||
) : VectorBaseFragment<FragmentThreadListBinding>(),
|
) : VectorBaseFragment<FragmentThreadListBinding>(),
|
||||||
ThreadSummaryController.Listener {
|
ThreadListController.Listener {
|
||||||
|
|
||||||
private val threadSummaryViewModel: ThreadSummaryViewModel by fragmentViewModel()
|
private val threadListViewModel: ThreadListViewModel by fragmentViewModel()
|
||||||
|
|
||||||
private val threadListArgs: ThreadListArgs by args()
|
private val threadListArgs: ThreadListArgs by args()
|
||||||
|
|
||||||
|
@ -74,13 +74,13 @@ class ThreadListFragment @Inject constructor(
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
initToolbar()
|
initToolbar()
|
||||||
views.threadListRecyclerView.configureWith(threadSummaryController, TimelineItemAnimator(), hasFixedSize = false)
|
views.threadListRecyclerView.configureWith(threadListController, TimelineItemAnimator(), hasFixedSize = false)
|
||||||
threadSummaryController.listener = this
|
threadListController.listener = this
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
views.threadListRecyclerView.cleanup()
|
views.threadListRecyclerView.cleanup()
|
||||||
threadSummaryController.listener = null
|
threadListController.listener = null
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +89,8 @@ class ThreadListFragment @Inject constructor(
|
||||||
renderToolbar()
|
renderToolbar()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invalidate() = withState(threadSummaryViewModel) { state ->
|
override fun invalidate() = withState(threadListViewModel) { state ->
|
||||||
threadSummaryController.update(state)
|
threadListController.update(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderToolbar() {
|
private fun renderToolbar() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<translate android:fromXDelta="-100%p" android:toXDelta="0"
|
<translate
|
||||||
|
android:fromXDelta="-100%p" android:toXDelta="0"
|
||||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||||
</set>
|
</set>
|
|
@ -1,5 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<translate android:fromXDelta="100%p" android:toXDelta="0"
|
<translate
|
||||||
|
android:startOffset="250"
|
||||||
|
android:fromXDelta="100%p" android:toXDelta="0"
|
||||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||||
</set>
|
</set>
|
|
@ -1,5 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<translate android:fromXDelta="0" android:toXDelta="-100%p"
|
<translate
|
||||||
|
android:startOffset="250"
|
||||||
|
android:fromXDelta="0" android:toXDelta="-100%p"
|
||||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||||
</set>
|
</set>
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<translate android:fromXDelta="0" android:toXDelta="100%p"
|
<translate
|
||||||
|
android:fromXDelta="0" android:toXDelta="100%p"
|
||||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||||
</set>
|
</set>
|
|
@ -34,7 +34,7 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:background="?android:colorBackground"
|
android:background="?android:colorBackground"
|
||||||
tools:listitem="@layout/item_thread_summary" />
|
tools:listitem="@layout/item_thread_list" />
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Add table
Reference in a new issue