Settings: handle lost access to export folder

This commit is contained in:
Pierre-Yves Nicolas
2026-01-31 06:50:13 +01:00
parent 429d4e7a37
commit 6fa3fe68fb
15 changed files with 62 additions and 20 deletions

View File

@@ -248,6 +248,9 @@ class MainActivity : ComponentActivity() {
}
}
val settingsUiState by settingsViewModel.uiState.collectAsStateWithLifecycle()
LaunchedEffect(Unit) {
settingsViewModel.refreshExportDirName()
}
SettingsScreen(
settingsUiState,
onChooseDirectoryClick = {

View File

@@ -37,10 +37,8 @@ class SettingsRepository(private val context: Context) {
prefs[EXPORT_DIR_URI]
}
val exportDirName: Flow<String?> = exportDirUri.map { uriString ->
uriString?.let {
DocumentFile.fromTreeUri(context, it.toUri())?.name
}
fun resolveExportDirName(uri: String): String? {
return DocumentFile.fromTreeUri(context, uri.toUri())?.name
}
val exportFormat: Flow<ExportFormat> =

View File

@@ -14,8 +14,6 @@
*/
package org.fairscan.app.ui.screens.settings
import android.content.Context
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.clickable
@@ -41,14 +39,12 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import org.fairscan.app.R
import org.fairscan.app.domain.ExportQuality
import org.fairscan.app.ui.components.BackButton
@@ -92,7 +88,20 @@ private fun SettingsContent(
onExportQualityChanged: (ExportQuality) -> Unit,
modifier: Modifier = Modifier,
) {
val folderName = uiState.exportDirName ?: stringResource(R.string.download_dirname)
println(uiState)
val (folderLabel, folderLabelColor) = when {
uiState.exportDirUri == null ->
stringResource(R.string.download_dirname) to
MaterialTheme.colorScheme.onSurface
uiState.exportDirName != null ->
uiState.exportDirName to
MaterialTheme.colorScheme.onSurface
else ->
stringResource(R.string.export_folder_permission_lost) to
MaterialTheme.colorScheme.error
}
Column(
modifier
@@ -102,13 +111,14 @@ private fun SettingsContent(
) {
DirectorySettingItem(
label = stringResource(R.string.export_directory),
folderName = folderName,
onClick = onChooseDirectoryClick
folderLabel,
folderLabelColor,
onClick = onChooseDirectoryClick,
)
Spacer(Modifier.height(12.dp))
if (uiState.exportDirName != null) {
if (uiState.exportDirUri != null) {
OutlinedButton(
onClick = onResetExportDirClick,
border = BorderStroke(1.dp, MaterialTheme.colorScheme.primary),
@@ -156,9 +166,11 @@ private fun SettingsContent(
@Composable
fun DirectorySettingItem(
label: String,
folderName: String,
folderLabel: String,
folderLabelColor: Color,
onClick: () -> Unit,
) {
) {
Column {
Text(
text = label,
@@ -181,8 +193,9 @@ fun DirectorySettingItem(
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = folderName,
style = MaterialTheme.typography.bodyLarge
text = folderLabel,
style = MaterialTheme.typography.bodyLarge,
color = folderLabelColor,
)
Icon(

View File

@@ -16,14 +16,18 @@ package org.fairscan.app.ui.screens.settings
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.fairscan.app.AppContainer
import org.fairscan.app.domain.ExportQuality
data class SettingsUiState(
val exportDirUri: String? = null,
val exportDirName: String? = null,
val exportFormat: ExportFormat = ExportFormat.PDF,
val exportQuality: ExportQuality = ExportQuality.BALANCED,
@@ -33,13 +37,18 @@ class SettingsViewModel(container: AppContainer) : ViewModel() {
private val repo = container.settingsRepository
private val _dirName = MutableStateFlow<String?>(null)
val dirName: StateFlow<String?> = _dirName
val uiState = combine(
repo.exportDirName,
repo.exportDirUri,
dirName,
repo.exportFormat,
repo.exportQuality,
) { dir, format, quality ->
) { uri, name, format, quality ->
SettingsUiState(
exportDirName = dir,
exportDirUri = uri,
exportDirName = name,
exportFormat = format,
exportQuality = quality,
)
@@ -52,6 +61,7 @@ class SettingsViewModel(container: AppContainer) : ViewModel() {
fun setExportDirUri(uri: String?) {
viewModelScope.launch {
repo.setExportDirUri(uri)
refreshExportDirName()
}
}
@@ -66,4 +76,11 @@ class SettingsViewModel(container: AppContainer) : ViewModel() {
repo.setExportQuality(quality)
}
}
fun refreshExportDirName() {
viewModelScope.launch {
val uri = repo.exportDirUri.first()
_dirName.value = uri?.let { repo.resolveExportDirName(it) }
}
}
}

View File

@@ -28,6 +28,7 @@
<string name="export">Exportovat</string>
<string name="export_as">Exportovat jako %1$s</string>
<string name="export_directory">Složka pro export</string>
<string name="export_folder_permission_lost">Ztracený přístup ke složce</string>
<string name="export_format">Formát exportu</string>
<string name="export_quality">Kvalita exportu</string>
<string name="export_quality_low">Nízká</string>

View File

@@ -28,6 +28,7 @@
<string name="export">Exportieren</string>
<string name="export_as">Als %1$s exportieren</string>
<string name="export_directory">Exportordner</string>
<string name="export_folder_permission_lost">Zugriff auf Ordner verloren</string>
<string name="export_format">Exportformat</string>
<string name="export_quality">Exportqualität</string>
<string name="export_quality_low">Niedrig</string>

View File

@@ -28,6 +28,7 @@
<string name="export">Exportar</string>
<string name="export_as">Exportar como %1$s</string>
<string name="export_directory">Carpeta de exportación</string>
<string name="export_folder_permission_lost">Acceso a la carpeta perdido</string>
<string name="export_format">Formato de exportación</string>
<string name="export_quality">Calidad de exportación</string>
<string name="export_quality_low">Baja</string>

View File

@@ -28,6 +28,7 @@
<string name="export">Exporter</string>
<string name="export_as">Exporter en %1$s</string>
<string name="export_directory">Dossier dexport</string>
<string name="export_folder_permission_lost">Accès au dossier perdu</string>
<string name="export_format">Format dexport</string>
<string name="export_quality">Qualité dexport</string>
<string name="export_quality_low">Basse</string>

View File

@@ -28,6 +28,7 @@
<string name="export">Esporta</string>
<string name="export_as">Esporta come %1$s</string>
<string name="export_directory">Cartella di esportazione</string>
<string name="export_folder_permission_lost">Accesso alla cartella perso</string>
<string name="export_format">Formato di esportazione</string>
<string name="export_quality">Qualità di esportazione</string>
<string name="export_quality_low">Bassa</string>

View File

@@ -28,6 +28,7 @@
<string name="export">Exportar</string>
<string name="export_as">Exportar como %1$s</string>
<string name="export_directory">Diretório de exportação</string>
<string name="export_folder_permission_lost">Acesso à pasta perdido</string>
<string name="export_format">Formato de exportação</string>
<string name="export_quality">Qualidade de exportação</string>
<string name="export_quality_low">Baixa</string>

View File

@@ -28,6 +28,7 @@
<string name="export">Экспорт</string>
<string name="export_as">Экспортировать как %1$s</string>
<string name="export_directory">Папка экспорта</string>
<string name="export_folder_permission_lost">Доступ к папке потерян</string>
<string name="export_format">Формат экспорта</string>
<string name="export_quality">Качество экспорта</string>
<string name="export_quality_low">Низкое</string>

View File

@@ -28,6 +28,7 @@
<string name="export">Dışa aktar</string>
<string name="export_as">%1$s olarak dışa aktar</string>
<string name="export_directory">Dışa aktarma dizini</string>
<string name="export_folder_permission_lost">Klasör erişimi kaybedildi</string>
<string name="export_format">Dışa aktarma biçimi</string>
<string name="export_quality">Dışa aktarma kalitesi</string>
<string name="export_quality_low">Düşük</string>

View File

@@ -28,6 +28,7 @@
<string name="export">匯出</string>
<string name="export_as">匯出為 %1$s</string>
<string name="export_directory">匯出目錄</string>
<string name="export_folder_permission_lost">資料夾存取權限已遺失</string>
<string name="export_format">匯出格式</string>
<string name="export_quality">匯出品質</string>
<string name="export_quality_low"></string>

View File

@@ -28,6 +28,7 @@
<string name="export">导出</string>
<string name="export_as">导出为 %1$s</string>
<string name="export_directory">导出目录</string>
<string name="export_folder_permission_lost">文件夹访问权限已丢失</string>
<string name="export_format">导出格式</string>
<string name="export_quality">导出质量</string>
<string name="export_quality_low"></string>

View File

@@ -32,6 +32,7 @@
<string name="export">Export</string>
<string name="export_as">Export as %1$s</string>
<string name="export_directory">Export folder</string>
<string name="export_folder_permission_lost">Folder access lost</string>
<string name="export_format">Export format</string>
<string name="export_quality">Export quality</string>
<string name="export_quality_low">Low</string>