Skip to content

Conversation

@ouchadam
Copy link
Contributor

@ouchadam ouchadam commented Nov 19, 2021

Continuation of @onurays #4237 rebased on all of the refactors around the VoiceMessageRecorderView and MessageComposerViewModel refactors

  • This doesn't include moving any logic to the SDK yet but all the Text + Voice draft logic sits in one place under the MessageComposerViewModel
  • Also fixes [Bug|Crash] Voice Messages sending need more robustfully #3833 which was caused by only using a single file for all voice recordings, the fix is to simply use a unique file per voice recording
BEFORE AFTER
before-voice-draft after-voice-draft

private fun handleEntersBackground(composerText: String) {
withState {
if (it.isVoiceRecording) {
handleEndAllVoiceActions(deleteRecord = false)?.toContentAttachmentData()?.let { voiceDraft ->
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in order to move all of the voice draft logic to the SDK, we'd also need to move the voice helpers, is that what you had in mind @bmarty ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, I would like the SDK be able to manage the draft file storage itself, but not the logic. We can discuss this on Monday.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could imagine something like...

override fun initializeRecord(roomId: String) {
  outputFile = draftService.readFile(key = roomId)
}

override fun startRecord(roomId: String) {
  outputFile = draftService.createFile(key = roomId)
}

@github-actions
Copy link

github-actions bot commented Nov 19, 2021

Unit Test Results

  66 files  ±0    66 suites  ±0   58s ⏱️ -10s
135 tests ±0  135 ✔️ ±0  0 💤 ±0  0 ±0 
418 runs  ±0  418 ✔️ ±0  0 💤 ±0  0 ±0 

Results for commit 9939298. ± Comparison against base commit 61faf71.

♻️ This comment has been updated with latest results.

@DoM1niC
Copy link

DoM1niC commented Nov 19, 2021

This will fix @ouchadam ? #3833

in my case this could be reproduce in flight mode and more than one sendet Voice Messages after back online only one will be success send and the other show resend error state but couldn't be resend .... and have to dismiss and new recorded...

Bug in voice-composer Commit:
voice-composer changes brick the Message edit Stuff here with the Info you cant edit Messages while Recording a Voice Message :D ^^

@ouchadam
Copy link
Contributor Author

ouchadam commented Nov 22, 2021

This will fix @ouchadam ? #3833

in my case this could be reproduce in flight mode and more than one sendet Voice Messages after back online only one will be success send and the other show resend error state but couldn't be resend .... and have to dismiss and new recorded...

Not yet, but I have been able to reproduce the issue locally thanks to your steps, I'm looking into the cause 🤞

2021-11-22T12:56:54,356286228+00:00

Bug in voice-composer Commit: voice-composer changes brick the Message edit Stuff here with the Info you cant edit Messages while Recording a Voice Message :D ^^

great catch! 5687c36

BEFORE AFTER
before-edit-message after-edit-message

EDIT: turns out the offline messages fix was quite simple! 6e8c545

BEFORE AFTER
before-airplane-voice after-airplane-mode

…starting a recording, which means any previous unsent recordings get deleted
Base automatically changed from feature/adm/voice-composer to develop November 22, 2021 14:01
@ouchadam ouchadam marked this pull request as ready for review November 22, 2021 14:03
val content: String
val messageType: String

data class REGULAR(override val content: String, override val messageType: String) : UserDraft
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if Voice should be a dedicated draft type rather than a messageType sub type 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the code would be clearer with a VOICE data class (they are allcaps...). But I do not know if we will end up with many other cases. @onurays WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would also mean we can avoid any database entity changes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. That make sense and yes we are preserving the draftMode in DraftEntity. So no migration will be needed.

override fun startRecord(roomId: String) {
init()
outputFile = File(outputDirectory, "Voice message.$filenameExt")
val fileName = "Voice message-${UUID.randomUUID()}.$filenameExt"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using unique files for the recording fixes #3833

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filename can in some circumstance be visible to the user, is it possible to use a subfolder instead, and keep a human readable filename?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have a look, out of interest do we need to display the real file name here, could the label be hardcoded?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is another way to fix the display issue. But also the file can be downloaded, etc. so a human readable filename should still be nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c2ec157

We can use the file provider to provide a human readable name, downloads automatically append a timestamp

NAME DOWNLOAD
after-voice-message after-downloaded-vm

Copy link
Member

@bmarty bmarty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! Still some open question about who is responsible to save the draft voice file.

when (mode) {
is SendMode.REGULAR -> renderRegularMode(mode.text)
is SendMode.REGULAR -> {
if (mode.messageType == MessageType.MSGTYPE_AUDIO) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where the code is not typed enough IMO, MSGTYPE_AUDIO is not necessarily a voice message. But for draft this is the only possible case I think...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a sign to move away from the MSGTYPE and have a separate Voice send mode

handleEndAllVoiceActions(deleteRecord = false)?.toContentAttachmentData()?.let { voiceDraft ->
handleSaveDraft(draft = voiceDraft.toJsonString(), messageType = MessageType.MSGTYPE_AUDIO)
}
setState { it.copy(voiceRecordingUiState = VoiceMessageRecorderView.RecordingUiState.None) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth (re-)setting the state when entering Background? What about screen rotation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will check

Copy link
Contributor Author

@ouchadam ouchadam Nov 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this state update isn't needed, will remove and for rotation the recording stops and the playback composer is displayed until sent or deleted

4b67a6d

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to have: the recording should not stop on screen rotation... (maybe handle that in another PR)

Copy link
Contributor Author

@ouchadam ouchadam Nov 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not stopping the recording will probably mean moving the recording/playback to a service (it would also enable recording/playing whilst the screen is off or in other screens), would need its own ticket/issue

The rotation is already a bit funny in develop~

DEVELOP ROTATION PR - RECORDING ROTATION PR - DRAFT ROTATION
vm-rotation after-rotation after-draft-rotation

EDIT: we also lose some of the state during rotation because the VoiceMessagePlaybackTracker and the ViewModel creation isn't tied to the ViewModelFactory but instead the fragment/activity

withState {
if (it.isVoiceRecording) {
handleEndAllVoiceActions(deleteRecord = false)?.toContentAttachmentData()?.let { voiceDraft ->
handleSaveDraft(draft = voiceDraft.toJsonString(), messageType = MessageType.MSGTYPE_AUDIO)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here maybe give the voice file to the SDK (?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll give it a go 🤞

Copy link
Contributor Author

@ouchadam ouchadam Nov 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we pass the file it means the SDK will have parse the vector Uri https://github.com/vector-im/element-android/blob/develop/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt#L78 which includes interacting with the multipicker

the current recording and draft file are the same instance, the draft itself is the audio file metadata and the uri reference back to the file, other than creating the initial file and reopening I'm not sure we can move much else to the SDK (without moving more of the voice logic)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

val fileName = "Voice message-${UUID.randomUUID()}.$filenameExt"
val outputDirectoryForRoom = File(outputDirectory, roomId.md5()).apply {
if (!exists()) {
mkdirs()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mkdirs() do the existing check, do you remember :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ouchadam
Copy link
Contributor Author

closing whilst addressing comments

@ouchadam ouchadam closed this Nov 23, 2021
@ouchadam ouchadam reopened this Nov 23, 2021
@ouchadam ouchadam force-pushed the feature/adm/voice-draft branch from 3c5832d to bb2239c Compare November 23, 2021 12:48
@ouchadam
Copy link
Contributor Author

noticed some more oddities with rotation, closing again :(

@ouchadam ouchadam closed this Nov 23, 2021
…rkaround to inject into the viewmodel, fixes multiple instances being created out of sync when rotating
…le exists at a previously created folder directory
@ouchadam
Copy link
Contributor Author

closing again in favour of breaking this down into smaller PRs #4548 #4547

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug|Crash] Voice Messages sending need more robustfully

5 participants