Add PickerLauncher wrapper for media/file pickers. (#361)

* Add `PickerLauncher` wrapper for media/file pickers.

* Add FileProvider path, handle Camera picker and add NoOp implementation to fix tests.

* Move media pickers to their own module.

* Add missing media pickers

* Add feature flag and some extra tests
This commit is contained in:
Jorge Martin Espinosa 2023-04-28 10:52:34 +02:00 committed by GitHub
parent 78a715ce8d
commit eeca1c9ee3
16 changed files with 483 additions and 51 deletions

View file

@ -24,4 +24,6 @@ sealed interface MessageComposerEvents {
object CloseSpecialMode : MessageComposerEvents
data class SetMode(val composerMode: MessageComposerMode) : MessageComposerEvents
data class UpdateText(val text: CharSequence) : MessageComposerEvents
object TakePhoto : MessageComposerEvents
}

View file

@ -21,23 +21,37 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.data.StableCharSequence
import io.element.android.libraries.core.data.toStableCharSequence
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.mediapickers.PickerProvider
import io.element.android.libraries.textcomposer.MessageComposerMode
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
class MessageComposerPresenter @Inject constructor(
private val appCoroutineScope: CoroutineScope,
private val room: MatrixRoom
private val room: MatrixRoom,
private val mediaPickerProvider: PickerProvider,
private val featureFlagService: FeatureFlagService,
) : Presenter<MessageComposerState> {
@Composable
override fun present(): MessageComposerState {
val localCoroutineScope = rememberCoroutineScope()
// Example usage of custom pickers
val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(onResult = { uri ->
Timber.d("Photo saved at $uri")
})
val isFullScreen = rememberSaveable {
mutableStateOf(false)
}
@ -63,9 +77,14 @@ class MessageComposerPresenter @Inject constructor(
text.value = "".toStableCharSequence()
composerMode.setToNormal()
}
is MessageComposerEvents.SendMessage -> appCoroutineScope.sendMessage(event.message, composerMode, text)
is MessageComposerEvents.SetMode -> composerMode.value = event.composerMode
}
MessageComposerEvents.TakePhoto -> localCoroutineScope.launch {
if (featureFlagService.isFeatureEnabled(FeatureFlags.ShowMediaUploadingFlow)) {
cameraPhotoPicker.launch()
}
}}
}
return MessageComposerState(
@ -92,6 +111,7 @@ class MessageComposerPresenter @Inject constructor(
capturedMode.eventId,
text
)
is MessageComposerMode.Quote -> TODO()
is MessageComposerMode.Reply -> room.replyMessage(
capturedMode.eventId,

View file

@ -53,6 +53,9 @@ fun MessageComposerView(
composerMode = state.mode,
onCloseSpecialMode = ::onCloseSpecialMode,
onComposerTextChange = ::onComposerTextChange,
onAddAttachment = {
state.eventSink(MessageComposerEvents.TakePhoto)
},
composerCanSendMessage = state.isSendButtonVisible,
composerText = state.text?.charSequence?.toString(),
isInDarkMode = !ElementTheme.colors.isLight,