mirror of
https://github.com/immich-app/immich
synced 2026-08-15 13:03:57 +00:00
chore: more riverpod lints from dcm (#30447)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
parent
8450687db7
commit
1c7c28bb0d
57 changed files with 104 additions and 104 deletions
|
|
@ -112,7 +112,15 @@ dart_code_metrics:
|
||||||
- prefer-switch-expression
|
- prefer-switch-expression
|
||||||
|
|
||||||
# Riverpod
|
# Riverpod
|
||||||
|
- avoid-calling-notifier-members-inside-build
|
||||||
|
- avoid-notifier-constructors
|
||||||
|
- avoid-nullable-async-value-pattern
|
||||||
|
- avoid-public-notifier-properties
|
||||||
|
- avoid-ref-inside-state-dispose
|
||||||
|
- avoid-ref-read-inside-build
|
||||||
- avoid-ref-watch-outside-build
|
- avoid-ref-watch-outside-build
|
||||||
|
- avoid-unnecessary-consumer-widgets
|
||||||
|
- dispose-provided-instances
|
||||||
- prefer-immutable-provider-arguments
|
- prefer-immutable-provider-arguments
|
||||||
- use-ref-and-state-synchronously
|
- use-ref-and-state-synchronously
|
||||||
- use-ref-read-synchronously
|
- use-ref-read-synchronously
|
||||||
|
|
|
||||||
|
|
@ -81,8 +81,8 @@ class _DriftBackupPageState extends ConsumerState<DriftBackupPage> {
|
||||||
|
|
||||||
final error = ref.watch(driftBackupProvider.select((p) => p.error));
|
final error = ref.watch(driftBackupProvider.select((p) => p.error));
|
||||||
|
|
||||||
final backupNotifier = ref.read(driftBackupProvider.notifier);
|
final backupNotifier = ref.watch(driftBackupProvider.notifier);
|
||||||
final backupSyncManager = ref.read(backgroundSyncProvider);
|
final backupSyncManager = ref.watch(backgroundSyncProvider);
|
||||||
|
|
||||||
Future<void> startBackup() async {
|
Future<void> startBackup() async {
|
||||||
final currentUser = Store.tryGet(StoreKey.currentUser);
|
final currentUser = Store.tryGet(StoreKey.currentUser);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class DriftBackupOptionsPage extends ConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
bool hasPopped = false;
|
bool hasPopped = false;
|
||||||
final previousBackup = ref.read(appConfigProvider).backup;
|
final previousBackup = ref.watch(appConfigProvider.select((s) => s.backup));
|
||||||
final previousCellularForVideos = previousBackup.useCellularForVideos;
|
final previousCellularForVideos = previousBackup.useCellularForVideos;
|
||||||
final previousCellularForPhotos = previousBackup.useCellularForPhotos;
|
final previousCellularForPhotos = previousBackup.useCellularForPhotos;
|
||||||
return PopScope(
|
return PopScope(
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/log.model.dart';
|
import 'package:immich_mobile/domain/models/log.model.dart';
|
||||||
import 'package:immich_mobile/domain/services/log.service.dart';
|
import 'package:immich_mobile/domain/services/log.service.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
|
@ -13,11 +12,11 @@ import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:immich_mobile/services/immich_logger.service.dart';
|
import 'package:immich_mobile/services/immich_logger.service.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class AppLogPage extends HookConsumerWidget {
|
class AppLogPage extends HookWidget {
|
||||||
const AppLogPage({super.key});
|
const AppLogPage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final immichLogger = LogService.I;
|
final immichLogger = LogService.I;
|
||||||
final shouldReload = useState(false);
|
final shouldReload = useState(false);
|
||||||
final logMessages = useFuture(useMemoized(() => immichLogger.getMessages(), [shouldReload.value]));
|
final logMessages = useFuture(useMemoized(() => immichLogger.getMessages(), [shouldReload.value]));
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,18 @@ import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:immich_mobile/domain/models/log.model.dart';
|
import 'package:immich_mobile/domain/models/log.model.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class AppLogDetailPage extends HookConsumerWidget {
|
class AppLogDetailPage extends HookWidget {
|
||||||
const AppLogDetailPage({super.key, required this.logMessage});
|
const AppLogDetailPage({super.key, required this.logMessage});
|
||||||
|
|
||||||
final LogMessage logMessage;
|
final LogMessage logMessage;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
Padding buildTextWithCopyButton(String header, String text) {
|
Padding buildTextWithCopyButton(String header, String text) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class HeaderSettingsPage extends HookConsumerWidget {
|
||||||
final headers = useState<List<SettingsHeader>>([]);
|
final headers = useState<List<SettingsHeader>>([]);
|
||||||
final setInitialHeaders = useState(false);
|
final setInitialHeaders = useState(false);
|
||||||
|
|
||||||
final storedHeaders = ref.read(appConfigProvider).network.customHeaders;
|
final storedHeaders = ref.watch(appConfigProvider.select((s) => s.network.customHeaders));
|
||||||
if (!setInitialHeaders.value) {
|
if (!setInitialHeaders.value) {
|
||||||
storedHeaders.forEach((k, v) {
|
storedHeaders.forEach((k, v) {
|
||||||
final header = SettingsHeader();
|
final header = SettingsHeader();
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/widgets/forms/change_password_form.dart';
|
import 'package:immich_mobile/widgets/forms/change_password_form.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class ChangePasswordPage extends HookConsumerWidget {
|
class ChangePasswordPage extends StatelessWidget {
|
||||||
const ChangePasswordPage({super.key});
|
const ChangePasswordPage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) => const Scaffold(body: ChangePasswordForm());
|
||||||
return const Scaffold(body: ChangePasswordForm());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import 'dart:async';
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
|
|
@ -11,11 +10,11 @@ import 'package:immich_mobile/widgets/forms/login/login_form.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class LoginPage extends HookConsumerWidget {
|
class LoginPage extends HookWidget {
|
||||||
const LoginPage({super.key});
|
const LoginPage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final appVersion = useState('0.0.0');
|
final appVersion = useState('0.0.0');
|
||||||
|
|
||||||
Future<void> getAppInfo() async {
|
Future<void> getAppInfo() async {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/maplibrecontroller_extensions.dart';
|
import 'package:immich_mobile/extensions/maplibrecontroller_extensions.dart';
|
||||||
|
|
@ -14,13 +13,13 @@ import 'package:immich_mobile/widgets/map/map_theme_override.dart';
|
||||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class MapLocationPickerPage extends HookConsumerWidget {
|
class MapLocationPickerPage extends HookWidget {
|
||||||
final LatLng initialLatLng;
|
final LatLng initialLatLng;
|
||||||
|
|
||||||
const MapLocationPickerPage({super.key, this.initialLatLng = const LatLng(0, 0)});
|
const MapLocationPickerPage({super.key, this.initialLatLng = const LatLng(0, 0)});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final selectedLatLng = useValueNotifier<LatLng>(initialLatLng);
|
final selectedLatLng = useValueNotifier<LatLng>(initialLatLng);
|
||||||
final controller = useRef<MapLibreMapController?>(null);
|
final controller = useRef<MapLibreMapController?>(null);
|
||||||
final marker = useRef<Symbol?>(null);
|
final marker = useRef<Symbol?>(null);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class DriftActivitiesPage extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final activityNotifier = ref.read(albumActivityProvider((album.id, assetId)).notifier);
|
final activityNotifier = ref.watch(albumActivityProvider((album.id, assetId)).notifier);
|
||||||
final activities = ref.watch(albumActivityProvider((album.id, assetId)));
|
final activities = ref.watch(albumActivityProvider((album.id, assetId)));
|
||||||
final listViewScrollController = useScrollController();
|
final listViewScrollController = useScrollController();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@ import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
||||||
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
|
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class DriftAssetSelectionTimelinePage extends ConsumerWidget {
|
class DriftAssetSelectionTimelinePage extends StatelessWidget {
|
||||||
final Set<BaseAsset> lockedSelectionAssets;
|
final Set<BaseAsset> lockedSelectionAssets;
|
||||||
const DriftAssetSelectionTimelinePage({super.key, this.lockedSelectionAssets = const {}});
|
const DriftAssetSelectionTimelinePage({super.key, this.lockedSelectionAssets = const {}});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
return ProviderScope(
|
return ProviderScope(
|
||||||
overrides: [
|
overrides: [
|
||||||
multiSelectProvider.overrideWith(
|
multiSelectProvider.overrideWith(
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ import 'package:immich_mobile/extensions/platform_extensions.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class AssetTroubleshootPage extends ConsumerWidget {
|
class AssetTroubleshootPage extends StatelessWidget {
|
||||||
final BaseAsset asset;
|
final BaseAsset asset;
|
||||||
|
|
||||||
const AssetTroubleshootPage({super.key, required this.asset});
|
const AssetTroubleshootPage({super.key, required this.asset});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: Text('asset_troubleshoot'.tr())),
|
appBar: AppBar(title: Text('asset_troubleshoot'.tr())),
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
|
|
@ -29,13 +29,13 @@ class AssetTroubleshootPage extends ConsumerWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AssetDetailsView extends ConsumerWidget {
|
class _AssetDetailsView extends StatelessWidget {
|
||||||
final BaseAsset asset;
|
final BaseAsset asset;
|
||||||
|
|
||||||
const _AssetDetailsView({required this.asset});
|
const _AssetDetailsView({required this.asset});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,11 @@ import 'package:immich_mobile/widgets/map/map_thumbnail.dart';
|
||||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class DriftLibraryPage extends ConsumerWidget {
|
class DriftLibraryPage extends StatelessWidget {
|
||||||
const DriftLibraryPage({super.key});
|
const DriftLibraryPage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
return const Scaffold(
|
return const Scaffold(
|
||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
slivers: [
|
slivers: [
|
||||||
|
|
|
||||||
|
|
@ -439,7 +439,7 @@ class _AlbumKebabMenu extends ConsumerWidget {
|
||||||
|
|
||||||
return FutureBuilder<bool>(
|
return FutureBuilder<bool>(
|
||||||
future: ref
|
future: ref
|
||||||
.read(remoteAlbumServiceProvider)
|
.watch(remoteAlbumServiceProvider)
|
||||||
.getUserRole(album.id, user?.id ?? '')
|
.getUserRole(album.id, user?.id ?? '')
|
||||||
.then((role) => role == AlbumUserRole.editor),
|
.then((role) => role == AlbumUserRole.editor),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,7 @@ class _AspectRatioSelector extends ConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final editorState = ref.watch(editorStateProvider);
|
final editorState = ref.watch(editorStateProvider);
|
||||||
final editorNotifier = ref.read(editorStateProvider.notifier);
|
final editorNotifier = ref.watch(editorStateProvider.notifier);
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
|
|
@ -245,7 +245,7 @@ class _TransformControls extends ConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final editorNotifier = ref.read(editorStateProvider.notifier);
|
final editorNotifier = ref.watch(editorStateProvider.notifier);
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
|
@ -333,7 +333,7 @@ class _ResetEditsButton extends ConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final editorState = ref.watch(editorStateProvider);
|
final editorState = ref.watch(editorStateProvider);
|
||||||
final editorNotifier = ref.read(editorStateProvider.notifier);
|
final editorNotifier = ref.watch(editorStateProvider.notifier);
|
||||||
|
|
||||||
return ImmichTextButton(
|
return ImmichTextButton(
|
||||||
labelText: 'reset'.tr(),
|
labelText: 'reset'.tr(),
|
||||||
|
|
@ -384,7 +384,7 @@ class _EditorPreviewState extends ConsumerState<_EditorPreview> with TickerProvi
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final editorState = ref.watch(editorStateProvider);
|
final editorState = ref.watch(editorStateProvider);
|
||||||
final editorNotifier = ref.read(editorStateProvider.notifier);
|
final editorNotifier = ref.watch(editorStateProvider.notifier);
|
||||||
|
|
||||||
ref.listen(editorStateProvider, (previous, current) {
|
ref.listen(editorStateProvider, (previous, current) {
|
||||||
// Only re-apply the aspect ratio when it changes, otherwise the crop rect will shrink on every rotation
|
// Only re-apply the aspect ratio when it changes, otherwise the crop rect will shrink on every rotation
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
|
||||||
class BaseActionButton extends ConsumerWidget {
|
class BaseActionButton extends StatelessWidget {
|
||||||
const BaseActionButton({
|
const BaseActionButton({
|
||||||
super.key,
|
super.key,
|
||||||
required this.label,
|
required this.label,
|
||||||
|
|
@ -31,7 +30,7 @@ class BaseActionButton extends ConsumerWidget {
|
||||||
final void Function()? onLongPressed;
|
final void Function()? onLongPressed;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final miniWidth = minWidth ?? (context.isMobile ? context.width / 4.5 : 75.0);
|
final miniWidth = minWidth ?? (context.isMobile ? context.width / 4.5 : 75.0);
|
||||||
final iconTheme = IconTheme.of(context);
|
final iconTheme = IconTheme.of(context);
|
||||||
final iconSize = iconTheme.size ?? 24.0;
|
final iconSize = iconTheme.size ?? 24.0;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class MotionPhotoActionButton extends ConsumerWidget {
|
||||||
return BaseActionButton(
|
return BaseActionButton(
|
||||||
iconData: isPlaying ? Icons.motion_photos_pause_outlined : Icons.play_circle_outline_rounded,
|
iconData: isPlaying ? Icons.motion_photos_pause_outlined : Icons.play_circle_outline_rounded,
|
||||||
label: "play_motion_photo".t(context: context),
|
label: "play_motion_photo".t(context: context),
|
||||||
onPressed: ref.read(isPlayingMotionVideoProvider.notifier).toggle,
|
onPressed: ref.watch(isPlayingMotionVideoProvider.notifier).toggle,
|
||||||
iconOnly: iconOnly,
|
iconOnly: iconOnly,
|
||||||
menuItem: menuItem,
|
menuItem: menuItem,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -669,7 +669,7 @@ class _GridAlbumCard extends ConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final albumThumbnailAsset = ref.read(assetServiceProvider).getRemoteAsset(album.thumbnailAssetId ?? "");
|
final albumThumbnailAsset = ref.watch(assetServiceProvider).getRemoteAsset(album.thumbnailAssetId ?? "");
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => onAlbumSelected(album),
|
onTap: () => onAlbumSelected(album),
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class AlbumTile extends ConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final albumThumbnailAsset = ref.read(assetServiceProvider).getRemoteAsset(album.thumbnailAssetId ?? "");
|
final albumThumbnailAsset = ref.watch(assetServiceProvider).getRemoteAsset(album.thumbnailAssetId ?? "");
|
||||||
|
|
||||||
return LargeLeadingTile(
|
return LargeLeadingTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
|
|
|
||||||
|
|
@ -401,7 +401,7 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
||||||
_showingDetails = ref.watch(assetViewerProvider.select((s) => s.showingDetails));
|
_showingDetails = ref.watch(assetViewerProvider.select((s) => s.showingDetails));
|
||||||
final stackIndex = ref.watch(assetViewerProvider.select((s) => s.stackIndex));
|
final stackIndex = ref.watch(assetViewerProvider.select((s) => s.stackIndex));
|
||||||
final isPlayingMotionVideo = ref.watch(isPlayingMotionVideoProvider);
|
final isPlayingMotionVideo = ref.watch(isPlayingMotionVideoProvider);
|
||||||
final timelineOrigin = ref.read(timelineServiceProvider).origin;
|
final timelineOrigin = ref.watch(timelineServiceProvider).origin;
|
||||||
final showingOcr = ref.watch(assetViewerProvider.select((s) => s.showingOcr));
|
final showingOcr = ref.watch(assetViewerProvider.select((s) => s.showingOcr));
|
||||||
|
|
||||||
final asset = _asset;
|
final asset = _asset;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class AssetStackRow extends ConsumerWidget {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|
||||||
final hideAssetStack = ref.read(timelineServiceProvider).origin == TimelineOrigin.trash;
|
final hideAssetStack = ref.watch(timelineServiceProvider).origin == TimelineOrigin.trash;
|
||||||
if (hideAssetStack) {
|
if (hideAssetStack) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class ViewerBottomBar extends ConsumerWidget {
|
||||||
final isReadonlyModeEnabled = ref.watch(readonlyModeProvider);
|
final isReadonlyModeEnabled = ref.watch(readonlyModeProvider);
|
||||||
final showingDetails = ref.watch(assetViewerProvider.select((s) => s.showingDetails));
|
final showingDetails = ref.watch(assetViewerProvider.select((s) => s.showingDetails));
|
||||||
final isInLockedView = ref.watch(inLockedViewProvider);
|
final isInLockedView = ref.watch(inLockedViewProvider);
|
||||||
final isInTrash = ref.read(timelineServiceProvider).origin == TimelineOrigin.trash;
|
final isInTrash = ref.watch(timelineServiceProvider).origin == TimelineOrigin.trash;
|
||||||
|
|
||||||
final originalTheme = context.themeData;
|
final originalTheme = context.themeData;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class MotionPhotoPlayButton extends ConsumerWidget {
|
||||||
child: Center(
|
child: Center(
|
||||||
child: _MotionButton(
|
child: _MotionButton(
|
||||||
isPlaying: isPlaying,
|
isPlaying: isPlaying,
|
||||||
onPressed: ref.read(isPlayingMotionVideoProvider.notifier).toggle,
|
onPressed: ref.watch(isPlayingMotionVideoProvider.notifier).toggle,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class OcrToggleButton extends ConsumerWidget {
|
||||||
shape: const CircleBorder(),
|
shape: const CircleBorder(),
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: ref.read(assetViewerProvider.notifier).toggleOcr,
|
onTap: ref.watch(assetViewerProvider.notifier).toggleOcr,
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
padding: EdgeInsets.all(10.0),
|
padding: EdgeInsets.all(10.0),
|
||||||
child: Icon(Icons.text_fields_rounded, size: 22, color: Colors.white),
|
child: Icon(Icons.text_fields_rounded, size: 22, color: Colors.white),
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ class ViewerKebabMenu extends ConsumerWidget {
|
||||||
final user = ref.watch(currentUserProvider);
|
final user = ref.watch(currentUserProvider);
|
||||||
final isOwner = asset is RemoteAsset && asset.ownerId == user?.id;
|
final isOwner = asset is RemoteAsset && asset.ownerId == user?.id;
|
||||||
final isCasting = ref.watch(castProvider.select((c) => c.isCasting));
|
final isCasting = ref.watch(castProvider.select((c) => c.isCasting));
|
||||||
final timelineOrigin = ref.read(timelineServiceProvider).origin;
|
final timelineOrigin = ref.watch(timelineServiceProvider).origin;
|
||||||
final isTrashEnable = ref.watch(serverInfoProvider.select((state) => state.serverFeatures.trash));
|
final isTrashEnable = ref.watch(serverInfoProvider.select((state) => state.serverFeatures.trash));
|
||||||
final isInLockedView = ref.watch(inLockedViewProvider);
|
final isInLockedView = ref.watch(inLockedViewProvider);
|
||||||
final currentAlbum = ref.watch(currentRemoteAlbumProvider);
|
final currentAlbum = ref.watch(currentRemoteAlbumProvider);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/presentation/actions/action.widget.dart';
|
import 'package:immich_mobile/presentation/actions/action.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/actions/delete.action.dart';
|
import 'package:immich_mobile/presentation/actions/delete.action.dart';
|
||||||
import 'package:immich_mobile/presentation/actions/download.action.dart';
|
import 'package:immich_mobile/presentation/actions/download.action.dart';
|
||||||
|
|
@ -7,11 +6,11 @@ import 'package:immich_mobile/presentation/actions/lock.action.dart';
|
||||||
import 'package:immich_mobile/presentation/actions/share.action.dart';
|
import 'package:immich_mobile/presentation/actions/share.action.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
|
||||||
|
|
||||||
class LockedFolderBottomSheet extends ConsumerWidget {
|
class LockedFolderBottomSheet extends StatelessWidget {
|
||||||
const LockedFolderBottomSheet({super.key});
|
const LockedFolderBottomSheet({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
return const BaseBottomSheet(
|
return const BaseBottomSheet(
|
||||||
initialChildSize: 0.25,
|
initialChildSize: 0.25,
|
||||||
maxChildSize: 0.4,
|
maxChildSize: 0.4,
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/presentation/actions/action.widget.dart';
|
import 'package:immich_mobile/presentation/actions/action.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/actions/delete.action.dart';
|
import 'package:immich_mobile/presentation/actions/delete.action.dart';
|
||||||
import 'package:immich_mobile/presentation/actions/restore.action.dart';
|
import 'package:immich_mobile/presentation/actions/restore.action.dart';
|
||||||
|
|
||||||
class TrashBottomBar extends ConsumerWidget {
|
class TrashBottomBar extends StatelessWidget {
|
||||||
const TrashBottomBar({super.key});
|
const TrashBottomBar({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
return Align(
|
return Align(
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|
|
||||||
|
|
@ -45,13 +45,13 @@ class DriftMemoryLane extends ConsumerWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DriftMemoryCard extends ConsumerWidget {
|
class DriftMemoryCard extends StatelessWidget {
|
||||||
const DriftMemoryCard({super.key, required this.memory});
|
const DriftMemoryCard({super.key, required this.memory});
|
||||||
|
|
||||||
final DriftMemory memory;
|
final DriftMemory memory;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final yearsAgo = DateTime.now().year - memory.data.year;
|
final yearsAgo = DateTime.now().year - memory.data.year;
|
||||||
final title = 'years_ago'.t(context: context, args: {'years': yearsAgo.toString()});
|
final title = 'years_ago'.t(context: context, args: {'years': yearsAgo.toString()});
|
||||||
return Center(
|
return Center(
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||||
|
|
||||||
class PersonOptionSheet extends ConsumerWidget {
|
class PersonOptionSheet extends StatelessWidget {
|
||||||
const PersonOptionSheet({super.key, this.onEditName, this.onEditBirthday, this.birthdayExists = false});
|
const PersonOptionSheet({super.key, this.onEditName, this.onEditBirthday, this.birthdayExists = false});
|
||||||
|
|
||||||
final VoidCallback? onEditName;
|
final VoidCallback? onEditName;
|
||||||
|
|
@ -10,7 +9,7 @@ class PersonOptionSheet extends ConsumerWidget {
|
||||||
final bool birthdayExists;
|
final bool birthdayExists;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final TextStyle textStyle = Theme.of(context).textTheme.bodyLarge!.copyWith(fontWeight: FontWeight.w600);
|
final TextStyle textStyle = Theme.of(context).textTheme.bodyLarge!.copyWith(fontWeight: FontWeight.w600);
|
||||||
|
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart';
|
||||||
|
|
||||||
class DriftRemoteAlbumOption extends ConsumerWidget {
|
class DriftRemoteAlbumOption extends StatelessWidget {
|
||||||
const DriftRemoteAlbumOption({
|
const DriftRemoteAlbumOption({
|
||||||
super.key,
|
super.key,
|
||||||
this.onAddPhotos,
|
this.onAddPhotos,
|
||||||
|
|
@ -31,7 +30,7 @@ class DriftRemoteAlbumOption extends ConsumerWidget {
|
||||||
final List<Shadow>? iconShadows;
|
final List<Shadow>? iconShadows;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final theme = context.themeData;
|
final theme = context.themeData;
|
||||||
final menuChildren = <Widget>[];
|
final menuChildren = <Widget>[];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ class _FixedSegmentRow extends ConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final isScrubbing = ref.watch(timelineStateProvider.select((s) => s.isScrubbing));
|
final isScrubbing = ref.watch(timelineStateProvider.select((s) => s.isScrubbing));
|
||||||
final timelineService = ref.read(timelineServiceProvider);
|
final timelineService = ref.watch(timelineServiceProvider);
|
||||||
final isDynamicLayout = columnCount <= (context.isMobile ? 2 : 3);
|
final isDynamicLayout = columnCount <= (context.isMobile ? 2 : 3);
|
||||||
|
|
||||||
if (timelineService.hasRange(assetIndex, assetCount)) {
|
if (timelineService.hasRange(assetIndex, assetCount)) {
|
||||||
|
|
@ -261,7 +261,7 @@ class _AssetTileWidget extends ConsumerWidget {
|
||||||
final lockSelection = _getLockSelectionStatus(ref);
|
final lockSelection = _getLockSelectionStatus(ref);
|
||||||
final showStorageIndicator = ref.watch(timelineArgsProvider.select((args) => args.showStorageIndicator));
|
final showStorageIndicator = ref.watch(timelineArgsProvider.select((args) => args.showStorageIndicator));
|
||||||
final isReadonlyModeEnabled = ref.watch(readonlyModeProvider);
|
final isReadonlyModeEnabled = ref.watch(readonlyModeProvider);
|
||||||
final showStackIndicator = ref.read(timelineServiceProvider).origin != TimelineOrigin.trash;
|
final showStackIndicator = ref.watch(timelineServiceProvider).origin != TimelineOrigin.trash;
|
||||||
|
|
||||||
return RepaintBoundary(
|
return RepaintBoundary(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
||||||
|
|
@ -12,7 +13,7 @@ import 'package:immich_mobile/providers/infrastructure/readonly_mode.provider.da
|
||||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
||||||
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
|
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
|
||||||
|
|
||||||
class TimelineHeader extends HookConsumerWidget {
|
class TimelineHeader extends HookWidget {
|
||||||
final Bucket bucket;
|
final Bucket bucket;
|
||||||
final HeaderType header;
|
final HeaderType header;
|
||||||
final double height;
|
final double height;
|
||||||
|
|
@ -39,7 +40,7 @@ class TimelineHeader extends HookConsumerWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
if (bucket is! TimeBucket || header == HeaderType.none) {
|
if (bucket is! TimeBucket || header == HeaderType.none) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ final backgroundSyncProvider = Provider<BackgroundSyncManager>((ref) {
|
||||||
final manager = BackgroundSyncManager(
|
final manager = BackgroundSyncManager(
|
||||||
onRemoteSyncStart: () {
|
onRemoteSyncStart: () {
|
||||||
syncStatusNotifier.startRemoteSync();
|
syncStatusNotifier.startRemoteSync();
|
||||||
|
// ignore: dispose-provided-instances
|
||||||
final backupProvider = ref.read(driftBackupProvider.notifier);
|
final backupProvider = ref.read(driftBackupProvider.notifier);
|
||||||
if (backupProvider.mounted) {
|
if (backupProvider.mounted) {
|
||||||
backupProvider.updateError(BackupError.none);
|
backupProvider.updateError(BackupError.none);
|
||||||
|
|
@ -16,6 +17,7 @@ final backgroundSyncProvider = Provider<BackgroundSyncManager>((ref) {
|
||||||
},
|
},
|
||||||
onRemoteSyncComplete: (isSuccess) {
|
onRemoteSyncComplete: (isSuccess) {
|
||||||
syncStatusNotifier.completeRemoteSync();
|
syncStatusNotifier.completeRemoteSync();
|
||||||
|
// ignore: dispose-provided-instances
|
||||||
final backupProvider = ref.read(driftBackupProvider.notifier);
|
final backupProvider = ref.read(driftBackupProvider.notifier);
|
||||||
if (backupProvider.mounted) {
|
if (backupProvider.mounted) {
|
||||||
backupProvider.updateError(isSuccess == true ? BackupError.none : BackupError.syncFailed);
|
backupProvider.updateError(isSuccess == true ? BackupError.none : BackupError.syncFailed);
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,7 @@ import 'package:flutter/widgets.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
final searchInputFocusProvider = Provider((ref) {
|
final searchInputFocusProvider = Provider((ref) {
|
||||||
return FocusNode();
|
final focusNode = FocusNode();
|
||||||
|
ref.onDispose(focusNode.dispose);
|
||||||
|
return focusNode;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import 'package:immich_mobile/models/download/livephotos_medatada.model.dart';
|
||||||
import 'package:immich_mobile/services/api.service.dart';
|
import 'package:immich_mobile/services/api.service.dart';
|
||||||
import 'package:immich_mobile/utils/image_url_builder.dart';
|
import 'package:immich_mobile/utils/image_url_builder.dart';
|
||||||
|
|
||||||
|
// ignore: dispose-provided-instances
|
||||||
final downloadRepositoryProvider = Provider((ref) => DownloadRepository());
|
final downloadRepositoryProvider = Provider((ref) => DownloadRepository());
|
||||||
|
|
||||||
class DownloadRepository {
|
class DownloadRepository {
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ import 'package:maplibre_gl/maplibre_gl.dart';
|
||||||
part 'router.gr.dart';
|
part 'router.gr.dart';
|
||||||
|
|
||||||
final appRouterProvider = Provider(
|
final appRouterProvider = Provider(
|
||||||
|
// ignore: dispose-provided-instances
|
||||||
(ref) => AppRouter(
|
(ref) => AppRouter(
|
||||||
ref.watch(apiServiceProvider),
|
ref.watch(apiServiceProvider),
|
||||||
ref.watch(authServiceProvider),
|
ref.watch(authServiceProvider),
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ class UploadCallbacks {
|
||||||
}
|
}
|
||||||
|
|
||||||
final foregroundUploadServiceProvider = Provider((ref) {
|
final foregroundUploadServiceProvider = Provider((ref) {
|
||||||
|
// ignore: dispose-provided-instances
|
||||||
return ForegroundUploadService(
|
return ForegroundUploadService(
|
||||||
ref.watch(uploadRepositoryProvider),
|
ref.watch(uploadRepositoryProvider),
|
||||||
ref.watch(storageRepositoryProvider),
|
ref.watch(storageRepositoryProvider),
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class CommentBubble extends ConsumerWidget {
|
||||||
final isLike = activity.type == ActivityType.like;
|
final isLike = activity.type == ActivityType.like;
|
||||||
final bgColor = isOwn ? context.colorScheme.primaryContainer : context.colorScheme.surfaceContainer;
|
final bgColor = isOwn ? context.colorScheme.primaryContainer : context.colorScheme.surfaceContainer;
|
||||||
|
|
||||||
final activityNotifier = ref.read(
|
final activityNotifier = ref.watch(
|
||||||
albumActivityProvider((album.id, isAssetActivity ? activity.assetId : null)).notifier,
|
albumActivityProvider((album.id, isAssetActivity ? activity.assetId : null)).notifier,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class CastDialog extends ConsumerWidget {
|
||||||
width: 250,
|
width: 250,
|
||||||
height: 250,
|
height: 250,
|
||||||
child: FutureBuilder<List<(String, CastDestinationType, dynamic)>>(
|
child: FutureBuilder<List<(String, CastDestinationType, dynamic)>>(
|
||||||
future: ref.read(castProvider.notifier).getDevices(),
|
future: ref.watch(castProvider.notifier).getDevices(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasError) {
|
if (snapshot.hasError) {
|
||||||
return Text('error_saving_image'.tr(args: [snapshot.error.toString()]));
|
return Text('error_saving_image'.tr(args: [snapshot.error.toString()]));
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ class _VideoControlsState extends ConsumerState<VideoControls> {
|
||||||
});
|
});
|
||||||
ref.listen(_provider.select((v) => v.status), (_, __) => _hideTimer.reset());
|
ref.listen(_provider.select((v) => v.status), (_, __) => _hideTimer.reset());
|
||||||
|
|
||||||
final notifier = ref.read(_provider.notifier);
|
final notifier = ref.watch(_provider.notifier);
|
||||||
final isLoaded = duration != Duration.zero;
|
final isLoaded = duration != Duration.zero;
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@ Future<(Set<String>, Set<String>)?> showTagPickerModal({required BuildContext co
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TagPickerModal extends HookConsumerWidget {
|
class _TagPickerModal extends HookWidget {
|
||||||
final Set<String>? initialSelection;
|
final Set<String>? initialSelection;
|
||||||
|
|
||||||
const _TagPickerModal({this.initialSelection});
|
const _TagPickerModal({this.initialSelection});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final selectedTagIds = useState<Set<String>>(initialSelection ?? {});
|
final selectedTagIds = useState<Set<String>>(initialSelection ?? {});
|
||||||
final newTagValues = useState<Set<String>>({});
|
final newTagValues = useState<Set<String>>({});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,19 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/images/remote_image_provider.dart';
|
import 'package:immich_mobile/presentation/widgets/images/remote_image_provider.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
class UserCircleAvatar extends StatelessWidget {
|
||||||
class UserCircleAvatar extends ConsumerWidget {
|
|
||||||
final UserDto user;
|
final UserDto user;
|
||||||
double size;
|
final double size;
|
||||||
bool hasBorder;
|
final bool hasBorder;
|
||||||
double opacity;
|
final double opacity;
|
||||||
|
|
||||||
UserCircleAvatar({super.key, this.size = 44, this.hasBorder = false, this.opacity = 1, required this.user});
|
const UserCircleAvatar({super.key, this.size = 44, this.hasBorder = false, this.opacity = 1, required this.user});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final userAvatarColor = user.avatarColor.toColor().withValues(alpha: opacity);
|
final userAvatarColor = user.avatarColor.toColor().withValues(alpha: opacity);
|
||||||
final profileImageUrl =
|
final profileImageUrl =
|
||||||
'${Store.get(StoreKey.serverEndpoint)}/users/${user.id}/profile-image?d=${user.profileChangedAt.millisecondsSinceEpoch}';
|
'${Store.get(StoreKey.serverEndpoint)}/users/${user.id}/profile-image?d=${user.profileChangedAt.millisecondsSinceEpoch}';
|
||||||
|
|
|
||||||
|
|
@ -153,13 +153,13 @@ class ConfirmPasswordInput extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChangePasswordButton extends ConsumerWidget {
|
class ChangePasswordButton extends StatelessWidget {
|
||||||
final TextEditingController passwordController;
|
final TextEditingController passwordController;
|
||||||
final VoidCallback onPressed;
|
final VoidCallback onPressed;
|
||||||
const ChangePasswordButton({super.key, required this.passwordController, required this.onPressed});
|
const ChangePasswordButton({super.key, required this.passwordController, required this.onPressed});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
return ElevatedButton(
|
return ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
visualDensity: VisualDensity.standard,
|
visualDensity: VisualDensity.standard,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/maplibrecontroller_extensions.dart';
|
import 'package:immich_mobile/extensions/maplibrecontroller_extensions.dart';
|
||||||
|
|
@ -15,7 +14,7 @@ import 'package:maplibre_gl/maplibre_gl.dart';
|
||||||
/// User can provide either a [assetMarkerRemoteId] to display the asset's thumbnail or set
|
/// User can provide either a [assetMarkerRemoteId] to display the asset's thumbnail or set
|
||||||
/// [showMarkerPin] to true which would display a marker pin instead. If both are provided,
|
/// [showMarkerPin] to true which would display a marker pin instead. If both are provided,
|
||||||
/// [assetMarkerRemoteId] will take precedence
|
/// [assetMarkerRemoteId] will take precedence
|
||||||
class MapThumbnail extends HookConsumerWidget {
|
class MapThumbnail extends HookWidget {
|
||||||
final Function(Point<double>, LatLng)? onTap;
|
final Function(Point<double>, LatLng)? onTap;
|
||||||
final LatLng centre;
|
final LatLng centre;
|
||||||
final String? assetMarkerRemoteId;
|
final String? assetMarkerRemoteId;
|
||||||
|
|
@ -44,7 +43,7 @@ class MapThumbnail extends HookConsumerWidget {
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final controller = useRef<MapLibreMapController?>(null);
|
final controller = useRef<MapLibreMapController?>(null);
|
||||||
final styleLoaded = useState(false);
|
final styleLoaded = useState(false);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ class AdvancedSettings extends HookConsumerWidget {
|
||||||
final manageLocalMediaAndroid = useAppSettingsState(AppSettingsEnum.manageLocalMediaAndroid);
|
final manageLocalMediaAndroid = useAppSettingsState(AppSettingsEnum.manageLocalMediaAndroid);
|
||||||
final isManageMediaSupported = useState(false);
|
final isManageMediaSupported = useState(false);
|
||||||
final manageMediaAndroidPermission = useState(false);
|
final manageMediaAndroidPermission = useState(false);
|
||||||
final levelId = useState<int>(ref.read(appConfigProvider).logLevel.index);
|
final levelId = useState<int>(ref.watch(appConfigProvider).logLevel.index);
|
||||||
final preferRemote = useState(ref.read(appConfigProvider).image.preferRemote);
|
final preferRemote = useState(ref.watch(appConfigProvider).image.preferRemote);
|
||||||
useValueChanged(
|
useValueChanged(
|
||||||
preferRemote.value,
|
preferRemote.value,
|
||||||
(_, __) => unawaited(ref.read(settingsProvider).write(.imagePreferRemote, preferRemote.value)),
|
(_, __) => unawaited(ref.read(settingsProvider).write(.imagePreferRemote, preferRemote.value)),
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class LayoutSettings extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final tilesPerRow = useState(ref.read(appConfigProvider.select((s) => s.timeline.tilesPerRow)));
|
final tilesPerRow = useState(ref.watch(appConfigProvider.select((s) => s.timeline.tilesPerRow)));
|
||||||
useValueChanged<int, void>(tilesPerRow.value, (_, __) {
|
useValueChanged<int, void>(tilesPerRow.value, (_, __) {
|
||||||
unawaited(ref.read(settingsProvider).write(.timelineTilesPerRow, tilesPerRow.value));
|
unawaited(ref.read(settingsProvider).write(.timelineTilesPerRow, tilesPerRow.value));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ class ImageViewerQualitySetting extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final isOriginal = useState(ref.read(appConfigProvider).image.loadOriginal);
|
final isOriginal = useState(ref.watch(appConfigProvider).image.loadOriginal);
|
||||||
useValueChanged<bool, void>(isOriginal.value, (_, __) {
|
useValueChanged<bool, void>(isOriginal.value, (_, __) {
|
||||||
unawaited(ref.read(settingsProvider).write(.imageLoadOriginal, isOriginal.value));
|
unawaited(ref.read(settingsProvider).write(.imageLoadOriginal, isOriginal.value));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class ImageViewerTapToNavigateSetting extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final tapToNavigate = useState(ref.read(appConfigProvider).viewer.tapToNavigate);
|
final tapToNavigate = useState(ref.watch(appConfigProvider).viewer.tapToNavigate);
|
||||||
useValueChanged<bool, void>(tapToNavigate.value, (_, __) {
|
useValueChanged<bool, void>(tapToNavigate.value, (_, __) {
|
||||||
unawaited(ref.read(settingsProvider).write(.viewerTapToNavigate, tapToNavigate.value));
|
unawaited(ref.read(settingsProvider).write(.viewerTapToNavigate, tapToNavigate.value));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class SlideshowSettings extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final slideshow = ref.read(appConfigProvider).slideshow;
|
final slideshow = ref.watch(appConfigProvider).slideshow;
|
||||||
final useRepeat = useState(slideshow.repeat);
|
final useRepeat = useState(slideshow.repeat);
|
||||||
final useDuration = useState(slideshow.duration);
|
final useDuration = useState(slideshow.duration);
|
||||||
final useLook = useState(slideshow.look);
|
final useLook = useState(slideshow.look);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class VideoViewerSettings extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final viewer = ref.read(appConfigProvider).viewer;
|
final viewer = ref.watch(appConfigProvider).viewer;
|
||||||
final useAutoPlayVideo = useState(viewer.autoPlayVideo);
|
final useAutoPlayVideo = useState(viewer.autoPlayVideo);
|
||||||
final useLoopVideo = useState(viewer.loopVideo);
|
final useLoopVideo = useState(viewer.loopVideo);
|
||||||
final useOriginalVideo = useState(viewer.loadOriginalVideo);
|
final useOriginalVideo = useState(viewer.loadOriginalVideo);
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ import 'package:immich_mobile/widgets/settings/setting_group_title.dart';
|
||||||
import 'package:immich_mobile/widgets/settings/setting_list_tile.dart';
|
import 'package:immich_mobile/widgets/settings/setting_list_tile.dart';
|
||||||
import 'package:immich_mobile/widgets/settings/settings_sub_page_scaffold.dart';
|
import 'package:immich_mobile/widgets/settings/settings_sub_page_scaffold.dart';
|
||||||
|
|
||||||
class DriftBackupSettings extends ConsumerWidget {
|
class DriftBackupSettings extends StatelessWidget {
|
||||||
const DriftBackupSettings({super.key});
|
const DriftBackupSettings({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
return SettingsSubPageScaffold(
|
return SettingsSubPageScaffold(
|
||||||
settings: [
|
settings: [
|
||||||
SettingGroupTitle(
|
SettingGroupTitle(
|
||||||
|
|
@ -226,7 +226,7 @@ class _BackupOnlyWhenChargingButton extends ConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final fgService = ref.read(backgroundWorkerFgServiceProvider);
|
final fgService = ref.watch(backgroundWorkerFgServiceProvider);
|
||||||
return _BackupSwitchTile(
|
return _BackupSwitchTile(
|
||||||
metadataKey: SettingsKey.backupRequireCharging,
|
metadataKey: SettingsKey.backupRequireCharging,
|
||||||
selector: (c) => c.backup.requireCharging,
|
selector: (c) => c.backup.requireCharging,
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ class SyncStatusAndActions extends HookConsumerWidget {
|
||||||
leading: const Icon(Icons.cloud_circle_rounded),
|
leading: const Icon(Icons.cloud_circle_rounded),
|
||||||
subtitle: "tap_to_run_job".t(context: context),
|
subtitle: "tap_to_run_job".t(context: context),
|
||||||
trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).cloudIdSyncStatus),
|
trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).cloudIdSyncStatus),
|
||||||
onTap: ref.read(backgroundSyncProvider).syncCloudIds,
|
onTap: ref.watch(backgroundSyncProvider).syncCloudIds,
|
||||||
),
|
),
|
||||||
SettingListTile(
|
SettingListTile(
|
||||||
title: "hash_asset".t(context: context),
|
title: "hash_asset".t(context: context),
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,13 @@ import 'dart:async';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/constants/locales.dart';
|
import 'package:immich_mobile/constants/locales.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||||
import 'package:immich_mobile/services/localization.service.dart';
|
import 'package:immich_mobile/services/localization.service.dart';
|
||||||
import 'package:immich_mobile/widgets/common/search_field.dart';
|
import 'package:immich_mobile/widgets/common/search_field.dart';
|
||||||
|
|
||||||
class LanguageSettings extends HookConsumerWidget {
|
class LanguageSettings extends HookWidget {
|
||||||
const LanguageSettings({super.key});
|
const LanguageSettings({super.key});
|
||||||
|
|
||||||
Future<void> _applyLanguageChange(
|
Future<void> _applyLanguageChange(
|
||||||
|
|
@ -33,7 +32,7 @@ class LanguageSettings extends HookConsumerWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final localeEntries = useMemoized(() => locales.entries.toList(), const []);
|
final localeEntries = useMemoized(() => locales.entries.toList(), const []);
|
||||||
final currentLocale = context.locale;
|
final currentLocale = context.locale;
|
||||||
final filteredLocaleEntries = useState<List<MapEntry<String, Locale>>>(localeEntries);
|
final filteredLocaleEntries = useState<List<MapEntry<String, Locale>>>(localeEntries);
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class NetworkingSettings extends HookConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final currentEndpoint = getServerUrl();
|
final currentEndpoint = getServerUrl();
|
||||||
final featureEnabled = useState(ref.read(appConfigProvider).network.autoEndpointSwitching);
|
final featureEnabled = useState(ref.watch(appConfigProvider).network.autoEndpointSwitching);
|
||||||
useValueChanged<bool, void>(featureEnabled.value, (_, __) {
|
useValueChanged<bool, void>(featureEnabled.value, (_, __) {
|
||||||
unawaited(ref.read(settingsProvider).write(.networkAutoEndpointSwitching, featureEnabled.value));
|
unawaited(ref.read(settingsProvider).write(.networkAutoEndpointSwitching, featureEnabled.value));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||||
import 'package:immich_mobile/services/app_settings.service.dart';
|
import 'package:immich_mobile/services/app_settings.service.dart';
|
||||||
import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart';
|
import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart';
|
||||||
import 'package:immich_mobile/widgets/settings/setting_group_title.dart';
|
import 'package:immich_mobile/widgets/settings/setting_group_title.dart';
|
||||||
import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart';
|
import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart';
|
||||||
|
|
||||||
class HapticSetting extends HookConsumerWidget {
|
class HapticSetting extends HookWidget {
|
||||||
const HapticSetting({super.key});
|
const HapticSetting({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final hapticFeedbackSetting = useAppSettingsState(AppSettingsEnum.enableHapticFeedback);
|
final hapticFeedbackSetting = useAppSettingsState(AppSettingsEnum.enableHapticFeedback);
|
||||||
final isHapticFeedbackEnabled = useValueNotifier(hapticFeedbackSetting.value);
|
final isHapticFeedbackEnabled = useValueNotifier(hapticFeedbackSetting.value);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class PrimaryColorSetting extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final themeProvider = ref.read(immichThemeProvider);
|
final themeProvider = ref.watch(immichThemeProvider);
|
||||||
final themeConfig = ref.watch(appConfigProvider.select((config) => config.theme));
|
final themeConfig = ref.watch(appConfigProvider.select((config) => config.theme));
|
||||||
|
|
||||||
const tileSize = 55.0;
|
const tileSize = 55.0;
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class ThemeSetting extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final currentTheme = useState(ref.read(appConfigProvider.select((config) => config.theme.mode)));
|
final currentTheme = useState(ref.watch(appConfigProvider.select((config) => config.theme.mode)));
|
||||||
final isDarkTheme = useValueNotifier(currentTheme.value == ThemeMode.dark);
|
final isDarkTheme = useValueNotifier(currentTheme.value == ThemeMode.dark);
|
||||||
final isSystemTheme = useValueNotifier(currentTheme.value == ThemeMode.system);
|
final isSystemTheme = useValueNotifier(currentTheme.value == ThemeMode.system);
|
||||||
final colorfulInterface = useValueNotifier(
|
final colorfulInterface = useValueNotifier(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue