extract rememberSaveMediaAction to eliminate toast/permission duplication

This commit is contained in:
davotoula
2026-03-02 18:07:17 +00:00
parent 08f389230e
commit 3220b4a1a7
2 changed files with 32 additions and 58 deletions
@@ -20,10 +20,7 @@
*/ */
package com.vitorpamplona.amethyst.service.playback.composable.controls package com.vitorpamplona.amethyst.service.playback.composable.controls
import android.Manifest
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build
import android.widget.Toast
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@@ -32,14 +29,10 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.richtext.MediaUrlVideo import com.vitorpamplona.amethyst.commons.richtext.MediaUrlVideo
import com.vitorpamplona.amethyst.service.playback.composable.DEFAULT_MUTED_SETTING import com.vitorpamplona.amethyst.service.playback.composable.DEFAULT_MUTED_SETTING
import com.vitorpamplona.amethyst.service.playback.composable.MediaControllerState import com.vitorpamplona.amethyst.service.playback.composable.MediaControllerState
@@ -50,10 +43,8 @@ import com.vitorpamplona.amethyst.ui.components.ShareMediaAction
import com.vitorpamplona.amethyst.ui.components.getActivity import com.vitorpamplona.amethyst.ui.components.getActivity
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
import kotlinx.coroutines.launch
@Preview @Preview
@Composable @Composable
@@ -132,13 +123,10 @@ fun RenderTopButtons(
modifier: Modifier, modifier: Modifier,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
) { ) {
val context = LocalContext.current
val scope = rememberCoroutineScope()
val shareDialogVisible = remember { mutableStateOf(false) } val shareDialogVisible = remember { mutableStateOf(false) }
val saveAction =
val writeStoragePermission = rememberSaveMediaAction { context ->
rememberPermissionState(Manifest.permission.WRITE_EXTERNAL_STORAGE) { accountViewModel.saveMediaToGallery(mediaData.videoUri, mediaData.mimeType, context)
if (it) accountViewModel.saveMediaToGallery(mediaData.videoUri, mediaData.mimeType, context)
} }
LaunchedEffect(controllerVisible.value) { LaunchedEffect(controllerVisible.value) {
@@ -166,21 +154,7 @@ fun RenderTopButtons(
showSave = !isLive, showSave = !isLive,
showPip = pipSupported, showPip = pipSupported,
onShareClick = { shareDialogVisible.value = true }, onShareClick = { shareDialogVisible.value = true },
onSaveClick = { onSaveClick = saveAction,
scope.launch {
Toast
.makeText(
context,
stringRes(context, R.string.video_download_has_started_toast),
Toast.LENGTH_SHORT,
).show()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q || writeStoragePermission.status.isGranted) {
accountViewModel.saveMediaToGallery(mediaData.videoUri, mediaData.mimeType, context)
} else {
writeStoragePermission.launchPermissionRequest()
}
},
onPipClick = onPictureInPictureClick, onPipClick = onPictureInPictureClick,
) )
@@ -87,9 +87,36 @@ fun AnimatedSaveButton(
} }
} }
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun rememberSaveMediaAction(onSaveClick: (Context) -> Unit): () -> Unit {
val context = LocalContext.current
val scope = rememberCoroutineScope()
val writeStoragePermission =
rememberPermissionState(Manifest.permission.WRITE_EXTERNAL_STORAGE) { isGranted ->
if (isGranted) onSaveClick(context)
}
return {
scope.launch {
Toast
.makeText(
context,
stringRes(context, R.string.video_download_has_started_toast),
Toast.LENGTH_SHORT,
).show()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q || writeStoragePermission.status.isGranted) {
onSaveClick(context)
} else {
writeStoragePermission.launchPermissionRequest()
}
}
}
@OptIn(ExperimentalPermissionsApi::class) @OptIn(ExperimentalPermissionsApi::class)
@Composable @Composable
fun SaveMediaButton(onSaveClick: (localContext: Context) -> Unit) { fun SaveMediaButton(onSaveClick: (localContext: Context) -> Unit) {
val saveAction = rememberSaveMediaAction(onSaveClick)
Box(modifier = PinBottomIconSize) { Box(modifier = PinBottomIconSize) {
Box( Box(
Modifier Modifier
@@ -98,35 +125,8 @@ fun SaveMediaButton(onSaveClick: (localContext: Context) -> Unit) {
.align(Alignment.Center) .align(Alignment.Center)
.background(MaterialTheme.colorScheme.background), .background(MaterialTheme.colorScheme.background),
) )
val localContext = LocalContext.current
val writeStoragePermissionState =
rememberPermissionState(Manifest.permission.WRITE_EXTERNAL_STORAGE) { isGranted ->
if (isGranted) {
onSaveClick(localContext)
}
}
val scope = rememberCoroutineScope()
IconButton( IconButton(
onClick = { onClick = saveAction,
scope.launch {
Toast
.makeText(
localContext,
stringRes(localContext, R.string.video_download_has_started_toast),
Toast.LENGTH_SHORT,
).show()
}
if (
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ||
writeStoragePermissionState.status.isGranted
) {
onSaveClick(localContext)
} else {
writeStoragePermissionState.launchPermissionRequest()
}
},
modifier = Size50Modifier, modifier = Size50Modifier,
) { ) {
Icon( Icon(