From 2c9526543b6b0f139770ca4d76330c5080f4a25d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 4 Oct 2022 12:30:56 +0200 Subject: [PATCH] Remove coordinator, fix minor issues --- .../home/room/detail/TimelineFragment.kt | 31 +++++-------------- .../detail/composer/MessageComposerAction.kt | 7 +++-- .../composer/MessageComposerFragment.kt | 30 +++++++----------- .../composer/MessageComposerViewEvents.kt | 2 ++ .../composer/MessageComposerViewModel.kt | 13 +++++--- .../composer/MessageComposerViewState.kt | 11 ++++--- .../detail/timeline/item/AbsMessageItem.kt | 8 +---- 7 files changed, 41 insertions(+), 61 deletions(-) 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 ae52d36c7e..fe4f33f37d 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 @@ -129,7 +129,6 @@ import im.vector.app.features.crypto.verification.VerificationBottomSheet import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.arguments.TimelineArgs import im.vector.app.features.home.room.detail.composer.CanSendStatus -import im.vector.app.features.home.room.detail.composer.MessageComposer import im.vector.app.features.home.room.detail.composer.MessageComposerAction import im.vector.app.features.home.room.detail.composer.MessageComposerFragment import im.vector.app.features.home.room.detail.composer.MessageComposerViewModel @@ -289,8 +288,6 @@ class TimelineFragment : private val lazyLoadedViews = RoomDetailLazyLoadedViews() - private lateinit var composer: MessageComposer - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) analyticsScreenName = MobileScreen.ScreenName.Room @@ -301,15 +298,13 @@ class TimelineFragment : } } - val composer = childFragmentManager.findFragmentById(R.id.composerContainer) as? MessageComposerFragment ?: run { - val fragment = MessageComposerFragment() - fragment.arguments = timelineArgs.toMvRxBundle() + childFragmentManager.findFragmentById(R.id.composerContainer) as? MessageComposerFragment ?: run { childFragmentManager.commitTransaction { + val fragment = MessageComposerFragment() + fragment.arguments = timelineArgs.toMvRxBundle() replace(R.id.composerContainer, fragment) } - fragment } - this.composer = composer childFragmentManager.findFragmentById(R.id.voiceMessageRecorderContainer) as? VoiceRecorderFragment ?: run { childFragmentManager.commitTransaction { @@ -970,7 +965,7 @@ class TimelineFragment : is RoomDetailPendingAction.JumpToReadReceipt -> timelineViewModel.handle(RoomDetailAction.JumpToReadReceipt(roomDetailPendingAction.userId)) is RoomDetailPendingAction.MentionUser -> - insertUserDisplayNameInTextEditor(roomDetailPendingAction.userId) + messageComposerViewModel.handle(MessageComposerAction.InsertUserDisplayName(roomDetailPendingAction.userId)) is RoomDetailPendingAction.OpenRoom -> handleOpenRoom(RoomDetailViewEvents.OpenRoom(roomDetailPendingAction.roomId, roomDetailPendingAction.closeCurrentRoom)) } @@ -1051,7 +1046,7 @@ class TimelineFragment : override fun performQuickReplyOnHolder(model: EpoxyModel<*>) { (model as? AbsMessageItem)?.attributes?.informationData?.let { val eventId = it.eventId - messageComposerViewModel.handle(MessageComposerAction.EnterReplyMode(eventId, composer.getCurrentText().toString())) + messageComposerViewModel.handle(MessageComposerAction.EnterReplyMode(eventId)) } } @@ -1573,7 +1568,7 @@ class TimelineFragment : } override fun onMemberNameClicked(informationData: MessageInformationData) { - insertUserDisplayNameInTextEditor(informationData.senderId) + messageComposerViewModel.handle(MessageComposerAction.InsertUserDisplayName(informationData.senderId)) } override fun onClickOnReactionPill(informationData: MessageInformationData, reaction: String, on: Boolean) { @@ -1776,11 +1771,11 @@ class TimelineFragment : } } is EventSharedAction.Quote -> { - messageComposerViewModel.handle(MessageComposerAction.EnterQuoteMode(action.eventId, composer.getCurrentText().toString())) + messageComposerViewModel.handle(MessageComposerAction.EnterQuoteMode(action.eventId)) } is EventSharedAction.Reply -> { if (withState(messageComposerViewModel) { it.isVoiceMessageIdle }) { - messageComposerViewModel.handle(MessageComposerAction.EnterReplyMode(action.eventId, composer.getCurrentText().toString())) + messageComposerViewModel.handle(MessageComposerAction.EnterReplyMode(action.eventId)) } else { requireActivity().toast(R.string.error_voice_message_cannot_reply_or_edit) } @@ -1881,16 +1876,6 @@ class TimelineFragment : .show() } - /** - * Insert a user displayName in the message editor. - * - * @param userId the userId. - */ - @SuppressLint("SetTextI18n") - private fun insertUserDisplayNameInTextEditor(userId: String) { - composer.insertUserDisplayNameInTextEditor(userId) - } - private fun showSnackWithMessage(message: String) { view?.showOptimizedSnackbar(message) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt index ac39e0e915..97e6657fc2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt @@ -25,13 +25,14 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent sealed class MessageComposerAction : VectorViewModelAction { data class SendMessage(val text: CharSequence, val autoMarkdown: Boolean) : MessageComposerAction() data class EnterEditMode(val eventId: String) : MessageComposerAction() - data class EnterQuoteMode(val eventId: String, val text: String) : MessageComposerAction() - data class EnterReplyMode(val eventId: String, val text: String) : MessageComposerAction() - data class EnterRegularMode(val text: String, val fromSharing: Boolean) : MessageComposerAction() + data class EnterQuoteMode(val eventId: String) : MessageComposerAction() + data class EnterReplyMode(val eventId: String) : MessageComposerAction() + data class EnterRegularMode(val fromSharing: Boolean) : MessageComposerAction() data class UserIsTyping(val isTyping: Boolean) : MessageComposerAction() data class OnTextChanged(val text: CharSequence) : MessageComposerAction() data class OnEntersBackground(val composerText: String) : MessageComposerAction() data class SlashCommandConfirmed(val parsedCommand: ParsedCommand) : MessageComposerAction() + data class InsertUserDisplayName(val userId: String) : MessageComposerAction() // Voice Message data class InitializeVoiceRecorder(val attachmentData: ContentAttachmentData) : MessageComposerAction() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerFragment.kt index 103950b3b8..d78864d8d6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerFragment.kt @@ -22,7 +22,6 @@ import android.content.res.Configuration import android.net.Uri import android.os.Build import android.os.Bundle -import android.text.Editable import android.text.Spannable import android.text.format.DateUtils import android.view.KeyEvent @@ -112,13 +111,8 @@ import reactivecircus.flowbinding.android.widget.textChanges import timber.log.Timber import javax.inject.Inject -interface MessageComposer { - fun getCurrentText(): Editable? - fun insertUserDisplayNameInTextEditor(userId: String) -} - @AndroidEntryPoint -class MessageComposerFragment : VectorBaseFragment(), MessageComposer, AttachmentsHelper.Callback, AttachmentTypeSelectorView.Callback { +class MessageComposerFragment : VectorBaseFragment(), AttachmentsHelper.Callback, AttachmentTypeSelectorView.Callback { companion object { private const val ircPattern = " (IRC)" @@ -196,6 +190,7 @@ class MessageComposerFragment : VectorBaseFragment(), M } showErrorInSnackbar(it.throwable) } + is MessageComposerViewEvents.InsertUserDisplayName -> insertUserDisplayNameInTextEditor(it.userId) } } @@ -204,10 +199,10 @@ class MessageComposerFragment : VectorBaseFragment(), M return@onEach } when (mode) { - is SendMode.Regular -> renderRegularMode(mode.text) - is SendMode.Edit -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_edit, R.string.edit, mode.text) - is SendMode.Quote -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_quote, R.string.action_quote, mode.text) - is SendMode.Reply -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_reply, R.string.reply, mode.text) + is SendMode.Regular -> renderRegularMode(mode.text.toString()) + is SendMode.Edit -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_edit, R.string.edit, mode.text.toString()) + is SendMode.Quote -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_quote, R.string.action_quote, mode.text.toString()) + is SendMode.Reply -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_reply, R.string.reply, mode.text.toString()) is SendMode.Voice -> renderVoiceMessageMode(mode.text) } } @@ -304,7 +299,7 @@ class MessageComposerFragment : VectorBaseFragment(), M } override fun onCloseRelatedMessage() { - messageComposerViewModel.handle(MessageComposerAction.EnterRegularMode(views.composerLayout.text.toString(), false)) + messageComposerViewModel.handle(MessageComposerAction.EnterRegularMode(false)) } override fun onRichContentSelected(contentUri: Uri): Boolean { @@ -723,7 +718,8 @@ class MessageComposerFragment : VectorBaseFragment(), M private fun handleShareData() { when (val sharedData = timelineArgs.sharedData) { is SharedData.Text -> { - messageComposerViewModel.handle(MessageComposerAction.EnterRegularMode(sharedData.text, fromSharing = true)) + messageComposerViewModel.handle(MessageComposerAction.OnTextChanged(sharedData.text)) + messageComposerViewModel.handle(MessageComposerAction.EnterRegularMode(fromSharing = true)) } is SharedData.Attachments -> { // open share edition @@ -733,17 +729,13 @@ class MessageComposerFragment : VectorBaseFragment(), M } } - override fun getCurrentText(): Editable? { - return views.composerLayout.text - } - - override fun insertUserDisplayNameInTextEditor(userId: String) { + private fun insertUserDisplayNameInTextEditor(userId: String) { val startToCompose = views.composerLayout.text.isNullOrBlank() if (startToCompose && userId == session.myUserId) { // Empty composer, current user: start an emote - 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) } else { val roomMember = timelineViewModel.getMember(userId) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt index e1f6923d21..3a949acb07 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt @@ -47,4 +47,6 @@ sealed class MessageComposerViewEvents : VectorViewEvents { data class ShowRoomUpgradeDialog(val newVersion: String, val isPublic: Boolean) : MessageComposerViewEvents() data class VoicePlaybackOrRecordingFailure(val throwable: Throwable) : MessageComposerViewEvents() + + data class InsertUserDisplayName(val userId: String) : MessageComposerViewEvents() } 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 f9bf244eb1..afdd01ba46 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 @@ -113,6 +113,7 @@ class MessageComposerViewModel @AssistedInject constructor( is MessageComposerAction.VoiceWaveformMovedTo -> handleVoiceWaveformMovedTo(action) is MessageComposerAction.AudioSeekBarMovedTo -> handleAudioSeekBarMovedTo(action) is MessageComposerAction.SlashCommandConfirmed -> handleSlashCommandConfirmed(action) + is MessageComposerAction.InsertUserDisplayName -> handleInsertUserDisplayName(action) } } @@ -144,7 +145,7 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handleEnterRegularMode(action: MessageComposerAction.EnterRegularMode) = setState { - copy(sendMode = SendMode.Regular(action.text, action.fromSharing)) + copy(sendMode = SendMode.Regular(currentComposerText, action.fromSharing)) } private fun handleEnterEditMode(action: MessageComposerAction.EnterEditMode) { @@ -181,13 +182,13 @@ class MessageComposerViewModel @AssistedInject constructor( private fun handleEnterQuoteMode(action: MessageComposerAction.EnterQuoteMode) { room.getTimelineEvent(action.eventId)?.let { timelineEvent -> - setState { copy(sendMode = SendMode.Quote(timelineEvent, action.text)) } + setState { copy(sendMode = SendMode.Quote(timelineEvent, currentComposerText)) } } } private fun handleEnterReplyMode(action: MessageComposerAction.EnterReplyMode) { room.getTimelineEvent(action.eventId)?.let { timelineEvent -> - setState { copy(sendMode = SendMode.Reply(timelineEvent, action.text)) } + setState { copy(sendMode = SendMode.Reply(timelineEvent, currentComposerText)) } } } @@ -875,7 +876,7 @@ class MessageComposerViewModel @AssistedInject constructor( } } } - handleEnterRegularMode(MessageComposerAction.EnterRegularMode(text = "", fromSharing = false)) + handleEnterRegularMode(MessageComposerAction.EnterRegularMode(fromSharing = false)) } private fun handlePlayOrPauseVoicePlayback(action: MessageComposerAction.PlayOrPauseVoicePlayback) { @@ -943,6 +944,10 @@ class MessageComposerViewModel @AssistedInject constructor( } } + private fun handleInsertUserDisplayName(action: MessageComposerAction.InsertUserDisplayName) { + _viewEvents.post(MessageComposerViewEvents.InsertUserDisplayName(action.userId)) + } + private fun launchSlashCommandFlowSuspendable(parsedCommand: ParsedCommand, block: suspend () -> Unit) { _viewEvents.post(MessageComposerViewEvents.SlashCommandLoading) viewModelScope.launch { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewState.kt index 5698414ab4..47a7122584 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewState.kt @@ -33,15 +33,15 @@ import kotlin.random.Random */ sealed interface SendMode { data class Regular( - val text: String, + val text: CharSequence, val fromSharing: Boolean, // This is necessary for forcing refresh on selectSubscribe private val random: Int = Random.nextInt() ) : SendMode - data class Quote(val timelineEvent: TimelineEvent, val text: String) : SendMode - data class Edit(val timelineEvent: TimelineEvent, val text: String) : SendMode - data class Reply(val timelineEvent: TimelineEvent, val text: String) : SendMode + data class Quote(val timelineEvent: TimelineEvent, val text: CharSequence) : SendMode + data class Edit(val timelineEvent: TimelineEvent, val text: CharSequence) : SendMode + data class Reply(val timelineEvent: TimelineEvent, val text: CharSequence) : SendMode data class Voice(val text: String) : SendMode } @@ -66,7 +66,8 @@ data class MessageComposerViewState( val rootThreadEventId: String? = null, val startsThread: Boolean = false, val sendMode: SendMode = SendMode.Regular("", false), - val voiceRecordingUiState: VoiceMessageRecorderView.RecordingUiState = VoiceMessageRecorderView.RecordingUiState.Idle + val voiceRecordingUiState: VoiceMessageRecorderView.RecordingUiState = VoiceMessageRecorderView.RecordingUiState.Idle, + val text: CharSequence? = null, ) : MavericksState { val isVoiceRecording = when (voiceRecordingUiState) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt index 8dba0117b5..869b7d17e2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt @@ -63,12 +63,6 @@ abstract class AbsMessageItem( } } - private val _memberNameClickListener = object : ClickListener { - override fun invoke(p1: View) { - attributes.avatarCallback?.onMemberNameClicked(attributes.informationData) - } - } - private val _threadClickListener = object : ClickListener { override fun invoke(p1: View) { attributes.threadCallback?.onThreadSummaryClicked(attributes.informationData.eventId, attributes.threadDetails?.isRootThread ?: false) @@ -95,7 +89,7 @@ abstract class AbsMessageItem( holder.memberNameView.isVisible = true holder.memberNameView.text = attributes.informationData.memberName holder.memberNameView.setTextColor(attributes.getMemberNameColor()) - holder.memberNameView.onClick(_memberNameClickListener) + holder.memberNameView.onClick(attributes.memberClickListener) holder.memberNameView.setOnLongClickListener(attributes.itemLongClickListener) } else { holder.memberNameView.setOnClickListener(null)