Use awaitRoom on Timeline screen

This commit is contained in:
ganfra 2022-07-06 18:40:15 +02:00
parent 2acfce2d20
commit 12b681209f
5 changed files with 872 additions and 856 deletions

View File

@ -213,6 +213,7 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.billcarsonfr.jsonviewer.JSonViewerDialog
import org.commonmark.parser.Parser import org.commonmark.parser.Parser
@ -381,18 +382,20 @@ class TimelineFragment @Inject constructor(
) )
keyboardStateUtils = KeyboardStateUtils(requireActivity()) keyboardStateUtils = KeyboardStateUtils(requireActivity())
lazyLoadedViews.bind(views) lazyLoadedViews.bind(views)
setupToolbar(views.roomToolbar) viewLifecycleOwner.lifecycleScope.launch {
.allowBack() setupToolbar(views.roomToolbar)
setupRecyclerView() .allowBack()
setupComposer() setupRecyclerView()
setupNotificationView() setupComposer()
setupJumpToReadMarkerView() setupNotificationView()
setupActiveCallView() setupJumpToReadMarkerView()
setupJumpToBottomView() setupActiveCallView()
setupEmojiButton() setupJumpToBottomView()
setupRemoveJitsiWidgetView() setupEmojiButton()
setupVoiceMessageView() setupRemoveJitsiWidgetView()
setupLiveLocationIndicator() setupVoiceMessageView()
setupLiveLocationIndicator()
}
views.includeRoomToolbar.roomToolbarContentView.debouncedClicks { views.includeRoomToolbar.roomToolbarContentView.debouncedClicks {
navigator.openRoomProfile(requireActivity(), timelineArgs.roomId) navigator.openRoomProfile(requireActivity(), timelineArgs.roomId)
@ -979,16 +982,17 @@ class TimelineFragment @Inject constructor(
private fun setupJumpToBottomView() { private fun setupJumpToBottomView() {
views.jumpToBottomView.visibility = View.INVISIBLE views.jumpToBottomView.visibility = View.INVISIBLE
views.jumpToBottomView.debouncedClicks { views.jumpToBottomView.debouncedClicks {
timelineViewModel.handle(RoomDetailAction.ExitTrackingUnreadMessagesState) viewLifecycleOwner.lifecycleScope.launch {
views.jumpToBottomView.visibility = View.INVISIBLE timelineViewModel.handle(RoomDetailAction.ExitTrackingUnreadMessagesState)
if (!timelineViewModel.timeline.isLive) { views.jumpToBottomView.visibility = View.INVISIBLE
scrollOnNewMessageCallback.forceScrollOnNextUpdate() if (!timelineViewModel.timeline.await().isLive) {
timelineViewModel.timeline.restartWithEventId(null) scrollOnNewMessageCallback.forceScrollOnNextUpdate()
} else { timelineViewModel.timeline.await().restartWithEventId(null)
layoutManager.scrollToPosition(0) } else {
layoutManager.scrollToPosition(0)
}
} }
} }
jumpToBottomViewVisibilityManager = JumpToBottomViewVisibilityManager( jumpToBottomViewVisibilityManager = JumpToBottomViewVisibilityManager(
views.jumpToBottomView, views.jumpToBottomView,
debouncer, debouncer,
@ -1216,12 +1220,14 @@ class TimelineFragment @Inject constructor(
} }
private fun handleSearchAction() { private fun handleSearchAction() {
navigator.openSearch( viewLifecycleOwner.lifecycleScope.launch {
context = requireContext(), navigator.openSearch(
roomId = timelineArgs.roomId, context = requireContext(),
roomDisplayName = timelineViewModel.getRoomSummary()?.displayName, roomId = timelineArgs.roomId,
roomAvatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl roomDisplayName = timelineViewModel.getRoomSummary()?.displayName,
) roomAvatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl
)
}
} }
private fun displayDisabledIntegrationDialog() { private fun displayDisabledIntegrationDialog() {
@ -1416,9 +1422,9 @@ class TimelineFragment @Inject constructor(
// PRIVATE METHODS ***************************************************************************** // PRIVATE METHODS *****************************************************************************
private fun setupRecyclerView() { private suspend fun setupRecyclerView() {
timelineEventController.callback = this timelineEventController.callback = this
timelineEventController.timeline = timelineViewModel.timeline timelineEventController.timeline = timelineViewModel.timeline.await()
views.timelineRecyclerView.trackItemsVisibilityChange() views.timelineRecyclerView.trackItemsVisibilityChange()
layoutManager = object : LinearLayoutManager(context, RecyclerView.VERTICAL, true) { layoutManager = object : LinearLayoutManager(context, RecyclerView.VERTICAL, true) {
@ -2421,7 +2427,9 @@ class TimelineFragment @Inject constructor(
views.composerLayout.views.composerEditText.setText(Command.EMOTE.command + " ") views.composerLayout.views.composerEditText.setText(Command.EMOTE.command + " ")
views.composerLayout.views.composerEditText.setSelection(Command.EMOTE.command.length + 1) views.composerLayout.views.composerEditText.setSelection(Command.EMOTE.command.length + 1)
} else { } else {
val roomMember = timelineViewModel.getMember(userId) val roomMember = runBlocking {
timelineViewModel.getMember(userId)
}
// TODO move logic outside of fragment // TODO move logic outside of fragment
(roomMember?.displayName ?: userId) (roomMember?.displayName ?: userId)
.let { sanitizeDisplayName(it) } .let { sanitizeDisplayName(it) }
@ -2491,18 +2499,21 @@ class TimelineFragment @Inject constructor(
* using the ThreadsActivity. * using the ThreadsActivity.
*/ */
private fun navigateToThreadTimeline(rootThreadEventId: String, startsThread: Boolean = false, showKeyboard: Boolean = false) { private fun navigateToThreadTimeline(rootThreadEventId: String, startsThread: Boolean = false, showKeyboard: Boolean = false) {
analyticsTracker.capture(Interaction.Name.MobileRoomThreadSummaryItem.toAnalyticsInteraction()) viewLifecycleOwner.lifecycleScope.launch {
context?.let { analyticsTracker.capture(Interaction.Name.MobileRoomThreadSummaryItem.toAnalyticsInteraction())
val roomThreadDetailArgs = ThreadTimelineArgs( context?.let {
startsThread = startsThread, val roomSummary = timelineViewModel.awaitState().asyncRoomSummary()
roomId = timelineArgs.roomId, val roomThreadDetailArgs = ThreadTimelineArgs(
displayName = timelineViewModel.getRoomSummary()?.displayName, startsThread = startsThread,
avatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl, roomId = timelineArgs.roomId,
roomEncryptionTrustLevel = timelineViewModel.getRoomSummary()?.roomEncryptionTrustLevel, displayName = roomSummary?.displayName,
rootThreadEventId = rootThreadEventId, avatarUrl = roomSummary?.avatarUrl,
showKeyboard = showKeyboard roomEncryptionTrustLevel = roomSummary?.roomEncryptionTrustLevel,
) rootThreadEventId = rootThreadEventId,
navigator.openThread(it, roomThreadDetailArgs) showKeyboard = showKeyboard
)
navigator.openThread(it, roomThreadDetailArgs)
}
} }
} }
@ -2530,15 +2541,18 @@ class TimelineFragment @Inject constructor(
* using the ThreadsActivity. * using the ThreadsActivity.
*/ */
private fun navigateToThreadList() { private fun navigateToThreadList() {
analyticsTracker.capture(Interaction.Name.MobileRoomThreadListButton.toAnalyticsInteraction()) viewLifecycleOwner.lifecycleScope.launch {
context?.let { analyticsTracker.capture(Interaction.Name.MobileRoomThreadListButton.toAnalyticsInteraction())
val roomThreadDetailArgs = ThreadTimelineArgs( context?.let {
roomId = timelineArgs.roomId, val roomSummary = timelineViewModel.awaitState().asyncRoomSummary()
displayName = timelineViewModel.getRoomSummary()?.displayName, val roomThreadDetailArgs = ThreadTimelineArgs(
roomEncryptionTrustLevel = timelineViewModel.getRoomSummary()?.roomEncryptionTrustLevel, roomId = timelineArgs.roomId,
avatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl displayName = roomSummary?.displayName,
) roomEncryptionTrustLevel = roomSummary?.roomEncryptionTrustLevel,
navigator.openThreadList(it, roomThreadDetailArgs) avatarUrl = roomSummary?.avatarUrl
)
navigator.openThreadList(it, roomThreadDetailArgs)
}
} }
} }

View File

@ -20,6 +20,7 @@ import im.vector.app.features.call.vectorCallService
import im.vector.app.features.home.room.detail.timeline.helper.TimelineSettingsFactory import im.vector.app.features.home.room.detail.timeline.helper.TimelineSettingsFactory
import im.vector.app.features.home.room.detail.timeline.merged.MergedTimelines import im.vector.app.features.home.room.detail.timeline.merged.MergedTimelines
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.getRoom
@ -36,14 +37,14 @@ private val secondaryTimelineAllowedTypes = listOf(
class TimelineFactory @Inject constructor(private val session: Session, private val timelineSettingsFactory: TimelineSettingsFactory) { class TimelineFactory @Inject constructor(private val session: Session, private val timelineSettingsFactory: TimelineSettingsFactory) {
fun createTimeline( suspend fun createTimeline(
coroutineScope: CoroutineScope, coroutineScope: CoroutineScope,
mainRoom: Room, room: Deferred<Room>,
eventId: String?, eventId: String?,
rootThreadEventId: String? rootThreadEventId: String?
): Timeline { ): Timeline {
val settings = timelineSettingsFactory.create(rootThreadEventId) val settings = timelineSettingsFactory.create(rootThreadEventId)
val mainRoom = room.await()
if (!session.vectorCallService.protocolChecker.supportVirtualRooms) { if (!session.vectorCallService.protocolChecker.supportVirtualRooms) {
return mainRoom.timelineService().createTimeline(eventId, settings) return mainRoom.timelineService().createTimeline(eventId, settings)
} }

View File

@ -47,7 +47,7 @@ fun ElementWellKnown?.getOutboundSessionKeySharingStrategyOrDefault(): OutboundS
fun RawService.withElementWellKnown( fun RawService.withElementWellKnown(
coroutineScope: CoroutineScope, coroutineScope: CoroutineScope,
sessionParams: SessionParams, sessionParams: SessionParams,
block: ((ElementWellKnown?) -> Unit) block: suspend ((ElementWellKnown?) -> Unit)
) = with(coroutineScope) { ) = with(coroutineScope) {
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
block(getElementWellknown(sessionParams)) block(getElementWellknown(sessionParams))