Show the gallery folder name from the first frame
- Carry the folder name through GalleryRoute into the ViewModel's SavedStateHandle, so the TopBar title is correct immediately on navigation, before any directory listing completes - Seed a provisional name from the SAF URI segment in loadPhotos as a fallback for entry points without a name (after-camera navigation) - Drop the 'Gallery' fallback title and the unused gallery_title string
This commit is contained in:
1 parent
460c50bfd9
commit
428749d8a8
5 files changed
+20
-14
No files matched your search
@@ -32,7 +32,10 @@ import kotlinx.serialization.Serializable
|
|||||||
object FoldersRoute
|
object FoldersRoute
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class GalleryRoute(val folderUri: String)
|
data class GalleryRoute(
|
||||||
|
val folderUri: String,
|
||||||
|
val folderName: String = "",
|
||||||
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class CameraRoute(
|
data class CameraRoute(
|
||||||
@@ -70,8 +73,8 @@ fun OneCameraNavGraph(navController: NavHostController) {
|
|||||||
) {
|
) {
|
||||||
composable<FoldersRoute> {
|
composable<FoldersRoute> {
|
||||||
FoldersScreen(
|
FoldersScreen(
|
||||||
onNavigateToGallery = { folderUri ->
|
onNavigateToGallery = { folderUri, folderName ->
|
||||||
navController.navigate(GalleryRoute(folderUri))
|
navController.navigate(GalleryRoute(folderUri, folderName))
|
||||||
},
|
},
|
||||||
onNavigateToCamera = { folderUri ->
|
onNavigateToCamera = { folderUri ->
|
||||||
navController.navigate(
|
navController.navigate(
|
||||||
@@ -93,8 +96,8 @@ fun OneCameraNavGraph(navController: NavHostController) {
|
|||||||
onNavigateToCamera = { folderUri ->
|
onNavigateToCamera = { folderUri ->
|
||||||
navController.navigate(CameraRoute(folderUri))
|
navController.navigate(CameraRoute(folderUri))
|
||||||
},
|
},
|
||||||
onNavigateToSubfolder = { folderUri ->
|
onNavigateToSubfolder = { folderUri, folderName ->
|
||||||
navController.navigate(GalleryRoute(folderUri))
|
navController.navigate(GalleryRoute(folderUri, folderName))
|
||||||
},
|
},
|
||||||
onNavigateBack = { navController.popBackStack() },
|
onNavigateBack = { navController.popBackStack() },
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ import com.example.onecamera.ui.components.oneCameraTopAppBarColors
|
|||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun FoldersScreen(
|
fun FoldersScreen(
|
||||||
onNavigateToGallery: (String) -> Unit,
|
onNavigateToGallery: (folderUri: String, folderName: String) -> Unit,
|
||||||
onNavigateToCamera: (String) -> Unit,
|
onNavigateToCamera: (String) -> Unit,
|
||||||
onNavigateToSettings: () -> Unit,
|
onNavigateToSettings: () -> Unit,
|
||||||
viewModel: FoldersViewModel = hiltViewModel(),
|
viewModel: FoldersViewModel = hiltViewModel(),
|
||||||
@@ -230,7 +230,7 @@ fun FoldersScreen(
|
|||||||
|
|
||||||
onClick = {
|
onClick = {
|
||||||
viewModel.prefetchFolderForNavigation(folder.uri.toString())
|
viewModel.prefetchFolderForNavigation(folder.uri.toString())
|
||||||
onNavigateToGallery(folder.uri.toString())
|
onNavigateToGallery(folder.uri.toString(), folder.name)
|
||||||
},
|
},
|
||||||
onCompress = { viewModel.zipFolderAndShare(folder) },
|
onCompress = { viewModel.zipFolderAndShare(folder) },
|
||||||
onCompressJpeg85 = {
|
onCompressJpeg85 = {
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged
|
|||||||
fun GalleryScreen(
|
fun GalleryScreen(
|
||||||
folderUri: String,
|
folderUri: String,
|
||||||
onNavigateToCamera: (String) -> Unit,
|
onNavigateToCamera: (String) -> Unit,
|
||||||
onNavigateToSubfolder: (String) -> Unit,
|
onNavigateToSubfolder: (folderUri: String, folderName: String) -> Unit,
|
||||||
onNavigateBack: () -> Unit,
|
onNavigateBack: () -> Unit,
|
||||||
viewModel: GalleryViewModel = hiltViewModel(),
|
viewModel: GalleryViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
@@ -281,9 +281,7 @@ fun GalleryScreen(
|
|||||||
title = {
|
title = {
|
||||||
Column {
|
Column {
|
||||||
Text(
|
Text(
|
||||||
uiState.folderName.ifEmpty {
|
uiState.folderName,
|
||||||
stringResource(R.string.gallery_title)
|
|
||||||
},
|
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
@@ -434,7 +432,7 @@ fun GalleryScreen(
|
|||||||
|
|
||||||
onFolderClick = {
|
onFolderClick = {
|
||||||
viewModel.prefetchFolderForNavigation(it.uri.toString())
|
viewModel.prefetchFolderForNavigation(it.uri.toString())
|
||||||
onNavigateToSubfolder(it.uri.toString())
|
onNavigateToSubfolder(it.uri.toString(), it.name)
|
||||||
},
|
},
|
||||||
onFolderCompress = { viewModel.zipFolderAndShare(it) },
|
onFolderCompress = { viewModel.zipFolderAndShare(it) },
|
||||||
onFolderCompressJpeg85 = { viewModel.zipFolderCompressedJpegsAndShare(it) },
|
onFolderCompressJpeg85 = { viewModel.zipFolderCompressedJpegsAndShare(it) },
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.content.Context
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import coil3.SingletonImageLoader
|
import coil3.SingletonImageLoader
|
||||||
@@ -113,6 +114,7 @@ data class GalleryUiState(
|
|||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class GalleryViewModel @Inject constructor(
|
class GalleryViewModel @Inject constructor(
|
||||||
|
savedStateHandle: SavedStateHandle,
|
||||||
private val preferencesRepository: UserPreferencesRepository,
|
private val preferencesRepository: UserPreferencesRepository,
|
||||||
private val listGalleryUseCase: ListGalleryUseCase,
|
private val listGalleryUseCase: ListGalleryUseCase,
|
||||||
private val listFolderTreeUseCase: ListFolderTreeUseCase,
|
private val listFolderTreeUseCase: ListFolderTreeUseCase,
|
||||||
@@ -128,7 +130,11 @@ class GalleryViewModel @Inject constructor(
|
|||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
val uiState: StateFlow<GalleryUiState>
|
val uiState: StateFlow<GalleryUiState>
|
||||||
field: MutableStateFlow<GalleryUiState> = MutableStateFlow(GalleryUiState())
|
field: MutableStateFlow<GalleryUiState> = MutableStateFlow(
|
||||||
|
// Navigation puts type-safe route args into the SavedStateHandle, so the
|
||||||
|
// title is correct from the very first frame, before any listing completes.
|
||||||
|
GalleryUiState(folderName = savedStateHandle.get<String>("folderName").orEmpty()),
|
||||||
|
)
|
||||||
|
|
||||||
private var forceReload = false
|
private var forceReload = false
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,6 @@
|
|||||||
<item quantity="other">%d photos</item>
|
<item quantity="other">%d photos</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
<string name="gallery_title">Gallery</string>
|
|
||||||
<string name="gallery_create_subfolder">Create subfolder</string>
|
<string name="gallery_create_subfolder">Create subfolder</string>
|
||||||
<string name="gallery_sort_ascending">Sort ascending</string>
|
<string name="gallery_sort_ascending">Sort ascending</string>
|
||||||
<string name="gallery_sort_descending">Sort descending</string>
|
<string name="gallery_sort_descending">Sort descending</string>
|
||||||
|
|||||||
Reference in new issue
Block a user