Compare commits

...

4 Commits

Author SHA1 Message Date
Alex
04ce6b3bcb chore: using final 2025-03-17 14:04:49 -05:00
Alex
fc921fbe9f chore: minor styling tweak 2025-03-17 14:02:49 -05:00
Yaros
f588a609d9 fix: optimize code 2025-03-17 14:45:23 +01:00
Yaros
1496627551 feat(mobile): backup albums search 2025-03-15 16:47:49 +01:00

View File

@@ -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(
() { () {
@@ -33,6 +36,10 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
[], [],
); );
final filteredAlbums = albums.where((album) {
return album.name.toLowerCase().contains(searchQuery.value.toLowerCase());
}).toList();
buildAlbumSelectionList() { buildAlbumSelectionList() {
if (albums.isEmpty) { if (albums.isEmpty) {
return const SliverToBoxAdapter( return const SliverToBoxAdapter(
@@ -48,10 +55,10 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
delegate: SliverChildBuilderDelegate( delegate: SliverChildBuilderDelegate(
((context, index) { ((context, index) {
return AlbumInfoListTile( return AlbumInfoListTile(
album: albums[index], album: filteredAlbums[index],
); );
}), }),
childCount: albums.length, childCount: filteredAlbums.length,
), ),
), ),
); );
@@ -74,10 +81,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],
); );
}), }),
), ),
@@ -247,8 +254,9 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return AlertDialog(
shape: RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), borderRadius:
BorderRadius.all(Radius.circular(10)),
), ),
elevation: 5, elevation: 5,
title: Text( title: Text(
@@ -277,11 +285,56 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
}, },
), ),
), ),
// buildSearchBar(),
], ],
), ),
), ),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 4),
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: const BorderRadius.all(Radius.circular(25)),
borderSide: BorderSide(
color: context.colorScheme.surfaceContainerHighest,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(25)),
borderSide: BorderSide(
color: context.colorScheme.surfaceContainerHighest,
),
),
disabledBorder: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(25)),
borderSide: BorderSide(
color: context.colorScheme.surfaceContainerHighest,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(25)),
borderSide: BorderSide(
color: context.colorScheme.primary.withAlpha(150),
),
),
prefixIcon: Icon(
Icons.search_rounded,
color: context.colorScheme.primary,
),
hintText: 'search_albums'.tr(),
),
),
),
),
SliverLayoutBuilder( SliverLayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
if (constraints.crossAxisExtent > 600) { if (constraints.crossAxisExtent > 600) {