Compare commits

...

5 Commits

Author SHA1 Message Date
Yaros
161c7e0b8b Merge branch 'main' into fix/save-album-sort 2025-09-22 19:16:59 +02:00
Yaros
28a8a8c89c Merge branch 'main' into fix/save-album-sort 2025-09-17 18:24:31 +02:00
Yaros
aa0732158b Merge branch 'main' into fix/save-album-sort 2025-09-17 14:40:05 +02:00
Yaros
555837046d fix(mobile): persist album layout 2025-09-17 14:39:51 +02:00
Yaros
f02bc73f2c fix(mobile): persist album sorting in settings 2025-09-16 23:39:58 +02:00
4 changed files with 104 additions and 5 deletions

View File

@@ -70,6 +70,9 @@ enum StoreKey<T> {
// Read-only Mode settings
readonlyModeEnabled<bool>._(138),
// Album grid/list view settings
albumGridView<bool>._(139),
// Experimental stuff
photoManagerCustomFilter<bool>._(1000),
betaPromptShown<bool>._(1001),

View File

@@ -18,6 +18,9 @@ import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
import 'package:immich_mobile/providers/infrastructure/current_album.provider.dart';
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
import 'package:immich_mobile/providers/app_settings.provider.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/utils/album_filter.utils.dart';
import 'package:immich_mobile/widgets/common/confirm_dialog.dart';
@@ -52,8 +55,22 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
void initState() {
super.initState();
// Load albums when component mounts
WidgetsBinding.instance.addPostFrameCallback((_) {
final appSettings = ref.read(appSettingsServiceProvider);
final savedSortMode = appSettings.getSetting(AppSettingsEnum.selectedAlbumSortOrder);
final savedIsReverse = appSettings.getSetting(AppSettingsEnum.selectedAlbumSortReverse);
final savedIsGrid = appSettings.getSetting(AppSettingsEnum.albumGridView);
final albumSortMode = AlbumSortMode.values.firstWhere(
(e) => e.storeIndex == savedSortMode,
orElse: () => AlbumSortMode.lastModified,
);
setState(() {
sort = AlbumSort(mode: toRemoteAlbumSortMode(albumSortMode), isReverse: savedIsReverse);
isGrid = savedIsGrid;
});
ref.read(remoteAlbumProvider.notifier).refresh();
});
@@ -83,6 +100,7 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
setState(() {
isGrid = !isGrid;
});
ref.read(appSettingsServiceProvider).setSetting(AppSettingsEnum.albumGridView, isGrid);
}
void changeFilter(QuickFilterMode mode) {
@@ -98,6 +116,11 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
this.sort = sort;
});
final appSettings = ref.read(appSettingsServiceProvider);
final albumSortMode = toAlbumSortMode(sort.mode);
await appSettings.setSetting(AppSettingsEnum.selectedAlbumSortOrder, albumSortMode.storeIndex);
await appSettings.setSetting(AppSettingsEnum.selectedAlbumSortReverse, sort.isReverse);
await sortAlbums();
}
@@ -182,6 +205,8 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
onToggleViewMode: toggleViewMode,
onSortChanged: changeSort,
controller: menuController,
currentSortMode: sort.mode,
currentIsReverse: sort.isReverse,
),
isGrid
? _AlbumGrid(albums: shownAlbums, userId: userId, onAlbumSelected: widget.onAlbumSelected)
@@ -193,20 +218,45 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
}
class _SortButton extends ConsumerStatefulWidget {
const _SortButton(this.onSortChanged, {this.controller});
const _SortButton(
this.onSortChanged, {
required this.initialSortMode,
required this.initialIsReverse,
this.controller,
});
final Future<void> Function(AlbumSort) onSortChanged;
final MenuController? controller;
final RemoteAlbumSortMode initialSortMode;
final bool initialIsReverse;
@override
ConsumerState<_SortButton> createState() => _SortButtonState();
}
class _SortButtonState extends ConsumerState<_SortButton> {
RemoteAlbumSortMode albumSortOption = RemoteAlbumSortMode.lastModified;
bool albumSortIsReverse = true;
late RemoteAlbumSortMode albumSortOption;
late bool albumSortIsReverse;
bool isSorting = false;
@override
void initState() {
super.initState();
albumSortOption = widget.initialSortMode;
albumSortIsReverse = widget.initialIsReverse;
}
@override
void didUpdateWidget(_SortButton oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.initialSortMode != widget.initialSortMode || oldWidget.initialIsReverse != widget.initialIsReverse) {
setState(() {
albumSortOption = widget.initialSortMode;
albumSortIsReverse = widget.initialIsReverse;
});
}
}
Future<void> onMenuTapped(RemoteAlbumSortMode sortMode) async {
final selected = albumSortOption == sortMode;
// Switch direction
@@ -466,6 +516,8 @@ class _QuickSortAndViewMode extends StatelessWidget {
required this.isGrid,
required this.onToggleViewMode,
required this.onSortChanged,
required this.currentSortMode,
required this.currentIsReverse,
this.controller,
});
@@ -473,6 +525,8 @@ class _QuickSortAndViewMode extends StatelessWidget {
final VoidCallback onToggleViewMode;
final MenuController? controller;
final Future<void> Function(AlbumSort) onSortChanged;
final RemoteAlbumSortMode currentSortMode;
final bool currentIsReverse;
@override
Widget build(BuildContext context) {
@@ -482,7 +536,12 @@ class _QuickSortAndViewMode extends StatelessWidget {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_SortButton(onSortChanged, controller: controller),
_SortButton(
onSortChanged,
controller: controller,
initialSortMode: currentSortMode,
initialIsReverse: currentIsReverse,
),
IconButton(
icon: Icon(isGrid ? Icons.view_list_outlined : Icons.grid_view_outlined, size: 24),
onPressed: onToggleViewMode,

View File

@@ -50,6 +50,8 @@ enum AppSettingsEnum<T> {
enableBackup<bool>(StoreKey.enableBackup, null, false),
useCellularForUploadVideos<bool>(StoreKey.useWifiForUploadVideos, null, false),
useCellularForUploadPhotos<bool>(StoreKey.useWifiForUploadPhotos, null, false),
readonlyModeEnabled<bool>(StoreKey.readonlyModeEnabled, "readonlyModeEnabled", false),
albumGridView<bool>(StoreKey.albumGridView, "albumGridView", false);
backupRequireCharging<bool>(StoreKey.backupRequireCharging, null, false),
backupTriggerDelay<int>(StoreKey.backupTriggerDelay, null, 30),
readonlyModeEnabled<bool>(StoreKey.readonlyModeEnabled, "readonlyModeEnabled", false);

View File

@@ -1,5 +1,6 @@
import 'package:immich_mobile/domain/services/remote_album.service.dart';
import 'package:immich_mobile/models/albums/album_search.model.dart';
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
class AlbumFilter {
String? userId;
@@ -23,3 +24,37 @@ class AlbumSort {
return AlbumSort(mode: mode ?? this.mode, isReverse: isReverse ?? this.isReverse);
}
}
RemoteAlbumSortMode toRemoteAlbumSortMode(AlbumSortMode mode) {
switch (mode) {
case AlbumSortMode.title:
return RemoteAlbumSortMode.title;
case AlbumSortMode.assetCount:
return RemoteAlbumSortMode.assetCount;
case AlbumSortMode.lastModified:
return RemoteAlbumSortMode.lastModified;
case AlbumSortMode.created:
return RemoteAlbumSortMode.created;
case AlbumSortMode.mostRecent:
return RemoteAlbumSortMode.mostRecent;
case AlbumSortMode.mostOldest:
return RemoteAlbumSortMode.mostOldest;
}
}
AlbumSortMode toAlbumSortMode(RemoteAlbumSortMode mode) {
switch (mode) {
case RemoteAlbumSortMode.title:
return AlbumSortMode.title;
case RemoteAlbumSortMode.assetCount:
return AlbumSortMode.assetCount;
case RemoteAlbumSortMode.lastModified:
return AlbumSortMode.lastModified;
case RemoteAlbumSortMode.created:
return AlbumSortMode.created;
case RemoteAlbumSortMode.mostRecent:
return AlbumSortMode.mostRecent;
case RemoteAlbumSortMode.mostOldest:
return AlbumSortMode.mostOldest;
}
}