-
Notifications
You must be signed in to change notification settings - Fork 743
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Voice Message - Draft support #4237
Changes from all commits
b356a5c
950c6f2
67f25d1
b54079a
2e078ca
139c2bf
26713c4
5cb49ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Voice messages: Persist drafts of voice messages when navigating between rooms |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -202,6 +202,7 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageFormat | |
import org.matrix.android.sdk.api.session.room.model.message.MessageImageInfoContent | ||
import org.matrix.android.sdk.api.session.room.model.message.MessageStickerContent | ||
import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent | ||
import org.matrix.android.sdk.api.session.room.model.message.MessageType | ||
import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationRequestContent | ||
import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent | ||
import org.matrix.android.sdk.api.session.room.model.message.MessageWithAttachmentContent | ||
|
@@ -388,7 +389,13 @@ class RoomDetailFragment @Inject constructor( | |
return@onEach | ||
} | ||
when (mode) { | ||
is SendMode.REGULAR -> renderRegularMode(mode.text) | ||
is SendMode.REGULAR -> { | ||
if (mode.messageType == MessageType.MSGTYPE_AUDIO) { | ||
renderVoiceMessageMode(mode.text) | ||
} else { | ||
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.quote, mode.text) | ||
is SendMode.REPLY -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_reply, R.string.reply, mode.text) | ||
|
@@ -457,6 +464,7 @@ class RoomDetailFragment @Inject constructor( | |
RoomDetailViewEvents.StopChatEffects -> handleStopChatEffects() | ||
is RoomDetailViewEvents.DisplayAndAcceptCall -> acceptIncomingCall(it) | ||
RoomDetailViewEvents.RoomReplacementStarted -> handleRoomReplacement() | ||
is RoomDetailViewEvents.SaveDraft -> handleSaveDraft(it.defaultContent, it.messageType) | ||
}.exhaustive | ||
} | ||
|
||
|
@@ -466,6 +474,15 @@ class RoomDetailFragment @Inject constructor( | |
} | ||
} | ||
|
||
private fun renderVoiceMessageMode(content: String) { | ||
ContentAttachmentData.fromJsonString(content)?.let { audioAttachmentData -> | ||
views.voiceMessageRecorderView.isVisible = true | ||
roomDetailViewModel.handle(RoomDetailAction.InitializeVoiceRecorder(audioAttachmentData)) | ||
textComposerViewModel.handle(TextComposerAction.OnVoiceRecordingStateChanged(true)) | ||
views.voiceMessageRecorderView.initVoiceRecordingViews(isInPlaybackMode = true) | ||
} | ||
} | ||
|
||
private fun handleSendButtonVisibilityChanged(event: TextComposerViewEvents.AnimateSendButtonVisibility) { | ||
if (event.isVisible) { | ||
views.voiceMessageRecorderView.isVisible = false | ||
|
@@ -581,6 +598,20 @@ class RoomDetailFragment @Inject constructor( | |
} | ||
} | ||
|
||
private fun handleSaveDraft(defaultContent: String?, messageType: String) { | ||
if (messageType == MessageType.MSGTYPE_AUDIO) { | ||
defaultContent?.let { | ||
textComposerViewModel.handle( | ||
TextComposerAction.SaveDraft(it, MessageType.MSGTYPE_AUDIO) | ||
) | ||
} | ||
} else { | ||
textComposerViewModel.handle( | ||
TextComposerAction.SaveDraft(views.composerLayout.text.toString(), MessageType.MSGTYPE_TEXT) | ||
) | ||
} | ||
} | ||
|
||
private fun requestNativeWidgetPermission(it: RoomDetailViewEvents.RequestNativeWidgetPermission) { | ||
val tag = RoomWidgetPermissionBottomSheet::class.java.name | ||
val dFrag = childFragmentManager.findFragmentByTag(tag) as? RoomWidgetPermissionBottomSheet | ||
|
@@ -1015,10 +1046,10 @@ class RoomDetailFragment @Inject constructor( | |
.show() | ||
} | ||
|
||
private fun renderRegularMode(text: String) { | ||
private fun renderRegularMode(content: String) { | ||
autoCompleter.exitSpecialMode() | ||
views.composerLayout.collapse() | ||
views.composerLayout.setTextIfDifferent(text) | ||
views.composerLayout.setTextIfDifferent(content) | ||
views.composerLayout.views.sendButton.contentDescription = getString(R.string.send) | ||
} | ||
|
||
|
@@ -1102,11 +1133,11 @@ class RoomDetailFragment @Inject constructor( | |
|
||
notificationDrawerManager.setCurrentRoom(null) | ||
|
||
textComposerViewModel.handle(TextComposerAction.SaveDraft(views.composerLayout.text.toString())) | ||
|
||
// We should improve the UX to support going into playback mode when paused and delete the media when the view is destroyed. | ||
roomDetailViewModel.handle(RoomDetailAction.EndAllVoiceActions(deleteRecord = false)) | ||
views.voiceMessageRecorderView.initVoiceRecordingViews() | ||
roomDetailViewModel.handle( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do not talk to the textComposerViewModel anymore here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. roomDetailViewModel will decide it and communicate with textComposerViewModel later with SaveDraft event. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK |
||
RoomDetailAction.OnRoomDetailEntersBackground( | ||
isVoiceMessageActive = views.voiceMessageRecorderView.isActive() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is strange to ask the view about the state. The ViewModel should be aware of the current state. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I found it complex to determine the state here, especially if there is already a draft in the room. |
||
) | ||
) | ||
} | ||
|
||
private val attachmentFileActivityResultLauncher = registerStartForActivityResult { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,6 +72,7 @@ import org.matrix.android.sdk.api.MatrixPatterns | |
import org.matrix.android.sdk.api.extensions.tryOrNull | ||
import org.matrix.android.sdk.api.query.QueryStringValue | ||
import org.matrix.android.sdk.api.session.Session | ||
import org.matrix.android.sdk.api.session.content.ContentAttachmentData | ||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError | ||
import org.matrix.android.sdk.api.session.events.model.EventType | ||
import org.matrix.android.sdk.api.session.events.model.LocalEcho | ||
|
@@ -86,6 +87,7 @@ import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams | |
import org.matrix.android.sdk.api.session.room.model.Membership | ||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary | ||
import org.matrix.android.sdk.api.session.room.model.RoomSummary | ||
import org.matrix.android.sdk.api.session.room.model.message.MessageType | ||
import org.matrix.android.sdk.api.session.room.model.message.getFileUrl | ||
import org.matrix.android.sdk.api.session.room.model.tombstone.RoomTombstoneContent | ||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper | ||
|
@@ -342,6 +344,7 @@ class RoomDetailViewModel @AssistedInject constructor( | |
is RoomDetailAction.DoNotShowPreviewUrlFor -> handleDoNotShowPreviewUrlFor(action) | ||
RoomDetailAction.RemoveAllFailedMessages -> handleRemoveAllFailedMessages() | ||
RoomDetailAction.ResendAll -> handleResendAll() | ||
is RoomDetailAction.InitializeVoiceRecorder -> handleInitializeVoiceRecorder(action.attachmentData) | ||
RoomDetailAction.StartRecordingVoiceMessage -> handleStartRecordingVoiceMessage() | ||
is RoomDetailAction.EndRecordingVoiceMessage -> handleEndRecordingVoiceMessage(action.isCancelled) | ||
is RoomDetailAction.PlayOrPauseVoicePlayback -> handlePlayOrPauseVoicePlayback(action) | ||
|
@@ -354,6 +357,7 @@ class RoomDetailViewModel @AssistedInject constructor( | |
} | ||
_viewEvents.post(RoomDetailViewEvents.OpenRoom(action.replacementRoomId, closeCurrentRoom = true)) | ||
} | ||
is RoomDetailAction.OnRoomDetailEntersBackground -> handleRoomDetailEntersBackground(action.isVoiceMessageActive) | ||
}.exhaustive | ||
} | ||
|
||
|
@@ -611,9 +615,13 @@ class RoomDetailViewModel @AssistedInject constructor( | |
} | ||
} | ||
|
||
private fun handleInitializeVoiceRecorder(attachmentData: ContentAttachmentData) { | ||
voiceMessageHelper.initializeRecorder(room.roomId, attachmentData) | ||
} | ||
|
||
private fun handleStartRecordingVoiceMessage() { | ||
try { | ||
voiceMessageHelper.startRecording() | ||
voiceMessageHelper.startRecording(room.roomId) | ||
} catch (failure: Throwable) { | ||
_viewEvents.post(RoomDetailViewEvents.Failure(failure)) | ||
} | ||
|
@@ -657,6 +665,16 @@ class RoomDetailViewModel @AssistedInject constructor( | |
voiceMessageHelper.stopAllVoiceActions(deleteRecord) | ||
} | ||
|
||
private fun handleRoomDetailEntersBackground(isVoiceMessageActive: Boolean) { | ||
if (isVoiceMessageActive) { | ||
val audioType = voiceMessageHelper.stopAllVoiceActions(deleteRecord = false) | ||
val audioJsonString = audioType?.toContentAttachmentData()?.toJsonString() | ||
_viewEvents.post(RoomDetailViewEvents.SaveDraft(audioJsonString, MessageType.MSGTYPE_AUDIO)) | ||
} else { | ||
_viewEvents.post(RoomDetailViewEvents.SaveDraft(null, MessageType.MSGTYPE_TEXT)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. weird arch |
||
} | ||
} | ||
|
||
private fun handlePauseRecordingVoiceMessage() { | ||
voiceMessageHelper.pauseRecording() | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be a problem for those who are already on version 19. In this case you should create a version 20.