diff --git a/mobile/lib/domain/utils/background_sync.dart b/mobile/lib/domain/utils/background_sync.dart index 4877009eb0..12bb696caf 100644 --- a/mobile/lib/domain/utils/background_sync.dart +++ b/mobile/lib/domain/utils/background_sync.dart @@ -44,9 +44,8 @@ class BackgroundSyncManager { _userSyncTask = runInIsolateGentle( computation: (ref) => ref.read(syncStreamServiceProvider).syncUsers(), ); - return _userSyncTask! - ..whenComplete(() { - _userSyncTask = null; - }); + return _userSyncTask!.whenComplete(() { + _userSyncTask = null; + }); } } diff --git a/mobile/lib/pages/photos/photos.page.dart b/mobile/lib/pages/photos/photos.page.dart index 62ac96c8aa..1a07183e7c 100644 --- a/mobile/lib/pages/photos/photos.page.dart +++ b/mobile/lib/pages/photos/photos.page.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:auto_route/auto_route.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -13,6 +14,7 @@ import 'package:immich_mobile/providers/server_info.provider.dart'; import 'package:immich_mobile/providers/timeline.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/providers/websocket.provider.dart'; +import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/widgets/asset_grid/multiselect_grid.dart'; import 'package:immich_mobile/widgets/common/immich_app_bar.dart'; import 'package:immich_mobile/widgets/common/immich_loading_indicator.dart'; @@ -128,7 +130,15 @@ class PhotosPage extends HookConsumerWidget { child: Container( height: kToolbarHeight + context.padding.top, color: context.themeData.appBarTheme.backgroundColor, - child: const ImmichAppBar(), + child: ImmichAppBar( + actions: [ + if (kDebugMode) + IconButton( + icon: const Icon(Icons.science_rounded), + onPressed: () => context.pushRoute(const FeatInDevRoute()), + ), + ], + ), ), ), ], diff --git a/mobile/lib/presentation/pages/feat_in_development.page.dart b/mobile/lib/presentation/pages/feat_in_development.page.dart new file mode 100644 index 0000000000..a955c2dfe7 --- /dev/null +++ b/mobile/lib/presentation/pages/feat_in_development.page.dart @@ -0,0 +1,59 @@ +import 'dart:async'; + +import 'package:auto_route/auto_route.dart'; +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/providers/background_sync.provider.dart'; + +final _features = [ + _Features( + name: 'Sync Local', + icon: Icons.photo_album_rounded, + onTap: (ref) => ref.read(backgroundSyncProvider).syncDeviceAlbums(), + ), + _Features( + name: 'Sync Remote', + icon: Icons.refresh_rounded, + onTap: (ref) => ref.read(backgroundSyncProvider).syncUsers(), + ), +]; + +@RoutePage() +class FeatInDevPage extends StatelessWidget { + const FeatInDevPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Features in Development'), + centerTitle: true, + ), + body: ListView.builder( + itemBuilder: (_, index) { + final feat = _features[index]; + return Consumer( + builder: (ctx, ref, _) => ListTile( + title: Text(feat.name), + trailing: Icon(feat.icon), + onTap: () => unawaited(feat.onTap(ref)), + ), + ); + }, + itemCount: _features.length, + ), + ); + } +} + +class _Features { + const _Features({ + required this.name, + required this.icon, + required this.onTap, + }); + + final String name; + final IconData icon; + final Future Function(WidgetRef _) onTap; +} diff --git a/mobile/lib/routing/router.dart b/mobile/lib/routing/router.dart index d7edc6fd28..5b771d3acc 100644 --- a/mobile/lib/routing/router.dart +++ b/mobile/lib/routing/router.dart @@ -61,6 +61,7 @@ import 'package:immich_mobile/pages/search/person_result.page.dart'; import 'package:immich_mobile/pages/search/recently_added.page.dart'; import 'package:immich_mobile/pages/search/search.page.dart'; import 'package:immich_mobile/pages/share_intent/share_intent.page.dart'; +import 'package:immich_mobile/presentation/pages/feat_in_development.page.dart'; import 'package:immich_mobile/providers/api.provider.dart'; import 'package:immich_mobile/providers/gallery_permission.provider.dart'; import 'package:immich_mobile/routing/auth_guard.dart'; @@ -289,6 +290,10 @@ class AppRouter extends RootStackRouter { page: ShareIntentRoute.page, guards: [_authGuard, _duplicateGuard], ), + AutoRoute( + page: FeatInDevRoute.page, + guards: [_authGuard, _duplicateGuard], + ), ]; } diff --git a/mobile/lib/routing/router.gr.dart b/mobile/lib/routing/router.gr.dart index a78371e05e..fbc730fed2 100644 --- a/mobile/lib/routing/router.gr.dart +++ b/mobile/lib/routing/router.gr.dart @@ -736,6 +736,25 @@ class FavoritesRoute extends PageRouteInfo { ); } +/// generated route for +/// [FeatInDevPage] +class FeatInDevRoute extends PageRouteInfo { + const FeatInDevRoute({List? children}) + : super( + FeatInDevRoute.name, + initialChildren: children, + ); + + static const String name = 'FeatInDevRoute'; + + static PageInfo page = PageInfo( + name, + builder: (data) { + return const FeatInDevPage(); + }, + ); +} + /// generated route for /// [FilterImagePage] class FilterImageRoute extends PageRouteInfo {