mirror of
https://github.com/immich-app/immich.git
synced 2025-06-01 04:36:19 -04:00
feat(mobile): backup albums search
This commit is contained in:
parent
9a4495eb5b
commit
1496627551
@ -75,6 +75,7 @@
|
|||||||
"backup_album_selection_page_albums_device": "Albums on device ({})",
|
"backup_album_selection_page_albums_device": "Albums on device ({})",
|
||||||
"backup_album_selection_page_albums_tap": "Tap to include, double tap to exclude",
|
"backup_album_selection_page_albums_tap": "Tap to include, double tap to exclude",
|
||||||
"backup_album_selection_page_assets_scatter": "Assets can scatter across multiple albums. Thus, albums can be included or excluded during the backup process.",
|
"backup_album_selection_page_assets_scatter": "Assets can scatter across multiple albums. Thus, albums can be included or excluded during the backup process.",
|
||||||
|
"backup_album_selection_page_search_hint": "Filter albums",
|
||||||
"backup_album_selection_page_select_albums": "Select albums",
|
"backup_album_selection_page_select_albums": "Select albums",
|
||||||
"backup_album_selection_page_selection_info": "Selection Info",
|
"backup_album_selection_page_selection_info": "Selection Info",
|
||||||
"backup_album_selection_page_total_assets": "Total unique assets",
|
"backup_album_selection_page_total_assets": "Total unique assets",
|
||||||
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/providers/album/album.provider.dart';
|
import 'package:immich_mobile/providers/album/album.provider.dart';
|
||||||
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
||||||
import 'package:immich_mobile/services/app_settings.service.dart';
|
import 'package:immich_mobile/services/app_settings.service.dart';
|
||||||
@ -24,6 +25,8 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
|
|||||||
useAppSettingsState(AppSettingsEnum.syncAlbums);
|
useAppSettingsState(AppSettingsEnum.syncAlbums);
|
||||||
final isDarkTheme = context.isDarkTheme;
|
final isDarkTheme = context.isDarkTheme;
|
||||||
final albums = ref.watch(backupProvider).availableAlbums;
|
final albums = ref.watch(backupProvider).availableAlbums;
|
||||||
|
final searchQuery = useState('');
|
||||||
|
final formFocus = useFocusNode();
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() {
|
() {
|
||||||
@ -42,16 +45,22 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var filteredAlbums = albums.where((album) {
|
||||||
|
return album.name
|
||||||
|
.toLowerCase()
|
||||||
|
.contains(searchQuery.value.toLowerCase());
|
||||||
|
}).toList();
|
||||||
|
|
||||||
return SliverPadding(
|
return SliverPadding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12.0),
|
padding: const EdgeInsets.symmetric(vertical: 12.0),
|
||||||
sliver: SliverList(
|
sliver: SliverList(
|
||||||
delegate: SliverChildBuilderDelegate(
|
delegate: SliverChildBuilderDelegate(
|
||||||
((context, index) {
|
((context, index) {
|
||||||
return AlbumInfoListTile(
|
return AlbumInfoListTile(
|
||||||
album: albums[index],
|
album: filteredAlbums[index],
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
childCount: albums.length,
|
childCount: filteredAlbums.length,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -66,6 +75,12 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var filteredAlbums = albums.where((album) {
|
||||||
|
return album.name
|
||||||
|
.toLowerCase()
|
||||||
|
.contains(searchQuery.value.toLowerCase());
|
||||||
|
}).toList();
|
||||||
|
|
||||||
return SliverPadding(
|
return SliverPadding(
|
||||||
padding: const EdgeInsets.all(12.0),
|
padding: const EdgeInsets.all(12.0),
|
||||||
sliver: SliverGrid.builder(
|
sliver: SliverGrid.builder(
|
||||||
@ -74,10 +89,10 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
|
|||||||
mainAxisSpacing: 12,
|
mainAxisSpacing: 12,
|
||||||
crossAxisSpacing: 12,
|
crossAxisSpacing: 12,
|
||||||
),
|
),
|
||||||
itemCount: albums.length,
|
itemCount: filteredAlbums.length,
|
||||||
itemBuilder: ((context, index) {
|
itemBuilder: ((context, index) {
|
||||||
return AlbumInfoCard(
|
return AlbumInfoCard(
|
||||||
album: albums[index],
|
album: filteredAlbums[index],
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
@ -282,6 +297,53 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
child: TextField(
|
||||||
|
focusNode: formFocus,
|
||||||
|
onChanged: (value) => searchQuery.value = value,
|
||||||
|
onTapOutside: (_) => formFocus.unfocus(),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
contentPadding: const EdgeInsets.only(left: 24),
|
||||||
|
filled: true,
|
||||||
|
fillColor: context.primaryColor.withValues(alpha: 0.1),
|
||||||
|
hintStyle: context.textTheme.bodyLarge?.copyWith(
|
||||||
|
color: context.themeData.colorScheme.onSurfaceSecondary,
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(25),
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: context.colorScheme.surfaceContainerHighest,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(25),
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: context.colorScheme.surfaceContainerHighest,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
disabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(25),
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: context.colorScheme.surfaceContainerHighest,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(25),
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: context.colorScheme.primary.withAlpha(150),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
prefixIcon: Icon(
|
||||||
|
Icons.search_rounded,
|
||||||
|
color: context.colorScheme.primary,
|
||||||
|
),
|
||||||
|
hintText: 'backup_album_selection_page_search_hint'.tr(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
SliverLayoutBuilder(
|
SliverLayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
if (constraints.crossAxisExtent > 600) {
|
if (constraints.crossAxisExtent > 600) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user