1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-29 15:11:58 +00:00

deps(mobile): flutter 3.16 (#6677)

* dep(mobile): update flutter and deps

* chore: dart analyzer

* chore: update flutter workflow version

* chore: dart format

* fix: gallery_viewer PopScope

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
shenlong 2024-01-27 16:14:32 +00:00 committed by GitHub
parent 0522058fdf
commit 27488ceb67
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
116 changed files with 625 additions and 622 deletions

View file

@ -45,7 +45,7 @@ jobs:
uses: subosito/flutter-action@v2 uses: subosito/flutter-action@v2
with: with:
channel: "stable" channel: "stable"
flutter-version: "3.13.6" flutter-version: "3.16.9"
cache: true cache: true
- name: Create the Keystore - name: Create the Keystore

View file

@ -23,7 +23,7 @@ jobs:
uses: subosito/flutter-action@v2 uses: subosito/flutter-action@v2
with: with:
channel: "stable" channel: "stable"
flutter-version: "3.13.6" flutter-version: "3.16.9"
- name: Install dependencies - name: Install dependencies
run: dart pub get run: dart pub get

View file

@ -204,7 +204,7 @@ jobs:
uses: subosito/flutter-action@v2 uses: subosito/flutter-action@v2
with: with:
channel: "stable" channel: "stable"
flutter-version: "3.13.6" flutter-version: "3.16.9"
- name: Run tests - name: Run tests
working-directory: ./mobile working-directory: ./mobile
run: flutter test -j 1 run: flutter test -j 1

View file

@ -1,3 +1,3 @@
{ {
"flutter": "3.13.6" "flutter": "3.16.9"
} }

View file

@ -1,5 +1,5 @@
{ {
"dart.flutterSdkPath": ".fvm\\versions\\3.13.6", "dart.flutterSdkPath": ".fvm\\versions\\3.16.9",
"search.exclude": { "search.exclude": {
"**/.fvm": true "**/.fvm": true
}, },

View file

@ -34,7 +34,7 @@ if (keystorePropertiesFile.exists()) {
android { android {
compileSdkVersion 33 compileSdkVersion 34
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8

View file

@ -52,7 +52,10 @@ class ImmichTestLoginHelper {
} }
Future<void> pressLoginButton() async { Future<void> pressLoginButton() async {
await pumpUntilFound(tester, find.textContaining("login_form_button_text".tr())); await pumpUntilFound(
tester,
find.textContaining("login_form_button_text".tr()),
);
final button = find.textContaining("login_form_button_text".tr()); final button = find.textContaining("login_form_button_text".tr());
await tester.tap(button); await tester.tap(button);
} }
@ -62,7 +65,7 @@ class ImmichTestLoginHelper {
} }
Future<void> assertLoginFailed({int timeoutSeconds = 15}) async { Future<void> assertLoginFailed({int timeoutSeconds = 15}) async {
await pumpUntilFound(tester, find.text("login_form_failed_login".tr())); await pumpUntilFound(tester, find.text("login_form_failed_login".tr()));
} }
} }
@ -80,9 +83,9 @@ enum LoginCredentials {
), ),
wrongInstanceUrl( wrongInstanceUrl(
"https://does-not-exist.preview.immich.app", "https://does-not-exist.preview.immich.app",
"demo@immich.app", "demo@immich.app",
"demo", "demo",
); );
const LoginCredentials(this.server, this.email, this.password); const LoginCredentials(this.server, this.email, this.password);

View file

@ -19,9 +19,9 @@ class AddToAlbumBottomSheet extends HookConsumerWidget {
final List<Asset> assets; final List<Asset> assets;
const AddToAlbumBottomSheet({ const AddToAlbumBottomSheet({
Key? key, super.key,
required this.assets, required this.assets,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -13,12 +13,12 @@ class AddToAlbumSliverList extends HookConsumerWidget {
final bool enabled; final bool enabled;
const AddToAlbumSliverList({ const AddToAlbumSliverList({
Key? key, super.key,
required this.onAddToAlbum, required this.onAddToAlbum,
required this.albums, required this.albums,
required this.sharedAlbums, required this.sharedAlbums,
this.enabled = true, this.enabled = true,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -7,11 +7,11 @@ class AlbumActionOutlinedButton extends StatelessWidget {
final IconData iconData; final IconData iconData;
const AlbumActionOutlinedButton({ const AlbumActionOutlinedButton({
Key? key, super.key,
this.onPressed, this.onPressed,
required this.labelText, required this.labelText,
required this.iconData, required this.iconData,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -13,11 +13,11 @@ class AlbumThumbnailCard extends StatelessWidget {
final bool showOwner; final bool showOwner;
const AlbumThumbnailCard({ const AlbumThumbnailCard({
Key? key, super.key,
required this.album, required this.album,
this.onTap, this.onTap,
this.showOwner = false, this.showOwner = false,
}) : super(key: key); });
final Album album; final Album album;

View file

@ -11,10 +11,10 @@ import 'package:openapi/api.dart';
class AlbumThumbnailListTile extends StatelessWidget { class AlbumThumbnailListTile extends StatelessWidget {
const AlbumThumbnailListTile({ const AlbumThumbnailListTile({
Key? key, super.key,
required this.album, required this.album,
this.onTap, this.onTap,
}) : super(key: key); });
final Album album; final Album album;
final void Function()? onTap; final void Function()? onTap;

View file

@ -6,12 +6,12 @@ import 'package:immich_mobile/modules/album/providers/album_title.provider.dart'
class AlbumTitleTextField extends ConsumerWidget { class AlbumTitleTextField extends ConsumerWidget {
const AlbumTitleTextField({ const AlbumTitleTextField({
Key? key, super.key,
required this.isAlbumTitleEmpty, required this.isAlbumTitleEmpty,
required this.albumTitleTextFieldFocusNode, required this.albumTitleTextFieldFocusNode,
required this.albumTitleController, required this.albumTitleController,
required this.isAlbumTitleTextFieldFocus, required this.isAlbumTitleTextFieldFocus,
}) : super(key: key); });
final ValueNotifier<bool> isAlbumTitleEmpty; final ValueNotifier<bool> isAlbumTitleEmpty;
final FocusNode albumTitleTextFieldFocusNode; final FocusNode albumTitleTextFieldFocusNode;

View file

@ -16,14 +16,14 @@ import 'package:immich_mobile/shared/views/immich_loading_overlay.dart';
class AlbumViewerAppbar extends HookConsumerWidget class AlbumViewerAppbar extends HookConsumerWidget
implements PreferredSizeWidget { implements PreferredSizeWidget {
const AlbumViewerAppbar({ const AlbumViewerAppbar({
Key? key, super.key,
required this.album, required this.album,
required this.userId, required this.userId,
required this.titleFocusNode, required this.titleFocusNode,
this.onAddPhotos, this.onAddPhotos,
this.onAddUsers, this.onAddUsers,
required this.onActivities, required this.onActivities,
}) : super(key: key); });
final Album album; final Album album;
final String userId; final String userId;

View file

@ -10,10 +10,10 @@ class AlbumViewerEditableTitle extends HookConsumerWidget {
final Album album; final Album album;
final FocusNode titleFocusNode; final FocusNode titleFocusNode;
const AlbumViewerEditableTitle({ const AlbumViewerEditableTitle({
Key? key, super.key,
required this.album, required this.album,
required this.titleFocusNode, required this.titleFocusNode,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -6,8 +6,7 @@ import 'package:immich_mobile/shared/ui/immich_image.dart';
class SharedAlbumThumbnailImage extends HookConsumerWidget { class SharedAlbumThumbnailImage extends HookConsumerWidget {
final Asset asset; final Asset asset;
const SharedAlbumThumbnailImage({Key? key, required this.asset}) const SharedAlbumThumbnailImage({super.key, required this.asset});
: super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -31,7 +31,7 @@ import 'package:immich_mobile/shared/views/immich_loading_overlay.dart';
class AlbumViewerPage extends HookConsumerWidget { class AlbumViewerPage extends HookConsumerWidget {
final int albumId; final int albumId;
const AlbumViewerPage({Key? key, required this.albumId}) : super(key: key); const AlbumViewerPage({super.key, required this.albumId});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -15,11 +15,11 @@ import 'package:isar/isar.dart';
@RoutePage<AssetSelectionPageResult?>() @RoutePage<AssetSelectionPageResult?>()
class AssetSelectionPage extends HookConsumerWidget { class AssetSelectionPage extends HookConsumerWidget {
const AssetSelectionPage({ const AssetSelectionPage({
Key? key, super.key,
required this.existingAssets, required this.existingAssets,
this.canDeselect = false, this.canDeselect = false,
required this.query, required this.query,
}) : super(key: key); });
final Set<Asset> existingAssets; final Set<Asset> existingAssets;
final QueryBuilder<Asset, Asset, QAfterSortBy>? query; final QueryBuilder<Asset, Asset, QAfterSortBy>? query;

View file

@ -21,10 +21,10 @@ class CreateAlbumPage extends HookConsumerWidget {
final List<Asset>? initialAssets; final List<Asset>? initialAssets;
const CreateAlbumPage({ const CreateAlbumPage({
Key? key, super.key,
required this.isSharedAlbum, required this.isSharedAlbum,
this.initialAssets, this.initialAssets,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -13,7 +13,7 @@ import 'package:immich_mobile/shared/ui/immich_app_bar.dart';
@RoutePage() @RoutePage()
class LibraryPage extends HookConsumerWidget { class LibraryPage extends HookConsumerWidget {
const LibraryPage({Key? key}) : super(key: key); const LibraryPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -14,8 +14,7 @@ import 'package:immich_mobile/shared/ui/user_circle_avatar.dart';
class SelectAdditionalUserForSharingPage extends HookConsumerWidget { class SelectAdditionalUserForSharingPage extends HookConsumerWidget {
final Album album; final Album album;
const SelectAdditionalUserForSharingPage({Key? key, required this.album}) const SelectAdditionalUserForSharingPage({super.key, required this.album});
: super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -15,8 +15,7 @@ import 'package:immich_mobile/shared/ui/user_circle_avatar.dart';
@RoutePage<List<String>>() @RoutePage<List<String>>()
class SelectUserForSharingPage extends HookConsumerWidget { class SelectUserForSharingPage extends HookConsumerWidget {
const SelectUserForSharingPage({Key? key, required this.assets}) const SelectUserForSharingPage({super.key, required this.assets});
: super(key: key);
final Set<Asset> assets; final Set<Asset> assets;

View file

@ -16,7 +16,7 @@ import 'package:immich_mobile/shared/ui/immich_image.dart';
@RoutePage() @RoutePage()
class SharingPage extends HookConsumerWidget { class SharingPage extends HookConsumerWidget {
const SharingPage({Key? key}) : super(key: key); const SharingPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -14,7 +14,7 @@ class AssetDescriptionNotifier extends StateNotifier<String> {
AssetDescriptionNotifier( AssetDescriptionNotifier(
this._db, this._db,
this._service, this._service,
this._asset, this._asset,
) : super('') { ) : super('') {
_fetchLocalDescription(); _fetchLocalDescription();
@ -34,9 +34,7 @@ class AssetDescriptionNotifier extends StateNotifier<String> {
} }
// Subscribe to local changes // Subscribe to local changes
final exifInfo = await _db final exifInfo = await _db.exifInfos.get(localExifId);
.exifInfos
.get(localExifId);
// Guard // Guard
if (exifInfo?.description == null) { if (exifInfo?.description == null) {
@ -75,13 +73,11 @@ class AssetDescriptionNotifier extends StateNotifier<String> {
return; return;
} }
return _service return _service.setDescription(description, remoteAssetId, localExifId);
.setDescription(description, remoteAssetId, localExifId);
} }
} }
final assetDescriptionProvider = StateNotifierProvider final assetDescriptionProvider = StateNotifierProvider.autoDispose
.autoDispose
.family<AssetDescriptionNotifier, String, Asset>( .family<AssetDescriptionNotifier, String, Asset>(
(ref, asset) => AssetDescriptionNotifier( (ref, asset) => AssetDescriptionNotifier(
ref.watch(dbProvider), ref.watch(dbProvider),
@ -89,5 +85,3 @@ final assetDescriptionProvider = StateNotifierProvider
asset, asset,
), ),
); );

View file

@ -24,11 +24,13 @@ class ImageViewerService {
try { try {
// Download LivePhotos image and motion part // Download LivePhotos image and motion part
if (asset.isImage && asset.livePhotoVideoId != null && Platform.isIOS) { if (asset.isImage && asset.livePhotoVideoId != null && Platform.isIOS) {
var imageResponse = await _apiService.assetApi.downloadFileOldWithHttpInfo( var imageResponse =
await _apiService.assetApi.downloadFileOldWithHttpInfo(
asset.remoteId!, asset.remoteId!,
); );
var motionReponse = await _apiService.assetApi.downloadFileOldWithHttpInfo( var motionReponse =
await _apiService.assetApi.downloadFileOldWithHttpInfo(
asset.livePhotoVideoId!, asset.livePhotoVideoId!,
); );

View file

@ -7,8 +7,7 @@ import 'package:immich_mobile/shared/models/asset.dart';
class AdvancedBottomSheet extends HookConsumerWidget { class AdvancedBottomSheet extends HookConsumerWidget {
final Asset assetDetail; final Asset assetDetail;
const AdvancedBottomSheet({Key? key, required this.assetDetail}) const AdvancedBottomSheet({super.key, required this.assetDetail});
: super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -3,11 +3,11 @@ import 'package:flutter/material.dart';
/// A widget that animates implicitly between a play and a pause icon. /// A widget that animates implicitly between a play and a pause icon.
class AnimatedPlayPause extends StatefulWidget { class AnimatedPlayPause extends StatefulWidget {
const AnimatedPlayPause({ const AnimatedPlayPause({
Key? key, super.key,
required this.playing, required this.playing,
this.size, this.size,
this.color, this.color,
}) : super(key: key); });
final double? size; final double? size;
final bool playing; final bool playing;

View file

@ -3,14 +3,14 @@ import 'package:immich_mobile/modules/asset_viewer/ui/animated_play_pause.dart';
class CenterPlayButton extends StatelessWidget { class CenterPlayButton extends StatelessWidget {
const CenterPlayButton({ const CenterPlayButton({
Key? key, super.key,
required this.backgroundColor, required this.backgroundColor,
this.iconColor, this.iconColor,
required this.show, required this.show,
required this.isPlaying, required this.isPlaying,
required this.isFinished, required this.isFinished,
this.onPressed, this.onPressed,
}) : super(key: key); });
final Color backgroundColor; final Color backgroundColor;
final Color? iconColor; final Color? iconColor;

View file

@ -19,7 +19,7 @@ import 'package:url_launcher/url_launcher.dart';
class ExifBottomSheet extends HookConsumerWidget { class ExifBottomSheet extends HookConsumerWidget {
final Asset asset; final Asset asset;
const ExifBottomSheet({Key? key, required this.asset}) : super(key: key); const ExifBottomSheet({super.key, required this.asset});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -8,7 +8,7 @@ import 'package:immich_mobile/shared/providers/asset.provider.dart';
class TopControlAppBar extends HookConsumerWidget { class TopControlAppBar extends HookConsumerWidget {
const TopControlAppBar({ const TopControlAppBar({
Key? key, super.key,
required this.asset, required this.asset,
required this.onMoreInfoPressed, required this.onMoreInfoPressed,
required this.onDownloadPressed, required this.onDownloadPressed,
@ -20,7 +20,7 @@ class TopControlAppBar extends HookConsumerWidget {
required this.isOwner, required this.isOwner,
required this.onActivitiesPressed, required this.onActivitiesPressed,
required this.isPartner, required this.isPartner,
}) : super(key: key); });
final Asset asset; final Asset asset;
final Function onMoreInfoPressed; final Function onMoreInfoPressed;

View file

@ -12,8 +12,8 @@ import 'package:video_player/video_player.dart';
class VideoPlayerControls extends ConsumerStatefulWidget { class VideoPlayerControls extends ConsumerStatefulWidget {
const VideoPlayerControls({ const VideoPlayerControls({
Key? key, super.key,
}) : super(key: key); });
@override @override
VideoPlayerControlsState createState() => VideoPlayerControlsState(); VideoPlayerControlsState createState() => VideoPlayerControlsState();

View file

@ -751,15 +751,16 @@ class GalleryViewerPage extends HookConsumerWidget {
} }
}); });
return Scaffold( return PopScope(
backgroundColor: Colors.black, canPop: false,
body: WillPopScope( onPopInvoked: (_) {
onWillPop: () async { // Change immersive mode back to normal "edgeToEdge" mode
// Change immersive mode back to normal "edgeToEdge" mode SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); context.pop();
return true; },
}, child: Scaffold(
child: Stack( backgroundColor: Colors.black,
body: Stack(
children: [ children: [
PhotoViewGallery.builder( PhotoViewGallery.builder(
scaleStateChangedCallback: (state) { scaleStateChangedCallback: (state) {

View file

@ -26,14 +26,14 @@ class VideoViewerPage extends HookConsumerWidget {
final VoidCallback? onPaused; final VoidCallback? onPaused;
const VideoViewerPage({ const VideoViewerPage({
Key? key, super.key,
required this.asset, required this.asset,
required this.isMotionVideo, required this.isMotionVideo,
required this.onVideoEnded, required this.onVideoEnded,
this.onPlaying, this.onPlaying,
this.onPaused, this.onPaused,
this.placeholder, this.placeholder,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
@ -112,7 +112,7 @@ class VideoPlayer extends StatefulWidget {
final Widget? placeholder; final Widget? placeholder;
const VideoPlayer({ const VideoPlayer({
Key? key, super.key,
this.url, this.url,
this.jwtToken, this.jwtToken,
this.file, this.file,
@ -121,7 +121,7 @@ class VideoPlayer extends StatefulWidget {
this.onPlaying, this.onPlaying,
this.onPaused, this.onPaused,
this.placeholder, this.placeholder,
}) : super(key: key); });
@override @override
State<VideoPlayer> createState() => _VideoPlayerState(); State<VideoPlayer> createState() => _VideoPlayerState();

View file

@ -15,24 +15,27 @@ class IOSBackgroundSettings {
}); });
} }
class IOSBackgroundSettingsNotifier extends StateNotifier<IOSBackgroundSettings?> { class IOSBackgroundSettingsNotifier
extends StateNotifier<IOSBackgroundSettings?> {
final BackgroundService _service; final BackgroundService _service;
IOSBackgroundSettingsNotifier(this._service) : super(null); IOSBackgroundSettingsNotifier(this._service) : super(null);
IOSBackgroundSettings? get settings => state; IOSBackgroundSettings? get settings => state;
Future<IOSBackgroundSettings> refresh() async { Future<IOSBackgroundSettings> refresh() async {
final lastFetchTime = await _service.getIOSBackupLastRun(IosBackgroundTask.fetch); final lastFetchTime =
final lastProcessingTime = await _service.getIOSBackupLastRun(IosBackgroundTask.processing); await _service.getIOSBackupLastRun(IosBackgroundTask.fetch);
final lastProcessingTime =
await _service.getIOSBackupLastRun(IosBackgroundTask.processing);
int numberOfProcesses = await _service.getIOSBackupNumberOfProcesses(); int numberOfProcesses = await _service.getIOSBackupNumberOfProcesses();
final appRefreshEnabled = await _service.getIOSBackgroundAppRefreshEnabled(); final appRefreshEnabled =
await _service.getIOSBackgroundAppRefreshEnabled();
// If this is enabled and there are no background processes, // If this is enabled and there are no background processes,
// the user just enabled app refresh in Settings. // the user just enabled app refresh in Settings.
// But we don't have any background services running, since it was disabled // But we don't have any background services running, since it was disabled
// before. // before.
if (await _service.isBackgroundBackupEnabled() && if (await _service.isBackgroundBackupEnabled() && numberOfProcesses == 0) {
numberOfProcesses == 0) {
// We need to restart the background service // We need to restart the background service
await _service.enableService(); await _service.enableService();
numberOfProcesses = await _service.getIOSBackupNumberOfProcesses(); numberOfProcesses = await _service.getIOSBackupNumberOfProcesses();
@ -48,10 +51,9 @@ class IOSBackgroundSettingsNotifier extends StateNotifier<IOSBackgroundSettings?
state = settings; state = settings;
return settings; return settings;
} }
} }
final iOSBackgroundSettingsProvider = StateNotifierProvider<IOSBackgroundSettingsNotifier, IOSBackgroundSettings?>( final iOSBackgroundSettingsProvider = StateNotifierProvider<
IOSBackgroundSettingsNotifier, IOSBackgroundSettings?>(
(ref) => IOSBackgroundSettingsNotifier(ref.watch(backgroundServiceProvider)), (ref) => IOSBackgroundSettingsNotifier(ref.watch(backgroundServiceProvider)),
); );

View file

@ -429,10 +429,10 @@ class BackupService {
class MultipartRequest extends http.MultipartRequest { class MultipartRequest extends http.MultipartRequest {
/// Creates a new [MultipartRequest]. /// Creates a new [MultipartRequest].
MultipartRequest( MultipartRequest(
String method, super.method,
Uri url, { super.url, {
required this.onProgress, required this.onProgress,
}) : super(method, url); });
final void Function(int bytes, int totalBytes) onProgress; final void Function(int bytes, int totalBytes) onProgress;

View file

@ -14,8 +14,7 @@ class AlbumInfoCard extends HookConsumerWidget {
final Uint8List? imageData; final Uint8List? imageData;
final AvailableAlbum albumInfo; final AvailableAlbum albumInfo;
const AlbumInfoCard({Key? key, this.imageData, required this.albumInfo}) const AlbumInfoCard({super.key, this.imageData, required this.albumInfo});
: super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -14,8 +14,7 @@ class AlbumInfoListTile extends HookConsumerWidget {
final Uint8List? imageData; final Uint8List? imageData;
final AvailableAlbum albumInfo; final AvailableAlbum albumInfo;
const AlbumInfoListTile({Key? key, this.imageData, required this.albumInfo}) const AlbumInfoListTile({super.key, this.imageData, required this.albumInfo});
: super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -7,11 +7,11 @@ class BackupInfoCard extends StatelessWidget {
final String subtitle; final String subtitle;
final String info; final String info;
const BackupInfoCard({ const BackupInfoCard({
Key? key, super.key,
required this.title, required this.title,
required this.subtitle, required this.subtitle,
required this.info, required this.info,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -10,7 +10,7 @@ import 'package:photo_manager/photo_manager.dart';
@RoutePage() @RoutePage()
class AlbumPreviewPage extends HookConsumerWidget { class AlbumPreviewPage extends HookConsumerWidget {
final AssetPathEntity album; final AssetPathEntity album;
const AlbumPreviewPage({Key? key, required this.album}) : super(key: key); const AlbumPreviewPage({super.key, required this.album});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -12,7 +12,7 @@ import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
@RoutePage() @RoutePage()
class BackupAlbumSelectionPage extends HookConsumerWidget { class BackupAlbumSelectionPage extends HookConsumerWidget {
const BackupAlbumSelectionPage({Key? key}) : super(key: key); const BackupAlbumSelectionPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
// final availableAlbums = ref.watch(backupProvider).availableAlbums; // final availableAlbums = ref.watch(backupProvider).availableAlbums;

View file

@ -20,7 +20,7 @@ import 'package:immich_mobile/modules/backup/ui/backup_info_card.dart';
@RoutePage() @RoutePage()
class BackupControllerPage extends HookConsumerWidget { class BackupControllerPage extends HookConsumerWidget {
const BackupControllerPage({Key? key}) : super(key: key); const BackupControllerPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -25,7 +25,7 @@ import 'package:wakelock_plus/wakelock_plus.dart';
@RoutePage() @RoutePage()
class BackupOptionsPage extends HookConsumerWidget { class BackupOptionsPage extends HookConsumerWidget {
const BackupOptionsPage({Key? key}) : super(key: key); const BackupOptionsPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
BackUpState backupState = ref.watch(backupProvider); BackUpState backupState = ref.watch(backupProvider);

View file

@ -5,10 +5,11 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/providers/error_backup_list.provider.dart'; import 'package:immich_mobile/modules/backup/providers/error_backup_list.provider.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:photo_manager/photo_manager.dart'; import 'package:photo_manager/photo_manager.dart';
import 'package:photo_manager_image_provider/photo_manager_image_provider.dart';
@RoutePage() @RoutePage()
class FailedBackupStatusPage extends HookConsumerWidget { class FailedBackupStatusPage extends HookConsumerWidget {
const FailedBackupStatusPage({Key? key}) : super(key: key); const FailedBackupStatusPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final errorBackupList = ref.watch(errorBackupListProvider); final errorBackupList = ref.watch(errorBackupListProvider);

View file

@ -8,7 +8,7 @@ import 'package:immich_mobile/shared/ui/asset_grid/multiselect_grid.dart';
@RoutePage() @RoutePage()
class FavoritesPage extends HookConsumerWidget { class FavoritesPage extends HookConsumerWidget {
const FavoritesPage({Key? key}) : super(key: key); const FavoritesPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -4,10 +4,10 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart';
class DisableMultiSelectButton extends ConsumerWidget { class DisableMultiSelectButton extends ConsumerWidget {
const DisableMultiSelectButton({ const DisableMultiSelectButton({
Key? key, super.key,
required this.onPressed, required this.onPressed,
required this.selectedItemCount, required this.selectedItemCount,
}) : super(key: key); });
final Function onPressed; final Function onPressed;
final int selectedItemCount; final int selectedItemCount;

View file

@ -57,7 +57,7 @@ class DraggableScrollbar extends StatefulWidget {
final Function(bool scrolling) scrollStateListener; final Function(bool scrolling) scrollStateListener;
DraggableScrollbar.semicircle({ DraggableScrollbar.semicircle({
Key? key, super.key,
Key? scrollThumbKey, Key? scrollThumbKey,
this.alwaysVisibleScrollThumb = false, this.alwaysVisibleScrollThumb = false,
required this.child, required this.child,
@ -76,8 +76,7 @@ class DraggableScrollbar extends StatefulWidget {
heightScrollThumb * 0.6, heightScrollThumb * 0.6,
scrollThumbKey, scrollThumbKey,
alwaysVisibleScrollThumb, alwaysVisibleScrollThumb,
), );
super(key: key);
@override @override
DraggableScrollbarState createState() => DraggableScrollbarState(); DraggableScrollbarState createState() => DraggableScrollbarState();
@ -170,12 +169,12 @@ class ScrollLabel extends StatelessWidget {
BoxConstraints.tightFor(width: 72.0, height: 28.0); BoxConstraints.tightFor(width: 72.0, height: 28.0);
const ScrollLabel({ const ScrollLabel({
Key? key, super.key,
required this.child, required this.child,
required this.animation, required this.animation,
required this.backgroundColor, required this.backgroundColor,
this.constraints = _defaultConstraints, this.constraints = _defaultConstraints,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -509,10 +508,10 @@ class SlideFadeTransition extends StatelessWidget {
final Widget child; final Widget child;
const SlideFadeTransition({ const SlideFadeTransition({
Key? key, super.key,
required this.animation, required this.animation,
required this.child, required this.child,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -9,13 +9,13 @@ import 'package:immich_mobile/modules/settings/services/app_settings.service.dar
class GroupDividerTitle extends HookConsumerWidget { class GroupDividerTitle extends HookConsumerWidget {
const GroupDividerTitle({ const GroupDividerTitle({
Key? key, super.key,
required this.text, required this.text,
required this.multiselectEnabled, required this.multiselectEnabled,
required this.onSelect, required this.onSelect,
required this.onDeselect, required this.onDeselect,
required this.selected, required this.selected,
}) : super(key: key); });
final String text; final String text;
final bool multiselectEnabled; final bool multiselectEnabled;

View file

@ -389,15 +389,6 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
} }
} }
Future<bool> onWillPop() async {
if (widget.selectionActive && _selectedAssets.isNotEmpty) {
_deselectAll();
return false;
}
return true;
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -438,8 +429,9 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return WillPopScope( return PopScope(
onWillPop: onWillPop, canPop: !(widget.selectionActive && _selectedAssets.isNotEmpty),
onPopInvoked: (didPop) => !didPop ? _deselectAll() : null,
child: Stack( child: Stack(
children: [ children: [
_buildAssetGrid(), _buildAssetGrid(),

View file

@ -23,7 +23,7 @@ class ThumbnailImage extends StatelessWidget {
final int heroOffset; final int heroOffset;
const ThumbnailImage({ const ThumbnailImage({
Key? key, super.key,
required this.asset, required this.asset,
required this.index, required this.index,
required this.loadAsset, required this.loadAsset,
@ -36,7 +36,7 @@ class ThumbnailImage extends StatelessWidget {
this.onDeselect, this.onDeselect,
this.onSelect, this.onSelect,
this.heroOffset = 0, this.heroOffset = 0,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -33,7 +33,7 @@ class ControlBottomAppBar extends ConsumerWidget {
final SelectionAssetState selectionAssetState; final SelectionAssetState selectionAssetState;
const ControlBottomAppBar({ const ControlBottomAppBar({
Key? key, super.key,
required this.onShare, required this.onShare,
this.onFavorite, this.onFavorite,
this.onArchive, this.onArchive,
@ -51,7 +51,7 @@ class ControlBottomAppBar extends ConsumerWidget {
this.enabled = true, this.enabled = true,
this.unarchive = false, this.unarchive = false,
this.unfavorite = false, this.unfavorite = false,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -6,9 +6,8 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/ui/confirm_dialog.dart'; import 'package:immich_mobile/shared/ui/confirm_dialog.dart';
class DeleteDialog extends ConfirmDialog { class DeleteDialog extends ConfirmDialog {
const DeleteDialog({Key? key, String? alert, required Function onDelete}) const DeleteDialog({super.key, String? alert, required Function onDelete})
: super( : super(
key: key,
title: "delete_dialog_title", title: "delete_dialog_title",
content: alert ?? "delete_dialog_alert", content: alert ?? "delete_dialog_alert",
cancel: "delete_dialog_cancel", cancel: "delete_dialog_cancel",

View file

@ -52,7 +52,7 @@ class DraggableScrollbar extends StatefulWidget {
final bool alwaysVisibleScrollThumb; final bool alwaysVisibleScrollThumb;
DraggableScrollbar({ DraggableScrollbar({
Key? key, super.key,
this.alwaysVisibleScrollThumb = false, this.alwaysVisibleScrollThumb = false,
required this.heightScrollThumb, required this.heightScrollThumb,
required this.backgroundColor, required this.backgroundColor,
@ -64,11 +64,10 @@ class DraggableScrollbar extends StatefulWidget {
this.scrollbarTimeToFade = const Duration(milliseconds: 600), this.scrollbarTimeToFade = const Duration(milliseconds: 600),
this.labelTextBuilder, this.labelTextBuilder,
this.labelConstraints, this.labelConstraints,
}) : assert(child.scrollDirection == Axis.vertical), }) : assert(child.scrollDirection == Axis.vertical);
super(key: key);
DraggableScrollbar.rrect({ DraggableScrollbar.rrect({
Key? key, super.key,
Key? scrollThumbKey, Key? scrollThumbKey,
this.alwaysVisibleScrollThumb = false, this.alwaysVisibleScrollThumb = false,
required this.child, required this.child,
@ -82,11 +81,10 @@ class DraggableScrollbar extends StatefulWidget {
this.labelConstraints, this.labelConstraints,
}) : assert(child.scrollDirection == Axis.vertical), }) : assert(child.scrollDirection == Axis.vertical),
scrollThumbBuilder = scrollThumbBuilder =
_thumbRRectBuilder(scrollThumbKey, alwaysVisibleScrollThumb), _thumbRRectBuilder(scrollThumbKey, alwaysVisibleScrollThumb);
super(key: key);
DraggableScrollbar.arrows({ DraggableScrollbar.arrows({
Key? key, super.key,
Key? scrollThumbKey, Key? scrollThumbKey,
this.alwaysVisibleScrollThumb = false, this.alwaysVisibleScrollThumb = false,
required this.child, required this.child,
@ -100,11 +98,10 @@ class DraggableScrollbar extends StatefulWidget {
this.labelConstraints, this.labelConstraints,
}) : assert(child.scrollDirection == Axis.vertical), }) : assert(child.scrollDirection == Axis.vertical),
scrollThumbBuilder = scrollThumbBuilder =
_thumbArrowBuilder(scrollThumbKey, alwaysVisibleScrollThumb), _thumbArrowBuilder(scrollThumbKey, alwaysVisibleScrollThumb);
super(key: key);
DraggableScrollbar.semicircle({ DraggableScrollbar.semicircle({
Key? key, super.key,
Key? scrollThumbKey, Key? scrollThumbKey,
this.alwaysVisibleScrollThumb = false, this.alwaysVisibleScrollThumb = false,
required this.child, required this.child,
@ -121,8 +118,7 @@ class DraggableScrollbar extends StatefulWidget {
heightScrollThumb * 0.6, heightScrollThumb * 0.6,
scrollThumbKey, scrollThumbKey,
alwaysVisibleScrollThumb, alwaysVisibleScrollThumb,
), );
super(key: key);
@override @override
DraggableScrollbarState createState() => DraggableScrollbarState(); DraggableScrollbarState createState() => DraggableScrollbarState();
@ -288,12 +284,12 @@ class ScrollLabel extends StatelessWidget {
BoxConstraints.tightFor(width: 72.0, height: 28.0); BoxConstraints.tightFor(width: 72.0, height: 28.0);
const ScrollLabel({ const ScrollLabel({
Key? key, super.key,
required this.child, required this.child,
required this.animation, required this.animation,
required this.backgroundColor, required this.backgroundColor,
this.constraints = _defaultConstraints, this.constraints = _defaultConstraints,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -625,10 +621,10 @@ class SlideFadeTransition extends StatelessWidget {
final Widget child; final Widget child;
const SlideFadeTransition({ const SlideFadeTransition({
Key? key, super.key,
required this.animation, required this.animation,
required this.child, required this.child,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -1,12 +1,10 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/shared/ui/confirm_dialog.dart'; import 'package:immich_mobile/shared/ui/confirm_dialog.dart';
class UploadDialog extends ConfirmDialog { class UploadDialog extends ConfirmDialog {
final Function onUpload; final Function onUpload;
const UploadDialog({Key? key, required this.onUpload}) const UploadDialog({super.key, required this.onUpload})
: super( : super(
key: key,
title: 'upload_dialog_title', title: 'upload_dialog_title',
content: 'upload_dialog_info', content: 'upload_dialog_info',
cancel: 'upload_dialog_cancel', cancel: 'upload_dialog_cancel',

View file

@ -20,7 +20,7 @@ import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
@RoutePage() @RoutePage()
class HomePage extends HookConsumerWidget { class HomePage extends HookConsumerWidget {
const HomePage({Key? key}) : super(key: key); const HomePage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -63,7 +63,7 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
if (Platform.isIOS) { if (Platform.isIOS) {
var iosInfo = await deviceInfoPlugin.iosInfo; var iosInfo = await deviceInfoPlugin.iosInfo;
_apiService.authenticationApi.apiClient _apiService.authenticationApi.apiClient
.addDefaultHeader('deviceModel', iosInfo.utsname.machine ?? ''); .addDefaultHeader('deviceModel', iosInfo.utsname.machine);
_apiService.authenticationApi.apiClient _apiService.authenticationApi.apiClient
.addDefaultHeader('deviceType', 'iOS'); .addDefaultHeader('deviceType', 'iOS');
} else { } else {

View file

@ -13,7 +13,7 @@ import 'package:immich_mobile/shared/providers/websocket.provider.dart';
import 'package:immich_mobile/shared/ui/immich_toast.dart'; import 'package:immich_mobile/shared/ui/immich_toast.dart';
class ChangePasswordForm extends HookConsumerWidget { class ChangePasswordForm extends HookConsumerWidget {
const ChangePasswordForm({Key? key}) : super(key: key); const ChangePasswordForm({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
@ -128,7 +128,7 @@ class ChangePasswordForm extends HookConsumerWidget {
class PasswordInput extends StatelessWidget { class PasswordInput extends StatelessWidget {
final TextEditingController controller; final TextEditingController controller;
const PasswordInput({Key? key, required this.controller}) : super(key: key); const PasswordInput({super.key, required this.controller});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -149,10 +149,10 @@ class ConfirmPasswordInput extends StatelessWidget {
final TextEditingController confirmController; final TextEditingController confirmController;
const ConfirmPasswordInput({ const ConfirmPasswordInput({
Key? key, super.key,
required this.originalController, required this.originalController,
required this.confirmController, required this.confirmController,
}) : super(key: key); });
String? _validateInput(String? email) { String? _validateInput(String? email) {
if (confirmController.value != originalController.value) { if (confirmController.value != originalController.value) {
@ -181,10 +181,10 @@ class ChangePasswordButton extends ConsumerWidget {
final TextEditingController passwordController; final TextEditingController passwordController;
final VoidCallback onPressed; final VoidCallback onPressed;
const ChangePasswordButton({ const ChangePasswordButton({
Key? key, super.key,
required this.passwordController, required this.passwordController,
required this.onPressed, required this.onPressed,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -22,7 +22,7 @@ import 'package:openapi/api.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
class LoginForm extends HookConsumerWidget { class LoginForm extends HookConsumerWidget {
const LoginForm({Key? key}) : super(key: key); const LoginForm({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
@ -426,11 +426,11 @@ class ServerEndpointInput extends StatelessWidget {
final Function()? onSubmit; final Function()? onSubmit;
const ServerEndpointInput({ const ServerEndpointInput({
Key? key, super.key,
required this.controller, required this.controller,
required this.focusNode, required this.focusNode,
this.onSubmit, this.onSubmit,
}) : super(key: key); });
String? _validateInput(String? url) { String? _validateInput(String? url) {
if (url == null || url.isEmpty) return null; if (url == null || url.isEmpty) return null;
@ -474,11 +474,11 @@ class EmailInput extends StatelessWidget {
final Function()? onSubmit; final Function()? onSubmit;
const EmailInput({ const EmailInput({
Key? key, super.key,
required this.controller, required this.controller,
this.focusNode, this.focusNode,
this.onSubmit, this.onSubmit,
}) : super(key: key); });
String? _validateInput(String? email) { String? _validateInput(String? email) {
if (email == null || email == '') return null; if (email == null || email == '') return null;
@ -521,11 +521,11 @@ class PasswordInput extends StatelessWidget {
final Function()? onSubmit; final Function()? onSubmit;
const PasswordInput({ const PasswordInput({
Key? key, super.key,
required this.controller, required this.controller,
this.focusNode, this.focusNode,
this.onSubmit, this.onSubmit,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -554,9 +554,9 @@ class LoginButton extends ConsumerWidget {
final Function() onPressed; final Function() onPressed;
const LoginButton({ const LoginButton({
Key? key, super.key,
required this.onPressed, required this.onPressed,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
@ -581,12 +581,12 @@ class OAuthLoginButton extends ConsumerWidget {
final Function() onPressed; final Function() onPressed;
const OAuthLoginButton({ const OAuthLoginButton({
Key? key, super.key,
required this.serverEndpointController, required this.serverEndpointController,
required this.isLoading, required this.isLoading,
required this.buttonLabel, required this.buttonLabel,
required this.onPressed, required this.onPressed,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
@ -606,7 +606,7 @@ class OAuthLoginButton extends ConsumerWidget {
} }
class LoadingIcon extends StatelessWidget { class LoadingIcon extends StatelessWidget {
const LoadingIcon({Key? key}) : super(key: key); const LoadingIcon({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -5,7 +5,7 @@ import 'package:immich_mobile/modules/login/ui/change_password_form.dart';
@RoutePage() @RoutePage()
class ChangePasswordPage extends HookConsumerWidget { class ChangePasswordPage extends HookConsumerWidget {
const ChangePasswordPage({Key? key}) : super(key: key); const ChangePasswordPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -9,7 +9,7 @@ import 'package:package_info_plus/package_info_plus.dart';
@RoutePage() @RoutePage()
class LoginPage extends HookConsumerWidget { class LoginPage extends HookConsumerWidget {
const LoginPage({Key? key}) : super(key: key); const LoginPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -92,7 +92,7 @@ class _AssetMarkerIcon extends StatelessWidget {
"Authorization": "Authorization":
"Bearer ${Store.get(StoreKey.accessToken)}", "Bearer ${Store.get(StoreKey.accessToken)}",
}, },
errorListener: () => errorListener: (_) =>
const Icon(Icons.image_not_supported_outlined), const Icon(Icons.image_not_supported_outlined),
), ),
), ),

View file

@ -7,7 +7,7 @@ import 'package:immich_mobile/shared/models/user.dart';
import 'package:immich_mobile/shared/ui/user_avatar.dart'; import 'package:immich_mobile/shared/ui/user_avatar.dart';
class PartnerList extends HookConsumerWidget { class PartnerList extends HookConsumerWidget {
const PartnerList({Key? key, required this.partner}) : super(key: key); const PartnerList({super.key, required this.partner});
final List<User> partner; final List<User> partner;

View file

@ -11,7 +11,7 @@ import 'package:immich_mobile/shared/ui/immich_toast.dart';
@RoutePage() @RoutePage()
class PartnerDetailPage extends HookConsumerWidget { class PartnerDetailPage extends HookConsumerWidget {
const PartnerDetailPage({Key? key, required this.partner}) : super(key: key); const PartnerDetailPage({super.key, required this.partner});
final User partner; final User partner;

View file

@ -12,7 +12,7 @@ import 'package:immich_mobile/shared/ui/user_avatar.dart';
@RoutePage() @RoutePage()
class PartnerPage extends HookConsumerWidget { class PartnerPage extends HookConsumerWidget {
const PartnerPage({Key? key}) : super(key: key); const PartnerPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -1,5 +1,5 @@
/// A wrapper for [CuratedLocationsResponseDto] objects /// A wrapper for [CuratedLocationsResponseDto] objects
/// and [CuratedObjectsResponseDto] to be displayed in /// and [CuratedObjectsResponseDto] to be displayed in
/// a view /// a view
class CuratedContent { class CuratedContent {
/// The label to show associated with this curated object /// The label to show associated with this curated object

View file

@ -3,10 +3,11 @@ import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/providers/db.provider.dart'; import 'package:immich_mobile/shared/providers/db.provider.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
final allMotionPhotosProvider = FutureProvider<List<Asset>>( (ref) async { final allMotionPhotosProvider = FutureProvider<List<Asset>>((ref) async {
return ref.watch(dbProvider) return ref
.assets .watch(dbProvider)
.filter() .assets
.livePhotoVideoIdIsNotNull() .filter()
.findAll(); .livePhotoVideoIdIsNotNull()
.findAll();
}); });

View file

@ -3,8 +3,9 @@ import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/providers/db.provider.dart'; import 'package:immich_mobile/shared/providers/db.provider.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
final recentlyAddedProvider = FutureProvider<List<Asset>>( (ref) async { final recentlyAddedProvider = FutureProvider<List<Asset>>((ref) async {
return ref.watch(dbProvider) return ref
.watch(dbProvider)
.assets .assets
.where() .where()
.sortByFileCreatedAtDesc() .sortByFileCreatedAtDesc()

View file

@ -8,10 +8,10 @@ import 'package:immich_mobile/modules/search/providers/search_page_state.provide
class ImmichSearchBar extends HookConsumerWidget class ImmichSearchBar extends HookConsumerWidget
implements PreferredSizeWidget { implements PreferredSizeWidget {
const ImmichSearchBar({ const ImmichSearchBar({
Key? key, super.key,
required this.searchFocusNode, required this.searchFocusNode,
required this.onSubmitted, required this.onSubmitted,
}) : super(key: key); });
final FocusNode searchFocusNode; final FocusNode searchFocusNode;
final Function(String) onSubmitted; final Function(String) onSubmitted;

View file

@ -5,8 +5,7 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart'; import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart';
class SearchSuggestionList extends ConsumerWidget { class SearchSuggestionList extends ConsumerWidget {
const SearchSuggestionList({Key? key, required this.onSubmitted}) const SearchSuggestionList({super.key, required this.onSubmitted});
: super(key: key);
final Function(String) onSubmitted; final Function(String) onSubmitted;
@override @override

View file

@ -7,13 +7,13 @@ import 'package:immich_mobile/extensions/string_extensions.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class ThumbnailWithInfo extends StatelessWidget { class ThumbnailWithInfo extends StatelessWidget {
ThumbnailWithInfo({ ThumbnailWithInfo({
Key? key, super.key,
required this.textInfo, required this.textInfo,
this.imageUrl, this.imageUrl,
this.noImageIcon, this.noImageIcon,
this.borderRadius = 10, this.borderRadius = 10,
required this.onTap, required this.onTap,
}) : super(key: key); });
final String textInfo; final String textInfo;
final String? imageUrl; final String? imageUrl;

View file

@ -22,7 +22,7 @@ import 'package:immich_mobile/shared/ui/scaffold_error_body.dart';
@RoutePage() @RoutePage()
// ignore: must_be_immutable // ignore: must_be_immutable
class SearchPage extends HookConsumerWidget { class SearchPage extends HookConsumerWidget {
SearchPage({Key? key}) : super(key: key); SearchPage({super.key});
FocusNode searchFocusNode = FocusNode(); FocusNode searchFocusNode = FocusNode();

View file

@ -28,9 +28,9 @@ SearchType _getSearchType(String searchTerm) {
@RoutePage() @RoutePage()
class SearchResultPage extends HookConsumerWidget { class SearchResultPage extends HookConsumerWidget {
const SearchResultPage({ const SearchResultPage({
Key? key, super.key,
required this.searchTerm, required this.searchTerm,
}) : super(key: key); });
final String searchTerm; final String searchTerm;

View file

@ -4,11 +4,12 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
class NotificationPermissionNotifier extends StateNotifier<PermissionStatus> { class NotificationPermissionNotifier extends StateNotifier<PermissionStatus> {
NotificationPermissionNotifier() : NotificationPermissionNotifier()
super(Platform.isAndroid : super(
? PermissionStatus.granted Platform.isAndroid
: PermissionStatus.restricted, ? PermissionStatus.granted
) { : PermissionStatus.restricted,
) {
// Sets the initial state // Sets the initial state
getNotificationPermission().then((p) => state = p); getNotificationPermission().then((p) => state = p);
} }
@ -16,9 +17,9 @@ class NotificationPermissionNotifier extends StateNotifier<PermissionStatus> {
/// Requests the notification permission /// Requests the notification permission
/// Note: In Android, this is always granted /// Note: In Android, this is always granted
Future<PermissionStatus> requestNotificationPermission() async { Future<PermissionStatus> requestNotificationPermission() async {
final permission = await Permission.notification.request(); final permission = await Permission.notification.request();
state = permission; state = permission;
return permission; return permission;
} }
/// Whether the user has the permission or not /// Whether the user has the permission or not
@ -37,8 +38,9 @@ class NotificationPermissionNotifier extends StateNotifier<PermissionStatus> {
Future<bool> hasOrAskForNotificationPermission() { Future<bool> hasOrAskForNotificationPermission() {
return requestNotificationPermission().then((p) => p.isGranted); return requestNotificationPermission().then((p) => p.isGranted);
} }
} }
final notificationPermissionProvider
= StateNotifierProvider<NotificationPermissionNotifier, PermissionStatus> final notificationPermissionProvider =
((ref) => NotificationPermissionNotifier()); StateNotifierProvider<NotificationPermissionNotifier, PermissionStatus>(
(ref) => NotificationPermissionNotifier(),
);

View file

@ -9,8 +9,8 @@ import 'package:immich_mobile/modules/settings/services/app_settings.service.dar
class LayoutSettings extends HookConsumerWidget { class LayoutSettings extends HookConsumerWidget {
const LayoutSettings({ const LayoutSettings({
Key? key, super.key,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -7,8 +7,8 @@ import 'asset_list_tiles_per_row.dart';
class AssetListSettings extends StatelessWidget { class AssetListSettings extends StatelessWidget {
const AssetListSettings({ const AssetListSettings({
Key? key, super.key,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -8,8 +8,8 @@ import 'package:immich_mobile/modules/settings/services/app_settings.service.dar
class StorageIndicator extends HookConsumerWidget { class StorageIndicator extends HookConsumerWidget {
const StorageIndicator({ const StorageIndicator({
Key? key, super.key,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -8,8 +8,8 @@ import 'package:immich_mobile/modules/settings/services/app_settings.service.dar
class TilesPerRow extends HookConsumerWidget { class TilesPerRow extends HookConsumerWidget {
const TilesPerRow({ const TilesPerRow({
Key? key, super.key,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -9,8 +9,8 @@ import 'package:immich_mobile/modules/settings/ui/settings_switch_list_tile.dart
class ImageViewerQualitySetting extends HookConsumerWidget { class ImageViewerQualitySetting extends HookConsumerWidget {
const ImageViewerQualitySetting({ const ImageViewerQualitySetting({
Key? key, super.key,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -11,8 +11,8 @@ import 'package:permission_handler/permission_handler.dart';
class NotificationSetting extends HookConsumerWidget { class NotificationSetting extends HookConsumerWidget {
const NotificationSetting({ const NotificationSetting({
Key? key, super.key,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -9,8 +9,8 @@ import 'package:immich_mobile/utils/immich_app_theme.dart';
class ThemeSetting extends HookConsumerWidget { class ThemeSetting extends HookConsumerWidget {
const ThemeSetting({ const ThemeSetting({
Key? key, super.key,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -12,7 +12,7 @@ import 'package:immich_mobile/modules/settings/ui/theme_setting/theme_setting.da
@RoutePage() @RoutePage()
class SettingsPage extends HookConsumerWidget { class SettingsPage extends HookConsumerWidget {
const SettingsPage({Key? key}) : super(key: key); const SettingsPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
@ -43,7 +43,7 @@ class SettingsPage extends HookConsumerWidget {
const LocalStorageSettings(), const LocalStorageSettings(),
const AdvancedSettings(), const AdvancedSettings(),
], ],
).toList(), ),
], ],
), ),
); );

View file

@ -11,7 +11,7 @@ import 'package:immich_mobile/modules/shared_link/ui/shared_link_item.dart';
@RoutePage() @RoutePage()
class SharedLinkPage extends HookConsumerWidget { class SharedLinkPage extends HookConsumerWidget {
const SharedLinkPage({Key? key}) : super(key: key); const SharedLinkPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -13,7 +13,6 @@ class AuthGuard extends AutoRouteGuard {
AuthGuard(this._apiService); AuthGuard(this._apiService);
@override @override
void onNavigation(NavigationResolver resolver, StackRouter router) async { void onNavigation(NavigationResolver resolver, StackRouter router) async {
resolver.next(true); resolver.next(true);
try { try {

View file

@ -8,7 +8,9 @@ class DuplicateGuard extends AutoRouteGuard {
void onNavigation(NavigationResolver resolver, StackRouter router) async { void onNavigation(NavigationResolver resolver, StackRouter router) async {
// Duplicate navigation // Duplicate navigation
if (resolver.route.name == router.current.name) { if (resolver.route.name == router.current.name) {
debugPrint('DuplicateGuard: Preventing duplicate route navigation for ${resolver.route.name}'); debugPrint(
'DuplicateGuard: Preventing duplicate route navigation for ${resolver.route.name}',
);
resolver.next(false); resolver.next(false);
} else { } else {
resolver.next(true); resolver.next(true);

View file

@ -95,15 +95,15 @@ class StoreValue {
T? _extract<T>(StoreKey<T> key) { T? _extract<T>(StoreKey<T> key) {
switch (key.type) { switch (key.type) {
case int: case const (int):
return intValue as T?; return intValue as T?;
case bool: case const (bool):
return intValue == null ? null : (intValue! == 1) as T; return intValue == null ? null : (intValue! == 1) as T;
case DateTime: case const (DateTime):
return intValue == null return intValue == null
? null ? null
: DateTime.fromMicrosecondsSinceEpoch(intValue!) as T; : DateTime.fromMicrosecondsSinceEpoch(intValue!) as T;
case String: case const (String):
return strValue as T?; return strValue as T?;
default: default:
if (key.fromDb != null) { if (key.fromDb != null) {
@ -117,16 +117,16 @@ class StoreValue {
int? i; int? i;
String? s; String? s;
switch (key.type) { switch (key.type) {
case int: case const (int):
i = value as int?; i = value as int?;
break; break;
case bool: case const (bool):
i = value == null ? null : (value == true ? 1 : 0); i = value == null ? null : (value == true ? 1 : 0);
break; break;
case DateTime: case const (DateTime):
i = value == null ? null : (value as DateTime).microsecondsSinceEpoch; i = value == null ? null : (value as DateTime).microsecondsSinceEpoch;
break; break;
case String: case const (String):
s = value as String?; s = value as String?;
break; break;
default: default:

View file

@ -3,5 +3,5 @@ import 'package:immich_mobile/shared/providers/user.provider.dart';
final isAdminProvider = Provider<bool>((ref) { final isAdminProvider = Provider<bool>((ref) {
final currentUser = ref.watch(currentUserProvider); final currentUser = ref.watch(currentUserProvider);
return currentUser?.isAdmin ?? false; // Default to non-admin if no user return currentUser?.isAdmin ?? false; // Default to non-admin if no user
}); });

View file

@ -11,8 +11,8 @@ import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
class AppBarProfileInfoBox extends HookConsumerWidget { class AppBarProfileInfoBox extends HookConsumerWidget {
const AppBarProfileInfoBox({ const AppBarProfileInfoBox({
Key? key, super.key,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -10,8 +10,8 @@ import 'package:package_info_plus/package_info_plus.dart';
class AppBarServerInfo extends HookConsumerWidget { class AppBarServerInfo extends HookConsumerWidget {
const AppBarServerInfo({ const AppBarServerInfo({
Key? key, super.key,
}) : super(key: key); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View file

@ -30,7 +30,7 @@ import 'package:immich_mobile/utils/selection_handlers.dart';
class MultiselectGrid extends HookConsumerWidget { class MultiselectGrid extends HookConsumerWidget {
const MultiselectGrid({ const MultiselectGrid({
Key? key, super.key,
required this.renderListProvider, required this.renderListProvider,
this.onRefresh, this.onRefresh,
this.buildLoadingIndicator, this.buildLoadingIndicator,
@ -43,7 +43,7 @@ class MultiselectGrid extends HookConsumerWidget {
this.editEnabled = false, this.editEnabled = false,
this.unarchive = false, this.unarchive = false,
this.unfavorite = false, this.unfavorite = false,
}) : super(key: key); });
final ProviderListenable<AsyncValue<RenderList>> renderListProvider; final ProviderListenable<AsyncValue<RenderList>> renderListProvider;
final Future<void> Function()? onRefresh; final Future<void> Function()? onRefresh;

View file

@ -10,13 +10,13 @@ class ConfirmDialog extends StatelessWidget {
final String ok; final String ok;
const ConfirmDialog({ const ConfirmDialog({
Key? key, super.key,
required this.onOk, required this.onOk,
required this.title, required this.title,
required this.content, required this.content,
this.cancel = "delete_dialog_cancel", this.cancel = "delete_dialog_cancel",
this.ok = "backup_controller_page_background_battery_info_ok", this.ok = "backup_controller_page_background_battery_info_ok",
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -19,12 +19,12 @@ class CustomDraggingHandle extends StatelessWidget {
class ControlBoxButton extends StatelessWidget { class ControlBoxButton extends StatelessWidget {
const ControlBoxButton({ const ControlBoxButton({
Key? key, super.key,
required this.label, required this.label,
required this.iconData, required this.iconData,
this.onPressed, this.onPressed,
this.onLongPressed, this.onLongPressed,
}) : super(key: key); });
final String label; final String label;
final IconData iconData; final IconData iconData;

View file

@ -8,6 +8,7 @@ import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/utils/image_url_builder.dart'; import 'package:immich_mobile/utils/image_url_builder.dart';
import 'package:photo_manager/photo_manager.dart'; import 'package:photo_manager/photo_manager.dart';
import 'package:openapi/api.dart' as api; import 'package:openapi/api.dart' as api;
import 'package:photo_manager_image_provider/photo_manager_image_provider.dart';
/// Renders an Asset using local data if available, else remote data /// Renders an Asset using local data if available, else remote data
class ImmichImage extends StatelessWidget { class ImmichImage extends StatelessWidget {

View file

@ -5,9 +5,9 @@ class ImmichLoadingIndicator extends StatelessWidget {
final double? borderRadius; final double? borderRadius;
const ImmichLoadingIndicator({ const ImmichLoadingIndicator({
Key? key, super.key,
this.borderRadius, this.borderRadius,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -21,5 +21,4 @@ class ImmichLogo extends StatelessWidget {
), ),
); );
} }
} }

View file

@ -233,7 +233,7 @@ class PhotoView extends StatefulWidget {
/// ///
/// Internally, the image is rendered within an [Image] widget. /// Internally, the image is rendered within an [Image] widget.
const PhotoView({ const PhotoView({
Key? key, super.key,
required this.imageProvider, required this.imageProvider,
required this.index, required this.index,
this.loadingBuilder, this.loadingBuilder,
@ -264,8 +264,7 @@ class PhotoView extends StatefulWidget {
this.errorBuilder, this.errorBuilder,
this.enablePanAlways, this.enablePanAlways,
}) : child = null, }) : child = null,
childSize = null, childSize = null;
super(key: key);
/// Creates a widget that displays a zoomable child. /// Creates a widget that displays a zoomable child.
/// ///
@ -274,7 +273,7 @@ class PhotoView extends StatefulWidget {
/// Instead of a [imageProvider], this constructor will receive a [child] and a [childSize]. /// Instead of a [imageProvider], this constructor will receive a [child] and a [childSize].
/// ///
const PhotoView.customChild({ const PhotoView.customChild({
Key? key, super.key,
required this.child, required this.child,
this.childSize, this.childSize,
this.backgroundDecoration, this.backgroundDecoration,
@ -305,8 +304,7 @@ class PhotoView extends StatefulWidget {
imageProvider = null, imageProvider = null,
gaplessPlayback = false, gaplessPlayback = false,
loadingBuilder = null, loadingBuilder = null,
index = 0, index = 0;
super(key: key);
/// Given a [imageProvider] it resolves into an zoomable image widget using. It /// Given a [imageProvider] it resolves into an zoomable image widget using. It
/// is required /// is required

View file

@ -107,7 +107,7 @@ typedef PhotoViewGalleryBuilder = PhotoViewGalleryPageOptions Function(
class PhotoViewGallery extends StatefulWidget { class PhotoViewGallery extends StatefulWidget {
/// Construct a gallery with static items through a list of [PhotoViewGalleryPageOptions]. /// Construct a gallery with static items through a list of [PhotoViewGalleryPageOptions].
const PhotoViewGallery({ const PhotoViewGallery({
Key? key, super.key,
required this.pageOptions, required this.pageOptions,
this.loadingBuilder, this.loadingBuilder,
this.backgroundDecoration, this.backgroundDecoration,
@ -123,14 +123,13 @@ class PhotoViewGallery extends StatefulWidget {
this.customSize, this.customSize,
this.allowImplicitScrolling = false, this.allowImplicitScrolling = false,
}) : itemCount = null, }) : itemCount = null,
builder = null, builder = null;
super(key: key);
/// Construct a gallery with dynamic items. /// Construct a gallery with dynamic items.
/// ///
/// The builder must return a [PhotoViewGalleryPageOptions]. /// The builder must return a [PhotoViewGalleryPageOptions].
const PhotoViewGallery.builder({ const PhotoViewGallery.builder({
Key? key, super.key,
required this.itemCount, required this.itemCount,
required this.builder, required this.builder,
this.loadingBuilder, this.loadingBuilder,
@ -148,8 +147,7 @@ class PhotoViewGallery extends StatefulWidget {
this.allowImplicitScrolling = false, this.allowImplicitScrolling = false,
}) : pageOptions = null, }) : pageOptions = null,
assert(itemCount != null), assert(itemCount != null),
assert(builder != null), assert(builder != null);
super(key: key);
/// A list of options to describe the items in the gallery /// A list of options to describe the items in the gallery
final List<PhotoViewGalleryPageOptions>? pageOptions; final List<PhotoViewGalleryPageOptions>? pageOptions;

View file

@ -25,7 +25,7 @@ const _defaultDecoration = BoxDecoration(
/// to user gestures, updates to the controller state and mounts the entire PhotoView Layout /// to user gestures, updates to the controller state and mounts the entire PhotoView Layout
class PhotoViewCore extends StatefulWidget { class PhotoViewCore extends StatefulWidget {
const PhotoViewCore({ const PhotoViewCore({
Key? key, super.key,
required this.imageProvider, required this.imageProvider,
required this.backgroundDecoration, required this.backgroundDecoration,
required this.gaplessPlayback, required this.gaplessPlayback,
@ -47,11 +47,10 @@ class PhotoViewCore extends StatefulWidget {
required this.filterQuality, required this.filterQuality,
required this.disableGestures, required this.disableGestures,
required this.enablePanAlways, required this.enablePanAlways,
}) : customChild = null, }) : customChild = null;
super(key: key);
const PhotoViewCore.customChild({ const PhotoViewCore.customChild({
Key? key, super.key,
required this.customChild, required this.customChild,
required this.backgroundDecoration, required this.backgroundDecoration,
this.heroAttributes, this.heroAttributes,
@ -73,8 +72,7 @@ class PhotoViewCore extends StatefulWidget {
required this.disableGestures, required this.disableGestures,
required this.enablePanAlways, required this.enablePanAlways,
}) : imageProvider = null, }) : imageProvider = null,
gaplessPlayback = false, gaplessPlayback = false;
super(key: key);
final Decoration? backgroundDecoration; final Decoration? backgroundDecoration;
final ImageProvider? imageProvider; final ImageProvider? imageProvider;
@ -359,15 +357,15 @@ class PhotoViewCoreState extends State<PhotoViewCore>
onScaleStart: onScaleStart, onScaleStart: onScaleStart,
onScaleUpdate: onScaleUpdate, onScaleUpdate: onScaleUpdate,
onScaleEnd: onScaleEnd, onScaleEnd: onScaleEnd,
onDragStart: widget.onDragStart != null onDragStart: widget.onDragStart != null
? (details) => widget.onDragStart!(context, details, value) ? (details) => widget.onDragStart!(context, details, value)
: null, : null,
onDragEnd: widget.onDragEnd != null onDragEnd: widget.onDragEnd != null
? (details) => widget.onDragEnd!(context, details, value) ? (details) => widget.onDragEnd!(context, details, value)
: null, : null,
onDragUpdate: widget.onDragUpdate != null onDragUpdate: widget.onDragUpdate != null
? (details) => widget.onDragUpdate!(context, details, value) ? (details) => widget.onDragUpdate!(context, details, value)
: null, : null,
hitDetector: this, hitDetector: this,
onTapUp: widget.onTapUp != null onTapUp: widget.onTapUp != null
? (details) => widget.onTapUp!(context, details, value) ? (details) => widget.onTapUp!(context, details, value)

View file

@ -7,7 +7,7 @@ import 'photo_view_hit_corners.dart';
/// for the gist /// for the gist
class PhotoViewGestureDetector extends StatelessWidget { class PhotoViewGestureDetector extends StatelessWidget {
const PhotoViewGestureDetector({ const PhotoViewGestureDetector({
Key? key, super.key,
this.hitDetector, this.hitDetector,
this.onScaleStart, this.onScaleStart,
this.onScaleUpdate, this.onScaleUpdate,
@ -20,7 +20,7 @@ class PhotoViewGestureDetector extends StatelessWidget {
this.onTapUp, this.onTapUp,
this.onTapDown, this.onTapDown,
this.behavior, this.behavior,
}) : super(key: key); });
final GestureDoubleTapCallback? onDoubleTap; final GestureDoubleTapCallback? onDoubleTap;
final HitCornersDetector? hitDetector; final HitCornersDetector? hitDetector;
@ -63,14 +63,14 @@ class PhotoViewGestureDetector extends StatelessWidget {
} }
if (onDragStart != null || onDragEnd != null || onDragUpdate != null) { if (onDragStart != null || onDragEnd != null || onDragUpdate != null) {
gestures[VerticalDragGestureRecognizer] = gestures[VerticalDragGestureRecognizer] =
GestureRecognizerFactoryWithHandlers<VerticalDragGestureRecognizer>( GestureRecognizerFactoryWithHandlers<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer(debugOwner: this), () => VerticalDragGestureRecognizer(debugOwner: this),
(VerticalDragGestureRecognizer instance) { (VerticalDragGestureRecognizer instance) {
instance instance
..onStart = onDragStart ..onStart = onDragStart
..onUpdate = onDragUpdate ..onUpdate = onDragUpdate
..onEnd = onDragEnd; ..onEnd = onDragEnd;
}, },
); );
} }
@ -86,11 +86,11 @@ class PhotoViewGestureDetector extends StatelessWidget {
gestures[PhotoViewGestureRecognizer] = gestures[PhotoViewGestureRecognizer] =
GestureRecognizerFactoryWithHandlers<PhotoViewGestureRecognizer>( GestureRecognizerFactoryWithHandlers<PhotoViewGestureRecognizer>(
() => PhotoViewGestureRecognizer( () => PhotoViewGestureRecognizer(
hitDetector: hitDetector, hitDetector: hitDetector,
debugOwner: this, debugOwner: this,
validateAxis: axis, validateAxis: axis,
touchSlopFactor: touchSlopFactor, touchSlopFactor: touchSlopFactor,
), ),
(PhotoViewGestureRecognizer instance) { (PhotoViewGestureRecognizer instance) {
instance instance
..onStart = onScaleStart ..onStart = onScaleStart
@ -110,11 +110,11 @@ class PhotoViewGestureDetector extends StatelessWidget {
class PhotoViewGestureRecognizer extends ScaleGestureRecognizer { class PhotoViewGestureRecognizer extends ScaleGestureRecognizer {
PhotoViewGestureRecognizer({ PhotoViewGestureRecognizer({
this.hitDetector, this.hitDetector,
Object? debugOwner, super.debugOwner,
this.validateAxis, this.validateAxis,
this.touchSlopFactor = 1, this.touchSlopFactor = 1,
PointerDeviceKind? kind, PointerDeviceKind? kind,
}) : super(debugOwner: debugOwner, supportedDevices: null); }) : super(supportedDevices: null);
final HitCornersDetector? hitDetector; final HitCornersDetector? hitDetector;
final Axis? validateAxis; final Axis? validateAxis;
final double touchSlopFactor; final double touchSlopFactor;
@ -236,11 +236,11 @@ class PhotoViewGestureRecognizer extends ScaleGestureRecognizer {
/// ``` /// ```
class PhotoViewGestureDetectorScope extends InheritedWidget { class PhotoViewGestureDetectorScope extends InheritedWidget {
const PhotoViewGestureDetectorScope({ const PhotoViewGestureDetectorScope({
super.key, super.key,
this.axis, this.axis,
this.touchSlopFactor = .2, this.touchSlopFactor = .2,
required Widget child, required super.child,
}) : super(child: child); });
static PhotoViewGestureDetectorScope? of(BuildContext context) { static PhotoViewGestureDetectorScope? of(BuildContext context) {
final PhotoViewGestureDetectorScope? scope = context final PhotoViewGestureDetectorScope? scope = context
@ -254,11 +254,12 @@ class PhotoViewGestureDetectorScope extends InheritedWidget {
// 0: most reactive but will not let tap recognizers accept gestures // 0: most reactive but will not let tap recognizers accept gestures
// <1: less reactive but gives the most leeway to other recognizers // <1: less reactive but gives the most leeway to other recognizers
// 1: will not be able to compete with a `HorizontalDragGestureRecognizer` up the widget tree // 1: will not be able to compete with a `HorizontalDragGestureRecognizer` up the widget tree
final double touchSlopFactor; final double touchSlopFactor;
@override @override
bool updateShouldNotify(PhotoViewGestureDetectorScope oldWidget) { bool updateShouldNotify(PhotoViewGestureDetectorScope oldWidget) {
return axis != oldWidget.axis && touchSlopFactor != oldWidget.touchSlopFactor; return axis != oldWidget.axis &&
touchSlopFactor != oldWidget.touchSlopFactor;
} }
} }
@ -269,16 +270,14 @@ class PhotoViewGestureDetectorScope extends InheritedWidget {
class PhotoViewPageViewScrollPhysics extends ScrollPhysics { class PhotoViewPageViewScrollPhysics extends ScrollPhysics {
const PhotoViewPageViewScrollPhysics({ const PhotoViewPageViewScrollPhysics({
this.touchSlopFactor = 0.1, this.touchSlopFactor = 0.1,
ScrollPhysics? parent, super.parent,
}) : super(parent: parent); });
// in [0, 1] // in [0, 1]
// 0: most reactive but will not let PhotoView recognizers accept gestures // 0: most reactive but will not let PhotoView recognizers accept gestures
// 1: less reactive but gives the most leeway to PhotoView recognizers // 1: less reactive but gives the most leeway to PhotoView recognizers
final double touchSlopFactor; final double touchSlopFactor;
@override @override
PhotoViewPageViewScrollPhysics applyTo(ScrollPhysics? ancestor) { PhotoViewPageViewScrollPhysics applyTo(ScrollPhysics? ancestor) {
return PhotoViewPageViewScrollPhysics( return PhotoViewPageViewScrollPhysics(
@ -287,7 +286,6 @@ class PhotoViewPageViewScrollPhysics extends ScrollPhysics {
); );
} }
@override @override
double get dragStartDistanceMotionThreshold => kTouchSlop * touchSlopFactor; double get dragStartDistanceMotionThreshold => kTouchSlop * touchSlopFactor;
} }

View file

@ -26,7 +26,11 @@ mixin HitCornersDetector on PhotoViewControllerDelegate {
return HitCorners(y <= cornersY.min, y >= cornersY.max); return HitCorners(y <= cornersY.min, y >= cornersY.max);
} }
bool _shouldMoveAxis(HitCorners hitCorners, double mainAxisMove, double crossAxisMove) { bool _shouldMoveAxis(
HitCorners hitCorners,
double mainAxisMove,
double crossAxisMove,
) {
if (mainAxisMove == 0) { if (mainAxisMove == 0) {
return false; return false;
} }

View file

@ -1,8 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class PhotoViewDefaultError extends StatelessWidget { class PhotoViewDefaultError extends StatelessWidget {
const PhotoViewDefaultError({Key? key, required this.decoration}) const PhotoViewDefaultError({super.key, required this.decoration});
: super(key: key);
final BoxDecoration decoration; final BoxDecoration decoration;
@ -22,7 +21,7 @@ class PhotoViewDefaultError extends StatelessWidget {
} }
class PhotoViewDefaultLoading extends StatelessWidget { class PhotoViewDefaultLoading extends StatelessWidget {
const PhotoViewDefaultLoading({Key? key, this.event}) : super(key: key); const PhotoViewDefaultLoading({super.key, this.event});
final ImageChunkEvent? event; final ImageChunkEvent? event;

Some files were not shown because too many files have changed in this diff Show more