chore: bump dart sdk to 3.8 (#20355)

* chore: bump dart sdk to 3.8

* chore: make build

* make pigeon

* chore: format files

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
shenlong 2025-07-29 00:34:03 +05:30 committed by GitHub
parent 9b3718120b
commit e52b9d15b5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
643 changed files with 32561 additions and 35292 deletions

View file

@ -15,13 +15,7 @@ class CuratedPeopleRow extends StatelessWidget {
final Function(SearchCuratedContent, int)? onTap;
final Function(SearchCuratedContent, int)? onNameTap;
const CuratedPeopleRow({
super.key,
required this.content,
this.onTap,
this.padding,
required this.onNameTap,
});
const CuratedPeopleRow({super.key, required this.content, this.onTap, this.padding, required this.onNameTap});
@override
Widget build(BuildContext context) {
@ -50,19 +44,13 @@ class CuratedPeopleRow extends StatelessWidget {
elevation: 3,
child: CircleAvatar(
maxRadius: imageSize / 2,
backgroundImage: NetworkImage(
getFaceThumbnailUrl(person.id),
headers: headers,
),
backgroundImage: NetworkImage(getFaceThumbnailUrl(person.id), headers: headers),
),
),
),
),
const SizedBox(height: 8),
SizedBox(
width: imageSize,
child: _buildPersonLabel(context, person, index),
),
SizedBox(width: imageSize, child: _buildPersonLabel(context, person, index)),
],
),
);
@ -72,19 +60,13 @@ class CuratedPeopleRow extends StatelessWidget {
);
}
Widget _buildPersonLabel(
BuildContext context,
SearchCuratedContent person,
int index,
) {
Widget _buildPersonLabel(BuildContext context, SearchCuratedContent person, int index) {
if (person.label.isEmpty) {
return GestureDetector(
onTap: () => onNameTap?.call(person, index),
child: Text(
"exif_bottom_sheet_person_add_person",
style: context.textTheme.labelLarge?.copyWith(
color: context.primaryColor,
),
style: context.textTheme.labelLarge?.copyWith(color: context.primaryColor),
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
@ -101,11 +83,7 @@ class CuratedPeopleRow extends StatelessWidget {
style: context.textTheme.labelLarge,
maxLines: 2,
),
if (person.subtitle != null)
Text(
person.subtitle!,
textAlign: TextAlign.center,
),
if (person.subtitle != null) Text(person.subtitle!, textAlign: TextAlign.center),
],
);
}

View file

@ -31,9 +31,7 @@ class CuratedPlacesRow extends StatelessWidget {
height: imageSize,
child: ListView.separated(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(
horizontal: 16,
),
padding: const EdgeInsets.symmetric(horizontal: 16),
separatorBuilder: (context, index) => const SizedBox(width: 10),
itemBuilder: (context, index) {
// Injecting Map thumbnail as the first element

View file

@ -13,11 +13,7 @@ class ExploreGrid extends StatelessWidget {
final List<SearchCuratedContent> curatedContent;
final bool isPeople;
const ExploreGrid({
super.key,
required this.curatedContent,
this.isPeople = false,
});
const ExploreGrid({super.key, required this.curatedContent, this.isPeople = false});
@override
Widget build(BuildContext context) {
@ -27,10 +23,7 @@ class ExploreGrid extends StatelessWidget {
child: SizedBox(
height: 100,
width: 100,
child: ThumbnailWithInfo(
textInfo: '',
onTap: () {},
),
child: ThumbnailWithInfo(textInfo: '', onTap: () {}),
),
);
}
@ -53,26 +46,15 @@ class ExploreGrid extends StatelessWidget {
borderRadius: 0,
onTap: () {
isPeople
? context.pushRoute(
PersonResultRoute(
personId: content.id,
personName: content.label,
),
)
? context.pushRoute(PersonResultRoute(personId: content.id, personName: content.label))
: context.pushRoute(
SearchRoute(
prefilter: SearchFilter(
people: {},
location: SearchLocationFilter(
city: content.label,
),
location: SearchLocationFilter(city: content.label),
camera: SearchCameraFilter(),
date: SearchDateFilter(),
display: SearchDisplayFilters(
isNotInAlbum: false,
isArchive: false,
isFavorite: false,
),
display: SearchDisplayFilters(isNotInAlbum: false, isArchive: false, isFavorite: false),
mediaType: AssetType.other,
),
),

View file

@ -16,11 +16,7 @@ class PersonNameEditForm extends HookConsumerWidget {
final String personId;
final String personName;
const PersonNameEditForm({
super.key,
required this.personId,
required this.personName,
});
const PersonNameEditForm({super.key, required this.personId, required this.personName});
@override
Widget build(BuildContext context, WidgetRef ref) {
@ -28,10 +24,7 @@ class PersonNameEditForm extends HookConsumerWidget {
final isError = useState(false);
return AlertDialog(
title: const Text(
"add_a_name",
style: TextStyle(fontWeight: FontWeight.bold),
).tr(),
title: const Text("add_a_name", style: TextStyle(fontWeight: FontWeight.bold)).tr(),
content: SingleChildScrollView(
child: TextFormField(
controller: controller,
@ -46,23 +39,16 @@ class PersonNameEditForm extends HookConsumerWidget {
),
actions: [
TextButton(
onPressed: () => context.pop(
const PersonNameEditFormResult(false, ''),
),
onPressed: () => context.pop(const PersonNameEditFormResult(false, '')),
child: Text(
"cancel",
style: TextStyle(
color: Colors.red[300],
fontWeight: FontWeight.bold,
),
style: TextStyle(color: Colors.red[300], fontWeight: FontWeight.bold),
).tr(),
),
TextButton(
onPressed: () async {
isError.value = false;
final result = await ref.read(
updatePersonNameProvider(personId, controller.text).future,
);
final result = await ref.read(updatePersonNameProvider(personId, controller.text).future);
isError.value = !result;
if (result) {
context.pop(PersonNameEditFormResult(true, controller.text));
@ -70,10 +56,7 @@ class PersonNameEditForm extends HookConsumerWidget {
},
child: Text(
"save",
style: TextStyle(
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
style: TextStyle(color: context.primaryColor, fontWeight: FontWeight.bold),
).tr(),
),
],

View file

@ -21,30 +21,14 @@ class CameraPicker extends HookConsumerWidget {
final selectedMake = useState<String?>(filter?.make);
final selectedModel = useState<String?>(filter?.model);
final make = ref.watch(
getSearchSuggestionsProvider(
SearchSuggestionType.cameraMake,
),
);
final make = ref.watch(getSearchSuggestionsProvider(SearchSuggestionType.cameraMake));
final models = ref.watch(
getSearchSuggestionsProvider(
SearchSuggestionType.cameraModel,
make: selectedMake.value,
),
);
final models = ref.watch(getSearchSuggestionsProvider(SearchSuggestionType.cameraModel, make: selectedMake.value));
final makeWidget = SearchDropdown(
dropdownMenuEntries: switch (make) {
AsyncError() => [],
AsyncData(:final value) => value
.map(
(e) => DropdownMenuEntry(
value: e,
label: e,
),
)
.toList(),
AsyncData(:final value) => value.map((e) => DropdownMenuEntry(value: e, label: e)).toList(),
_ => [],
},
label: const Text('make').tr(),
@ -56,24 +40,14 @@ class CameraPicker extends HookConsumerWidget {
}
selectedMake.value = value.toString();
modelTextController.value = TextEditingValue.empty;
onSelect({
'make': selectedMake.value,
'model': null,
});
onSelect({'make': selectedMake.value, 'model': null});
},
);
final modelWidget = SearchDropdown(
dropdownMenuEntries: switch (models) {
AsyncError() => [],
AsyncData(:final value) => value
.map(
(e) => DropdownMenuEntry(
value: e,
label: e,
),
)
.toList(),
AsyncData(:final value) => value.map((e) => DropdownMenuEntry(value: e, label: e)).toList(),
_ => [],
},
label: const Text('model').tr(),
@ -81,21 +55,12 @@ class CameraPicker extends HookConsumerWidget {
leadingIcon: const Icon(Icons.camera),
onSelected: (value) {
selectedModel.value = value.toString();
onSelect({
'make': selectedMake.value,
'model': selectedModel.value,
});
onSelect({'make': selectedMake.value, 'model': selectedModel.value});
},
);
if (context.isMobile) {
return Column(
children: [
makeWidget,
const SizedBox(height: 8),
modelWidget,
],
);
return Column(children: [makeWidget, const SizedBox(height: 8), modelWidget]);
}
return Row(

View file

@ -20,9 +20,7 @@ class SearchDropdown<T> extends StatelessWidget {
Widget build(BuildContext context) {
final menuStyle = const MenuStyle(
shape: WidgetStatePropertyAll<OutlinedBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15)),
),
RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(15))),
),
);

View file

@ -3,18 +3,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:immich_mobile/models/search/search_filter.model.dart';
enum DisplayOption {
notInAlbum,
favorite,
archive,
}
enum DisplayOption { notInAlbum, favorite, archive }
class DisplayOptionPicker extends HookWidget {
const DisplayOptionPicker({
super.key,
required this.onSelect,
this.filter,
});
const DisplayOptionPicker({super.key, required this.onSelect, this.filter});
final Function(Map<DisplayOption, bool>) onSelect;
final SearchDisplayFilters? filter;
@ -34,10 +26,7 @@ class DisplayOptionPicker extends HookWidget {
title: const Text('search_filter_display_option_not_in_album').tr(),
value: options.value[DisplayOption.notInAlbum],
onChanged: (bool? value) {
options.value = {
...options.value,
DisplayOption.notInAlbum: value!,
};
options.value = {...options.value, DisplayOption.notInAlbum: value!};
onSelect(options.value);
},
),
@ -45,10 +34,7 @@ class DisplayOptionPicker extends HookWidget {
title: const Text('favorite').tr(),
value: options.value[DisplayOption.favorite],
onChanged: (value) {
options.value = {
...options.value,
DisplayOption.favorite: value!,
};
options.value = {...options.value, DisplayOption.favorite: value!};
onSelect(options.value);
},
),
@ -56,10 +42,7 @@ class DisplayOptionPicker extends HookWidget {
title: const Text('archive').tr(),
value: options.value[DisplayOption.archive],
onChanged: (value) {
options.value = {
...options.value,
DisplayOption.archive: value!,
};
options.value = {...options.value, DisplayOption.archive: value!};
onSelect(options.value);
},
),

View file

@ -33,10 +33,7 @@ class FilterBottomSheetScaffold extends StatelessWidget {
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
title,
style: context.textTheme.headlineSmall,
),
child: Text(title, style: context.textTheme.headlineSmall),
),
buildChildWidget(),
Padding(

View file

@ -52,14 +52,7 @@ class LocationPicker extends HookConsumerWidget {
SearchDropdown(
dropdownMenuEntries: switch (countries) {
AsyncError() => [],
AsyncData(:final value) => value
.map(
(e) => DropdownMenuEntry(
value: e,
label: e,
),
)
.toList(),
AsyncData(:final value) => value.map((e) => DropdownMenuEntry(value: e, label: e)).toList(),
_ => [],
},
label: const Text('country').tr(),
@ -71,27 +64,14 @@ class LocationPicker extends HookConsumerWidget {
selectedCountry.value = value.toString();
stateTextController.value = TextEditingValue.empty;
cityTextController.value = TextEditingValue.empty;
onSelected({
'country': selectedCountry.value,
'state': null,
'city': null,
});
onSelected({'country': selectedCountry.value, 'state': null, 'city': null});
},
),
const SizedBox(
height: 16,
),
const SizedBox(height: 16),
SearchDropdown(
dropdownMenuEntries: switch (states) {
AsyncError() => [],
AsyncData(:final value) => value
.map(
(e) => DropdownMenuEntry(
value: e,
label: e,
),
)
.toList(),
AsyncData(:final value) => value.map((e) => DropdownMenuEntry(value: e, label: e)).toList(),
_ => [],
},
label: const Text('state').tr(),
@ -102,38 +82,21 @@ class LocationPicker extends HookConsumerWidget {
}
selectedState.value = value.toString();
cityTextController.value = TextEditingValue.empty;
onSelected({
'country': selectedCountry.value,
'state': selectedState.value,
'city': null,
});
onSelected({'country': selectedCountry.value, 'state': selectedState.value, 'city': null});
},
),
const SizedBox(
height: 16,
),
const SizedBox(height: 16),
SearchDropdown(
dropdownMenuEntries: switch (cities) {
AsyncError() => [],
AsyncData(:final value) => value
.map(
(e) => DropdownMenuEntry(
value: e,
label: e,
),
)
.toList(),
AsyncData(:final value) => value.map((e) => DropdownMenuEntry(value: e, label: e)).toList(),
_ => [],
},
label: const Text('city').tr(),
controller: cityTextController,
onSelected: (value) {
selectedCity.value = value.toString();
onSelected({
'country': selectedCountry.value,
'state': selectedState.value,
'city': selectedCity.value,
});
onSelected({'country': selectedCountry.value, 'state': selectedState.value, 'city': selectedCity.value});
},
),
],

View file

@ -40,10 +40,7 @@ class PeoplePicker extends HookConsumerWidget {
),
Padding(
padding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 0),
child: Divider(
color: context.colorScheme.surfaceContainerHighest,
thickness: 1,
),
child: Divider(color: context.colorScheme.surfaceContainerHighest, thickness: 1),
),
Expanded(
child: people.widgetWhen(
@ -51,16 +48,12 @@ class PeoplePicker extends HookConsumerWidget {
return ListView.builder(
shrinkWrap: true,
itemCount: people
.where(
(person) => person.name.toLowerCase().contains(searchQuery.value.toLowerCase()),
)
.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()),
)
.where((person) => person.name.toLowerCase().contains(searchQuery.value.toLowerCase()))
.toList()[index];
final isSelected = selectedPeople.value.contains(person);
@ -82,10 +75,7 @@ class PeoplePicker extends HookConsumerWidget {
elevation: 3,
child: CircleAvatar(
maxRadius: imageSize / 2,
backgroundImage: NetworkImage(
getFaceThumbnailUrl(person.id),
headers: headers,
),
backgroundImage: NetworkImage(getFaceThumbnailUrl(person.id), headers: headers),
),
),
),

View file

@ -7,13 +7,7 @@ class SearchFilterChip extends StatelessWidget {
final Widget? currentFilter;
final IconData icon;
const SearchFilterChip({
super.key,
required this.label,
required this.onTap,
required this.icon,
this.currentFilter,
});
const SearchFilterChip({super.key, required this.label, required this.onTap, required this.icon, this.currentFilter});
@override
Widget build(BuildContext context) {
@ -23,21 +17,10 @@ class SearchFilterChip extends StatelessWidget {
child: Card(
elevation: 0,
color: context.primaryColor.withValues(alpha: .5),
shape: StadiumBorder(
side: BorderSide(color: context.colorScheme.secondaryContainer),
),
shape: StadiumBorder(side: BorderSide(color: context.colorScheme.secondaryContainer)),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 14.0),
child: Row(
children: [
Icon(
icon,
size: 18,
),
const SizedBox(width: 4.0),
currentFilter!,
],
),
child: Row(children: [Icon(icon, size: 18), const SizedBox(width: 4.0), currentFilter!]),
),
),
);
@ -46,21 +29,10 @@ class SearchFilterChip extends StatelessWidget {
onTap: onTap,
child: Card(
elevation: 0,
shape: StadiumBorder(
side: BorderSide(color: context.colorScheme.outline.withAlpha(15)),
),
shape: StadiumBorder(side: BorderSide(color: context.colorScheme.outline.withAlpha(15))),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 14.0),
child: Row(
children: [
Icon(
icon,
size: 18,
),
const SizedBox(width: 4.0),
Text(label),
],
),
child: Row(children: [Icon(icon, size: 18), const SizedBox(width: 4.0), Text(label)]),
),
),
);

View file

@ -7,10 +7,7 @@ import 'package:immich_mobile/widgets/search/thumbnail_with_info_container.dart'
import 'package:maplibre_gl/maplibre_gl.dart';
class SearchMapThumbnail extends StatelessWidget {
const SearchMapThumbnail({
super.key,
this.size = 60.0,
});
const SearchMapThumbnail({super.key, this.size = 60.0});
final double size;
final bool showTitle = true;
@ -23,16 +20,7 @@ class SearchMapThumbnail extends StatelessWidget {
context.pushRoute(MapRoute());
},
child: IgnorePointer(
child: MapThumbnail(
zoom: 2,
centre: const LatLng(
47,
5,
),
height: size,
width: size,
showAttribution: false,
),
child: MapThumbnail(zoom: 2, centre: const LatLng(47, 5), height: size, width: size, showAttribution: false),
),
);
}

View file

@ -25,10 +25,7 @@ class SearchRowSection extends StatelessWidget {
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: SearchRowTitle(
onViewAllPressed: onViewAllPressed,
title: title,
),
child: SearchRowTitle(onViewAllPressed: onViewAllPressed, title: title),
),
child,
],

View file

@ -3,11 +3,7 @@ import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class SearchRowTitle extends StatelessWidget {
const SearchRowTitle({
super.key,
required this.onViewAllPressed,
required this.title,
});
const SearchRowTitle({super.key, required this.onViewAllPressed, required this.title});
final Function() onViewAllPressed;
final String title;
@ -17,19 +13,12 @@ class SearchRowTitle extends StatelessWidget {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
style: context.textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.w500,
),
),
Text(title, style: context.textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w500)),
TextButton(
onPressed: onViewAllPressed,
child: Text(
'search_page_view_all_button',
style: context.textTheme.labelLarge?.copyWith(
color: context.primaryColor,
),
style: context.textTheme.labelLarge?.copyWith(color: context.primaryColor),
).tr(),
),
],

View file

@ -39,12 +39,7 @@ class ThumbnailWithInfo extends StatelessWidget {
errorWidget: (context, url, error) => const Icon(Icons.image_not_supported_outlined),
),
)
: Center(
child: Icon(
noImageIcon ?? Icons.not_listed_location,
color: textAndIconColor,
),
),
: Center(child: Icon(noImageIcon ?? Icons.not_listed_location, color: textAndIconColor)),
);
}
}

View file

@ -27,10 +27,7 @@ class ThumbnailWithInfoContainer extends StatelessWidget {
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius),
gradient: LinearGradient(
colors: [
context.colorScheme.surfaceContainer,
context.colorScheme.surfaceContainer.darken(amount: .1),
],
colors: [context.colorScheme.surfaceContainer, context.colorScheme.surfaceContainer.darken(amount: .1)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
@ -54,11 +51,7 @@ class ThumbnailWithInfoContainer extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 8) + const EdgeInsets.only(bottom: 8),
child: Text(
label,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14,
),
style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 14),
maxLines: 2,
softWrap: false,
overflow: TextOverflow.ellipsis,