diff --git a/vector/src/main/res/anim/animation_slide_in_left.xml b/library/ui-styles/src/main/res/anim/animation_slide_in_left.xml similarity index 100% rename from vector/src/main/res/anim/animation_slide_in_left.xml rename to library/ui-styles/src/main/res/anim/animation_slide_in_left.xml diff --git a/vector/src/main/res/anim/animation_slide_in_right.xml b/library/ui-styles/src/main/res/anim/animation_slide_in_right.xml similarity index 100% rename from vector/src/main/res/anim/animation_slide_in_right.xml rename to library/ui-styles/src/main/res/anim/animation_slide_in_right.xml diff --git a/vector/src/main/res/anim/animation_slide_out_left.xml b/library/ui-styles/src/main/res/anim/animation_slide_out_left.xml similarity index 100% rename from vector/src/main/res/anim/animation_slide_out_left.xml rename to library/ui-styles/src/main/res/anim/animation_slide_out_left.xml diff --git a/vector/src/main/res/anim/animation_slide_out_right.xml b/library/ui-styles/src/main/res/anim/animation_slide_out_right.xml similarity index 100% rename from vector/src/main/res/anim/animation_slide_out_right.xml rename to library/ui-styles/src/main/res/anim/animation_slide_out_right.xml diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt index 147eff6ab0..047aefe88d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt @@ -222,8 +222,8 @@ data class Event( private fun getDecryptedValue(key: String = "body"): String? { return if (isEncrypted()) { @Suppress("UNCHECKED_CAST") - val content = mxDecryptionResult?.payload?.get("content") as? JsonDict - content?.get(key) as? String + val decryptedContent = mxDecryptionResult?.payload?.get("content") as? JsonDict + decryptedContent?.get(key) as? String } else { content?.get(key) as? String } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/RelationType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/RelationType.kt index 18bb946462..fb26264ad7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/RelationType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/RelationType.kt @@ -28,7 +28,7 @@ object RelationType { /** Lets you define an event which references an existing event.*/ const val REFERENCE = "m.reference" - /** Lets you define an event which is a reply to an existing event.*/ + /** Lets you define an event which is a thread reply to an existing event.*/ const val THREAD = "m.thread" const val IO_THREAD = "io.element.thread" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineService.kt index bf48353918..aefda755f1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineService.kt @@ -57,13 +57,13 @@ interface TimelineService { fun getAttachmentMessages(): List /** - * Get a live list of all the thread for the specified roomId + * Get a live list of all the TimelineEvents which have thread replies for the specified roomId * @return the [LiveData] of [TimelineEvent] */ fun getAllThreadsLive(): LiveData> /** - * Get a list of all the thread for the specified roomId + * Get a list of all the TimelineEvents which have thread replies for the specified roomId * @return the [LiveData] of [TimelineEvent] */ fun getAllThreads(): List diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt index 58cc3a0706..8566d68aa5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt @@ -27,7 +27,7 @@ enum class ThreadNotificationState { // There is at least one new message NEW_MESSAGE, - // The is at least one new message that should bi highlighted + // The is at least one new message that should be highlighted // ex. "Hello @aris.kotsomitopoulos" NEW_HIGHLIGHTED_MESSAGE; } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadMoreResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadMoreResult.kt index 2949e35bd3..c419e8325e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadMoreResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadMoreResult.kt @@ -20,5 +20,4 @@ internal enum class LoadMoreResult { REACHED_END, SUCCESS, FAILURE - // evenIDS } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt index 24854b601f..ee606d1fac 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt @@ -223,7 +223,7 @@ internal class ThreadsAwarenessHandler @Inject constructor( body) val messageTextContent = MessageTextContent( - msgType = "m.text", + msgType = MessageType.MSGTYPE_TEXT, format = MessageFormat.FORMAT_MATRIX_HTML, body = body, formattedBody = replyFormatted diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 83ebefb658..b954634129 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -203,7 +203,7 @@ interface FragmentModule { @Binds @IntoMap @FragmentKey(TimelineFragment::class) - fun bindRoomDetailFragment(fragment: TimelineFragment): Fragment + fun bindTimelineFragment(fragment: TimelineFragment): Fragment @Binds @IntoMap @@ -933,7 +933,7 @@ interface FragmentModule { @Binds @IntoMap @FragmentKey(ThreadListFragment::class) - fun bindRoomThreadDetailFragment(fragment: ThreadListFragment): Fragment + fun bindThreadListFragment(fragment: ThreadListFragment): Fragment @Binds @IntoMap diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index cc31a7dca6..98b1a5d048 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -44,7 +44,7 @@ import im.vector.app.features.home.UnknownDeviceDetectorSharedViewModel import im.vector.app.features.home.UnreadMessagesSharedViewModel import im.vector.app.features.home.UserColorAccountDataViewModel import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsViewModel -import im.vector.app.features.home.room.detail.RoomDetailViewModel +import im.vector.app.features.home.room.detail.TimelineViewModel import im.vector.app.features.home.room.detail.composer.MessageComposerViewModel import im.vector.app.features.home.room.detail.search.SearchViewModel import im.vector.app.features.home.room.detail.timeline.action.MessageActionsViewModel @@ -536,8 +536,8 @@ interface MavericksViewModelModule { @Binds @IntoMap - @MavericksViewModelKey(RoomDetailViewModel::class) - fun roomDetailViewModelFactory(factory: RoomDetailViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + @MavericksViewModelKey(TimelineViewModel::class) + fun roomDetailViewModelFactory(factory: TimelineViewModel.Factory): MavericksAssistedViewModelFactory<*, *> @Binds @IntoMap diff --git a/vector/src/main/java/im/vector/app/core/extensions/TextView.kt b/vector/src/main/java/im/vector/app/core/extensions/TextView.kt index c0911aec8b..8e7b6a4a80 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/TextView.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/TextView.kt @@ -126,7 +126,7 @@ fun TextView.setLeftDrawable(@DrawableRes iconRes: Int, @AttrRes tintColor: Int? } fun TextView.clearDrawables() { - this.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) + setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) } /** diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt index ba559677c9..99843084ec 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt @@ -44,7 +44,7 @@ class JoinReplacementRoomBottomSheet : @Inject lateinit var errorFormatter: ErrorFormatter - private val viewModel: RoomDetailViewModel by parentFragmentViewModel() + private val viewModel: TimelineViewModel by parentFragmentViewModel() override val showExpanded: Boolean get() = true diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/StartCallActionsHandler.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/StartCallActionsHandler.kt index 6b5ed3ba66..193dc42f33 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/StartCallActionsHandler.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/StartCallActionsHandler.kt @@ -32,7 +32,7 @@ class StartCallActionsHandler( private val fragment: Fragment, private val callManager: WebRtcCallManager, private val vectorPreferences: VectorPreferences, - private val roomDetailViewModel: RoomDetailViewModel, + private val timelineViewModel: TimelineViewModel, private val startCallActivityResultLauncher: ActivityResultLauncher>, private val showDialogWithMessage: (String) -> Unit, private val onTapToReturnToCall: () -> Unit) { @@ -45,7 +45,7 @@ class StartCallActionsHandler( handleCallRequest(false) } - private fun handleCallRequest(isVideoCall: Boolean) = withState(roomDetailViewModel) { state -> + private fun handleCallRequest(isVideoCall: Boolean) = withState(timelineViewModel) { state -> val roomSummary = state.asyncRoomSummary.invoke() ?: return@withState when (roomSummary.joinedMembersCount) { 1 -> { @@ -95,7 +95,7 @@ class StartCallActionsHandler( .setMessage(R.string.audio_video_meeting_description) .setPositiveButton(fragment.getString(R.string.create)) { _, _ -> // create the widget, then navigate to it.. - roomDetailViewModel.handle(RoomDetailAction.AddJitsiWidget(isVideoCall)) + timelineViewModel.handle(RoomDetailAction.AddJitsiWidget(isVideoCall)) } .setNegativeButton(fragment.getString(R.string.action_cancel), null) .show() @@ -121,22 +121,22 @@ class StartCallActionsHandler( private fun safeStartCall2(isVideoCall: Boolean) { val startCallAction = RoomDetailAction.StartCall(isVideoCall) - roomDetailViewModel.pendingAction = startCallAction + timelineViewModel.pendingAction = startCallAction if (isVideoCall) { if (checkPermissions(PERMISSIONS_FOR_VIDEO_IP_CALL, fragment.requireActivity(), startCallActivityResultLauncher, R.string.permissions_rationale_msg_camera_and_audio)) { - roomDetailViewModel.pendingAction = null - roomDetailViewModel.handle(startCallAction) + timelineViewModel.pendingAction = null + timelineViewModel.handle(startCallAction) } } else { if (checkPermissions(PERMISSIONS_FOR_AUDIO_IP_CALL, fragment.requireActivity(), startCallActivityResultLauncher, R.string.permissions_rationale_msg_record_audio)) { - roomDetailViewModel.pendingAction = null - roomDetailViewModel.handle(startCallAction) + timelineViewModel.pendingAction = null + timelineViewModel.handle(startCallAction) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 2c4ac2d9d7..1401a045fc 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -117,7 +117,7 @@ import im.vector.app.core.utils.shareText import im.vector.app.core.utils.startInstallFromSourceIntent import im.vector.app.core.utils.toast import im.vector.app.databinding.DialogReportContentBinding -import im.vector.app.databinding.FragmentRoomDetailBinding +import im.vector.app.databinding.FragmentTimelineBinding import im.vector.app.features.attachments.AttachmentTypeSelectorView import im.vector.app.features.attachments.AttachmentsHelper import im.vector.app.features.attachments.ContactAttachment @@ -255,7 +255,7 @@ class TimelineFragment @Inject constructor( private val voiceMessagePlaybackTracker: VoiceMessagePlaybackTracker, private val clock: Clock ) : - VectorBaseFragment(), + VectorBaseFragment(), TimelineEventController.Callback, VectorInviteView.Callback, AttachmentTypeSelectorView.Callback, @@ -295,15 +295,15 @@ class TimelineFragment @Inject constructor( autoCompleterFactory.create(timelineArgs.roomId, isThreadTimeLine()) } - private val roomDetailViewModel: RoomDetailViewModel by fragmentViewModel() + private val timelineViewModel: TimelineViewModel by fragmentViewModel() private val messageComposerViewModel: MessageComposerViewModel by fragmentViewModel() private val debouncer = Debouncer(createUIHandler()) private lateinit var scrollOnNewMessageCallback: ScrollOnNewMessageCallback private lateinit var scrollOnHighlightedEventCallback: ScrollOnHighlightedEventCallback - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomDetailBinding { - return FragmentRoomDetailBinding.inflate(inflater, container, false) + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentTimelineBinding { + return FragmentTimelineBinding.inflate(inflater, container, false) } override fun getMenuRes() = R.menu.menu_timeline @@ -335,7 +335,7 @@ class TimelineFragment @Inject constructor( super.onCreate(savedInstanceState) setFragmentResultListener(MigrateRoomBottomSheet.REQUEST_KEY) { _, bundle -> bundle.getString(MigrateRoomBottomSheet.BUNDLE_KEY_REPLACEMENT_ROOM)?.let { replacementRoomId -> - roomDetailViewModel.handle(RoomDetailAction.RoomUpgradeSuccess(replacementRoomId)) + timelineViewModel.handle(RoomDetailAction.RoomUpgradeSuccess(replacementRoomId)) } } } @@ -351,7 +351,7 @@ class TimelineFragment @Inject constructor( roomId = timelineArgs.roomId, fragment = this, vectorPreferences = vectorPreferences, - roomDetailViewModel = roomDetailViewModel, + timelineViewModel = timelineViewModel, callManager = callManager, startCallActivityResultLauncher = startCallActivityResultLauncher, showDialogWithMessage = ::showDialogWithMessage, @@ -388,7 +388,7 @@ class TimelineFragment @Inject constructor( invalidateOptionsMenu() } - roomDetailViewModel.onEach(RoomDetailViewState::canShowJumpToReadMarker, RoomDetailViewState::unreadState) { _, _ -> + timelineViewModel.onEach(RoomDetailViewState::canShowJumpToReadMarker, RoomDetailViewState::unreadState) { _, _ -> updateJumpToReadMarkerViewVisibility() } @@ -405,7 +405,7 @@ class TimelineFragment @Inject constructor( } } - roomDetailViewModel.onEach( + timelineViewModel.onEach( RoomDetailViewState::syncState, RoomDetailViewState::incrementalSyncStatus, RoomDetailViewState::pushCounter @@ -435,7 +435,7 @@ class TimelineFragment @Inject constructor( }.exhaustive } - roomDetailViewModel.observeViewEvents { + timelineViewModel.observeViewEvents { when (it) { is RoomDetailViewEvents.Failure -> showErrorInSnackbar(it.throwable) is RoomDetailViewEvents.OnNewTimelineEvents -> scrollOnNewMessageCallback.addNewTimelineEventIds(it.eventIds) @@ -501,12 +501,12 @@ class TimelineFragment @Inject constructor( private fun setupRemoveJitsiWidgetView() { views.removeJitsiWidgetView.onCompleteSliding = { - withState(roomDetailViewModel) { + withState(timelineViewModel) { val jitsiWidgetId = it.jitsiState.widgetId ?: return@withState if (it.jitsiState.hasJoined) { leaveJitsiConference() } - roomDetailViewModel.handle(RoomDetailAction.RemoveWidget(jitsiWidgetId)) + timelineViewModel.handle(RoomDetailAction.RemoveWidget(jitsiWidgetId)) } } } @@ -516,7 +516,7 @@ class TimelineFragment @Inject constructor( } private fun onBroadcastJitsiEvent(conferenceEvent: ConferenceEvent) { - roomDetailViewModel.handle(RoomDetailAction.UpdateJoinJitsiCallStatus(conferenceEvent)) + timelineViewModel.handle(RoomDetailAction.UpdateJoinJitsiCallStatus(conferenceEvent)) } private fun onCannotRecord() { @@ -577,7 +577,7 @@ class TimelineFragment @Inject constructor( override fun onImageReady(uri: Uri?) { uri ?: return - roomDetailViewModel.handle( + timelineViewModel.handle( RoomDetailAction.SetAvatarAction( newAvatarUri = uri, newAvatarFileName = getFilenameFromUri(requireContext(), uri) ?: UUID.randomUUID().toString() @@ -616,7 +616,7 @@ class TimelineFragment @Inject constructor( ).apply { directListener = { granted -> if (granted) { - roomDetailViewModel.handle(RoomDetailAction.EnsureNativeWidgetAllowed( + timelineViewModel.handle(RoomDetailAction.EnsureNativeWidgetAllowed( widget = it.widget, userJustAccepted = true, grantedEvents = it.grantedEvents @@ -696,13 +696,13 @@ class TimelineFragment @Inject constructor( .setMessage(getString(R.string.event_status_delete_all_failed_dialog_message)) .setNegativeButton(R.string.no, null) .setPositiveButton(R.string.yes) { _, _ -> - roomDetailViewModel.handle(RoomDetailAction.RemoveAllFailedMessages) + timelineViewModel.handle(RoomDetailAction.RemoveAllFailedMessages) } .show() } override fun onRetryClicked() { - roomDetailViewModel.handle(RoomDetailAction.ResendAll) + timelineViewModel.handle(RoomDetailAction.ResendAll) } } } @@ -799,7 +799,7 @@ class TimelineFragment @Inject constructor( val safeContext = context ?: return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (!safeContext.packageManager.canRequestPackageInstalls()) { - roomDetailViewModel.pendingEvent = action + timelineViewModel.pendingEvent = action startInstallFromSourceIntent(safeContext, installApkActivityResultLauncher) } else { openFile(action) @@ -811,7 +811,7 @@ class TimelineFragment @Inject constructor( private val installApkActivityResultLauncher = registerStartForActivityResult { activityResult -> if (activityResult.resultCode == Activity.RESULT_OK) { - roomDetailViewModel.pendingEvent?.let { + timelineViewModel.pendingEvent?.let { if (it is RoomDetailViewEvents.OpenFile) { openFile(it) } @@ -819,7 +819,7 @@ class TimelineFragment @Inject constructor( } else { // User cancelled } - roomDetailViewModel.pendingEvent = null + timelineViewModel.pendingEvent = null } private fun displayPromptForIntegrationManager() { @@ -879,18 +879,18 @@ class TimelineFragment @Inject constructor( } override fun onDestroy() { - roomDetailViewModel.handle(RoomDetailAction.ExitTrackingUnreadMessagesState) + timelineViewModel.handle(RoomDetailAction.ExitTrackingUnreadMessagesState) super.onDestroy() } private fun setupJumpToBottomView() { views.jumpToBottomView.visibility = View.INVISIBLE views.jumpToBottomView.debouncedClicks { - roomDetailViewModel.handle(RoomDetailAction.ExitTrackingUnreadMessagesState) + timelineViewModel.handle(RoomDetailAction.ExitTrackingUnreadMessagesState) views.jumpToBottomView.visibility = View.INVISIBLE - if (!roomDetailViewModel.timeline.isLive) { + if (!timelineViewModel.timeline.isLive) { scrollOnNewMessageCallback.forceScrollOnNextUpdate() - roomDetailViewModel.timeline.restartWithEventId(null) + timelineViewModel.timeline.restartWithEventId(null) } else { layoutManager.scrollToPosition(0) } @@ -909,7 +909,7 @@ class TimelineFragment @Inject constructor( onJumpToReadMarkerClicked() } views.jumpToReadMarkerView.setOnCloseIconClickListener { - roomDetailViewModel.handle(RoomDetailAction.MarkAllAsRead) + timelineViewModel.handle(RoomDetailAction.MarkAllAsRead) } } @@ -952,11 +952,11 @@ class TimelineFragment @Inject constructor( private fun setupNotificationView() { views.notificationAreaView.delegate = object : NotificationAreaView.Delegate { override fun onTombstoneEventClicked() { - roomDetailViewModel.handle(RoomDetailAction.JoinAndOpenReplacementRoom) + timelineViewModel.handle(RoomDetailAction.JoinAndOpenReplacementRoom) } override fun onMisconfiguredEncryptionClicked() { - roomDetailViewModel.handle(RoomDetailAction.OnClickMisconfiguredEncryption) + timelineViewModel.handle(RoomDetailAction.OnClickMisconfiguredEncryption) } } } @@ -971,7 +971,7 @@ class TimelineFragment @Inject constructor( } val joinConfItem = menu.findItem(R.id.join_conference) (joinConfItem.actionView as? JoinConferenceView)?.onJoinClicked = { - roomDetailViewModel.handle(RoomDetailAction.JoinJitsiCall) + timelineViewModel.handle(RoomDetailAction.JoinJitsiCall) } // Custom thread notification menu item @@ -984,10 +984,10 @@ class TimelineFragment @Inject constructor( override fun onPrepareOptionsMenu(menu: Menu) { menu.forEach { - it.isVisible = roomDetailViewModel.isMenuItemVisible(it.itemId) + it.isVisible = timelineViewModel.isMenuItemVisible(it.itemId) } - withState(roomDetailViewModel) { state -> + withState(timelineViewModel) { state -> // Set the visual state of the call buttons (voice/video) to enabled/disabled according to user permissions val hasCallInRoom = callManager.getCallsByRoomId(state.roomId).isNotEmpty() || state.jitsiState.hasJoined val callButtonsEnabled = !hasCallInRoom && when (state.asyncRoomSummary.invoke()?.joinedMembersCount) { @@ -1035,7 +1035,7 @@ class TimelineFragment @Inject constructor( true } R.id.open_matrix_apps -> { - roomDetailViewModel.handle(RoomDetailAction.ManageIntegrations) + timelineViewModel.handle(RoomDetailAction.ManageIntegrations) true } R.id.voice_call -> { @@ -1123,8 +1123,8 @@ class TimelineFragment @Inject constructor( navigator.openSearch( context = requireContext(), roomId = timelineArgs.roomId, - roomDisplayName = roomDetailViewModel.getRoomSummary()?.displayName, - roomAvatarUrl = roomDetailViewModel.getRoomSummary()?.avatarUrl + roomDisplayName = timelineViewModel.getRoomSummary()?.displayName, + roomAvatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl ) } else { showDialogWithMessage(getString(R.string.search_is_not_supported_in_e2e_room)) @@ -1219,11 +1219,11 @@ class TimelineFragment @Inject constructor( private fun handlePendingAction(roomDetailPendingAction: RoomDetailPendingAction) { when (roomDetailPendingAction) { is RoomDetailPendingAction.JumpToReadReceipt -> - roomDetailViewModel.handle(RoomDetailAction.JumpToReadReceipt(roomDetailPendingAction.userId)) + timelineViewModel.handle(RoomDetailAction.JumpToReadReceipt(roomDetailPendingAction.userId)) is RoomDetailPendingAction.MentionUser -> insertUserDisplayNameInTextEditor(roomDetailPendingAction.userId) is RoomDetailPendingAction.OpenOrCreateDm -> - roomDetailViewModel.handle(RoomDetailAction.OpenOrCreateDm(roomDetailPendingAction.userId)) + timelineViewModel.handle(RoomDetailAction.OpenOrCreateDm(roomDetailPendingAction.userId)) is RoomDetailPendingAction.OpenRoom -> handleOpenRoom(RoomDetailViewEvents.OpenRoom(roomDetailPendingAction.roomId, roomDetailPendingAction.closeCurrentRoom)) }.exhaustive @@ -1276,7 +1276,7 @@ class TimelineFragment @Inject constructor( if (activityResult.resultCode == Activity.RESULT_OK) { val sendData = AttachmentsPreviewActivity.getOutput(data) val keepOriginalSize = AttachmentsPreviewActivity.getKeepOriginalSize(data) - roomDetailViewModel.handle(RoomDetailAction.SendMedia(sendData, !keepOriginalSize)) + timelineViewModel.handle(RoomDetailAction.SendMedia(sendData, !keepOriginalSize)) } } @@ -1285,7 +1285,7 @@ class TimelineFragment @Inject constructor( val eventId = EmojiReactionPickerActivity.getOutputEventId(activityResult.data) val reaction = EmojiReactionPickerActivity.getOutputReaction(activityResult.data) if (eventId != null && reaction != null) { - roomDetailViewModel.handle(RoomDetailAction.SendReaction(eventId, reaction)) + timelineViewModel.handle(RoomDetailAction.SendReaction(eventId, reaction)) } } } @@ -1295,16 +1295,16 @@ class TimelineFragment @Inject constructor( if (activityResult.resultCode == Activity.RESULT_OK) { WidgetActivity.getOutput(data).toModel() ?.let { content -> - roomDetailViewModel.handle(RoomDetailAction.SendSticker(content)) + timelineViewModel.handle(RoomDetailAction.SendSticker(content)) } } } private val startCallActivityResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently -> if (allGranted) { - (roomDetailViewModel.pendingAction as? RoomDetailAction.StartCall)?.let { - roomDetailViewModel.pendingAction = null - roomDetailViewModel.handle(it) + (timelineViewModel.pendingAction as? RoomDetailAction.StartCall)?.let { + timelineViewModel.pendingAction = null + timelineViewModel.handle(it) } } else { if (deniedPermanently) { @@ -1318,7 +1318,7 @@ class TimelineFragment @Inject constructor( private fun setupRecyclerView() { timelineEventController.callback = this - timelineEventController.timeline = roomDetailViewModel.timeline + timelineEventController.timeline = timelineViewModel.timeline views.timelineRecyclerView.trackItemsVisibilityChange() layoutManager = object : LinearLayoutManager(context, RecyclerView.VERTICAL, true) { @@ -1388,7 +1388,7 @@ class TimelineFragment @Inject constructor( private fun updateJumpToReadMarkerViewVisibility() { if (isThreadTimeLine()) return viewLifecycleOwner.lifecycleScope.launchWhenResumed { - val state = roomDetailViewModel.awaitState() + val state = timelineViewModel.awaitState() val showJumpToUnreadBanner = when (state.unreadState) { UnreadState.Unknown, UnreadState.HasNoUnread -> false @@ -1500,7 +1500,7 @@ class TimelineFragment @Inject constructor( views.composerLayout.views.composerEditText.focusChanges() .onEach { - roomDetailViewModel.handle(RoomDetailAction.ComposerFocusChange(it)) + timelineViewModel.handle(RoomDetailAction.ComposerFocusChange(it)) } .launchIn(viewLifecycleOwner.lifecycleScope) } @@ -1514,7 +1514,7 @@ class TimelineFragment @Inject constructor( return isHandled } - override fun invalidate() = withState(roomDetailViewModel, messageComposerViewModel) { mainState, messageComposerState -> + override fun invalidate() = withState(timelineViewModel, messageComposerViewModel) { mainState, messageComposerState -> invalidateOptionsMenu() val summary = mainState.asyncRoomSummary() renderToolbar(summary, mainState.formattedTypingUsers) @@ -1568,7 +1568,7 @@ class TimelineFragment @Inject constructor( } } - private fun FragmentRoomDetailBinding.hideComposerViews() { + private fun FragmentTimelineBinding.hideComposerViews() { composerLayout.isVisible = false voiceMessageRecorderView.isVisible = false } @@ -1679,7 +1679,7 @@ class TimelineFragment @Inject constructor( .setView(layout) .setPositiveButton(R.string.report_content_custom_submit) { _, _ -> val reason = views.dialogReportContentInput.text.toString() - roomDetailViewModel.handle(RoomDetailAction.ReportContent(action.eventId, action.senderId, reason)) + timelineViewModel.handle(RoomDetailAction.ReportContent(action.eventId, action.senderId, reason)) } .setNegativeButton(R.string.action_cancel, null) .show() @@ -1695,7 +1695,7 @@ class TimelineFragment @Inject constructor( reasonHintRes = R.string.delete_event_dialog_reason_hint, titleRes = action.dialogTitleRes ) { reason -> - roomDetailViewModel.handle(RoomDetailAction.RedactAction(action.eventId, reason)) + timelineViewModel.handle(RoomDetailAction.RedactAction(action.eventId, reason)) } } @@ -1717,7 +1717,7 @@ class TimelineFragment @Inject constructor( .setMessage(R.string.content_reported_as_spam_content) .setPositiveButton(R.string.ok, null) .setNegativeButton(R.string.block_user) { _, _ -> - roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId)) + timelineViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId)) } .show() } @@ -1727,7 +1727,7 @@ class TimelineFragment @Inject constructor( .setMessage(R.string.content_reported_as_inappropriate_content) .setPositiveButton(R.string.ok, null) .setNegativeButton(R.string.block_user) { _, _ -> - roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId)) + timelineViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId)) } .show() } @@ -1737,7 +1737,7 @@ class TimelineFragment @Inject constructor( .setMessage(R.string.content_reported_content) .setPositiveButton(R.string.ok, null) .setNegativeButton(R.string.block_user) { _, _ -> - roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId)) + timelineViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId)) } .show() } @@ -1791,7 +1791,7 @@ class TimelineFragment @Inject constructor( true } else { // Highlight and scroll to this event - roomDetailViewModel.handle(RoomDetailAction.NavigateToEvent(eventId, true)) + timelineViewModel.handle(RoomDetailAction.NavigateToEvent(eventId, true)) true } } else { @@ -1800,7 +1800,7 @@ class TimelineFragment @Inject constructor( true } else if (rootThreadEventId == getRootThreadEventId() && eventId != null) { // we are in the same thread - roomDetailViewModel.handle(RoomDetailAction.NavigateToEvent(eventId, true)) + timelineViewModel.handle(RoomDetailAction.NavigateToEvent(eventId, true)) true } else { false @@ -1847,11 +1847,11 @@ class TimelineFragment @Inject constructor( } override fun onEventVisible(event: TimelineEvent) { - roomDetailViewModel.handle(RoomDetailAction.TimelineEventTurnsVisible(event)) + timelineViewModel.handle(RoomDetailAction.TimelineEventTurnsVisible(event)) } override fun onEventInvisible(event: TimelineEvent) { - roomDetailViewModel.handle(RoomDetailAction.TimelineEventTurnsInvisible(event)) + timelineViewModel.handle(RoomDetailAction.TimelineEventTurnsInvisible(event)) } override fun onEncryptedMessageClicked(informationData: MessageInformationData, view: View) { @@ -1896,7 +1896,7 @@ class TimelineFragment @Inject constructor( private fun cleanUpAfterPermissionNotGranted() { // Reset all pending data - roomDetailViewModel.pendingAction = null + timelineViewModel.pendingAction = null attachmentsHelper.pendingType = null } @@ -1905,23 +1905,23 @@ class TimelineFragment @Inject constructor( // } override fun onLoadMore(direction: Timeline.Direction) { - roomDetailViewModel.handle(RoomDetailAction.LoadMoreTimelineEvents(direction)) + timelineViewModel.handle(RoomDetailAction.LoadMoreTimelineEvents(direction)) } override fun onEventCellClicked(informationData: MessageInformationData, messageContent: Any?, view: View, isRootThreadEvent: Boolean) { when (messageContent) { is MessageVerificationRequestContent -> { - roomDetailViewModel.handle(RoomDetailAction.ResumeVerification(informationData.eventId, null)) + timelineViewModel.handle(RoomDetailAction.ResumeVerification(informationData.eventId, null)) } is MessageWithAttachmentContent -> { val action = RoomDetailAction.DownloadOrOpen(informationData.eventId, informationData.senderId, messageContent) - roomDetailViewModel.handle(action) + timelineViewModel.handle(action) } is EncryptedEventContent -> { if (isRootThreadEvent) { onThreadSummaryClicked(informationData.eventId, isRootThreadEvent) } else { - roomDetailViewModel.handle(RoomDetailAction.TapOnFailedToDecrypt(informationData.eventId)) + timelineViewModel.handle(RoomDetailAction.TapOnFailedToDecrypt(informationData.eventId)) } } else -> { @@ -1944,14 +1944,14 @@ class TimelineFragment @Inject constructor( private fun handleCancelSend(action: EventSharedAction.Cancel) { if (action.force) { - roomDetailViewModel.handle(RoomDetailAction.CancelSend(action.eventId, true)) + timelineViewModel.handle(RoomDetailAction.CancelSend(action.eventId, true)) } else { MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.dialog_title_confirmation) .setMessage(getString(R.string.event_status_cancel_sending_dialog_message)) .setNegativeButton(R.string.no, null) .setPositiveButton(R.string.yes) { _, _ -> - roomDetailViewModel.handle(RoomDetailAction.CancelSend(action.eventId, false)) + timelineViewModel.handle(RoomDetailAction.CancelSend(action.eventId, false)) } .show() } @@ -1979,10 +1979,10 @@ class TimelineFragment @Inject constructor( override fun onClickOnReactionPill(informationData: MessageInformationData, reaction: String, on: Boolean) { if (on) { // we should test the current real state of reaction on this event - roomDetailViewModel.handle(RoomDetailAction.SendReaction(informationData.eventId, reaction)) + timelineViewModel.handle(RoomDetailAction.SendReaction(informationData.eventId, reaction)) } else { // I need to redact a reaction - roomDetailViewModel.handle(RoomDetailAction.UndoReaction(informationData.eventId, reaction)) + timelineViewModel.handle(RoomDetailAction.UndoReaction(informationData.eventId, reaction)) } } @@ -1997,11 +1997,11 @@ class TimelineFragment @Inject constructor( } override fun onTimelineItemAction(itemAction: RoomDetailAction) { - roomDetailViewModel.handle(itemAction) + timelineViewModel.handle(itemAction) } override fun getPreviewUrlRetriever(): PreviewUrlRetriever { - return roomDetailViewModel.previewUrlRetriever + return timelineViewModel.previewUrlRetriever } override fun onRoomCreateLinkClicked(url: String) { @@ -2022,7 +2022,7 @@ class TimelineFragment @Inject constructor( } override fun onReadMarkerVisible() { - roomDetailViewModel.handle(RoomDetailAction.EnterTrackingUnreadMessagesState) + timelineViewModel.handle(RoomDetailAction.EnterTrackingUnreadMessagesState) } override fun onPreviewUrlClicked(url: String) { @@ -2030,7 +2030,7 @@ class TimelineFragment @Inject constructor( } override fun onPreviewUrlCloseClicked(eventId: String, url: String) { - roomDetailViewModel.handle(RoomDetailAction.DoNotShowPreviewUrlFor(eventId, url)) + timelineViewModel.handle(RoomDetailAction.DoNotShowPreviewUrlFor(eventId, url)) } override fun onPreviewUrlImageClicked(sharedView: View?, mxcUrl: String?, title: String?) { @@ -2140,7 +2140,7 @@ class TimelineFragment @Inject constructor( } is EventSharedAction.QuickReact -> { // eventId,ClickedOn,Add - roomDetailViewModel.handle(RoomDetailAction.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) + timelineViewModel.handle(RoomDetailAction.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) } is EventSharedAction.Edit -> { if (withState(messageComposerViewModel) { it.isVoiceMessageIdle }) { @@ -2179,20 +2179,20 @@ class TimelineFragment @Inject constructor( showSnackWithMessage(getString(R.string.copied_to_clipboard)) } is EventSharedAction.Resend -> { - roomDetailViewModel.handle(RoomDetailAction.ResendMessage(action.eventId)) + timelineViewModel.handle(RoomDetailAction.ResendMessage(action.eventId)) } is EventSharedAction.Remove -> { - roomDetailViewModel.handle(RoomDetailAction.RemoveFailedEcho(action.eventId)) + timelineViewModel.handle(RoomDetailAction.RemoveFailedEcho(action.eventId)) } is EventSharedAction.Cancel -> { handleCancelSend(action) } is EventSharedAction.ReportContentSpam -> { - roomDetailViewModel.handle(RoomDetailAction.ReportContent( + timelineViewModel.handle(RoomDetailAction.ReportContent( action.eventId, action.senderId, "This message is spam", spam = true)) } is EventSharedAction.ReportContentInappropriate -> { - roomDetailViewModel.handle(RoomDetailAction.ReportContent( + timelineViewModel.handle(RoomDetailAction.ReportContent( action.eventId, action.senderId, "This message is inappropriate", inappropriate = true)) } is EventSharedAction.ReportContentCustom -> { @@ -2208,7 +2208,7 @@ class TimelineFragment @Inject constructor( onUrlLongClicked(action.url) } is EventSharedAction.ReRequestKey -> { - roomDetailViewModel.handle(RoomDetailAction.ReRequestKeys(action.eventId)) + timelineViewModel.handle(RoomDetailAction.ReRequestKeys(action.eventId)) } is EventSharedAction.UseKeyBackup -> { context?.let { @@ -2227,7 +2227,7 @@ class TimelineFragment @Inject constructor( .setMessage(R.string.end_poll_confirmation_description) .setNegativeButton(R.string.action_cancel, null) .setPositiveButton(R.string.end_poll_confirmation_approve_button) { _, _ -> - roomDetailViewModel.handle(RoomDetailAction.EndPoll(eventId)) + timelineViewModel.handle(RoomDetailAction.EndPoll(eventId)) } .show() } @@ -2238,7 +2238,7 @@ class TimelineFragment @Inject constructor( .setMessage(R.string.room_participants_action_ignore_prompt_msg) .setNegativeButton(R.string.action_cancel, null) .setPositiveButton(R.string.room_participants_action_ignore) { _, _ -> - roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(senderId)) + timelineViewModel.handle(RoomDetailAction.IgnoreUser(senderId)) } .show() } @@ -2258,7 +2258,7 @@ class TimelineFragment @Inject constructor( views.composerLayout.views.composerEditText.setText(Command.EMOTE.command + " ") views.composerLayout.views.composerEditText.setSelection(Command.EMOTE.length) } else { - val roomMember = roomDetailViewModel.getMember(userId) + val roomMember = timelineViewModel.getMember(userId) // TODO move logic outside of fragment (roomMember?.displayName ?: userId) .let { sanitizeDisplayName(it) } @@ -2320,9 +2320,9 @@ class TimelineFragment @Inject constructor( context?.let { val roomThreadDetailArgs = ThreadTimelineArgs( roomId = timelineArgs.roomId, - displayName = roomDetailViewModel.getRoomSummary()?.displayName, - avatarUrl = roomDetailViewModel.getRoomSummary()?.avatarUrl, - roomEncryptionTrustLevel = roomDetailViewModel.getRoomSummary()?.roomEncryptionTrustLevel, + displayName = timelineViewModel.getRoomSummary()?.displayName, + avatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl, + roomEncryptionTrustLevel = timelineViewModel.getRoomSummary()?.roomEncryptionTrustLevel, rootThreadEventId = rootThreadEventId) navigator.openThread(it, roomThreadDetailArgs) } @@ -2337,9 +2337,9 @@ class TimelineFragment @Inject constructor( context?.let { val roomThreadDetailArgs = ThreadTimelineArgs( roomId = timelineArgs.roomId, - displayName = roomDetailViewModel.getRoomSummary()?.displayName, - roomEncryptionTrustLevel = roomDetailViewModel.getRoomSummary()?.roomEncryptionTrustLevel, - avatarUrl = roomDetailViewModel.getRoomSummary()?.avatarUrl) + displayName = timelineViewModel.getRoomSummary()?.displayName, + roomEncryptionTrustLevel = timelineViewModel.getRoomSummary()?.roomEncryptionTrustLevel, + avatarUrl = timelineViewModel.getRoomSummary()?.avatarUrl) navigator.openThreadList(it, roomThreadDetailArgs) } } @@ -2348,20 +2348,20 @@ class TimelineFragment @Inject constructor( override fun onAcceptInvite() { notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(timelineArgs.roomId) } - roomDetailViewModel.handle(RoomDetailAction.AcceptInvite) + timelineViewModel.handle(RoomDetailAction.AcceptInvite) } override fun onRejectInvite() { notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(timelineArgs.roomId) } - roomDetailViewModel.handle(RoomDetailAction.RejectInvite) + timelineViewModel.handle(RoomDetailAction.RejectInvite) } - private fun onJumpToReadMarkerClicked() = withState(roomDetailViewModel) { + private fun onJumpToReadMarkerClicked() = withState(timelineViewModel) { if (it.unreadState is UnreadState.HasUnread) { - roomDetailViewModel.handle(RoomDetailAction.NavigateToEvent(it.unreadState.firstUnreadEventId, false)) + timelineViewModel.handle(RoomDetailAction.NavigateToEvent(it.unreadState.firstUnreadEventId, false)) } if (it.unreadState is UnreadState.ReadMarkerNotLoaded) { - roomDetailViewModel.handle(RoomDetailAction.NavigateToEvent(it.unreadState.readMarkerId, false)) + timelineViewModel.handle(RoomDetailAction.NavigateToEvent(it.unreadState.readMarkerId, false)) } } @@ -2401,7 +2401,7 @@ class TimelineFragment @Inject constructor( AttachmentTypeSelectorView.Type.FILE -> attachmentsHelper.selectFile(attachmentFileActivityResultLauncher) AttachmentTypeSelectorView.Type.GALLERY -> attachmentsHelper.selectGallery(attachmentMediaActivityResultLauncher) AttachmentTypeSelectorView.Type.CONTACT -> attachmentsHelper.selectContact(attachmentContactActivityResultLauncher) - AttachmentTypeSelectorView.Type.STICKER -> roomDetailViewModel.handle(RoomDetailAction.SelectStickerAttachment) + AttachmentTypeSelectorView.Type.STICKER -> timelineViewModel.handle(RoomDetailAction.SelectStickerAttachment) AttachmentTypeSelectorView.Type.POLL -> navigator.openCreatePoll(requireContext(), timelineArgs.roomId) }.exhaustive } @@ -2412,7 +2412,7 @@ class TimelineFragment @Inject constructor( val grouped = attachments.toGroupedContentAttachmentData() if (grouped.notPreviewables.isNotEmpty()) { // Send the not previewable attachments right now (?) - roomDetailViewModel.handle(RoomDetailAction.SendMedia(grouped.notPreviewables, false)) + timelineViewModel.handle(RoomDetailAction.SendMedia(grouped.notPreviewables, false)) } if (grouped.previewables.isNotEmpty()) { val intent = AttachmentsPreviewActivity.newIntent(requireContext(), AttachmentsPreviewArgs(grouped.previewables)) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt similarity index 99% rename from vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt rename to vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index ade037b4e4..6e51fc7aa0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -103,7 +103,7 @@ import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode import timber.log.Timber import java.util.concurrent.atomic.AtomicBoolean -class RoomDetailViewModel @AssistedInject constructor( +class TimelineViewModel @AssistedInject constructor( @Assisted private val initialState: RoomDetailViewState, private val vectorPreferences: VectorPreferences, private val vectorDataStore: VectorDataStore, @@ -144,11 +144,11 @@ class RoomDetailViewModel @AssistedInject constructor( private var prepareToEncrypt: Async = Uninitialized @AssistedFactory - interface Factory : MavericksAssistedViewModelFactory { - override fun create(initialState: RoomDetailViewState): RoomDetailViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: RoomDetailViewState): TimelineViewModel } - companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { const val PAGINATION_COUNT = 50 } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt index 9d85ec0a07..62598551de 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt @@ -215,7 +215,7 @@ class MessageComposerViewModel @AssistedInject constructor( if (state.rootThreadEventId != null) { room.replyInThread( rootThreadEventId = state.rootThreadEventId, - replyInThreadText = action.text.toString(), + replyInThreadText = slashCommandResult.message, autoMarkdown = false) } else { room.sendTextMessage(slashCommandResult.message, autoMarkdown = false) @@ -270,7 +270,7 @@ class MessageComposerViewModel @AssistedInject constructor( is ParsedCommand.SendEmote -> { state.rootThreadEventId?.let { room.replyInThread( - rootThreadEventId = state.rootThreadEventId, + rootThreadEventId = it, replyInThreadText = slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) @@ -282,7 +282,7 @@ class MessageComposerViewModel @AssistedInject constructor( val message = slashCommandResult.message.toString() state.rootThreadEventId?.let { room.replyInThread( - rootThreadEventId = state.rootThreadEventId, + rootThreadEventId = it, replyInThreadText = slashCommandResult.message, formattedText = rainbowGenerator.generate(message)) } ?: room.sendFormattedTextMessage(message, rainbowGenerator.generate(message)) @@ -293,7 +293,7 @@ class MessageComposerViewModel @AssistedInject constructor( val message = slashCommandResult.message.toString() state.rootThreadEventId?.let { room.replyInThread( - rootThreadEventId = state.rootThreadEventId, + rootThreadEventId = it, replyInThreadText = slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE, formattedText = rainbowGenerator.generate(message)) @@ -307,7 +307,7 @@ class MessageComposerViewModel @AssistedInject constructor( val formattedText = "${slashCommandResult.message}" state.rootThreadEventId?.let { room.replyInThread( - rootThreadEventId = state.rootThreadEventId, + rootThreadEventId = it, replyInThreadText = text, formattedText = formattedText) } ?: room.sendFormattedTextMessage( @@ -479,9 +479,9 @@ class MessageComposerViewModel @AssistedInject constructor( } is SendMode.Reply -> { val timelineEvent = state.sendMode.timelineEvent - state.rootThreadEventId?.let { rootThreadEventId -> + state.rootThreadEventId?.let { room.replyInThread( - rootThreadEventId = rootThreadEventId, + rootThreadEventId = it, replyInThreadText = action.text.toString(), autoMarkdown = action.autoMarkdown, eventReplied = timelineEvent) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/EventSharedAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/EventSharedAction.kt index d611639463..cc2f8a2ac5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/EventSharedAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/EventSharedAction.kt @@ -48,11 +48,9 @@ sealed class EventSharedAction(@StringRes val titleRes: Int, data class Reply(val eventId: String) : EventSharedAction(R.string.reply, R.drawable.ic_reply) - // TODO add translations data class ReplyInThread(val eventId: String) : EventSharedAction(R.string.reply_in_thread, R.drawable.ic_reply_in_thread) - // TODO add translations object ViewInRoom : EventSharedAction(R.string.view_in_room, R.drawable.ic_thread_view_in_room_menu_item) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index fe615d8c01..e979704d6a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -441,13 +441,12 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } /** - * Determine whether or not the Reply In Thread bottom sheet setting will be visible + * Determine whether or not the Reply In Thread bottom sheet action will be visible * to the user */ private fun canReplyInThread(event: TimelineEvent, messageContent: MessageContent?, actionPermissions: ActionPermissions): Boolean { - // Only event of type EventType.MESSAGE are supported for the moment if (!BuildConfig.THREADING_ENABLED) return false if (initialState.isFromThreadTimeline) return false if (event.root.getClearType() != EventType.MESSAGE && @@ -468,13 +467,11 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } /** - * Determine whether or no the selected event is a root thread event from within - * a thread timeline + * Determine whether or not the view in room action will be available for the current event */ private fun canViewInRoom(event: TimelineEvent, messageContent: MessageContent?, actionPermissions: ActionPermissions): Boolean { - // Only event of type EventType.MESSAGE are supported for the moment if (!BuildConfig.THREADING_ENABLED) return false if (!initialState.isFromThreadTimeline) return false if (event.root.getClearType() != EventType.MESSAGE && diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/views/RoomDetailLazyLoadedViews.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/views/RoomDetailLazyLoadedViews.kt index fafb49ad5c..a7eb6ee78f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/views/RoomDetailLazyLoadedViews.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/views/RoomDetailLazyLoadedViews.kt @@ -19,7 +19,7 @@ package im.vector.app.features.home.room.detail.views import android.view.View import android.view.ViewStub import im.vector.app.core.ui.views.FailedMessagesWarningView -import im.vector.app.databinding.FragmentRoomDetailBinding +import im.vector.app.databinding.FragmentTimelineBinding import im.vector.app.features.invite.VectorInviteView import kotlin.reflect.KMutableProperty0 @@ -29,12 +29,12 @@ import kotlin.reflect.KMutableProperty0 */ class RoomDetailLazyLoadedViews { - private var roomDetailBinding: FragmentRoomDetailBinding? = null + private var roomDetailBinding: FragmentTimelineBinding? = null private var failedMessagesWarningView: FailedMessagesWarningView? = null private var inviteView: VectorInviteView? = null - fun bind(roomDetailBinding: FragmentRoomDetailBinding) { + fun bind(roomDetailBinding: FragmentTimelineBinding) { this.roomDetailBinding = roomDetailBinding } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt index aa6966254f..65f3d16ad4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt @@ -30,8 +30,8 @@ import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding import im.vector.app.features.home.room.detail.RoomDetailAction -import im.vector.app.features.home.room.detail.RoomDetailViewModel import im.vector.app.features.home.room.detail.RoomDetailViewState +import im.vector.app.features.home.room.detail.TimelineViewModel import im.vector.app.features.navigation.Navigator import org.matrix.android.sdk.api.session.widgets.model.Widget import javax.inject.Inject @@ -48,7 +48,7 @@ class RoomWidgetsBottomSheet : @Inject lateinit var colorProvider: ColorProvider @Inject lateinit var navigator: Navigator - private val roomDetailViewModel: RoomDetailViewModel by parentFragmentViewModel() + private val timelineViewModel: TimelineViewModel by parentFragmentViewModel() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding { return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false) @@ -61,7 +61,7 @@ class RoomWidgetsBottomSheet : views.bottomSheetTitle.textSize = 20f views.bottomSheetTitle.setTextColor(colorProvider.getColorFromAttribute(R.attr.vctr_content_primary)) epoxyController.listener = this - roomDetailViewModel.onAsync(RoomDetailViewState::activeRoomWidgets) { + timelineViewModel.onAsync(RoomDetailViewState::activeRoomWidgets) { epoxyController.setData(it) } } @@ -72,13 +72,13 @@ class RoomWidgetsBottomSheet : super.onDestroyView() } - override fun didSelectWidget(widget: Widget) = withState(roomDetailViewModel) { + override fun didSelectWidget(widget: Widget) = withState(timelineViewModel) { navigator.openRoomWidget(requireContext(), it.roomId, widget) dismiss() } override fun didSelectManageWidgets() { - roomDetailViewModel.handle(RoomDetailAction.OpenIntegrationManager) + timelineViewModel.handle(RoomDetailAction.OpenIntegrationManager) dismiss() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/threads/list/model/ThreadListModel.kt b/vector/src/main/java/im/vector/app/features/home/room/threads/list/model/ThreadListItem.kt similarity index 96% rename from vector/src/main/java/im/vector/app/features/home/room/threads/list/model/ThreadListModel.kt rename to vector/src/main/java/im/vector/app/features/home/room/threads/list/model/ThreadListItem.kt index 72ba673972..2364e86166 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/threads/list/model/ThreadListModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/threads/list/model/ThreadListItem.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019 New Vector Ltd + * Copyright 2021 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. @@ -36,8 +36,8 @@ import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.session.threads.ThreadNotificationState import org.matrix.android.sdk.api.util.MatrixItem -@EpoxyModelClass(layout = R.layout.item_thread_list) -abstract class ThreadListModel : VectorEpoxyModel() { +@EpoxyModelClass(layout = R.layout.item_thread) +abstract class ThreadListItem : VectorEpoxyModel() { @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer @EpoxyAttribute lateinit var matrixItem: MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/home/room/threads/list/viewmodel/ThreadListController.kt b/vector/src/main/java/im/vector/app/features/home/room/threads/list/viewmodel/ThreadListController.kt index 984c8e8f7e..c123bceafb 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/threads/list/viewmodel/ThreadListController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/threads/list/viewmodel/ThreadListController.kt @@ -22,7 +22,7 @@ import im.vector.app.core.date.DateFormatKind import im.vector.app.core.date.VectorDateFormatter import im.vector.app.core.resources.StringProvider import im.vector.app.features.home.AvatarRenderer -import im.vector.app.features.home.room.threads.list.model.threadList +import im.vector.app.features.home.room.threads.list.model.threadListItem import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.threads.ThreadNotificationState import org.matrix.android.sdk.api.util.toMatrixItem @@ -60,7 +60,7 @@ class ThreadListController @Inject constructor( ?.forEach { timelineEvent -> val date = dateFormatter.format(timelineEvent.root.threadDetails?.lastMessageTimestamp, DateFormatKind.ROOM_LIST) val decryptionErrorMessage = stringProvider.getString(R.string.encrypted_message) - threadList { + threadListItem { id(timelineEvent.eventId) avatarRenderer(host.avatarRenderer) matrixItem(timelineEvent.senderInfo.toMatrixItem()) diff --git a/vector/src/main/java/im/vector/app/features/home/room/threads/list/views/ThreadListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/threads/list/views/ThreadListFragment.kt index 2a14ce3aa0..f388ce1410 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/threads/list/views/ThreadListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/threads/list/views/ThreadListFragment.kt @@ -75,6 +75,7 @@ class ThreadListFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initToolbar() + initTextConstants() views.threadListRecyclerView.configureWith(threadListController, TimelineItemAnimator(), hasFixedSize = false) threadListController.listener = this } @@ -90,6 +91,12 @@ class ThreadListFragment @Inject constructor( renderToolbar() } + private fun initTextConstants() { + views.threadListEmptyNoticeTextView.text = String.format( + resources.getString(R.string.thread_list_empty_notice), + resources.getString(R.string.reply_in_thread)) + } + override fun invalidate() = withState(threadListViewModel) { state -> renderEmptyStateIfNeeded(state) threadListController.update(state) diff --git a/vector/src/main/res/layout/fragment_thread_list.xml b/vector/src/main/res/layout/fragment_thread_list.xml index 77f46bf3ee..7e7c79f8c3 100644 --- a/vector/src/main/res/layout/fragment_thread_list.xml +++ b/vector/src/main/res/layout/fragment_thread_list.xml @@ -34,7 +34,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/threadListAppBarLayout" - tools:listitem="@layout/item_thread_list" + tools:listitem="@layout/item_thread" tools:visibility="gone" /> + tools:text="@string/thread_list_empty_notice" /> diff --git a/vector/src/main/res/layout/fragment_room_detail.xml b/vector/src/main/res/layout/fragment_timeline.xml similarity index 100% rename from vector/src/main/res/layout/fragment_room_detail.xml rename to vector/src/main/res/layout/fragment_timeline.xml diff --git a/vector/src/main/res/layout/item_thread_list.xml b/vector/src/main/res/layout/item_thread.xml similarity index 100% rename from vector/src/main/res/layout/item_thread_list.xml rename to vector/src/main/res/layout/item_thread.xml diff --git a/vector/src/main/res/layout/view_room_detail_thread_toolbar.xml b/vector/src/main/res/layout/view_room_detail_thread_toolbar.xml index 6a72422e20..e16912246e 100644 --- a/vector/src/main/res/layout/view_room_detail_thread_toolbar.xml +++ b/vector/src/main/res/layout/view_room_detail_thread_toolbar.xml @@ -56,7 +56,7 @@ app:layout_constraintBottom_toBottomOf="@id/roomToolbarThreadImageView" app:layout_constraintStart_toEndOf="@id/roomToolbarThreadImageView" app:layout_constraintTop_toTopOf="@id/roomToolbarThreadImageView" - tools:text="RoomName" + tools:text="@sample/rooms.json/data/name" tools:visibility="visible" /> diff --git a/vector/src/main/res/layout/view_thread_room_summary.xml b/vector/src/main/res/layout/view_thread_room_summary.xml index b1c490e5b3..0f184edef3 100644 --- a/vector/src/main/res/layout/view_thread_room_summary.xml +++ b/vector/src/main/res/layout/view_thread_room_summary.xml @@ -55,5 +55,5 @@ app:layout_constraintHorizontal_bias="0" app:layout_constraintStart_toEndOf="@id/messageThreadSummaryAvatarImageView" app:layout_constraintTop_toTopOf="parent" - tools:text="Hello There, whats up! Its a large sentence whats up! Its a large centence" /> + tools:text="@sample/messages.json/data/message" /> diff --git a/vector/src/main/res/menu/menu_timeline.xml b/vector/src/main/res/menu/menu_timeline.xml index 10f4fb0575..962c505e4e 100644 --- a/vector/src/main/res/menu/menu_timeline.xml +++ b/vector/src/main/res/menu/menu_timeline.xml @@ -90,7 +90,7 @@ diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index b86b2dd27f..4e3b132be7 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -472,7 +472,6 @@ View in room Copy link to thread - Share Confirmation @@ -1048,7 +1047,8 @@ Shows all threads you’ve participated in Keep discussions organised with threads Threads help keep your conversations on-topic and easy to track. - Tip: Long tap a message and use “Reply in thread”. + + Tip: Long tap a message and use “%s”. Reason for reporting this content