diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/Tiles/SaveFolderTile.kt b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/Tiles/SaveFolderTile.kt
index 16b7547..bd8bd0c 100644
--- a/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/Tiles/SaveFolderTile.kt
+++ b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/Tiles/SaveFolderTile.kt
@@ -3,6 +3,10 @@ package app.myzel394.alibi.ui.components.SettingsScreen.Tiles
import android.Manifest
import android.content.Intent
import android.net.Uri
+import android.os.Build
+import android.os.Environment
+import android.provider.MediaStore
+import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -15,10 +19,12 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.CameraAlt
import androidx.compose.material.icons.filled.Cancel
import androidx.compose.material.icons.filled.Folder
import androidx.compose.material.icons.filled.InsertDriveFile
import androidx.compose.material.icons.filled.Lock
+import androidx.compose.material.icons.filled.Mic
import androidx.compose.material.icons.filled.PermMedia
import androidx.compose.material.icons.filled.Warning
import androidx.compose.material3.AlertDialog
@@ -55,10 +61,14 @@ import androidx.documentfile.provider.DocumentFile
import app.myzel394.alibi.R
import app.myzel394.alibi.dataStore
import app.myzel394.alibi.db.AppSettings
+import app.myzel394.alibi.helpers.AudioBatchesFolder
+import app.myzel394.alibi.helpers.VideoBatchesFolder
+import app.myzel394.alibi.ui.MEDIA_SUBFOLDER_NAME
import app.myzel394.alibi.ui.RECORDER_MEDIA_SELECTED_VALUE
import app.myzel394.alibi.ui.SHEET_BOTTOM_OFFSET
import app.myzel394.alibi.ui.SUPPORTS_SAVING_VIDEOS_IN_CUSTOM_FOLDERS
import app.myzel394.alibi.ui.SUPPORTS_SCOPED_STORAGE
+import app.myzel394.alibi.ui.components.SettingsScreen.atoms.FolderBreadcrumbs
import app.myzel394.alibi.ui.components.atoms.MessageBox
import app.myzel394.alibi.ui.components.atoms.MessageType
import app.myzel394.alibi.ui.components.atoms.PermissionRequester
@@ -129,6 +139,16 @@ fun SaveFolderTile(
)
}
+ var showDCIMFolderHelpSheet by remember { mutableStateOf(false) }
+
+ if (showDCIMFolderHelpSheet) {
+ MediaFoldersExplanationDialog(
+ onDismiss = {
+ showDCIMFolderHelpSheet = false
+ }
+ )
+ }
+
SettingsTile(
title = stringResource(R.string.ui_settings_option_saveFolder_title),
description = stringResource(R.string.ui_settings_option_saveFolder_explanation),
@@ -181,20 +201,12 @@ fun SaveFolderTile(
when (settings.saveFolder) {
null -> {}
- RECORDER_MEDIA_SELECTED_VALUE -> {}
- // Custom folder
- else ->
+ RECORDER_MEDIA_SELECTED_VALUE -> {
Button(
onClick = {
- openFolder(
- DocumentFile.fromTreeUri(
- context,
- settings.saveFolder.toUri(),
- )!!.uri
- )
+ showDCIMFolderHelpSheet = true
},
shape = MaterialTheme.shapes.small,
- // TODO: Adjust padding everywhere
contentPadding = ButtonDefaults.TextButtonContentPadding,
colors = ButtonDefaults.filledTonalButtonColors(
contentColor = MaterialTheme.colorScheme.onTertiaryContainer,
@@ -202,16 +214,149 @@ fun SaveFolderTile(
),
) {
Text(
- stringResource(R.string.ui_settings_option_saveFolder_openFolder_label),
+ stringResource(R.string.ui_settings_option_saveFolder_explainMediaFolder_label),
fontSize = MaterialTheme.typography.bodySmall.fontSize,
)
}
+ }
+ // Custom folder
+ else ->
+ // Doesn't seem to reliably work on all devices, 30 & 33
+ // has been tested; so we just show the button for versions
+ // above 30
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
+ Button(
+ onClick = {
+ openFolder(
+ DocumentFile.fromTreeUri(
+ context,
+ settings.saveFolder.toUri(),
+ )!!.uri
+ )
+ },
+ shape = MaterialTheme.shapes.small,
+ // TODO: Adjust padding everywhere
+ contentPadding = ButtonDefaults.TextButtonContentPadding,
+ colors = ButtonDefaults.filledTonalButtonColors(
+ contentColor = MaterialTheme.colorScheme.onTertiaryContainer,
+ containerColor = MaterialTheme.colorScheme.tertiaryContainer,
+ ),
+ ) {
+ Text(
+ stringResource(R.string.ui_settings_option_saveFolder_openFolder_label),
+ fontSize = MaterialTheme.typography.bodySmall.fontSize,
+ )
+ }
}
}
}
)
}
+@Composable
+fun MediaFoldersExplanationDialog(
+ onDismiss: () -> Unit,
+) {
+ val context = LocalContext.current
+ val openFolder = rememberOpenUri()
+
+ AlertDialog(
+ onDismissRequest = onDismiss,
+ icon = {
+ Icon(
+ Icons.Default.PermMedia,
+ contentDescription = null,
+ )
+ },
+ title = {
+ Text(stringResource(R.string.ui_settings_option_saveFolder_explainMediaFolder_label))
+ },
+ confirmButton = {
+ Button(
+ onClick = onDismiss,
+ ) {
+ Text(stringResource(R.string.dialog_close_neutral_label))
+ }
+ },
+ text = {
+ Column(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.spacedBy(32.dp),
+ ) {
+ Text(
+ stringResource(R.string.ui_settings_option_saveFolder_explainMediaFolder_generalExplanation),
+ style = MaterialTheme.typography.bodySmall,
+ color = MaterialTheme.colorScheme.onSurface,
+ )
+ // I tried adding support for opening the folder directly by tapping on the
+ // breadcrumbs, but couldn't get it to work.
+ Column(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.spacedBy(8.dp),
+ ) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.SpaceBetween,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 8.dp)
+ .clip(MaterialTheme.shapes.medium)
+ .background(MaterialTheme.colorScheme.surfaceVariant)
+ .padding(16.dp)
+ ) {
+ Icon(
+ Icons.Default.Mic,
+ contentDescription = null,
+ )
+ FolderBreadcrumbs(
+ folders = listOf(
+ if (SUPPORTS_SCOPED_STORAGE)
+ AudioBatchesFolder.BASE_SCOPED_STORAGE_RELATIVE_PATH
+ else
+ AudioBatchesFolder.BASE_LEGACY_STORAGE_FOLDER,
+ MEDIA_SUBFOLDER_NAME
+ )
+ )
+ Box {}
+ }
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.SpaceBetween,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 8.dp)
+ .clip(MaterialTheme.shapes.medium)
+ .background(MaterialTheme.colorScheme.surfaceVariant)
+ .padding(16.dp)
+ ) {
+ Icon(
+ Icons.Default.CameraAlt,
+ contentDescription = null,
+ )
+ FolderBreadcrumbs(
+ folders = listOf(
+ if (SUPPORTS_SCOPED_STORAGE)
+ VideoBatchesFolder.BASE_SCOPED_STORAGE_RELATIVE_PATH
+ else
+ VideoBatchesFolder.BASE_LEGACY_STORAGE_FOLDER,
+ MEDIA_SUBFOLDER_NAME
+ )
+ )
+ Box {}
+ }
+ }
+ Text(
+ stringResource(R.string.ui_settings_option_saveFolder_explainMediaFolder_subfoldersExplanation),
+ style = MaterialTheme.typography.bodySmall,
+ color = MaterialTheme.colorScheme.onSurface,
+ )
+ }
+ }
+ )
+}
+
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SelectionSheet(
diff --git a/app/src/main/java/app/myzel394/alibi/ui/effects/open-uri.kt b/app/src/main/java/app/myzel394/alibi/ui/effects/open-uri.kt
index 9e0ef36..910679a 100644
--- a/app/src/main/java/app/myzel394/alibi/ui/effects/open-uri.kt
+++ b/app/src/main/java/app/myzel394/alibi/ui/effects/open-uri.kt
@@ -2,6 +2,7 @@ package app.myzel394.alibi.ui.effects
import android.content.Intent
import android.net.Uri
+import android.provider.DocumentsContract
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
@@ -10,7 +11,9 @@ fun rememberOpenUri(): (uri: Uri) -> Unit {
val context = LocalContext.current
return fun(uri: Uri) {
- val intent = Intent(Intent.ACTION_VIEW, uri)
+ val intent = Intent(Intent.ACTION_VIEW, uri).apply {
+ setDataAndType(uri, DocumentsContract.Document.MIME_TYPE_DIR)
+ }
context.startActivity(intent)
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b373d12..0e6cd29 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -183,4 +183,8 @@
Alibi couldn\'t find a file manager app on your phone. Please install a file manager app and try again. If this message still appears, you can try using a custom batches folder in the advanced settings section. Alibi may not fully work on your device.
Recording Video
Open Folder in Files
+ Where are my batches stored?
+ To view your batches, open the Files app, go to the internal storage and then you will find your batches in following folders:
+ The final merged recordings will be saved in those folders. Each recording creates a subfolder to store the short batches in ("%s" for audio recordings, "%s" for video recordings). To view the individual batches, you may need to enable hidden files in the Files app.
+ Tap on a folder to open it in the Files app
\ No newline at end of file