mirror of
https://github.com/immich-app/immich.git
synced 2026-07-30 23:50:36 -07:00
chore(mobile): Apply stricter linting rules for correctness (#30372)
* chore(mobile): Apply stricter linting rules for correctness * Added discarded_futures rule
This commit is contained in:
@@ -28,7 +28,6 @@ linter:
|
||||
rules:
|
||||
# Formatting
|
||||
avoid_print: true
|
||||
unawaited_futures: true
|
||||
require_trailing_commas: true
|
||||
unrelated_type_equality_checks: true
|
||||
prefer_const_constructors: true
|
||||
@@ -50,6 +49,17 @@ linter:
|
||||
avoid_multiple_declarations_per_line: true
|
||||
unnecessary_breaks: true
|
||||
|
||||
# Correctness
|
||||
no_adjacent_strings_in_list: true
|
||||
cancel_subscriptions: true
|
||||
close_sinks: true
|
||||
unawaited_futures: true
|
||||
discarded_futures: true
|
||||
no_self_assignments: true
|
||||
throw_in_finally: true
|
||||
collection_methods_unrelated_type: true
|
||||
cast_nullable_to_non_nullable: true
|
||||
|
||||
# Known issues
|
||||
avoid_slow_async_io: true
|
||||
avoid_type_to_string: true
|
||||
|
||||
@@ -23,7 +23,7 @@ class Onboarding {
|
||||
}
|
||||
|
||||
factory Onboarding.fromMap(Map<String, Object?> map) {
|
||||
return Onboarding(isOnboarded: map["isOnboarded"] as bool);
|
||||
return Onboarding(isOnboarded: map["isOnboarded"]! as bool);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -195,9 +195,9 @@ class License {
|
||||
|
||||
factory License.fromMap(Map<String, Object?> map) {
|
||||
return License(
|
||||
activatedAt: DateTime.parse(map["activatedAt"] as String),
|
||||
activationKey: map["activationKey"] as String,
|
||||
licenseKey: map["licenseKey"] as String,
|
||||
activatedAt: DateTime.parse(map["activatedAt"]! as String),
|
||||
activationKey: map["activationKey"]! as String,
|
||||
licenseKey: map["licenseKey"]! as String,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class HashService {
|
||||
}) : _batchSize = batchSize ?? kBatchHashFileLimit {
|
||||
// Stop the in-flight native hash call promptly on cancellation; the loops
|
||||
// below also observe [isCancelled] to bail between batches.
|
||||
_cancellation?.future.then((_) => _nativeSyncApi.cancelHashing().onError(_log.warning));
|
||||
unawaited(_cancellation?.future.then((_) => _nativeSyncApi.cancelHashing().onError(_log.warning)));
|
||||
}
|
||||
|
||||
bool get isCancelled => _cancellation?.isCompleted ?? false;
|
||||
|
||||
@@ -40,7 +40,7 @@ class LocalSyncService {
|
||||
required this._permissionRepository,
|
||||
this._cancellation,
|
||||
}) {
|
||||
_cancellation?.future.then((_) => _nativeSyncApi.cancelSync().onError(_log.warning));
|
||||
unawaited(_cancellation?.future.then((_) => _nativeSyncApi.cancelSync().onError(_log.warning)));
|
||||
}
|
||||
|
||||
bool get _isCancelled => _cancellation?.isCompleted ?? false;
|
||||
|
||||
@@ -106,32 +106,34 @@ class TimelineService {
|
||||
|
||||
TimelineService._({required this._assetSource, required this._bucketSource, required this.origin}) {
|
||||
_bucketSubscription = _bucketSource().listen((buckets) {
|
||||
_mutex.run(() async {
|
||||
final totalAssets = buckets.fold<int>(0, (acc, bucket) => acc + bucket.assetCount);
|
||||
unawaited(
|
||||
_mutex.run(() async {
|
||||
final totalAssets = buckets.fold<int>(0, (acc, bucket) => acc + bucket.assetCount);
|
||||
|
||||
if (totalAssets == 0) {
|
||||
_bufferOffset = 0;
|
||||
_buffer = [];
|
||||
} else {
|
||||
final int offset;
|
||||
final int count;
|
||||
// When the buffer is empty or the old bufferOffset is greater than the new total assets,
|
||||
// we need to reset the buffer and load the first batch of assets.
|
||||
if (_bufferOffset >= totalAssets || _buffer.isEmpty) {
|
||||
offset = 0;
|
||||
count = kTimelineAssetLoadBatchSize;
|
||||
if (totalAssets == 0) {
|
||||
_bufferOffset = 0;
|
||||
_buffer = [];
|
||||
} else {
|
||||
offset = _bufferOffset;
|
||||
count = math.min(_buffer.length, totalAssets - _bufferOffset);
|
||||
final int offset;
|
||||
final int count;
|
||||
// When the buffer is empty or the old bufferOffset is greater than the new total assets,
|
||||
// we need to reset the buffer and load the first batch of assets.
|
||||
if (_bufferOffset >= totalAssets || _buffer.isEmpty) {
|
||||
offset = 0;
|
||||
count = kTimelineAssetLoadBatchSize;
|
||||
} else {
|
||||
offset = _bufferOffset;
|
||||
count = math.min(_buffer.length, totalAssets - _bufferOffset);
|
||||
}
|
||||
_buffer = await _assetSource(offset, count);
|
||||
_bufferOffset = offset;
|
||||
}
|
||||
_buffer = await _assetSource(offset, count);
|
||||
_bufferOffset = offset;
|
||||
}
|
||||
|
||||
// change the state's total assets count only after the buffer is reloaded
|
||||
_totalAssets = totalAssets;
|
||||
EventStream.shared.emit(const TimelineReloadEvent());
|
||||
});
|
||||
// change the state's total assets count only after the buffer is reloaded
|
||||
_totalAssets = totalAssets;
|
||||
EventStream.shared.emit(const TimelineReloadEvent());
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class EventStream {
|
||||
}
|
||||
|
||||
/// Closes the stream controller
|
||||
void dispose() {
|
||||
_controller.close();
|
||||
Future<void> dispose() {
|
||||
return _controller.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class AssetEditEntity extends Table with DriftDefaultsMixin {
|
||||
}
|
||||
|
||||
final JsonTypeConverter2<Map<String, Object?>, Uint8List, Object?> editParameterConverter = TypeConverter.jsonb(
|
||||
fromJson: (json) => json as Map<String, Object?>,
|
||||
fromJson: (json) => json! as Map<String, Object?>,
|
||||
);
|
||||
|
||||
extension AssetEditEntityDataDomainEx on AssetEditEntityData {
|
||||
|
||||
@@ -17,5 +17,5 @@ class UserMetadataEntity extends Table with DriftDefaultsMixin {
|
||||
}
|
||||
|
||||
final JsonTypeConverter2<Map<String, Object?>, Uint8List, Object?> userMetadataConverter = TypeConverter.jsonb(
|
||||
fromJson: (json) => json as Map<String, Object?>,
|
||||
fromJson: (json) => json! as Map<String, Object?>,
|
||||
);
|
||||
|
||||
@@ -358,12 +358,12 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||
final map = metadata.value as Map<String, Object?>;
|
||||
final companion = RemoteAssetCloudIdEntityCompanion(
|
||||
cloudId: Value(map['iCloudId']?.toString()),
|
||||
createdAt: Value(map['createdAt'] != null ? DateTime.parse(map['createdAt'] as String) : null),
|
||||
createdAt: Value(map['createdAt'] != null ? DateTime.parse(map['createdAt']! as String) : null),
|
||||
adjustmentTime: Value(
|
||||
map['adjustmentTime'] != null ? DateTime.parse(map['adjustmentTime'] as String) : null,
|
||||
map['adjustmentTime'] != null ? DateTime.parse(map['adjustmentTime']! as String) : null,
|
||||
),
|
||||
latitude: Value(map['latitude'] != null ? (double.tryParse(map['latitude'] as String)) : null),
|
||||
longitude: Value(map['longitude'] != null ? (double.tryParse(map['longitude'] as String)) : null),
|
||||
latitude: Value(map['latitude'] != null ? (double.tryParse(map['latitude']! as String)) : null),
|
||||
longitude: Value(map['longitude'] != null ? (double.tryParse(map['longitude']! as String)) : null),
|
||||
);
|
||||
batch.insert(
|
||||
_db.remoteAssetCloudIdEntity,
|
||||
|
||||
+14
-12
@@ -128,17 +128,17 @@ class ImmichAppState extends ConsumerState<ImmichApp> with WidgetsBindingObserve
|
||||
switch (state) {
|
||||
case AppLifecycleState.resumed:
|
||||
dPrint(() => "[APP STATE] resumed");
|
||||
ref.read(appStateProvider.notifier).handleAppResume();
|
||||
unawaited(ref.read(appStateProvider.notifier).handleAppResume());
|
||||
unawaited(ref.read(viewIntentHandlerProvider).onAppResumed());
|
||||
case AppLifecycleState.inactive:
|
||||
dPrint(() => "[APP STATE] inactive");
|
||||
ref.read(appStateProvider.notifier).handleAppInactivity();
|
||||
case AppLifecycleState.paused:
|
||||
dPrint(() => "[APP STATE] paused");
|
||||
ref.read(appStateProvider.notifier).handleAppPause();
|
||||
unawaited(ref.read(appStateProvider.notifier).handleAppPause());
|
||||
case AppLifecycleState.detached:
|
||||
dPrint(() => "[APP STATE] detached");
|
||||
ref.read(appStateProvider.notifier).handleAppDetached();
|
||||
unawaited(ref.read(appStateProvider.notifier).handleAppDetached());
|
||||
case AppLifecycleState.hidden:
|
||||
dPrint(() => "[APP STATE] hidden");
|
||||
ref.read(appStateProvider.notifier).handleAppHidden();
|
||||
@@ -216,17 +216,19 @@ class ImmichAppState extends ConsumerState<ImmichApp> with WidgetsBindingObserve
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
initApp().then((_) => dPrint(() => "App Init Completed"));
|
||||
unawaited(initApp().then((_) => dPrint(() => "App Init Completed")));
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// needs to be delayed so that EasyLocalization is working
|
||||
ref.read(backgroundWorkerFgServiceProvider).enable();
|
||||
unawaited(ref.read(backgroundWorkerFgServiceProvider).enable());
|
||||
if (Platform.isAndroid) {
|
||||
ref
|
||||
.read(backgroundWorkerFgServiceProvider)
|
||||
.saveNotificationMessage(
|
||||
StaticTranslations.instance.uploading_media,
|
||||
StaticTranslations.instance.backup_background_service_default_notification,
|
||||
);
|
||||
unawaited(
|
||||
ref
|
||||
.read(backgroundWorkerFgServiceProvider)
|
||||
.saveNotificationMessage(
|
||||
StaticTranslations.instance.uploading_media,
|
||||
StaticTranslations.instance.backup_background_service_default_notification,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -243,7 +245,7 @@ class ImmichAppState extends ConsumerState<ImmichApp> with WidgetsBindingObserve
|
||||
@override
|
||||
void reassemble() {
|
||||
if (kDebugMode) {
|
||||
NetworkRepository.init();
|
||||
unawaited(NetworkRepository.init());
|
||||
}
|
||||
super.reassemble();
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class _DriftBackupPageState extends ConsumerState<DriftBackupPage> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
WakelockPlus.enable();
|
||||
unawaited(WakelockPlus.enable());
|
||||
|
||||
final currentUser = ref.read(currentUserProvider);
|
||||
if (currentUser == null) {
|
||||
@@ -69,7 +69,7 @@ class _DriftBackupPageState extends ConsumerState<DriftBackupPage> {
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
WakelockPlus.disable();
|
||||
unawaited(WakelockPlus.disable());
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -111,7 +111,7 @@ class _DriftBackupPageState extends ConsumerState<DriftBackupPage> {
|
||||
title: Text("backup_controller_page_backup".t()),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
context.maybePop(true);
|
||||
unawaited(context.maybePop(true));
|
||||
},
|
||||
splashRadius: 24,
|
||||
icon: const Icon(Icons.arrow_back_ios_rounded),
|
||||
@@ -119,7 +119,7 @@ class _DriftBackupPageState extends ConsumerState<DriftBackupPage> {
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context.pushRoute(const DriftBackupOptionsRoute());
|
||||
unawaited(context.pushRoute(const DriftBackupOptionsRoute()));
|
||||
},
|
||||
icon: const Icon(Icons.settings_outlined),
|
||||
tooltip: "backup_options".t(context: context),
|
||||
@@ -207,8 +207,8 @@ class _BackupFooterState extends ConsumerState<_BackupFooter> with WidgetsBindin
|
||||
}
|
||||
}
|
||||
|
||||
void showPermissionsDialog() {
|
||||
showDialog(
|
||||
Future<void> showPermissionsDialog() {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
content: Text(context.t.notification_permission_dialog_content),
|
||||
@@ -225,7 +225,7 @@ class _BackupFooterState extends ConsumerState<_BackupFooter> with WidgetsBindin
|
||||
expanded: false,
|
||||
onPressed: () {
|
||||
ContextHelper(context).pop();
|
||||
openAppSettings();
|
||||
unawaited(openAppSettings());
|
||||
},
|
||||
),
|
||||
],
|
||||
@@ -233,8 +233,8 @@ class _BackupFooterState extends ConsumerState<_BackupFooter> with WidgetsBindin
|
||||
);
|
||||
}
|
||||
|
||||
void showBatteryOptimizationInfo() {
|
||||
showDialog<void>(
|
||||
Future<void> showBatteryOptimizationInfo() {
|
||||
return showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext ctx) {
|
||||
@@ -246,7 +246,8 @@ class _BackupFooterState extends ConsumerState<_BackupFooter> with WidgetsBindin
|
||||
labelText: context.t.backup_controller_page_background_battery_info_link,
|
||||
variant: .ghost,
|
||||
expanded: false,
|
||||
onPressed: () => launchUrl(Uri.parse('https://dontkillmyapp.com'), mode: LaunchMode.externalApplication),
|
||||
onPressed: () =>
|
||||
unawaited(launchUrl(Uri.parse('https://dontkillmyapp.com'), mode: LaunchMode.externalApplication)),
|
||||
),
|
||||
ImmichTextButton(
|
||||
labelText: context.t.backup_controller_page_background_battery_info_ok,
|
||||
@@ -279,11 +280,13 @@ class _BackupFooterState extends ConsumerState<_BackupFooter> with WidgetsBindin
|
||||
style: context.textTheme.bodySmall?.copyWith(color: context.colorScheme.onSurfaceSecondary),
|
||||
),
|
||||
onPressed: () {
|
||||
ref.read(notificationPermissionProvider.notifier).requestNotificationPermission().then((p) {
|
||||
if (p == PermissionStatus.permanentlyDenied) {
|
||||
showPermissionsDialog();
|
||||
}
|
||||
});
|
||||
unawaited(
|
||||
ref.read(notificationPermissionProvider.notifier).requestNotificationPermission().then((p) {
|
||||
if (p == PermissionStatus.permanentlyDenied) {
|
||||
unawaited(showPermissionsDialog());
|
||||
}
|
||||
}),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (notificationStatus != PermissionStatus.granted && batteryOptimizationStatus != PermissionStatus.granted)
|
||||
@@ -297,7 +300,7 @@ class _BackupFooterState extends ConsumerState<_BackupFooter> with WidgetsBindin
|
||||
textAlign: TextAlign.left,
|
||||
style: context.textTheme.bodySmall?.copyWith(color: context.colorScheme.onSurfaceSecondary),
|
||||
),
|
||||
onPressed: showBatteryOptimizationInfo,
|
||||
onPressed: () => unawaited(showBatteryOptimizationInfo()),
|
||||
),
|
||||
],
|
||||
TextButton.icon(
|
||||
|
||||
@@ -214,34 +214,36 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState<DriftBackupAlbum
|
||||
splashRadius: 16,
|
||||
icon: Icon(Icons.info, size: 20, color: context.primaryColor),
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
),
|
||||
elevation: 5,
|
||||
title: Text(
|
||||
'backup_album_selection_page_selection_info',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: context.primaryColor,
|
||||
unawaited(
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
),
|
||||
).t(context: context),
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(
|
||||
children: [
|
||||
const Text(
|
||||
'backup_album_selection_page_assets_scatter',
|
||||
style: TextStyle(fontSize: 14),
|
||||
).t(context: context),
|
||||
],
|
||||
elevation: 5,
|
||||
title: Text(
|
||||
'backup_album_selection_page_selection_info',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
).t(context: context),
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(
|
||||
children: [
|
||||
const Text(
|
||||
'backup_album_selection_page_assets_scatter',
|
||||
style: TextStyle(fontSize: 14),
|
||||
).t(context: context),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -364,14 +366,14 @@ class _SelectedAlbumNameChips extends ConsumerWidget {
|
||||
children: selectedBackupAlbums.asMap().entries.map((entry) {
|
||||
final album = entry.value;
|
||||
|
||||
void removeSelection() {
|
||||
ref.read(backupAlbumProvider.notifier).deselectAlbum(album);
|
||||
Future<void> removeSelection() {
|
||||
return ref.read(backupAlbumProvider.notifier).deselectAlbum(album);
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: GestureDetector(
|
||||
onTap: removeSelection,
|
||||
onTap: () => unawaited(removeSelection()),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeInOut,
|
||||
@@ -387,7 +389,7 @@ class _SelectedAlbumNameChips extends ConsumerWidget {
|
||||
backgroundColor: context.primaryColor,
|
||||
deleteIconColor: context.isDarkTheme ? Colors.black : Colors.white,
|
||||
deleteIcon: const Icon(Icons.cancel_rounded, size: 15),
|
||||
onDeleted: removeSelection,
|
||||
onDeleted: () => unawaited(removeSelection()),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -408,12 +410,12 @@ class _ExcludedAlbumNameChips extends ConsumerWidget {
|
||||
children: excludedBackupAlbums.asMap().entries.map((entry) {
|
||||
final album = entry.value;
|
||||
|
||||
void removeSelection() {
|
||||
ref.read(backupAlbumProvider.notifier).deselectAlbum(album);
|
||||
Future<void> removeSelection() {
|
||||
return ref.read(backupAlbumProvider.notifier).deselectAlbum(album);
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
onTap: removeSelection,
|
||||
onTap: () => unawaited(removeSelection()),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: AnimatedContainer(
|
||||
@@ -427,7 +429,7 @@ class _ExcludedAlbumNameChips extends ConsumerWidget {
|
||||
backgroundColor: Colors.red[300],
|
||||
deleteIconColor: context.scaffoldBackgroundColor,
|
||||
deleteIcon: const Icon(Icons.cancel_rounded, size: 15),
|
||||
onDeleted: removeSelection,
|
||||
onDeleted: () => unawaited(removeSelection()),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -457,7 +459,7 @@ class _SelectAllButton extends ConsumerWidget {
|
||||
? () {
|
||||
for (final album in filteredAlbums) {
|
||||
if (album.backupSelection != BackupSelection.selected) {
|
||||
ref.read(backupAlbumProvider.notifier).selectAlbum(album);
|
||||
unawaited(ref.read(backupAlbumProvider.notifier).selectAlbum(album));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -477,7 +479,7 @@ class _SelectAllButton extends ConsumerWidget {
|
||||
? () {
|
||||
for (final album in filteredAlbums) {
|
||||
if (album.backupSelection == BackupSelection.selected) {
|
||||
ref.read(backupAlbumProvider.notifier).deselectAlbum(album);
|
||||
unawaited(ref.read(backupAlbumProvider.notifier).deselectAlbum(album));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -61,7 +63,7 @@ class AppLogPage extends HookConsumerWidget {
|
||||
size: 20.0,
|
||||
),
|
||||
onPressed: () {
|
||||
immichLogger.clearLogs();
|
||||
unawaited(immichLogger.clearLogs());
|
||||
shouldReload.value = !shouldReload.value;
|
||||
},
|
||||
),
|
||||
@@ -70,7 +72,7 @@ class AppLogPage extends HookConsumerWidget {
|
||||
return IconButton(
|
||||
icon: Icon(Icons.share_rounded, color: context.primaryColor, semanticLabel: "Share logs", size: 20.0),
|
||||
onPressed: () {
|
||||
ImmichLogger.shareLogs(iconContext);
|
||||
unawaited(ImmichLogger.shareLogs(iconContext));
|
||||
},
|
||||
);
|
||||
},
|
||||
@@ -78,7 +80,7 @@ class AppLogPage extends HookConsumerWidget {
|
||||
],
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
context.maybePop();
|
||||
unawaited(context.maybePop());
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back_ios_new_rounded, size: 20.0),
|
||||
),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -33,16 +35,18 @@ class AppLogDetailPage extends HookConsumerWidget {
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Clipboard.setData(ClipboardData(text: text)).then((_) {
|
||||
context.scaffoldMessenger.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
"copied_to_clipboard".tr(),
|
||||
style: context.textTheme.bodyLarge?.copyWith(color: context.primaryColor),
|
||||
unawaited(
|
||||
Clipboard.setData(ClipboardData(text: text)).then((_) {
|
||||
context.scaffoldMessenger.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
"copied_to_clipboard".tr(),
|
||||
style: context.textTheme.bodyLarge?.copyWith(color: context.primaryColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
);
|
||||
}),
|
||||
);
|
||||
},
|
||||
icon: Icon(Icons.copy, size: 16.0, color: context.primaryColor),
|
||||
),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:background_downloader/background_downloader.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -15,7 +17,7 @@ class DownloadPanel extends ConsumerWidget {
|
||||
final tasks = ref.watch(downloadStateProvider.select((state) => state.taskProgress)).entries.toList();
|
||||
|
||||
void onCancelDownload(String id) {
|
||||
ref.watch(downloadStateProvider.notifier).cancelDownload(id);
|
||||
unawaited(ref.watch(downloadStateProvider.notifier).cancelDownload(id));
|
||||
}
|
||||
|
||||
return Positioned(
|
||||
|
||||
@@ -282,11 +282,13 @@ class SplashScreenPageState extends ConsumerState<SplashScreenPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
ref
|
||||
.read(authProvider.notifier)
|
||||
.setOpenApiServiceEndpoint()
|
||||
.then(logConnectionInfo)
|
||||
.whenComplete(() => resumeSession());
|
||||
unawaited(
|
||||
ref
|
||||
.read(authProvider.notifier)
|
||||
.setOpenApiServiceEndpoint()
|
||||
.then(logConnectionInfo)
|
||||
.whenComplete(() => resumeSession()),
|
||||
);
|
||||
}
|
||||
|
||||
void logConnectionInfo(String? endpoint) {
|
||||
@@ -327,7 +329,7 @@ class SplashScreenPageState extends ConsumerState<SplashScreenPage> {
|
||||
if (syncSuccess) {
|
||||
await Future.wait([
|
||||
backgroundManager.hashAssets().then((_) {
|
||||
_resumeBackup(backupProvider);
|
||||
unawaited(_resumeBackup(backupProvider));
|
||||
}),
|
||||
_resumeBackup(backupProvider),
|
||||
// TODO: Bring back when the soft freeze issue is addressed
|
||||
|
||||
@@ -126,7 +126,7 @@ void _onNavigationSelected(TabsRouter router, int index, WidgetRef ref) {
|
||||
|
||||
// Album page
|
||||
if (index == kAlbumTabIndex) {
|
||||
ref.read(remoteAlbumProvider.notifier).refresh();
|
||||
unawaited(ref.read(remoteAlbumProvider.notifier).refresh());
|
||||
}
|
||||
|
||||
// Library page
|
||||
@@ -168,7 +168,7 @@ class _BottomNavigationBarState extends ConsumerState<_BottomNavigationBar> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_eventSubscription?.cancel();
|
||||
unawaited(_eventSubscription?.cancel());
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@@ -53,7 +55,7 @@ class FolderPage extends HookConsumerWidget {
|
||||
|
||||
useEffect(() {
|
||||
if (folder == null) {
|
||||
ref.read(folderStructureProvider.notifier).fetchFolders(sortOrder.value);
|
||||
unawaited(ref.read(folderStructureProvider.notifier).fetchFolders(sortOrder.value));
|
||||
}
|
||||
return null;
|
||||
}, []);
|
||||
@@ -72,7 +74,7 @@ class FolderPage extends HookConsumerWidget {
|
||||
void onToggleSortOrder() {
|
||||
final newOrder = sortOrder.value == SortOrder.asc ? SortOrder.desc : SortOrder.asc;
|
||||
|
||||
ref.read(folderStructureProvider.notifier).fetchFolders(newOrder);
|
||||
unawaited(ref.read(folderStructureProvider.notifier).fetchFolders(newOrder));
|
||||
|
||||
sortOrder.value = newOrder;
|
||||
}
|
||||
@@ -118,7 +120,7 @@ class FolderContent extends HookConsumerWidget {
|
||||
if (folder == null) {
|
||||
return;
|
||||
}
|
||||
ref.read(folderRenderListProvider(folder!).notifier).fetchAssets(sortOrder);
|
||||
unawaited(ref.read(folderRenderListProvider(folder!).notifier).fetchAssets(sortOrder));
|
||||
return null;
|
||||
}, [folder]);
|
||||
|
||||
@@ -176,12 +178,14 @@ class FolderContent extends HookConsumerWidget {
|
||||
(index, asset) => LargeLeadingTile(
|
||||
onTap: () {
|
||||
AssetViewer.setAsset(ref, asset);
|
||||
context.pushRoute(
|
||||
AssetViewerRoute(
|
||||
initialIndex: index,
|
||||
timelineService: ref
|
||||
.read(timelineFactoryProvider)
|
||||
.fromAssets(folderAssets, TimelineOrigin.folder),
|
||||
unawaited(
|
||||
context.pushRoute(
|
||||
AssetViewerRoute(
|
||||
initialIndex: index,
|
||||
timelineService: ref
|
||||
.read(timelineFactoryProvider)
|
||||
.fromAssets(folderAssets, TimelineOrigin.folder),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -38,8 +38,8 @@ class PinAuthPage extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
void enableBiometricAuth() {
|
||||
showDialog(
|
||||
Future<void> enableBiometricAuth() {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (buildContext) {
|
||||
return SimpleDialog(
|
||||
@@ -53,7 +53,7 @@ class PinAuthPage extends HookConsumerWidget {
|
||||
description: 'enable_biometric_auth_description'.tr(),
|
||||
onSuccess: (pinCode) {
|
||||
Navigator.pop(buildContext);
|
||||
registerBiometric(pinCode);
|
||||
unawaited(registerBiometric(pinCode));
|
||||
},
|
||||
autoFocus: true,
|
||||
icon: Icons.fingerprint_rounded,
|
||||
@@ -83,7 +83,7 @@ class PinAuthPage extends HookConsumerWidget {
|
||||
child: PinVerificationForm(
|
||||
autoFocus: true,
|
||||
onSuccess: (_) {
|
||||
context.replaceRoute(const DriftLockedFolderRoute());
|
||||
unawaited(context.replaceRoute(const DriftLockedFolderRoute()));
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -93,7 +93,7 @@ class PinAuthPage extends HookConsumerWidget {
|
||||
padding: const EdgeInsets.only(right: 16.0),
|
||||
child: TextButton.icon(
|
||||
icon: const Icon(Icons.fingerprint, size: 28),
|
||||
onPressed: enableBiometricAuth,
|
||||
onPressed: () => unawaited(enableBiometricAuth()),
|
||||
label: Text(
|
||||
'use_biometric'.tr(),
|
||||
style: context.textTheme.labelLarge?.copyWith(color: context.primaryColor, fontSize: 18),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -17,7 +19,7 @@ class SharedLinkPage extends HookConsumerWidget {
|
||||
final sharedLinks = ref.watch(sharedLinksStateProvider);
|
||||
|
||||
useEffect(() {
|
||||
ref.read(sharedLinksStateProvider.notifier).fetchLinks();
|
||||
unawaited(ref.read(sharedLinksStateProvider.notifier).fetchLinks());
|
||||
return () {
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
@@ -22,7 +24,7 @@ class LoginPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
useEffect(() {
|
||||
getAppInfo();
|
||||
unawaited(getAppInfo());
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -55,7 +57,7 @@ class LoginPage extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
context.pushRoute(const AppLogRoute());
|
||||
unawaited(context.pushRoute(const AppLogRoute()));
|
||||
},
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
@@ -37,7 +38,7 @@ class MapLocationPickerPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
void onClose([LatLng? selected]) {
|
||||
context.maybePop(selected);
|
||||
unawaited(context.maybePop(selected));
|
||||
}
|
||||
|
||||
Future<void> getCurrentLocation() async {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -65,7 +67,7 @@ class ShareIntentPage extends ConsumerWidget {
|
||||
),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
context.navigateTo(const TabShellRoute());
|
||||
unawaited(context.navigateTo(const TabShellRoute()));
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -15,7 +17,7 @@ class DownloadInfoPage extends ConsumerWidget {
|
||||
final tasks = ref.watch(downloadStateProvider.select((state) => state.taskProgress)).entries.toList();
|
||||
|
||||
void onCancelDownload(String id) {
|
||||
ref.watch(downloadStateProvider.notifier).cancelDownload(id);
|
||||
unawaited(ref.watch(downloadStateProvider.notifier).cancelDownload(id));
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
|
||||
@@ -25,13 +27,17 @@ class DriftActivitiesPage extends HookConsumerWidget {
|
||||
final activities = ref.watch(albumActivityProvider((album.id, assetId)));
|
||||
final listViewScrollController = useScrollController();
|
||||
|
||||
void scrollToBottom() {
|
||||
listViewScrollController.animateTo(0, duration: const Duration(milliseconds: 300), curve: Curves.fastOutSlowIn);
|
||||
Future<void> scrollToBottom() {
|
||||
return listViewScrollController.animateTo(
|
||||
0,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.fastOutSlowIn,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> onAddComment(String comment) async {
|
||||
await activityNotifier.addComment(comment);
|
||||
scrollToBottom();
|
||||
unawaited(scrollToBottom());
|
||||
}
|
||||
|
||||
return ProviderScope(
|
||||
|
||||
@@ -53,7 +53,7 @@ class _DriftAlbumsPageState extends ConsumerState<DriftAlbumsPage> {
|
||||
),
|
||||
AlbumSelector(
|
||||
onAlbumSelected: (album) {
|
||||
context.router.push(RemoteAlbumRoute(album: album));
|
||||
unawaited(context.router.push(RemoteAlbumRoute(album: album)));
|
||||
},
|
||||
),
|
||||
],
|
||||
|
||||
@@ -110,18 +110,20 @@ class DriftAlbumOptionsPage extends HookConsumerWidget {
|
||||
];
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
backgroundColor: context.colorScheme.surfaceContainer,
|
||||
isScrollControlled: false,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 24.0),
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [...actions]),
|
||||
),
|
||||
);
|
||||
},
|
||||
unawaited(
|
||||
showModalBottomSheet(
|
||||
backgroundColor: context.colorScheme.surfaceContainer,
|
||||
isScrollControlled: false,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 24.0),
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [...actions]),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -78,11 +80,13 @@ class _AssetPropertiesSectionState extends ConsumerState<_AssetPropertiesSection
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_buildAssetProperties(widget.asset).whenComplete(() {
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
unawaited(
|
||||
_buildAssetProperties(widget.asset).whenComplete(() {
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -39,8 +41,8 @@ class _DriftLockedFolderPageState extends ConsumerState<DriftLockedFolderPage> w
|
||||
return;
|
||||
}
|
||||
if (state == AppLifecycleState.paused) {
|
||||
ref.read(authProvider.notifier).lockPinCode();
|
||||
context.navigateTo(const TabShellRoute());
|
||||
unawaited(ref.read(authProvider.notifier).lockPinCode());
|
||||
unawaited(context.navigateTo(const TabShellRoute()));
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
@@ -11,8 +13,8 @@ class DriftMapPage extends StatelessWidget {
|
||||
|
||||
const DriftMapPage({super.key, this.initialLocation});
|
||||
|
||||
void onSettingsPressed(BuildContext context) {
|
||||
showModalBottomSheet(
|
||||
Future<void> onSettingsPressed(BuildContext context) {
|
||||
return showModalBottomSheet(
|
||||
elevation: 0.0,
|
||||
showDragHandle: true,
|
||||
isScrollControlled: true,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
@@ -47,21 +49,21 @@ class DriftMemoryPage extends HookConsumerWidget {
|
||||
|
||||
useEffect(() {
|
||||
// Memories is an immersive activity
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
|
||||
unawaited(SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive));
|
||||
return () {
|
||||
// Clean up to normal edge to edge when we are done
|
||||
restoreEdgeToEdge();
|
||||
unawaited(restoreEdgeToEdge());
|
||||
};
|
||||
});
|
||||
|
||||
void toNextMemory() {
|
||||
memoryPageController.nextPage(duration: const Duration(milliseconds: 500), curve: Curves.easeIn);
|
||||
unawaited(memoryPageController.nextPage(duration: const Duration(milliseconds: 500), curve: Curves.easeIn));
|
||||
}
|
||||
|
||||
void toPreviousMemory() {
|
||||
if (currentMemoryIndex.value > 0) {
|
||||
// Move to the previous memory page
|
||||
memoryPageController.previousPage(duration: const Duration(milliseconds: 500), curve: Curves.easeIn);
|
||||
unawaited(memoryPageController.previousPage(duration: const Duration(milliseconds: 500), curve: Curves.easeIn));
|
||||
|
||||
// Wait for the next frame to ensure the page is built
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
@@ -88,7 +90,7 @@ class DriftMemoryPage extends HookConsumerWidget {
|
||||
// Go to the next asset
|
||||
final PageController controller = memoryAssetPageControllers[currentMemoryIndex.value];
|
||||
|
||||
controller.nextPage(curve: Curves.easeInOut, duration: const Duration(milliseconds: 500));
|
||||
unawaited(controller.nextPage(curve: Curves.easeInOut, duration: const Duration(milliseconds: 500)));
|
||||
} else {
|
||||
// Go to the next memory since we are at the end of our assets
|
||||
toNextMemory();
|
||||
@@ -100,7 +102,7 @@ class DriftMemoryPage extends HookConsumerWidget {
|
||||
// Go to the previous asset
|
||||
final PageController controller = memoryAssetPageControllers[currentMemoryIndex.value];
|
||||
|
||||
controller.previousPage(curve: Curves.easeInOut, duration: const Duration(milliseconds: 500));
|
||||
unawaited(controller.previousPage(curve: Curves.easeInOut, duration: const Duration(milliseconds: 500)));
|
||||
} else {
|
||||
// Go to the previous memory since we are at the end of our assets
|
||||
toPreviousMemory();
|
||||
@@ -153,7 +155,7 @@ class DriftMemoryPage extends HookConsumerWidget {
|
||||
|
||||
// Precache the next page right away if we are on the first page
|
||||
if (currentAssetPage.value == 0) {
|
||||
Future.delayed(const Duration(milliseconds: 200)).then((_) => precacheAsset(1));
|
||||
unawaited(Future.delayed(const Duration(milliseconds: 200)).then((_) => precacheAsset(1)));
|
||||
}
|
||||
|
||||
Future<void> onAssetChanged(int otherIndex) async {
|
||||
@@ -198,7 +200,7 @@ class DriftMemoryPage extends HookConsumerWidget {
|
||||
|
||||
final offset = notification.metrics.pixels;
|
||||
if (isEpiloguePage && (offset > notification.metrics.maxScrollExtent + 150)) {
|
||||
context.maybePop();
|
||||
unawaited(context.maybePop());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -328,8 +330,8 @@ class DriftMemoryPage extends HookConsumerWidget {
|
||||
// auto_route doesn't invoke pop scope, so
|
||||
// turn off full screen mode here
|
||||
// https://github.com/Milad-Akarie/auto_route_library/issues/1799
|
||||
context.maybePop();
|
||||
restoreEdgeToEdge();
|
||||
unawaited(context.maybePop());
|
||||
unawaited(restoreEdgeToEdge());
|
||||
},
|
||||
shape: const CircleBorder(),
|
||||
color: Colors.white.withValues(alpha: 0.2),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -86,7 +88,7 @@ class _DriftPeopleCollectionPageState extends ConsumerState<DriftPeopleCollectio
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
context.pushRoute(DriftPersonRoute(person: person));
|
||||
unawaited(context.pushRoute(DriftPersonRoute(person: person)));
|
||||
},
|
||||
child: Material(
|
||||
shape: const CircleBorder(side: BorderSide.none),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -49,8 +51,8 @@ class _DriftPersonPageState extends ConsumerState<DriftPersonPage> {
|
||||
}
|
||||
}
|
||||
|
||||
void showOptionSheet(BuildContext context) {
|
||||
showModalBottomSheet(
|
||||
Future<void> showOptionSheet(BuildContext context) {
|
||||
return showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: context.colorScheme.surface,
|
||||
isScrollControlled: false,
|
||||
|
||||
@@ -67,7 +67,7 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
||||
_updateNextIndex();
|
||||
ref.listenManual(appConfigProvider.select((s) => s.slideshow), _onConfigChanged);
|
||||
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
|
||||
unawaited(SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive));
|
||||
unawaited(WakelockPlus.enable());
|
||||
}
|
||||
|
||||
@@ -94,9 +94,9 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
||||
if (asset.isImage) {
|
||||
_createTimer();
|
||||
} else if (ref.read(videoPlayerProvider(asset.heroTag)).status == VideoPlaybackStatus.paused) {
|
||||
ref.read(videoPlayerProvider(asset.heroTag).notifier).play();
|
||||
unawaited(ref.read(videoPlayerProvider(asset.heroTag).notifier).play());
|
||||
} else {
|
||||
_nextPage();
|
||||
unawaited(_nextPage());
|
||||
}
|
||||
|
||||
_updateNextIndex();
|
||||
@@ -113,7 +113,7 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
||||
final asset = widget.timeline.getAssetSafe(_index)!;
|
||||
|
||||
if (!asset.isImage) {
|
||||
ref.read(videoPlayerProvider(asset.heroTag).notifier).pause();
|
||||
unawaited(ref.read(videoPlayerProvider(asset.heroTag).notifier).pause());
|
||||
}
|
||||
|
||||
setState(() {
|
||||
@@ -147,7 +147,7 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
||||
};
|
||||
|
||||
if (!widget.timeline.hasRange(_nextIndex, 1)) {
|
||||
widget.timeline.preloadAssets(_nextIndex);
|
||||
unawaited(widget.timeline.preloadAssets(_nextIndex));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,14 +184,16 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
||||
_crossfadeFromIndex = previousIndex;
|
||||
_crossfadeToIndex = page;
|
||||
});
|
||||
_crossfadeController.forward(from: 0.0).whenComplete(() {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_crossfadeFromIndex = null;
|
||||
_crossfadeToIndex = null;
|
||||
});
|
||||
}
|
||||
});
|
||||
unawaited(
|
||||
_crossfadeController.forward(from: 0.0).whenComplete(() {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_crossfadeFromIndex = null;
|
||||
_crossfadeToIndex = null;
|
||||
});
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _getCrossfadeLayer(BuildContext context, int index, {required bool isIncoming}) {
|
||||
@@ -238,7 +240,7 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
||||
_timer = Timer(Duration(milliseconds: _config.duration * 1000 - _stopwatch.elapsedMilliseconds), () {
|
||||
_stopwatch.stop();
|
||||
_stopwatch.reset();
|
||||
_nextPage();
|
||||
unawaited(_nextPage());
|
||||
});
|
||||
|
||||
_stopwatch.start();
|
||||
@@ -376,9 +378,9 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
||||
final position = ref.read(videoPlayerProvider(asset.heroTag)).position;
|
||||
|
||||
if (status == VideoPlaybackStatus.completed && isCurrent && position.inMicroseconds > 0) {
|
||||
_nextPage();
|
||||
unawaited(_nextPage());
|
||||
} else if (status == VideoPlaybackStatus.playing) {
|
||||
ref.read(videoPlayerProvider(asset.heroTag).notifier).setLoop(false);
|
||||
unawaited(ref.read(videoPlayerProvider(asset.heroTag).notifier).setLoop(false));
|
||||
}
|
||||
|
||||
return PhotoView.customChild(
|
||||
@@ -418,7 +420,7 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
_pause();
|
||||
context.pushRoute(SettingsSubRoute(section: SettingSection.assetViewer));
|
||||
unawaited(context.pushRoute(SettingsSubRoute(section: SettingSection.assetViewer)));
|
||||
},
|
||||
icon: const Icon(Icons.settings),
|
||||
),
|
||||
@@ -512,7 +514,7 @@ class _SlideshowProgressBarState extends State<_SlideshowProgressBar> with Singl
|
||||
animationBehavior: AnimationBehavior.preserve,
|
||||
)..value = (widget.elapsedMs / widget.durationMs).clamp(0.0, 1.0);
|
||||
if (!widget.paused) {
|
||||
_controller.forward();
|
||||
unawaited(_controller.forward());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -53,7 +55,7 @@ class DriftUserSelectionPage extends HookConsumerWidget {
|
||||
final sharedUsersList = useState<Set<UserDto>>({});
|
||||
|
||||
void addNewUsersHandler() {
|
||||
context.maybePop(sharedUsersList.value.map((e) => e.id).toList());
|
||||
unawaited(context.maybePop(sharedUsersList.value.map((e) => e.id).toList()));
|
||||
}
|
||||
|
||||
Widget buildTileIcon(UserDto user) {
|
||||
@@ -122,12 +124,12 @@ class DriftUserSelectionPage extends HookConsumerWidget {
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.close_rounded),
|
||||
onPressed: () {
|
||||
context.maybePop(null);
|
||||
unawaited(context.maybePop(null));
|
||||
},
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: sharedUsersList.value.isEmpty ? null : addNewUsersHandler,
|
||||
onPressed: sharedUsersList.value.isEmpty ? null : () => addNewUsersHandler(),
|
||||
child: const Text("add", style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold)).tr(),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -105,20 +105,22 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||
return null;
|
||||
}
|
||||
|
||||
Future.microtask(() {
|
||||
textSearchController.clear();
|
||||
peopleCurrentFilterWidget.value = null;
|
||||
dateRangeCurrentFilterWidget.value = null;
|
||||
cameraCurrentFilterWidget.value = null;
|
||||
tagCurrentFilterWidget.value = null;
|
||||
mediaTypeCurrentFilterWidget.value = null;
|
||||
ratingCurrentFilterWidget.value = null;
|
||||
displayOptionCurrentFilterWidget.value = null;
|
||||
locationCurrentFilterWidget.value = preFilter.location.city != null
|
||||
? Text(preFilter.location.city!, style: context.textTheme.labelLarge)
|
||||
: null;
|
||||
search(preFilter);
|
||||
});
|
||||
unawaited(
|
||||
Future.microtask(() {
|
||||
textSearchController.clear();
|
||||
peopleCurrentFilterWidget.value = null;
|
||||
dateRangeCurrentFilterWidget.value = null;
|
||||
cameraCurrentFilterWidget.value = null;
|
||||
tagCurrentFilterWidget.value = null;
|
||||
mediaTypeCurrentFilterWidget.value = null;
|
||||
ratingCurrentFilterWidget.value = null;
|
||||
displayOptionCurrentFilterWidget.value = null;
|
||||
locationCurrentFilterWidget.value = preFilter.location.city != null
|
||||
? Text(preFilter.location.city!, style: context.textTheme.labelLarge)
|
||||
: null;
|
||||
search(preFilter);
|
||||
}),
|
||||
);
|
||||
|
||||
return null;
|
||||
}, [preFilter]);
|
||||
@@ -141,17 +143,19 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||
search(filter.value.copyWith(people: people));
|
||||
}
|
||||
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
child: FractionallySizedBox(
|
||||
heightFactor: 0.8,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'search_filter_people_title'.t(context: context),
|
||||
expanded: true,
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: PeoplePicker(onSelect: handleOnSelect, filter: filter.value.people),
|
||||
unawaited(
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
child: FractionallySizedBox(
|
||||
heightFactor: 0.8,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'search_filter_people_title'.t(context: context),
|
||||
expanded: true,
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: PeoplePicker(onSelect: handleOnSelect, filter: filter.value.people),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -176,17 +180,19 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||
search(filter.value.copyWith(tagIds: tagIds));
|
||||
}
|
||||
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
child: FractionallySizedBox(
|
||||
heightFactor: 0.8,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'search_filter_tags_title'.t(context: context),
|
||||
expanded: true,
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: TagPicker(onSelectExistingTag: handleOnSelect, filter: (filter.value.tagIds ?? []).toSet()),
|
||||
unawaited(
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
child: FractionallySizedBox(
|
||||
heightFactor: 0.8,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'search_filter_tags_title'.t(context: context),
|
||||
expanded: true,
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: TagPicker(onSelectExistingTag: handleOnSelect, filter: (filter.value.tagIds ?? []).toSet()),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -216,21 +222,23 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||
search(filter.value.copyWith(location: location));
|
||||
}
|
||||
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
isDismissible: true,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'search_filter_location_title'.t(context: context),
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(bottom: context.viewInsets.bottom),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: LocationPicker(onSelected: handleOnSelect, filter: filter.value.location),
|
||||
unawaited(
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
isDismissible: true,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'search_filter_location_title'.t(context: context),
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(bottom: context.viewInsets.bottom),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: LocationPicker(onSelected: handleOnSelect, filter: filter.value.location),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -259,17 +267,19 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||
search(filter.value.copyWith(camera: camera));
|
||||
}
|
||||
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
isDismissible: true,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'search_filter_camera_title'.t(context: context),
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: CameraPicker(onSelect: handleOnSelect, filter: filter.value.camera),
|
||||
unawaited(
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
isDismissible: true,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'search_filter_camera_title'.t(context: context),
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: CameraPicker(onSelect: handleOnSelect, filter: filter.value.camera),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -339,22 +349,24 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
void showQuickDatePicker() {
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: "pick_date_range".tr(),
|
||||
expanded: true,
|
||||
onClear: () => datePicked(null),
|
||||
child: QuickDatePicker(
|
||||
currentInput: dateInputFilter.value,
|
||||
onRequestPicker: () {
|
||||
ContextHelper(context).pop();
|
||||
showDatePicker();
|
||||
},
|
||||
onSelect: (date) {
|
||||
ContextHelper(context).pop();
|
||||
datePicked(date);
|
||||
},
|
||||
unawaited(
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: "pick_date_range".tr(),
|
||||
expanded: true,
|
||||
onClear: () => datePicked(null),
|
||||
child: QuickDatePicker(
|
||||
currentInput: dateInputFilter.value,
|
||||
onRequestPicker: () {
|
||||
ContextHelper(context).pop();
|
||||
unawaited(showDatePicker());
|
||||
},
|
||||
onSelect: (date) {
|
||||
ContextHelper(context).pop();
|
||||
datePicked(date);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -383,13 +395,15 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||
search(filter.value.copyWith(mediaType: mediaType));
|
||||
}
|
||||
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'search_filter_media_type_title'.t(context: context),
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: MediaTypePicker(onSelect: handleOnSelected, filter: filter.value.mediaType),
|
||||
unawaited(
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'search_filter_media_type_title'.t(context: context),
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: MediaTypePicker(onSelect: handleOnSelected, filter: filter.value.mediaType),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -417,14 +431,16 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||
search(filter.value.copyWith(rating: rating));
|
||||
}
|
||||
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'rating'.t(context: context),
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: StarRatingPicker(onSelect: handleOnSelected, filter: filter.value.rating),
|
||||
unawaited(
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'rating'.t(context: context),
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: StarRatingPicker(onSelect: handleOnSelected, filter: filter.value.rating),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -462,13 +478,15 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||
search(filter.value.copyWith(display: display));
|
||||
}
|
||||
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'display_options'.t(context: context),
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: DisplayOptionPicker(onSelect: handleOnSelect, filter: filter.value.display),
|
||||
unawaited(
|
||||
showFilterBottomSheet(
|
||||
context: context,
|
||||
child: FilterBottomSheetScaffold(
|
||||
title: 'display_options'.t(context: context),
|
||||
onSearch: handleApply,
|
||||
onClear: handleClear,
|
||||
child: DisplayOptionPicker(onSelect: handleOnSelect, filter: filter.value.display),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -697,7 +715,7 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||
if (filter.value.isEmpty)
|
||||
const _SearchSuggestions()
|
||||
else
|
||||
_SearchResultGrid(onScrollEnd: loadMoreSearchResults),
|
||||
_SearchResultGrid(onScrollEnd: () => loadMoreSearchResults()),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -70,7 +70,7 @@ class PaginatedSearchNotifier extends StateNotifier<SearchState> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_assetCountController.close();
|
||||
unawaited(_assetCountController.close());
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -36,11 +38,11 @@ class _AddActionButtonState extends ConsumerState<AddActionButton> {
|
||||
case AddToMenuItem.album:
|
||||
_openAlbumSelector();
|
||||
case AddToMenuItem.archive:
|
||||
performArchiveAction(context, ref, source: ActionSource.viewer);
|
||||
unawaited(performArchiveAction(context, ref, source: ActionSource.viewer));
|
||||
case AddToMenuItem.unarchive:
|
||||
performUnArchiveAction(context, ref, source: ActionSource.viewer);
|
||||
unawaited(performUnArchiveAction(context, ref, source: ActionSource.viewer));
|
||||
case AddToMenuItem.lockedFolder:
|
||||
performMoveToLockFolderAction(context, ref, source: ActionSource.viewer);
|
||||
unawaited(performMoveToLockFolderAction(context, ref, source: ActionSource.viewer));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,21 +114,23 @@ class _AddActionButtonState extends ConsumerState<AddActionButton> {
|
||||
AlbumSelector(onAlbumSelected: (album) => _addCurrentAssetToAlbum(album)),
|
||||
];
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (_) {
|
||||
return BaseBottomSheet(
|
||||
actions: const [],
|
||||
slivers: slivers,
|
||||
initialChildSize: 0.6,
|
||||
minChildSize: 0.3,
|
||||
maxChildSize: 0.95,
|
||||
expand: false,
|
||||
backgroundColor: context.isDarkTheme ? Colors.black : Colors.white,
|
||||
);
|
||||
},
|
||||
unawaited(
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (_) {
|
||||
return BaseBottomSheet(
|
||||
actions: const [],
|
||||
slivers: slivers,
|
||||
initialChildSize: 0.6,
|
||||
minChildSize: 0.3,
|
||||
maxChildSize: 0.95,
|
||||
expand: false,
|
||||
backgroundColor: context.isDarkTheme ? Colors.black : Colors.white,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
@@ -21,7 +23,7 @@ class CastActionButton extends ConsumerWidget {
|
||||
iconColor: isCasting ? context.primaryColor : null, // null = default color
|
||||
label: "cast".t(context: context),
|
||||
onPressed: () {
|
||||
showDialog(context: context, builder: (context) => const CastDialog());
|
||||
unawaited(showDialog(context: context, builder: (context) => const CastDialog()));
|
||||
},
|
||||
iconOnly: iconOnly,
|
||||
menuItem: menuItem,
|
||||
|
||||
+3
-1
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -33,7 +35,7 @@ class DownloadStatusFloatingButton extends ConsumerWidget {
|
||||
: context.colorScheme.surfaceBright,
|
||||
elevation: 2,
|
||||
onPressed: () {
|
||||
context.pushRoute(const DownloadInfoRoute());
|
||||
unawaited(context.pushRoute(const DownloadInfoRoute()));
|
||||
},
|
||||
child: Stack(
|
||||
alignment: AlignmentDirectional.center,
|
||||
|
||||
+5
-3
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -13,12 +15,12 @@ class SetProfilePictureActionButton extends ConsumerWidget {
|
||||
|
||||
const SetProfilePictureActionButton({super.key, required this.asset, this.iconOnly = false, this.menuItem = false});
|
||||
|
||||
void _onTap(BuildContext context) {
|
||||
Future<void> _onTap(BuildContext context) async {
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.pushRoute(ProfilePictureCropRoute(asset: asset));
|
||||
await context.pushRoute(ProfilePictureCropRoute(asset: asset));
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -28,7 +30,7 @@ class SetProfilePictureActionButton extends ConsumerWidget {
|
||||
label: "set_as_profile_picture".t(context: context),
|
||||
iconOnly: iconOnly,
|
||||
menuItem: menuItem,
|
||||
onPressed: () => _onTap(context),
|
||||
onPressed: () => unawaited(_onTap(context)),
|
||||
maxWidth: 100,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -138,31 +138,33 @@ class ShareActionButton extends ConsumerWidget {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext buildContext) {
|
||||
ref
|
||||
.read(actionProvider.notifier)
|
||||
.shareAssets(
|
||||
source,
|
||||
context,
|
||||
fileType: fileType,
|
||||
cancelCompleter: cancelCompleter,
|
||||
onAssetDownloadProgress: (value) => progress.value = value,
|
||||
)
|
||||
.then((ActionResult result) {
|
||||
if (cancelCompleter.isCompleted || !context.mounted) {
|
||||
return;
|
||||
}
|
||||
unawaited(
|
||||
ref
|
||||
.read(actionProvider.notifier)
|
||||
.shareAssets(
|
||||
source,
|
||||
context,
|
||||
fileType: fileType,
|
||||
cancelCompleter: cancelCompleter,
|
||||
onAssetDownloadProgress: (value) => progress.value = value,
|
||||
)
|
||||
.then((ActionResult result) {
|
||||
if (cancelCompleter.isCompleted || !context.mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!result.success) {
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
msg: context.t.scaffold_body_error_occurred,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
toastType: ToastType.error,
|
||||
);
|
||||
}
|
||||
if (!result.success) {
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
msg: context.t.scaffold_body_error_occurred,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
toastType: ToastType.error,
|
||||
);
|
||||
}
|
||||
|
||||
buildContext.pop();
|
||||
});
|
||||
buildContext.pop();
|
||||
}),
|
||||
);
|
||||
|
||||
return preparingDialog;
|
||||
},
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -12,12 +14,12 @@ class SlideshowActionButton extends ConsumerWidget {
|
||||
|
||||
const SlideshowActionButton({super.key, this.iconOnly = false, this.menuItem = false});
|
||||
|
||||
void _onTap(BuildContext context, WidgetRef ref) {
|
||||
Future<void> _onTap(BuildContext context, WidgetRef ref) async {
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.pushRoute(DriftSlideshowRoute(timeline: ref.read(timelineServiceProvider)));
|
||||
await context.pushRoute(DriftSlideshowRoute(timeline: ref.read(timelineServiceProvider)));
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -27,7 +29,7 @@ class SlideshowActionButton extends ConsumerWidget {
|
||||
label: "slideshow".t(context: context),
|
||||
iconOnly: iconOnly,
|
||||
menuItem: menuItem,
|
||||
onPressed: () => _onTap(context, ref),
|
||||
onPressed: () => unawaited(_onTap(context, ref)),
|
||||
maxWidth: 100,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
|
||||
isGrid = albumConfig.isGrid;
|
||||
});
|
||||
|
||||
ref.read(remoteAlbumProvider.notifier).refresh();
|
||||
unawaited(ref.read(remoteAlbumProvider.notifier).refresh());
|
||||
});
|
||||
|
||||
searchController.addListener(() {
|
||||
@@ -81,7 +81,7 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
|
||||
final userId = ref.read(currentUserProvider)?.id;
|
||||
filter = filter.copyWith(query: searchTerm, userId: userId, mode: filterMode);
|
||||
|
||||
filterAlbums();
|
||||
unawaited(filterAlbums());
|
||||
}
|
||||
|
||||
Future<void> onRefresh() async {
|
||||
@@ -92,7 +92,7 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
|
||||
setState(() {
|
||||
isGrid = !isGrid;
|
||||
});
|
||||
ref.read(settingsProvider).write(.albumIsGrid, isGrid);
|
||||
unawaited(ref.read(settingsProvider).write(.albumIsGrid, isGrid));
|
||||
}
|
||||
|
||||
void changeFilter(QuickFilterMode mode) {
|
||||
@@ -100,7 +100,7 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
|
||||
filter = filter.copyWith(mode: mode);
|
||||
});
|
||||
|
||||
filterAlbums();
|
||||
unawaited(filterAlbums());
|
||||
}
|
||||
|
||||
Future<void> changeSort(AlbumSort sort) async {
|
||||
@@ -121,7 +121,7 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
|
||||
searchController.clear();
|
||||
});
|
||||
|
||||
filterAlbums();
|
||||
unawaited(filterAlbums());
|
||||
}
|
||||
|
||||
Future<void> sortAlbums() async {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
@@ -45,8 +47,8 @@ class PendingUploadsBanner extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
static void _openSheet(BuildContext context, String albumId) {
|
||||
showModalBottomSheet(
|
||||
static Future<void> _openSheet(BuildContext context, String albumId) {
|
||||
return showModalBottomSheet(
|
||||
context: context,
|
||||
showDragHandle: true,
|
||||
builder: (_) => _PendingUploadsSheet(albumId: albumId),
|
||||
@@ -97,7 +99,7 @@ class _PendingUploadsBannerContent extends StatelessWidget {
|
||||
return Material(
|
||||
color: hasFailures ? context.colorScheme.errorContainer : context.colorScheme.surfaceContainerHigh,
|
||||
child: InkWell(
|
||||
onTap: () => PendingUploadsBanner._openSheet(context, albumId),
|
||||
onTap: () => unawaited(PendingUploadsBanner._openSheet(context, albumId)),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
|
||||
+3
-1
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/constants/enums.dart';
|
||||
@@ -48,7 +50,7 @@ class _LocationDetailsState extends ConsumerState<LocationDetails> {
|
||||
if (widget.exifInfo != oldWidget.exifInfo) {
|
||||
final exif = widget.exifInfo;
|
||||
if (exif != null && exif.hasCoordinates) {
|
||||
_mapController?.moveCamera(CameraUpdate.newLatLng(LatLng(exif.latitude!, exif.longitude!)));
|
||||
unawaited(_mapController?.moveCamera(CameraUpdate.newLatLng(LatLng(exif.latitude!, exif.longitude!))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -74,7 +76,7 @@ class PeopleDetails extends ConsumerWidget {
|
||||
return;
|
||||
}
|
||||
ContextHelper(context).pop();
|
||||
context.pushRoute(DriftPersonRoute(person: person));
|
||||
unawaited(context.pushRoute(DriftPersonRoute(person: person)));
|
||||
},
|
||||
onNameTap: () => showNameEditModal(person),
|
||||
),
|
||||
|
||||
@@ -87,8 +87,8 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
_scaleBoundarySub?.cancel();
|
||||
_eventSubscription?.cancel();
|
||||
unawaited(_scaleBoundarySub?.cancel());
|
||||
unawaited(_eventSubscription?.cancel());
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
||||
return;
|
||||
}
|
||||
_viewer.setShowingDetails(true);
|
||||
_scrollController.animateTo(_snapOffset, duration: Durations.medium2, curve: Curves.easeOutCubic);
|
||||
unawaited(_scrollController.animateTo(_snapOffset, duration: Durations.medium2, curve: Curves.easeOutCubic));
|
||||
}
|
||||
|
||||
bool _willClose(double scrollVelocity) =>
|
||||
@@ -199,7 +199,7 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
||||
case _DragIntent.dismiss:
|
||||
const popThreshold = 75.0;
|
||||
if (details.localPosition.dy - start!.localPosition.dy > popThreshold) {
|
||||
context.maybePop();
|
||||
unawaited(context.maybePop());
|
||||
return;
|
||||
}
|
||||
_viewController?.animateMultiple(
|
||||
@@ -292,14 +292,14 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
||||
}
|
||||
|
||||
void _listenForScaleBoundaries(PhotoViewControllerBase? controller) {
|
||||
_scaleBoundarySub?.cancel();
|
||||
unawaited(_scaleBoundarySub?.cancel());
|
||||
_scaleBoundarySub = null;
|
||||
if (controller == null || controller.scaleBoundaries != null) {
|
||||
return;
|
||||
}
|
||||
_scaleBoundarySub = controller.outputStateStream.listen((_) {
|
||||
if (controller.scaleBoundaries != null) {
|
||||
_scaleBoundarySub?.cancel();
|
||||
unawaited(_scaleBoundarySub?.cancel());
|
||||
_scaleBoundarySub = null;
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
|
||||
@@ -107,7 +107,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
||||
final maxPage = _totalAssets - 1;
|
||||
if (target >= 0 && target <= maxPage) {
|
||||
_pageController.jumpToPage(target);
|
||||
_onAssetChanged(target);
|
||||
unawaited(_onAssetChanged(target));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,14 +126,14 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
||||
WidgetsBinding.instance.addPostFrameCallback(_onAssetInit);
|
||||
|
||||
final assetViewer = ref.read(assetViewerProvider);
|
||||
_setSystemUIMode(assetViewer.showingControls, assetViewer.showingDetails);
|
||||
unawaited(_setSystemUIMode(assetViewer.showingControls, assetViewer.showingDetails));
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pageController.dispose();
|
||||
_preloader.dispose();
|
||||
_reloadSubscription?.cancel();
|
||||
unawaited(_reloadSubscription?.cancel());
|
||||
_stackChildrenKeepAlive?.close();
|
||||
|
||||
unawaited(restoreEdgeToEdge());
|
||||
@@ -157,7 +157,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
||||
|
||||
final page = _pageController.page?.round();
|
||||
if (page != null && page != _currentPage) {
|
||||
_onAssetChanged(page);
|
||||
unawaited(_onAssetChanged(page));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
||||
case ViewerReloadAssetEvent():
|
||||
_onViewerReloadEvent();
|
||||
case final ViewerStackAssetDeletedEvent event:
|
||||
_onViewerStackAssetDeletedEvent(event);
|
||||
unawaited(_onViewerStackAssetDeletedEvent(event));
|
||||
default:
|
||||
}
|
||||
}
|
||||
@@ -235,8 +235,8 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
||||
|
||||
final index = _pageController.page?.round() ?? 0;
|
||||
final target = index >= _totalAssets - 1 ? index - 1 : index + 1;
|
||||
_pageController.animateToPage(target, duration: Durations.medium1, curve: Curves.easeInOut);
|
||||
_onAssetChanged(target);
|
||||
unawaited(_pageController.animateToPage(target, duration: Durations.medium1, curve: Curves.easeInOut));
|
||||
unawaited(_onAssetChanged(target));
|
||||
}
|
||||
|
||||
Future<void> _onViewerStackAssetDeletedEvent(ViewerStackAssetDeletedEvent event) async {
|
||||
@@ -271,7 +271,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
||||
final totalAssets = timelineService.totalAssets;
|
||||
|
||||
if (totalAssets == 0) {
|
||||
context.maybePop();
|
||||
unawaited(context.maybePop());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -281,14 +281,14 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
||||
|
||||
if (index != _currentPage) {
|
||||
_pageController.jumpToPage(index);
|
||||
_onAssetChanged(index);
|
||||
unawaited(_onAssetChanged(index));
|
||||
} else if (currentAsset is RemoteAsset && currentAsset.stackId != null && assetIndex == null) {
|
||||
final timelineAsset = timelineService.getAssetSafe(index);
|
||||
if (timelineAsset is! RemoteAsset || currentAsset.stackId != timelineAsset.stackId) {
|
||||
_onAssetChanged(index);
|
||||
unawaited(_onAssetChanged(index));
|
||||
}
|
||||
} else if (currentAsset != null && assetIndex == null) {
|
||||
_onAssetChanged(index);
|
||||
unawaited(_onAssetChanged(index));
|
||||
}
|
||||
|
||||
if (_totalAssets != totalAssets) {
|
||||
@@ -298,9 +298,9 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
||||
}
|
||||
}
|
||||
|
||||
void _setSystemUIMode(bool controls, bool details) {
|
||||
Future<void> _setSystemUIMode(bool controls, bool details) {
|
||||
final immersive = !controls || (CurrentPlatform.isIOS && details);
|
||||
unawaited(immersive ? SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky) : restoreEdgeToEdge());
|
||||
return immersive ? SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky) : restoreEdgeToEdge();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -324,7 +324,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
||||
|
||||
ref.listen(assetViewerProvider.select((value) => (value.showingControls, value.showingDetails)), (_, state) {
|
||||
final (controls, details) = state;
|
||||
_setSystemUIMode(controls, details);
|
||||
unawaited(_setSystemUIMode(controls, details));
|
||||
});
|
||||
|
||||
return AnnotatedRegion(
|
||||
|
||||
@@ -82,7 +82,7 @@ class _OcrOverlayState extends ConsumerState<OcrOverlay> {
|
||||
}
|
||||
|
||||
void _detachController() {
|
||||
_controllerSub?.cancel();
|
||||
unawaited(_controllerSub?.cancel());
|
||||
_controllerSub = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -26,7 +28,7 @@ class SheetTile extends ConsumerWidget {
|
||||
});
|
||||
|
||||
void copyTitle(BuildContext context, WidgetRef ref) {
|
||||
Clipboard.setData(ClipboardData(text: title));
|
||||
unawaited(Clipboard.setData(ClipboardData(text: title)));
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
msg: 'copied_to_clipboard'.t(context: context),
|
||||
|
||||
@@ -66,7 +66,7 @@ class _NativeVideoViewerState extends ConsumerState<NativeVideoViewer> with Widg
|
||||
|
||||
if (!widget.isCurrent) {
|
||||
_loadTimer?.cancel();
|
||||
_notifier.pause();
|
||||
unawaited(_notifier.pause());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ class _NativeVideoViewerState extends ConsumerState<NativeVideoViewer> with Widg
|
||||
_controller = nc;
|
||||
|
||||
if (widget.isCurrent) {
|
||||
_loadVideo();
|
||||
unawaited(_loadVideo());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -52,11 +54,13 @@ class ViewerTopAppBar extends ConsumerWidget implements PreferredSizeWidget {
|
||||
IconButton(
|
||||
icon: const Icon(Icons.chat_outlined),
|
||||
onPressed: () {
|
||||
context.router.push(
|
||||
DriftActivitiesRoute(
|
||||
album: album,
|
||||
assetId: asset is RemoteAsset ? asset.id : null,
|
||||
assetName: asset.name,
|
||||
unawaited(
|
||||
context.router.push(
|
||||
DriftActivitiesRoute(
|
||||
album: album,
|
||||
assetId: asset is RemoteAsset ? asset.id : null,
|
||||
assetName: asset.name,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
@@ -53,10 +55,12 @@ class _BaseDraggableScrollableSheetState extends ConsumerState<BaseBottomSheet>
|
||||
}
|
||||
|
||||
if (previous?.isInteracting != true && next.isInteracting) {
|
||||
_controller.animateTo(
|
||||
widget.minChildSize,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeInOut,
|
||||
unawaited(
|
||||
_controller.animateTo(
|
||||
widget.minChildSize,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeInOut,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@@ -60,7 +61,7 @@ class _FeatureMessageDialogState extends State<_FeatureMessageDialog> with Singl
|
||||
Navigator.of(context).pop();
|
||||
return;
|
||||
}
|
||||
_controller.nextPage(duration: const Duration(milliseconds: 320), curve: Curves.easeOutCubic);
|
||||
unawaited(_controller.nextPage(duration: const Duration(milliseconds: 320), curve: Curves.easeOutCubic));
|
||||
}
|
||||
|
||||
List<Color> _borderColors(BuildContext context) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
import 'package:immich_mobile/presentation/widgets/images/image_provider.dart';
|
||||
@@ -30,7 +32,7 @@ class FullImage extends StatelessWidget {
|
||||
height: size.height,
|
||||
fit: fit,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
provider.evict();
|
||||
unawaited(provider.evict());
|
||||
return const Icon(Icons.image_not_supported_outlined, size: 32);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
@@ -43,10 +44,12 @@ mixin CancellableImageProviderMixin<T extends Object> on CancellableImageProvide
|
||||
return cachedImage;
|
||||
}
|
||||
|
||||
completer.operation.valueOrCancellation().whenComplete(() {
|
||||
cachedStream.removeListener(listener);
|
||||
cachedOperation = null;
|
||||
});
|
||||
unawaited(
|
||||
completer.operation.valueOrCancellation().whenComplete(() {
|
||||
cachedStream.removeListener(listener);
|
||||
cachedOperation = null;
|
||||
}),
|
||||
);
|
||||
cachedOperation = completer.operation;
|
||||
return null;
|
||||
}
|
||||
@@ -138,7 +141,7 @@ mixin CancellableImageProviderMixin<T extends Object> on CancellableImageProvide
|
||||
final operation = cachedOperation;
|
||||
if (operation != null) {
|
||||
cachedOperation = null;
|
||||
operation.cancel();
|
||||
unawaited(operation.cancel());
|
||||
}
|
||||
|
||||
if (hasActiveWork) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -130,9 +131,9 @@ class _ThumbnailState extends State<Thumbnail> with SingleTickerProviderStateMix
|
||||
if ((synchronousCall && _providerImage == null) || !_isVisible()) {
|
||||
_fadeController.value = 1.0;
|
||||
} else if (_fadeController.isAnimating) {
|
||||
_fadeController.forward();
|
||||
unawaited(_fadeController.forward());
|
||||
} else {
|
||||
_fadeController.forward(from: 0.0);
|
||||
unawaited(_fadeController.forward(from: 0.0));
|
||||
}
|
||||
|
||||
setState(() {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/events.model.dart';
|
||||
@@ -87,32 +89,32 @@ class MapStateNotifier extends Notifier<MapState> {
|
||||
}
|
||||
|
||||
void switchFavoriteOnly(bool isFavoriteOnly) {
|
||||
ref.read(settingsProvider).write(.mapShowFavoriteOnly, isFavoriteOnly);
|
||||
unawaited(ref.read(settingsProvider).write(.mapShowFavoriteOnly, isFavoriteOnly));
|
||||
state = state.copyWith(onlyFavorites: isFavoriteOnly);
|
||||
EventStream.shared.emit(const MapMarkerReloadEvent());
|
||||
}
|
||||
|
||||
void switchIncludeArchived(bool isIncludeArchived) {
|
||||
ref.read(settingsProvider).write(.mapIncludeArchived, isIncludeArchived);
|
||||
unawaited(ref.read(settingsProvider).write(.mapIncludeArchived, isIncludeArchived));
|
||||
state = state.copyWith(includeArchived: isIncludeArchived);
|
||||
EventStream.shared.emit(const MapMarkerReloadEvent());
|
||||
}
|
||||
|
||||
void switchWithPartners(bool isWithPartners) {
|
||||
ref.read(settingsProvider).write(.mapWithPartners, isWithPartners);
|
||||
unawaited(ref.read(settingsProvider).write(.mapWithPartners, isWithPartners));
|
||||
state = state.copyWith(withPartners: isWithPartners);
|
||||
EventStream.shared.emit(const MapMarkerReloadEvent());
|
||||
}
|
||||
|
||||
void setRelativeTime(int relativeDays) {
|
||||
ref.read(settingsProvider).write(.mapRelativeDate, relativeDays);
|
||||
unawaited(ref.read(settingsProvider).write(.mapRelativeDate, relativeDays));
|
||||
state = state.copyWith(relativeDays: relativeDays);
|
||||
EventStream.shared.emit(const MapMarkerReloadEvent());
|
||||
}
|
||||
|
||||
void setCustomTimeRange(TimeRange range) {
|
||||
ref.read(settingsProvider).write(.mapCustomFrom, range.from);
|
||||
ref.read(settingsProvider).write(.mapCustomTo, range.to);
|
||||
unawaited(ref.read(settingsProvider).write(.mapCustomFrom, range.from));
|
||||
unawaited(ref.read(settingsProvider).write(.mapCustomTo, range.to));
|
||||
state = state.copyWith(timeRange: range);
|
||||
EventStream.shared.emit(const MapMarkerReloadEvent());
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class _DriftMapState extends ConsumerState<DriftMap> {
|
||||
void dispose() {
|
||||
_debouncer.dispose();
|
||||
bottomSheetOffset.dispose();
|
||||
_eventSubscription?.cancel();
|
||||
unawaited(_eventSubscription?.cancel());
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -33,7 +35,7 @@ class DriftMemoryLane extends ConsumerWidget {
|
||||
if (memories[index].assets.isNotEmpty) {
|
||||
DriftMemoryPage.setMemory(ref, memories[index]);
|
||||
}
|
||||
context.pushRoute(DriftMemoryRoute(memories: memories, memoryIndex: index));
|
||||
unawaited(context.pushRoute(DriftMemoryRoute(memories: memories, memoryIndex: index)));
|
||||
},
|
||||
children: memories
|
||||
.map((memory) => DriftMemoryCard(key: Key(memory.id), memory: memory))
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -105,7 +107,7 @@ class _BulkSelectIconButton extends ConsumerWidget {
|
||||
? const SizedBox.shrink()
|
||||
: IconButton(
|
||||
onPressed: () {
|
||||
ref.read(multiSelectProvider.notifier).toggleBucketSelection(assetOffset, bucket.assetCount);
|
||||
unawaited(ref.read(multiSelectProvider.notifier).toggleBucketSelection(assetOffset, bucket.assetCount));
|
||||
ref.read(hapticFeedbackProvider.notifier).heavyImpact();
|
||||
},
|
||||
icon: isAllSelected
|
||||
|
||||
@@ -152,7 +152,7 @@ class ScrubberState extends ConsumerState<Scrubber> with TickerProviderStateMixi
|
||||
void _resetThumbTimer() {
|
||||
_fadeOutTimer?.cancel();
|
||||
_fadeOutTimer = Timer(kTimelineScrubberFadeOutDuration, () {
|
||||
_thumbAnimationController.reverse();
|
||||
unawaited(_thumbAnimationController.reverse());
|
||||
_fadeOutTimer = null;
|
||||
});
|
||||
}
|
||||
@@ -177,10 +177,10 @@ class ScrubberState extends ConsumerState<Scrubber> with TickerProviderStateMixi
|
||||
if (notification is ScrollUpdateNotification) {
|
||||
_thumbTopOffset = _currentOffset;
|
||||
if (_labelAnimation.status != AnimationStatus.reverse) {
|
||||
_labelAnimationController.reverse();
|
||||
unawaited(_labelAnimationController.reverse());
|
||||
}
|
||||
if (_thumbAnimationController.status != AnimationStatus.forward) {
|
||||
_thumbAnimationController.forward();
|
||||
unawaited(_thumbAnimationController.forward());
|
||||
}
|
||||
}
|
||||
_resetThumbTimer();
|
||||
@@ -210,7 +210,7 @@ class ScrubberState extends ConsumerState<Scrubber> with TickerProviderStateMixi
|
||||
void _onDragStart(DragStartDetails _) {
|
||||
setState(() {
|
||||
_isDragging = true;
|
||||
_labelAnimationController.forward();
|
||||
unawaited(_labelAnimationController.forward());
|
||||
_fadeOutTimer?.cancel();
|
||||
_lastLabel = null;
|
||||
});
|
||||
@@ -226,7 +226,7 @@ class ScrubberState extends ConsumerState<Scrubber> with TickerProviderStateMixi
|
||||
}
|
||||
|
||||
if (_thumbAnimationController.status != AnimationStatus.forward) {
|
||||
_thumbAnimationController.forward();
|
||||
unawaited(_thumbAnimationController.forward());
|
||||
}
|
||||
|
||||
final dragPosition = _calculateDragPosition(details);
|
||||
@@ -344,7 +344,7 @@ class ScrubberState extends ConsumerState<Scrubber> with TickerProviderStateMixi
|
||||
}
|
||||
|
||||
void _onDragEnd(DragEndDetails _) {
|
||||
_labelAnimationController.reverse();
|
||||
unawaited(_labelAnimationController.reverse());
|
||||
setState(() {
|
||||
_isDragging = false;
|
||||
});
|
||||
|
||||
@@ -258,7 +258,7 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> with WidgetsBi
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
_scrollController.dispose();
|
||||
_eventSubscription?.cancel();
|
||||
unawaited(_eventSubscription?.cancel());
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -269,9 +269,11 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> with WidgetsBi
|
||||
|
||||
final timelineState = ref.read(timelineStateProvider.notifier);
|
||||
timelineState.setScrubbing(true);
|
||||
_scrollController
|
||||
.animateTo(0, duration: const Duration(milliseconds: 250), curve: Curves.easeInOut)
|
||||
.whenComplete(() => timelineState.setScrubbing(false));
|
||||
unawaited(
|
||||
_scrollController
|
||||
.animateTo(0, duration: const Duration(milliseconds: 250), curve: Curves.easeInOut)
|
||||
.whenComplete(() => timelineState.setScrubbing(false)),
|
||||
);
|
||||
}
|
||||
|
||||
void _scrollToDate(DateTime date) {
|
||||
@@ -303,13 +305,15 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> with WidgetsBi
|
||||
// Scroll to the segment with a small offset to show the header
|
||||
final targetOffset = fallbackSegment.startOffset - 50;
|
||||
timelineState.setScrubbing(true);
|
||||
_scrollController
|
||||
.animateTo(
|
||||
targetOffset.clamp(0.0, _scrollController.position.maxScrollExtent),
|
||||
duration: const Duration(milliseconds: 500),
|
||||
curve: Curves.easeInOut,
|
||||
)
|
||||
.whenComplete(() => timelineState.setScrubbing(false));
|
||||
unawaited(
|
||||
_scrollController
|
||||
.animateTo(
|
||||
targetOffset.clamp(0.0, _scrollController.position.maxScrollExtent),
|
||||
duration: const Duration(milliseconds: 500),
|
||||
curve: Curves.easeInOut,
|
||||
)
|
||||
.whenComplete(() => timelineState.setScrubbing(false)),
|
||||
);
|
||||
} else {
|
||||
timelineState.setScrubbing(false);
|
||||
}
|
||||
@@ -344,8 +348,8 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> with WidgetsBi
|
||||
});
|
||||
}
|
||||
|
||||
void _dragScroll(ScrollDirection direction) {
|
||||
_scrollController.animateTo(
|
||||
Future<void> _dragScroll(ScrollDirection direction) {
|
||||
return _scrollController.animateTo(
|
||||
_scrollController.offset + (direction == ScrollDirection.forward ? 175 : -175),
|
||||
duration: const Duration(milliseconds: 125),
|
||||
curve: Curves.easeOut,
|
||||
@@ -488,7 +492,7 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> with WidgetsBi
|
||||
_restoreAssetIndex = targetAssetIndex;
|
||||
});
|
||||
|
||||
ref.read(settingsProvider).write(.timelineTilesPerRow, _perRow);
|
||||
unawaited(ref.read(settingsProvider).write(.timelineTilesPerRow, _perRow));
|
||||
}
|
||||
};
|
||||
},
|
||||
@@ -498,7 +502,7 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> with WidgetsBi
|
||||
onStart: !isReadonlyModeEnabled ? _setDragStartIndex : null,
|
||||
onAssetEnter: _handleDragAssetEnter,
|
||||
onEnd: !isReadonlyModeEnabled ? _stopDrag : null,
|
||||
onScroll: _dragScroll,
|
||||
onScroll: (direction) => unawaited(_dragScroll(direction)),
|
||||
onScrollStart: () {
|
||||
// Minimize the bottom sheet when drag selection starts
|
||||
ref.read(timelineStateProvider.notifier).setScrolling(true);
|
||||
|
||||
@@ -120,7 +120,7 @@ class AppLifeCycleNotifier extends StateNotifier<AppLifeCycleEnum> {
|
||||
if (syncSuccess) {
|
||||
await Future.wait([
|
||||
_safeRun(backgroundManager.hashAssets(), "hashAssets").then((_) {
|
||||
_resumeBackup();
|
||||
unawaited(_resumeBackup());
|
||||
}),
|
||||
_resumeBackup(),
|
||||
// TODO: Bring back when the soft freeze issue is addressed
|
||||
|
||||
@@ -88,7 +88,7 @@ class AssetViewerStateNotifier extends Notifier<AssetViewerState> {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
_assetSubscription?.cancel();
|
||||
unawaited(_assetSubscription?.cancel());
|
||||
_assetSubscription = null;
|
||||
state = const AssetViewerState();
|
||||
}
|
||||
@@ -102,7 +102,7 @@ class AssetViewerStateNotifier extends Notifier<AssetViewerState> {
|
||||
}
|
||||
|
||||
void _watchCurrentAsset(BaseAsset asset) {
|
||||
_assetSubscription?.cancel();
|
||||
unawaited(_assetSubscription?.cancel());
|
||||
_assetSubscription = ref.read(assetServiceProvider).watchAsset(asset).listen((updated) {
|
||||
if (updated != null) {
|
||||
state = state.copyWith(currentAsset: updated);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -33,7 +34,7 @@ class ShareIntentUploadStateNotifier extends StateNotifier<List<ShareIntentAttac
|
||||
router.removeWhere((route) => route.name == "ShareIntentRoute");
|
||||
clearAttachments();
|
||||
addAttachments(attachments);
|
||||
router.push(ShareIntentRoute(attachments: attachments));
|
||||
unawaited(router.push(ShareIntentRoute(attachments: attachments)));
|
||||
}
|
||||
|
||||
void addAttachments(List<ShareIntentAttachment> attachments) {
|
||||
|
||||
@@ -50,7 +50,7 @@ class VideoPlayerNotifier extends StateNotifier<VideoPlayerState> {
|
||||
void dispose() {
|
||||
_bufferingTimer?.cancel();
|
||||
_seekTimer?.cancel();
|
||||
WakelockPlus.disable();
|
||||
unawaited(WakelockPlus.disable());
|
||||
_controller = null;
|
||||
|
||||
super.dispose();
|
||||
@@ -121,7 +121,7 @@ class VideoPlayerNotifier extends StateNotifier<VideoPlayerState> {
|
||||
}
|
||||
|
||||
_seekTimer = Timer(const Duration(milliseconds: 150), () {
|
||||
_controller?.seekTo(state.position.inMilliseconds);
|
||||
unawaited(_controller?.seekTo(state.position.inMilliseconds));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -130,11 +130,11 @@ class VideoPlayerNotifier extends StateNotifier<VideoPlayerState> {
|
||||
|
||||
switch (state.status) {
|
||||
case VideoPlaybackStatus.paused:
|
||||
play();
|
||||
unawaited(play());
|
||||
case VideoPlaybackStatus.playing || VideoPlaybackStatus.buffering:
|
||||
pause();
|
||||
unawaited(pause());
|
||||
case VideoPlaybackStatus.completed:
|
||||
restart();
|
||||
unawaited(restart());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ class VideoPlayerNotifier extends StateNotifier<VideoPlayerState> {
|
||||
}
|
||||
|
||||
_holdStatus = state.status;
|
||||
pause();
|
||||
unawaited(pause());
|
||||
}
|
||||
|
||||
/// Restores playback to the status before [hold] was called.
|
||||
@@ -155,7 +155,7 @@ class VideoPlayerNotifier extends StateNotifier<VideoPlayerState> {
|
||||
|
||||
switch (status) {
|
||||
case VideoPlaybackStatus.playing || VideoPlaybackStatus.buffering:
|
||||
play();
|
||||
unawaited(play());
|
||||
default:
|
||||
}
|
||||
}
|
||||
@@ -238,7 +238,7 @@ class VideoPlayerNotifier extends StateNotifier<VideoPlayerState> {
|
||||
final newStatus = _mapStatus(playbackInfo.status);
|
||||
switch (newStatus) {
|
||||
case VideoPlaybackStatus.playing:
|
||||
WakelockPlus.enable();
|
||||
unawaited(WakelockPlus.enable());
|
||||
_startBufferingTimer();
|
||||
default:
|
||||
onNativePlaybackEnded();
|
||||
@@ -250,7 +250,7 @@ class VideoPlayerNotifier extends StateNotifier<VideoPlayerState> {
|
||||
}
|
||||
|
||||
void onNativePlaybackEnded() {
|
||||
WakelockPlus.disable();
|
||||
unawaited(WakelockPlus.disable());
|
||||
_bufferingTimer?.cancel();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
||||
import 'package:immich_mobile/domain/services/local_album.service.dart';
|
||||
@@ -10,7 +12,7 @@ final backupAlbumProvider = StateNotifierProvider<BackupAlbumNotifier, List<Loca
|
||||
|
||||
class BackupAlbumNotifier extends StateNotifier<List<LocalAlbum>> {
|
||||
BackupAlbumNotifier(this._localAlbumService) : super([]) {
|
||||
getAll();
|
||||
unawaited(getAll());
|
||||
}
|
||||
|
||||
final LocalAlbumService _localAlbumService;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
import 'package:immich_mobile/models/cast/cast_manager_state.dart';
|
||||
@@ -51,7 +53,7 @@ class CastNotifier extends StateNotifier<CastManagerState> {
|
||||
}
|
||||
|
||||
void loadMedia(RemoteAsset asset, bool reload) {
|
||||
_gCastService.loadMedia(asset, reload);
|
||||
unawaited(_gCastService.loadMedia(asset, reload));
|
||||
}
|
||||
|
||||
Future<void> connect(CastDestinationType type, dynamic device) async {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/constants/enums.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
@@ -87,18 +89,18 @@ class CleanupNotifier extends StateNotifier<CleanupState> {
|
||||
state = state.copyWith(selectedDate: date, assetsToDelete: []);
|
||||
if (date != null) {
|
||||
final daysAgo = DateTime.now().difference(date).inDays;
|
||||
_settingsRepository.write(.cleanupCutoffDaysAgo, daysAgo);
|
||||
unawaited(_settingsRepository.write(.cleanupCutoffDaysAgo, daysAgo));
|
||||
}
|
||||
}
|
||||
|
||||
void setKeepMediaType(AssetKeepType keepMediaType) {
|
||||
state = state.copyWith(keepMediaType: keepMediaType, assetsToDelete: []);
|
||||
_settingsRepository.write(.cleanupKeepMediaType, keepMediaType);
|
||||
unawaited(_settingsRepository.write(.cleanupKeepMediaType, keepMediaType));
|
||||
}
|
||||
|
||||
void setKeepFavorites(bool keepFavorites) {
|
||||
state = state.copyWith(keepFavorites: keepFavorites, assetsToDelete: []);
|
||||
_settingsRepository.write(.cleanupKeepFavorites, keepFavorites);
|
||||
unawaited(_settingsRepository.write(.cleanupKeepFavorites, keepFavorites));
|
||||
}
|
||||
|
||||
void toggleKeepAlbum(String albumId) {
|
||||
@@ -118,7 +120,7 @@ class CleanupNotifier extends StateNotifier<CleanupState> {
|
||||
}
|
||||
|
||||
void _persistExcludedAlbumIds(Set<String> albumIds) {
|
||||
_settingsRepository.write(.cleanupKeepAlbumIds, albumIds.toList());
|
||||
unawaited(_settingsRepository.write(.cleanupKeepAlbumIds, albumIds.toList()));
|
||||
}
|
||||
|
||||
void cleanupStaleAlbumIds(Set<String> existingAlbumIds) {
|
||||
@@ -144,7 +146,7 @@ class CleanupNotifier extends StateNotifier<CleanupState> {
|
||||
_persistExcludedAlbumIds(keepAlbumIds);
|
||||
}
|
||||
|
||||
_settingsRepository.write(.cleanupDefaultsInitialized, true);
|
||||
unawaited(_settingsRepository.write(.cleanupDefaultsInitialized, true));
|
||||
}
|
||||
|
||||
Future<void> scanAssets() async {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
@@ -9,7 +10,7 @@ class GalleryPermissionNotifier extends StateNotifier<PermissionStatus> {
|
||||
: super(PermissionStatus.denied) // Denied is the initial state
|
||||
{
|
||||
// Sets the initial state
|
||||
getGalleryPermissionStatus();
|
||||
unawaited(getGalleryPermissionStatus());
|
||||
}
|
||||
|
||||
bool get hasPermission => state.isGranted || state.isLimited;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
||||
@@ -15,31 +17,31 @@ class HapticNotifier extends StateNotifier<void> {
|
||||
|
||||
void selectionClick() {
|
||||
if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
HapticFeedback.selectionClick();
|
||||
unawaited(HapticFeedback.selectionClick());
|
||||
}
|
||||
}
|
||||
|
||||
void lightImpact() {
|
||||
if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
HapticFeedback.lightImpact();
|
||||
unawaited(HapticFeedback.lightImpact());
|
||||
}
|
||||
}
|
||||
|
||||
void mediumImpact() {
|
||||
if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
HapticFeedback.mediumImpact();
|
||||
unawaited(HapticFeedback.mediumImpact());
|
||||
}
|
||||
}
|
||||
|
||||
void heavyImpact() {
|
||||
if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
HapticFeedback.heavyImpact();
|
||||
unawaited(HapticFeedback.heavyImpact());
|
||||
}
|
||||
}
|
||||
|
||||
void vibrate() {
|
||||
if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
HapticFeedback.vibrate();
|
||||
unawaited(HapticFeedback.vibrate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
||||
import 'package:immich_mobile/providers/auth.provider.dart';
|
||||
@@ -16,11 +18,11 @@ class ReadOnlyModeNotifier extends Notifier<bool> {
|
||||
|
||||
void setMode(bool value) {
|
||||
final isLoggedIn = ref.read(authProvider).isAuthenticated;
|
||||
_appSettingService.setSetting(AppSettingsEnum.readonlyModeEnabled, value);
|
||||
unawaited(_appSettingService.setSetting(AppSettingsEnum.readonlyModeEnabled, value));
|
||||
state = value;
|
||||
|
||||
if (value && isLoggedIn) {
|
||||
ref.read(appRouterProvider).navigate(const MainTimelineRoute());
|
||||
unawaited(ref.read(appRouterProvider).navigate(const MainTimelineRoute()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@@ -21,9 +23,11 @@ class LocalAuthNotifier extends StateNotifier<BiometricStatus> {
|
||||
|
||||
LocalAuthNotifier(this._localAuthService, this._secureStorageService)
|
||||
: super(const BiometricStatus(availableBiometrics: [], canAuthenticate: false)) {
|
||||
_localAuthService.getStatus().then((value) {
|
||||
state = state.copyWith(canAuthenticate: value.canAuthenticate, availableBiometrics: value.availableBiometrics);
|
||||
});
|
||||
unawaited(
|
||||
_localAuthService.getStatus().then((value) {
|
||||
state = state.copyWith(canAuthenticate: value.canAuthenticate, availableBiometrics: value.availableBiometrics);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool> registerBiometric(BuildContext context, String pinCode) async {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/models/map/map_state.model.dart';
|
||||
@@ -26,12 +28,12 @@ class MapStateNotifier extends Notifier<MapState> {
|
||||
}
|
||||
|
||||
void switchTheme(ThemeMode mode) {
|
||||
ref.read(settingsProvider).write(.mapThemeMode, mode);
|
||||
unawaited(ref.read(settingsProvider).write(.mapThemeMode, mode));
|
||||
state = state.copyWith(themeMode: mode);
|
||||
}
|
||||
|
||||
void switchFavoriteOnly(bool isFavoriteOnly) {
|
||||
ref.read(settingsProvider).write(.mapShowFavoriteOnly, isFavoriteOnly);
|
||||
unawaited(ref.read(settingsProvider).write(.mapShowFavoriteOnly, isFavoriteOnly));
|
||||
state = state.copyWith(showFavoriteOnly: isFavoriteOnly, shouldRefetchMarkers: true);
|
||||
}
|
||||
|
||||
@@ -40,17 +42,17 @@ class MapStateNotifier extends Notifier<MapState> {
|
||||
}
|
||||
|
||||
void switchIncludeArchived(bool isIncludeArchived) {
|
||||
ref.read(settingsProvider).write(.mapIncludeArchived, isIncludeArchived);
|
||||
unawaited(ref.read(settingsProvider).write(.mapIncludeArchived, isIncludeArchived));
|
||||
state = state.copyWith(includeArchived: isIncludeArchived, shouldRefetchMarkers: true);
|
||||
}
|
||||
|
||||
void switchWithPartners(bool isWithPartners) {
|
||||
ref.read(settingsProvider).write(.mapWithPartners, isWithPartners);
|
||||
unawaited(ref.read(settingsProvider).write(.mapWithPartners, isWithPartners));
|
||||
state = state.copyWith(withPartners: isWithPartners, shouldRefetchMarkers: true);
|
||||
}
|
||||
|
||||
void setRelativeTime(int relativeTime) {
|
||||
ref.read(settingsProvider).write(.mapRelativeDate, relativeTime);
|
||||
unawaited(ref.read(settingsProvider).write(.mapRelativeDate, relativeTime));
|
||||
state = state.copyWith(relativeTime: relativeTime, shouldRefetchMarkers: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ class NotificationPermissionNotifier extends StateNotifier<PermissionStatus> {
|
||||
NotificationPermissionNotifier()
|
||||
: super(Platform.isAndroid ? PermissionStatus.granted : PermissionStatus.restricted) {
|
||||
// Sets the initial state
|
||||
getNotificationPermission().then((p) => state = p);
|
||||
unawaited(getNotificationPermission().then((p) => state = p));
|
||||
}
|
||||
|
||||
/// Requests the notification permission
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||
import 'package:immich_mobile/models/server_info/server_config.model.dart';
|
||||
@@ -77,7 +79,7 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
|
||||
|
||||
void handleReleaseInfo(ServerVersion serverVersion, ServerVersion? latestVersion) {
|
||||
// Update local server version
|
||||
_checkServerVersionMismatch(serverVersion, latestVersion: latestVersion);
|
||||
unawaited(_checkServerVersionMismatch(serverVersion, latestVersion: latestVersion));
|
||||
}
|
||||
|
||||
Future<void> getServerFeatures() async {
|
||||
|
||||
@@ -8,7 +8,7 @@ class SharedLinksNotifier extends StateNotifier<AsyncValue<List<SharedLink>>> {
|
||||
final SharedLinkService _sharedLinkService;
|
||||
|
||||
SharedLinksNotifier(this._sharedLinkService) : super(const AsyncLoading()) {
|
||||
fetchLinks();
|
||||
unawaited(fetchLinks());
|
||||
}
|
||||
|
||||
Future<void> fetchLinks() async {
|
||||
|
||||
@@ -22,7 +22,7 @@ class CurrentUserProvider extends StateNotifier<UserDto?> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
streamSub.cancel();
|
||||
unawaited(streamSub.cancel());
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,8 +143,8 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
}
|
||||
|
||||
void _handleOnConfigUpdate(dynamic _) {
|
||||
_ref.read(serverInfoProvider.notifier).getServerFeatures();
|
||||
_ref.read(serverInfoProvider.notifier).getServerConfig();
|
||||
unawaited(_ref.read(serverInfoProvider.notifier).getServerFeatures());
|
||||
unawaited(_ref.read(serverInfoProvider.notifier).getServerConfig());
|
||||
}
|
||||
|
||||
void _handleReleaseUpdates(dynamic data) {
|
||||
@@ -203,7 +203,7 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
unawaited(
|
||||
_ref.read(backgroundSyncProvider).syncWebsocketBatchV1(_batchedAssetUploadReady.toList()).then((_) {
|
||||
if (isSyncAlbumEnabled) {
|
||||
_ref.read(backgroundSyncProvider).syncLinkedAlbum();
|
||||
unawaited(_ref.read(backgroundSyncProvider).syncLinkedAlbum());
|
||||
}
|
||||
}),
|
||||
);
|
||||
@@ -224,7 +224,7 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
unawaited(
|
||||
_ref.read(backgroundSyncProvider).syncWebsocketBatchV2(_batchedAssetUploadReady.toList()).then((_) {
|
||||
if (isSyncAlbumEnabled) {
|
||||
_ref.read(backgroundSyncProvider).syncLinkedAlbum();
|
||||
unawaited(_ref.read(backgroundSyncProvider).syncLinkedAlbum());
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -13,10 +13,12 @@ class AppNavigationObserver extends AutoRouterObserver {
|
||||
|
||||
@override
|
||||
void didPush(Route route, Route? previousRoute) {
|
||||
Future(() {
|
||||
ref.read(currentRouteNameProvider.notifier).state = route.settings.name;
|
||||
ref.read(previousRouteNameProvider.notifier).state = previousRoute?.settings.name;
|
||||
ref.read(previousRouteDataProvider.notifier).state = previousRoute?.settings;
|
||||
});
|
||||
unawaited(
|
||||
Future(() {
|
||||
ref.read(currentRouteNameProvider.notifier).state = route.settings.name;
|
||||
ref.read(previousRouteNameProvider.notifier).state = previousRoute?.settings.name;
|
||||
ref.read(previousRouteDataProvider.notifier).state = previousRoute?.settings;
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,12 +135,12 @@ class BackgroundUploadService {
|
||||
if (!_taskStatusController.isClosed) {
|
||||
_taskStatusController.add(update);
|
||||
}
|
||||
_handleTaskStatusUpdate(update);
|
||||
unawaited(_handleTaskStatusUpdate(update));
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
_taskStatusController.close();
|
||||
_taskProgressController.close();
|
||||
unawaited(_taskStatusController.close());
|
||||
unawaited(_taskProgressController.close());
|
||||
}
|
||||
|
||||
/// Enqueue tasks to the background upload queue
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:immich_mobile/mixins/error_logger.mixin.dart';
|
||||
import 'package:immich_mobile/models/map/map_marker.model.dart';
|
||||
import 'package:immich_mobile/services/api.service.dart';
|
||||
@@ -11,7 +13,7 @@ class MapService with ErrorLoggerMixin {
|
||||
final logger = Logger("MapService");
|
||||
|
||||
MapService(this._apiService) {
|
||||
_setMapUserAgentHeader();
|
||||
unawaited(_setMapUserAgentHeader());
|
||||
}
|
||||
|
||||
Future<void> _setMapUserAgentHeader() async {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/models/upload/share_intent_attachment.model.dart';
|
||||
import 'package:immich_mobile/repositories/share_handler.repository.dart';
|
||||
@@ -12,6 +14,6 @@ class ShareIntentService {
|
||||
|
||||
void init() {
|
||||
shareHandlerRepository.onSharedMedia = onSharedMedia;
|
||||
shareHandlerRepository.init();
|
||||
unawaited(shareHandlerRepository.init());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,12 @@ class AsyncMutex {
|
||||
Future<T> run<T>(Future<T> Function() operation) {
|
||||
final completer = Completer<T>();
|
||||
_enqueued++;
|
||||
_running.whenComplete(() {
|
||||
_enqueued--;
|
||||
completer.complete(Future<T>.sync(operation));
|
||||
});
|
||||
unawaited(
|
||||
_running.whenComplete(() {
|
||||
_enqueued--;
|
||||
completer.complete(Future<T>.sync(operation));
|
||||
}),
|
||||
);
|
||||
return _running = completer.future;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
|
||||
import 'package:immich_mobile/entities/store.entity.dart';
|
||||
@@ -7,7 +9,7 @@ ValueNotifier<T> useAppSettingsState<T>(AppSettingsEnum<T> key) {
|
||||
final notifier = useState<T>(Store.get(key.storeKey, key.defaultValue));
|
||||
|
||||
// Listen to changes to the notifier and update app settings
|
||||
useValueChanged(notifier.value, (_, __) => Store.put(key.storeKey, notifier.value));
|
||||
useValueChanged(notifier.value, (_, __) => unawaited(Store.put(key.storeKey, notifier.value)));
|
||||
|
||||
return notifier;
|
||||
}
|
||||
|
||||
@@ -15,13 +15,15 @@ Future<Uint8List> imageToUint8List(Image image) async {
|
||||
.resolve(ImageConfiguration.empty)
|
||||
.addListener(
|
||||
ImageStreamListener((ImageInfo info, bool _) {
|
||||
info.image.toByteData(format: ImageByteFormat.png).then((byteData) {
|
||||
if (byteData != null) {
|
||||
completer.complete(byteData.buffer.asUint8List());
|
||||
} else {
|
||||
completer.completeError('Failed to convert image to bytes');
|
||||
}
|
||||
});
|
||||
unawaited(
|
||||
info.image.toByteData(format: ImageByteFormat.png).then((byteData) {
|
||||
if (byteData != null) {
|
||||
completer.complete(byteData.buffer.asUint8List());
|
||||
} else {
|
||||
completer.completeError('Failed to convert image to bytes');
|
||||
}
|
||||
}),
|
||||
);
|
||||
}, onError: (exception, stackTrace) => completer.completeError(exception)),
|
||||
);
|
||||
return completer.future;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -27,9 +28,9 @@ class AnimatedPlayPauseState extends State<AnimatedPlayPause> with SingleTickerP
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.playing != oldWidget.playing) {
|
||||
if (widget.playing) {
|
||||
animationController.forward();
|
||||
unawaited(animationController.forward());
|
||||
} else {
|
||||
animationController.reverse();
|
||||
unawaited(animationController.reverse());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
@@ -54,7 +56,7 @@ class DriftAlbumInfoListTile extends HookConsumerWidget {
|
||||
ref.watch(hapticFeedbackProvider.notifier).selectionClick();
|
||||
|
||||
if (isExcluded) {
|
||||
ref.read(backupAlbumProvider.notifier).deselectAlbum(album);
|
||||
unawaited(ref.read(backupAlbumProvider.notifier).deselectAlbum(album));
|
||||
} else {
|
||||
if (album.id == 'isAll' || album.name == 'Recents') {
|
||||
ImmichToast.show(
|
||||
@@ -66,7 +68,7 @@ class DriftAlbumInfoListTile extends HookConsumerWidget {
|
||||
return;
|
||||
}
|
||||
|
||||
ref.read(backupAlbumProvider.notifier).excludeAlbum(album);
|
||||
unawaited(ref.read(backupAlbumProvider.notifier).excludeAlbum(album));
|
||||
}
|
||||
},
|
||||
child: ListTile(
|
||||
@@ -75,9 +77,9 @@ class DriftAlbumInfoListTile extends HookConsumerWidget {
|
||||
onTap: () {
|
||||
ref.read(hapticFeedbackProvider.notifier).selectionClick();
|
||||
if (isSelected) {
|
||||
ref.read(backupAlbumProvider.notifier).deselectAlbum(album);
|
||||
unawaited(ref.read(backupAlbumProvider.notifier).deselectAlbum(album));
|
||||
} else {
|
||||
ref.read(backupAlbumProvider.notifier).selectAlbum(album);
|
||||
unawaited(ref.read(backupAlbumProvider.notifier).selectAlbum(album));
|
||||
}
|
||||
},
|
||||
leading: buildIcon(),
|
||||
@@ -85,7 +87,7 @@ class DriftAlbumInfoListTile extends HookConsumerWidget {
|
||||
subtitle: buildSubtitle(),
|
||||
trailing: IconButton(
|
||||
onPressed: () {
|
||||
context.pushRoute(LocalTimelineRoute(album: album));
|
||||
unawaited(context.pushRoute(LocalTimelineRoute(album: album)));
|
||||
},
|
||||
icon: Icon(Icons.image_outlined, color: context.primaryColor, size: 24),
|
||||
splashRadius: 25,
|
||||
|
||||
@@ -38,8 +38,8 @@ class ImmichAppBarDialog extends HookConsumerWidget {
|
||||
final isReadonlyModeEnabled = ref.watch(readonlyModeProvider);
|
||||
|
||||
useEffect(() {
|
||||
ref.read(backupProvider.notifier).updateDiskInfo();
|
||||
ref.read(currentUserProvider.notifier).refresh();
|
||||
unawaited(ref.read(backupProvider.notifier).updateDiskInfo());
|
||||
unawaited(ref.read(currentUserProvider.notifier).refresh());
|
||||
return null;
|
||||
}, []);
|
||||
|
||||
@@ -180,7 +180,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
|
||||
InkWell(
|
||||
onTap: () {
|
||||
ContextHelper(context).pop();
|
||||
launchUrl(Uri.parse('https://docs.immich.app'), mode: LaunchMode.externalApplication);
|
||||
unawaited(launchUrl(Uri.parse('https://docs.immich.app'), mode: LaunchMode.externalApplication));
|
||||
},
|
||||
child: Text("documentation", style: context.textTheme.bodySmall).tr(),
|
||||
),
|
||||
@@ -188,7 +188,9 @@ class ImmichAppBarDialog extends HookConsumerWidget {
|
||||
InkWell(
|
||||
onTap: () {
|
||||
ContextHelper(context).pop();
|
||||
launchUrl(Uri.parse('https://github.com/immich-app/immich'), mode: LaunchMode.externalApplication);
|
||||
unawaited(
|
||||
launchUrl(Uri.parse('https://github.com/immich-app/immich'), mode: LaunchMode.externalApplication),
|
||||
);
|
||||
},
|
||||
child: Text("profile_drawer_github", style: context.textTheme.bodySmall).tr(),
|
||||
),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
|
||||
@@ -31,7 +33,7 @@ class AppBarServerInfo extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
useEffect(() {
|
||||
getPackageInfo();
|
||||
unawaited(getPackageInfo());
|
||||
return null;
|
||||
}, []);
|
||||
|
||||
@@ -87,7 +89,7 @@ class _ServerInfoItem extends StatelessWidget {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if (icon != null) ...[icon as Widget, const SizedBox(width: 8)],
|
||||
if (icon != null) ...[icon! as Widget, const SizedBox(width: 8)],
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@@ -20,7 +21,7 @@ class ServerUpdateNotification extends HookConsumerWidget {
|
||||
final Color infoColor = context.isDarkTheme
|
||||
? context.primaryColor.withAlpha(55)
|
||||
: context.primaryColor.withAlpha(25);
|
||||
void openUpdateLink() {
|
||||
Future<void> openUpdateLink() {
|
||||
String url;
|
||||
if (serverInfoState.versionStatus == VersionStatus.serverOutOfDate) {
|
||||
url = kImmichLatestRelease;
|
||||
@@ -35,7 +36,7 @@ class ServerUpdateNotification extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
launchUrlString(url, mode: LaunchMode.externalApplication);
|
||||
return launchUrlString(url, mode: LaunchMode.externalApplication);
|
||||
}
|
||||
|
||||
return SizedBox(
|
||||
@@ -68,7 +69,7 @@ class ServerUpdateNotification extends HookConsumerWidget {
|
||||
serverInfoState.versionStatus == VersionStatus.clientOutOfDate) ...[
|
||||
const SizedBox(width: 8),
|
||||
TextButton(
|
||||
onPressed: openUpdateLink,
|
||||
onPressed: () => unawaited(openUpdateLink()),
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.all(4),
|
||||
minimumSize: Size.zero,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -114,7 +116,7 @@ class DropdownSearchMenu<T> extends HookWidget {
|
||||
final bool highlight = AutocompleteHighlightedOption.of(context) == index;
|
||||
if (highlight) {
|
||||
SchedulerBinding.instance.addPostFrameCallback((Duration timeStamp) {
|
||||
Scrollable.ensureVisible(context, alignment: 0.5);
|
||||
unawaited(Scrollable.ensureVisible(context, alignment: 0.5));
|
||||
}, debugLabel: 'AutocompleteOptions.ensureVisible');
|
||||
}
|
||||
return Container(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:immich_mobile/widgets/common/immich_logo.dart';
|
||||
@@ -9,11 +11,12 @@ class ImmichLoadingIndicator extends HookWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final logoAnimationController = useAnimationController(duration: const Duration(seconds: 6))
|
||||
..reverse()
|
||||
..repeat();
|
||||
final logoAnimationController = useAnimationController(duration: const Duration(seconds: 6));
|
||||
unawaited(logoAnimationController.reverse());
|
||||
unawaited(logoAnimationController.repeat());
|
||||
|
||||
final borderAnimationController = useAnimationController(duration: const Duration(seconds: 6))..repeat();
|
||||
final borderAnimationController = useAnimationController(duration: const Duration(seconds: 6));
|
||||
unawaited(borderAnimationController.repeat());
|
||||
|
||||
return Container(
|
||||
height: 80,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
@@ -304,13 +305,13 @@ class _SyncStatusIndicatorState extends ConsumerState<_SyncStatusIndicator> with
|
||||
// Control animations based on sync status
|
||||
if (isSyncing) {
|
||||
if (!_rotationController.isAnimating) {
|
||||
_rotationController.repeat();
|
||||
unawaited(_rotationController.repeat());
|
||||
}
|
||||
_dismissalController.reset();
|
||||
} else {
|
||||
_rotationController.stop();
|
||||
if (_dismissalController.status == AnimationStatus.dismissed) {
|
||||
_dismissalController.forward();
|
||||
unawaited(_dismissalController.forward());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ class _ExpandedBackgroundState extends ConsumerState<_ExpandedBackground> with S
|
||||
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
if (mounted) {
|
||||
_slideController.forward();
|
||||
unawaited(_slideController.forward());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -228,7 +228,7 @@ class _ItemCountTextState extends ConsumerState<_ItemCountText> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_reloadSubscription?.cancel();
|
||||
unawaited(_reloadSubscription?.cancel());
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -311,13 +311,17 @@ class _RandomAssetBackgroundState extends State<_RandomAssetBackground> with Tic
|
||||
|
||||
void _startAnimationCycle() {
|
||||
if (_isZoomingIn) {
|
||||
_zoomController.forward().then((_) {
|
||||
_loadNextAsset();
|
||||
});
|
||||
unawaited(
|
||||
_zoomController.forward().then((_) {
|
||||
unawaited(_loadNextAsset());
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
_zoomController.reverse().then((_) {
|
||||
_loadNextAsset();
|
||||
});
|
||||
unawaited(
|
||||
_zoomController.reverse().then((_) {
|
||||
unawaited(_loadNextAsset());
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ class _ExpandedBackgroundState extends ConsumerState<_ExpandedBackground> with S
|
||||
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
if (mounted) {
|
||||
_slideController.forward();
|
||||
unawaited(_slideController.forward());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -335,7 +335,7 @@ class _ItemCountTextState extends ConsumerState<_ItemCountText> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_reloadSubscription?.cancel();
|
||||
unawaited(_reloadSubscription?.cancel());
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -416,13 +416,17 @@ class _RandomAssetBackgroundState extends State<_RandomAssetBackground> with Tic
|
||||
|
||||
void _startAnimationCycle() {
|
||||
if (_isZoomingIn) {
|
||||
_zoomController.forward().then((_) {
|
||||
_loadNextAsset();
|
||||
});
|
||||
unawaited(
|
||||
_zoomController.forward().then((_) {
|
||||
unawaited(_loadNextAsset());
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
_zoomController.reverse().then((_) {
|
||||
_loadNextAsset();
|
||||
});
|
||||
unawaited(
|
||||
_zoomController.reverse().then((_) {
|
||||
unawaited(_loadNextAsset());
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ class _ExpandedBackgroundState extends ConsumerState<_ExpandedBackground> with S
|
||||
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
if (mounted) {
|
||||
_slideController.forward();
|
||||
unawaited(_slideController.forward());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -309,7 +309,7 @@ class _ItemCountTextState extends ConsumerState<_ItemCountText> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_reloadSubscription?.cancel();
|
||||
unawaited(_reloadSubscription?.cancel());
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -390,13 +390,17 @@ class _RandomAssetBackgroundState extends State<_RandomAssetBackground> with Tic
|
||||
|
||||
void _startAnimationCycle() {
|
||||
if (_isZoomingIn) {
|
||||
_zoomController.forward().then((_) {
|
||||
_loadNextAsset();
|
||||
});
|
||||
unawaited(
|
||||
_zoomController.forward().then((_) {
|
||||
unawaited(_loadNextAsset());
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
_zoomController.reverse().then((_) {
|
||||
_loadNextAsset();
|
||||
});
|
||||
unawaited(
|
||||
_zoomController.reverse().then((_) {
|
||||
unawaited(_loadNextAsset());
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,8 @@ class LoginForm extends HookConsumerWidget {
|
||||
final isOauthEnable = useState<bool>(false);
|
||||
final isPasswordLoginEnable = useState<bool>(false);
|
||||
final oAuthButtonLabel = useState<String>('OAuth');
|
||||
final logoAnimationController = useAnimationController(duration: const Duration(seconds: 60))..repeat();
|
||||
final logoAnimationController = useAnimationController(duration: const Duration(seconds: 60));
|
||||
unawaited(logoAnimationController.repeat());
|
||||
final serverInfo = ref.watch(serverInfoProvider);
|
||||
final warningMessage = useState<String?>(null);
|
||||
final loginFormKey = GlobalKey<FormState>();
|
||||
@@ -358,7 +359,7 @@ class LoginForm extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
SingleChildRenderObjectWidget buildVersionCompatWarning() {
|
||||
checkVersionMismatch();
|
||||
unawaited(checkVersionMismatch());
|
||||
|
||||
if (warningMessage.value == null) {
|
||||
return const SizedBox.shrink();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user