Move bottom state to the View state
This commit is contained in:
parent
db0bca9721
commit
36eceb75e8
6 changed files with 58 additions and 38 deletions
|
|
@ -16,5 +16,8 @@ sealed interface MediaViewerEvents {
|
|||
data object RetryLoading : MediaViewerEvents
|
||||
data object ClearLoadingError : MediaViewerEvents
|
||||
data class ViewInTimeline(val eventId: EventId) : MediaViewerEvents
|
||||
data object OpenInfo : MediaViewerEvents
|
||||
data class ConfirmDelete(val eventId: EventId) : MediaViewerEvents
|
||||
data object CloseBottomSheet : MediaViewerEvents
|
||||
data class Delete(val eventId: EventId) : MediaViewerEvents
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,9 @@ import android.content.ActivityNotFoundException
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
|
|
@ -37,6 +35,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTran
|
|||
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
|
||||
import io.element.android.libraries.mediaviewer.api.local.LocalMedia
|
||||
import io.element.android.libraries.mediaviewer.api.local.LocalMediaFactory
|
||||
import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState
|
||||
import io.element.android.libraries.mediaviewer.impl.local.LocalMediaActions
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
|
@ -78,15 +77,7 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
mediaFile.value?.close()
|
||||
}
|
||||
}
|
||||
|
||||
val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
||||
val canDelete by produceState(false, syncUpdateFlow.value) {
|
||||
value = when (inputs.mediaInfo.senderId) {
|
||||
null -> false
|
||||
room.sessionId -> room.canRedactOwn().getOrElse { false } && inputs.eventId != null
|
||||
else -> room.canRedactOther().getOrElse { false } && inputs.eventId != null
|
||||
}
|
||||
}
|
||||
var mediaBottomSheetState by remember { mutableStateOf<MediaBottomSheetState>(MediaBottomSheetState.Hidden) }
|
||||
|
||||
fun handleEvents(mediaViewerEvents: MediaViewerEvents) {
|
||||
when (mediaViewerEvents) {
|
||||
|
|
@ -95,10 +86,36 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
MediaViewerEvents.SaveOnDisk -> coroutineScope.saveOnDisk(localMedia.value)
|
||||
MediaViewerEvents.Share -> coroutineScope.share(localMedia.value)
|
||||
MediaViewerEvents.OpenWith -> coroutineScope.open(localMedia.value)
|
||||
is MediaViewerEvents.Delete -> coroutineScope.delete(mediaViewerEvents.eventId)
|
||||
is MediaViewerEvents.Delete -> {
|
||||
mediaBottomSheetState = MediaBottomSheetState.Hidden
|
||||
coroutineScope.delete(mediaViewerEvents.eventId)
|
||||
}
|
||||
is MediaViewerEvents.ViewInTimeline -> {
|
||||
mediaBottomSheetState = MediaBottomSheetState.Hidden
|
||||
navigator.onViewInTimelineClick(mediaViewerEvents.eventId)
|
||||
}
|
||||
MediaViewerEvents.OpenInfo -> coroutineScope.launch {
|
||||
mediaBottomSheetState = MediaBottomSheetState.MediaDetailsBottomSheetState(
|
||||
eventId = inputs.eventId,
|
||||
canDelete = when (inputs.mediaInfo.senderId) {
|
||||
null -> false
|
||||
room.sessionId -> room.canRedactOwn().getOrElse { false } && inputs.eventId != null
|
||||
else -> room.canRedactOther().getOrElse { false } && inputs.eventId != null
|
||||
},
|
||||
mediaInfo = inputs.mediaInfo,
|
||||
thumbnailSource = inputs.thumbnailSource,
|
||||
)
|
||||
}
|
||||
is MediaViewerEvents.ConfirmDelete -> {
|
||||
mediaBottomSheetState = MediaBottomSheetState.MediaDeleteConfirmationState(
|
||||
eventId = mediaViewerEvents.eventId,
|
||||
mediaInfo = inputs.mediaInfo,
|
||||
thumbnailSource = inputs.thumbnailSource ?: inputs.mediaSource,
|
||||
)
|
||||
}
|
||||
MediaViewerEvents.CloseBottomSheet -> {
|
||||
mediaBottomSheetState = MediaBottomSheetState.Hidden
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +128,7 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
canShowInfo = inputs.canShowInfo,
|
||||
canDownload = inputs.canDownload,
|
||||
canShare = inputs.canShare,
|
||||
canDelete = canDelete,
|
||||
mediaBottomSheetState = mediaBottomSheetState,
|
||||
eventSink = ::handleEvents
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import io.element.android.libraries.matrix.api.core.EventId
|
|||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
import io.element.android.libraries.mediaviewer.api.MediaInfo
|
||||
import io.element.android.libraries.mediaviewer.api.local.LocalMedia
|
||||
import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState
|
||||
|
||||
data class MediaViewerState(
|
||||
val eventId: EventId?,
|
||||
|
|
@ -23,6 +24,6 @@ data class MediaViewerState(
|
|||
val canShowInfo: Boolean,
|
||||
val canDownload: Boolean,
|
||||
val canShare: Boolean,
|
||||
val canDelete: Boolean,
|
||||
val mediaBottomSheetState: MediaBottomSheetState,
|
||||
val eventSink: (MediaViewerEvents) -> Unit,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ import io.element.android.libraries.mediaviewer.api.anApkMediaInfo
|
|||
import io.element.android.libraries.mediaviewer.api.anAudioMediaInfo
|
||||
import io.element.android.libraries.mediaviewer.api.anImageMediaInfo
|
||||
import io.element.android.libraries.mediaviewer.api.local.LocalMedia
|
||||
import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState
|
||||
import io.element.android.libraries.mediaviewer.impl.details.aMediaDeleteConfirmationState
|
||||
import io.element.android.libraries.mediaviewer.impl.details.aMediaDetailsBottomSheetState
|
||||
|
||||
open class MediaViewerStateProvider : PreviewParameterProvider<MediaViewerState> {
|
||||
override val values: Sequence<MediaViewerState>
|
||||
|
|
@ -91,6 +94,12 @@ open class MediaViewerStateProvider : PreviewParameterProvider<MediaViewerState>
|
|||
canShare = false,
|
||||
)
|
||||
},
|
||||
aMediaViewerState(
|
||||
mediaBottomSheetState = aMediaDetailsBottomSheetState(),
|
||||
),
|
||||
aMediaViewerState(
|
||||
mediaBottomSheetState = aMediaDeleteConfirmationState(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -100,6 +109,7 @@ fun aMediaViewerState(
|
|||
canShowInfo: Boolean = true,
|
||||
canDownload: Boolean = true,
|
||||
canShare: Boolean = true,
|
||||
mediaBottomSheetState: MediaBottomSheetState = MediaBottomSheetState.Hidden,
|
||||
eventSink: (MediaViewerEvents) -> Unit = {},
|
||||
) = MediaViewerState(
|
||||
eventId = null,
|
||||
|
|
@ -110,6 +120,6 @@ fun aMediaViewerState(
|
|||
canShowInfo = canShowInfo,
|
||||
canDownload = canDownload,
|
||||
canShare = canShare,
|
||||
canDelete = true,
|
||||
mediaBottomSheetState = mediaBottomSheetState,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ fun MediaViewerView(
|
|||
val defaultBottomPaddingInPixels = if (LocalInspectionMode.current) 303 else 0
|
||||
var bottomPaddingInPixels by remember { mutableIntStateOf(defaultBottomPaddingInPixels) }
|
||||
BackHandler { onBackClick() }
|
||||
var mediaBottomSheetState by remember { mutableStateOf<MediaBottomSheetState>(MediaBottomSheetState.Hidden) }
|
||||
Scaffold(
|
||||
modifier,
|
||||
containerColor = Color.Transparent,
|
||||
|
|
@ -128,12 +127,7 @@ fun MediaViewerView(
|
|||
canShowInfo = state.canShowInfo,
|
||||
onBackClick = onBackClick,
|
||||
onInfoClick = {
|
||||
mediaBottomSheetState = MediaBottomSheetState.MediaDetailsBottomSheetState(
|
||||
eventId = state.eventId,
|
||||
canDelete = state.canDelete,
|
||||
mediaInfo = state.mediaInfo,
|
||||
thumbnailSource = state.thumbnailSource,
|
||||
)
|
||||
state.eventSink(MediaViewerEvents.OpenInfo)
|
||||
},
|
||||
eventSink = state.eventSink
|
||||
)
|
||||
|
|
@ -146,24 +140,19 @@ fun MediaViewerView(
|
|||
}
|
||||
}
|
||||
}
|
||||
when (val bottomSheetState = mediaBottomSheetState) {
|
||||
when (val bottomSheetState = state.mediaBottomSheetState) {
|
||||
MediaBottomSheetState.Hidden -> Unit
|
||||
is MediaBottomSheetState.MediaDetailsBottomSheetState -> {
|
||||
MediaDetailsBottomSheet(
|
||||
state = bottomSheetState,
|
||||
onViewInTimeline = {
|
||||
mediaBottomSheetState = MediaBottomSheetState.Hidden
|
||||
state.eventSink(MediaViewerEvents.ViewInTimeline(it))
|
||||
},
|
||||
onDelete = { eventId ->
|
||||
mediaBottomSheetState = MediaBottomSheetState.MediaDeleteConfirmationState(
|
||||
eventId = eventId,
|
||||
mediaInfo = state.mediaInfo,
|
||||
thumbnailSource = state.thumbnailSource,
|
||||
)
|
||||
state.eventSink(MediaViewerEvents.ConfirmDelete(eventId))
|
||||
},
|
||||
onDismiss = {
|
||||
mediaBottomSheetState = MediaBottomSheetState.Hidden
|
||||
state.eventSink(MediaViewerEvents.CloseBottomSheet)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -171,11 +160,10 @@ fun MediaViewerView(
|
|||
MediaDeleteConfirmationBottomSheet(
|
||||
state = bottomSheetState,
|
||||
onDelete = {
|
||||
mediaBottomSheetState = MediaBottomSheetState.Hidden
|
||||
state.eventSink(MediaViewerEvents.Delete(it))
|
||||
},
|
||||
onDismiss = {
|
||||
mediaBottomSheetState = MediaBottomSheetState.Hidden
|
||||
state.eventSink(MediaViewerEvents.CloseBottomSheet)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
|||
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
|
||||
import io.element.android.libraries.mediaviewer.api.anApkMediaInfo
|
||||
import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState
|
||||
import io.element.android.libraries.mediaviewer.test.FakeLocalMediaActions
|
||||
import io.element.android.libraries.mediaviewer.test.FakeLocalMediaFactory
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
|
|
@ -67,7 +68,7 @@ class MediaViewerPresenterTest {
|
|||
assertThat(initialState.canShowInfo).isTrue()
|
||||
assertThat(initialState.canDownload).isTrue()
|
||||
assertThat(initialState.canShare).isTrue()
|
||||
assertThat(initialState.canDelete).isFalse()
|
||||
assertThat(initialState.mediaBottomSheetState).isEqualTo(MediaBottomSheetState.Hidden)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +88,7 @@ class MediaViewerPresenterTest {
|
|||
assertThat(initialState.canShowInfo).isFalse()
|
||||
assertThat(initialState.canDownload).isTrue()
|
||||
assertThat(initialState.canShare).isTrue()
|
||||
assertThat(initialState.canDelete).isFalse()
|
||||
assertThat(initialState.mediaBottomSheetState).isEqualTo(MediaBottomSheetState.Hidden)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +108,7 @@ class MediaViewerPresenterTest {
|
|||
assertThat(initialState.canShowInfo).isTrue()
|
||||
assertThat(initialState.canDownload).isTrue()
|
||||
assertThat(initialState.canShare).isFalse()
|
||||
assertThat(initialState.canDelete).isFalse()
|
||||
assertThat(initialState.mediaBottomSheetState).isEqualTo(MediaBottomSheetState.Hidden)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +128,7 @@ class MediaViewerPresenterTest {
|
|||
assertThat(initialState.canShowInfo).isTrue()
|
||||
assertThat(initialState.canDownload).isFalse()
|
||||
assertThat(initialState.canShare).isTrue()
|
||||
assertThat(initialState.canDelete).isFalse()
|
||||
assertThat(initialState.mediaBottomSheetState).isEqualTo(MediaBottomSheetState.Hidden)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +148,7 @@ class MediaViewerPresenterTest {
|
|||
assertThat(initialState.canShowInfo).isTrue()
|
||||
assertThat(initialState.canDownload).isTrue()
|
||||
assertThat(initialState.canShare).isTrue()
|
||||
assertThat(initialState.canDelete).isTrue()
|
||||
assertThat(initialState.mediaBottomSheetState).isEqualTo(MediaBottomSheetState.Hidden)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +169,7 @@ class MediaViewerPresenterTest {
|
|||
assertThat(initialState.canShowInfo).isTrue()
|
||||
assertThat(initialState.canDownload).isTrue()
|
||||
assertThat(initialState.canShare).isTrue()
|
||||
assertThat(initialState.canDelete).isFalse()
|
||||
assertThat(initialState.mediaBottomSheetState).isEqualTo(MediaBottomSheetState.Hidden)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue