From 87c07e53274fcfabc1945f61b123411ec86e85e2 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 29 Jan 2025 15:00:05 -0600 Subject: [PATCH] feat: styling --- .../lib/pages/common/large_leading_tile.dart | 10 +- .../search/search_filter/people_picker.dart | 167 ++++++++++++------ 2 files changed, 118 insertions(+), 59 deletions(-) diff --git a/mobile/lib/pages/common/large_leading_tile.dart b/mobile/lib/pages/common/large_leading_tile.dart index f2cb9f19aea32..4f22a5f2b2885 100644 --- a/mobile/lib/pages/common/large_leading_tile.dart +++ b/mobile/lib/pages/common/large_leading_tile.dart @@ -16,6 +16,8 @@ class LargeLeadingTile extends StatelessWidget { this.trailing, this.selected = false, this.disabled = false, + this.selectedTileColor, + this.tileColor, }); final Widget leading; @@ -27,6 +29,9 @@ class LargeLeadingTile extends StatelessWidget { final Widget? trailing; final bool selected; final bool disabled; + final Color? selectedTileColor; + final Color? tileColor; + @override Widget build(BuildContext context) { return InkWell( @@ -35,8 +40,9 @@ class LargeLeadingTile extends StatelessWidget { child: Container( decoration: BoxDecoration( color: selected - ? Theme.of(context).primaryColor.withAlpha(30) - : Colors.transparent, + ? selectedTileColor ?? + Theme.of(context).primaryColor.withAlpha(30) + : tileColor ?? Colors.transparent, borderRadius: BorderRadius.circular(borderRadius), ), child: Row( diff --git a/mobile/lib/widgets/search/search_filter/people_picker.dart b/mobile/lib/widgets/search/search_filter/people_picker.dart index fc49df9d90104..9cc74bf93983d 100644 --- a/mobile/lib/widgets/search/search_filter/people_picker.dart +++ b/mobile/lib/widgets/search/search_filter/people_picker.dart @@ -4,7 +4,9 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/asyncvalue_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; +import 'package:immich_mobile/extensions/theme_extensions.dart'; import 'package:immich_mobile/interfaces/person_api.interface.dart'; +import 'package:immich_mobile/pages/common/large_leading_tile.dart'; import 'package:immich_mobile/providers/search/people.provider.dart'; import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/utils/image_url_builder.dart'; @@ -17,7 +19,8 @@ class PeoplePicker extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - var imageSize = 45.0; + final formFocus = useFocusNode(); + final imageSize = 75.0; final searchQuery = useState(''); final people = ref.watch(getAllPeopleProvider); final headers = ApiService.getRequestHeaders(); @@ -26,77 +29,127 @@ class PeoplePicker extends HookConsumerWidget { return Column( children: [ Padding( - padding: const EdgeInsets.all(16), + 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.withOpacity(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, ), - prefixIcon: const Icon(Icons.search_rounded), hintText: 'search_filter_people_hint'.tr(), ), ), ), - Expanded(child: people.widgetWhen(onData: (people) { - return ListView.builder( - shrinkWrap: true, - itemCount: people - .where((person) => person.name - .toLowerCase() - .contains(searchQuery.value.toLowerCase())) - .length, - padding: const EdgeInsets.all(8), - itemBuilder: (context, index) { - final person = people - .where((person) => person.name - .toLowerCase() - .contains(searchQuery.value.toLowerCase())) - .toList()[index]; - return Card( - elevation: 0, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(15)), - ), - child: ListTile( - title: Text( - person.name, - style: context.textTheme.bodyLarge, - ), - leading: SizedBox( - height: imageSize, - child: Material( - shape: const CircleBorder(side: BorderSide.none), - elevation: 3, - child: CircleAvatar( - maxRadius: imageSize / 2, - backgroundImage: NetworkImage( - getFaceThumbnailUrl(person.id), - headers: headers, + Padding( + padding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 0), + child: Divider( + color: context.colorScheme.surfaceContainerHighest, + thickness: 1, + ), + ), + Expanded( + child: people.widgetWhen( + onData: (people) { + return ListView.builder( + shrinkWrap: true, + itemCount: people + .where( + (person) => person.name + .toLowerCase() + .contains(searchQuery.value.toLowerCase()), + ) + .length, + padding: const EdgeInsets.all(8), + itemBuilder: (context, index) { + final person = people + .where( + (person) => person.name + .toLowerCase() + .contains(searchQuery.value.toLowerCase()), + ) + .toList()[index]; + final isSelected = selectedPeople.value.contains(person); + + return Padding( + padding: const EdgeInsets.only(bottom: 2.0), + child: LargeLeadingTile( + title: Text( + person.name, + style: context.textTheme.bodyLarge?.copyWith( + fontSize: 20, + fontWeight: FontWeight.w500, + color: isSelected + ? context.colorScheme.onPrimary + : context.colorScheme.onSurface, ), ), - ), - ), - onTap: () { - if (selectedPeople.value.contains(person)) { - selectedPeople.value.remove(person); - } else { - selectedPeople.value.add(person); - } + leading: SizedBox( + height: imageSize, + child: Material( + shape: const CircleBorder(side: BorderSide.none), + elevation: 3, + child: CircleAvatar( + maxRadius: imageSize / 2, + backgroundImage: NetworkImage( + getFaceThumbnailUrl(person.id), + headers: headers, + ), + ), + ), + ), + onTap: () { + if (selectedPeople.value.contains(person)) { + selectedPeople.value.remove(person); + } else { + selectedPeople.value.add(person); + } - selectedPeople.value = {...selectedPeople.value}; - onSelect(selectedPeople.value); - }, - selected: selectedPeople.value.contains(person), - selectedTileColor: context.primaryColor.withOpacity(0.2), - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(15)), - ), - ), + selectedPeople.value = {...selectedPeople.value}; + onSelect(selectedPeople.value); + }, + selected: isSelected, + selectedTileColor: context.primaryColor, + tileColor: context.primaryColor.withAlpha(25), + ), + ); + }, ); }, - ); - })) + ), + ), ], ); }