From c1b22125fd22fe9bf2a0a48a7097192223ba929f Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 15 Aug 2022 18:53:30 -0500 Subject: [PATCH] Add mobile dark mode and user setting (#468) * styling light and dark theme * Icon topbar * Fixed app bar title dark theme * Fixed issue with getting thumbnail for things * Refactor sharing page * Refactor scroll thumb * Refactor chip in auto backup indiation button * Refactor sharing page * Added theme toggle * Up version for testflight build * Refactor backup controller page * Refactor album selection page * refactor album pages * Refactor gradient color profile header * Added theme switcher * Register app theme correctly * Added locale to the app * Added translation key * Styling for bottomsheet colors * up server version * Fixed font size * Fixed overlapsed sliverappbar on photos screen --- mobile/android/fastlane/Fastfile | 4 +- mobile/assets/i18n/en-US.json | 13 +- mobile/ios/fastlane/Fastfile | 2 +- mobile/lib/constants/immich_colors.dart | 4 +- mobile/lib/main.dart | 27 ++-- .../ui/album_action_outlined_button.dart | 22 +-- .../album/ui/album_thumbnail_card.dart | 5 +- .../album/ui/album_title_text_field.dart | 11 +- .../modules/album/ui/album_viewer_appbar.dart | 2 +- .../album/ui/album_viewer_editable_title.dart | 10 +- .../album/ui/sharing_sliver_appbar.dart | 31 ++-- .../album/views/album_viewer_page.dart | 5 +- .../album/views/asset_selection_page.dart | 2 +- .../album/views/create_album_page.dart | 40 ++++-- .../lib/modules/album/views/library_page.dart | 4 +- .../views/select_user_for_sharing_page.dart | 13 +- .../lib/modules/album/views/sharing_page.dart | 24 ++-- .../asset_viewer/views/gallery_viewer.dart | 3 +- .../modules/backup/ui/album_info_card.dart | 20 +-- .../modules/backup/ui/backup_info_card.dart | 2 +- .../views/backup_album_selection_page.dart | 42 +++--- .../backup/views/backup_controller_page.dart | 69 ++++----- .../home/ui/control_bottom_app_bar.dart | 10 +- .../lib/modules/home/ui/daily_title_text.dart | 1 - .../home/ui/disable_multi_select_button.dart | 36 ++--- .../modules/home/ui/immich_sliver_appbar.dart | 9 +- .../modules/home/ui/monthly_title_text.dart | 2 +- .../ui/profile_drawer/profile_drawer.dart | 22 ++- .../profile_drawer/profile_drawer_header.dart | 25 ++-- .../ui/profile_drawer/server_info_box.dart | 12 +- mobile/lib/modules/home/views/home_page.dart | 4 +- .../search/ui/thumbnail_with_info.dart | 4 +- .../lib/modules/search/views/search_page.dart | 24 ++-- .../search/views/search_result_page.dart | 2 +- .../providers/app_settings.provider.dart | 4 + .../providers/store_providers_here.txt | 0 .../services/app_settings.service.dart | 8 +- .../settings/services/store_services_here.txt | 0 .../image_viewer_quality_setting.dart | 18 +-- .../three_stage_loading.dart | 12 +- .../ui/theme_setting/theme_setting.dart | 107 ++++++++++++++ .../modules/settings/views/settings_page.dart | 46 +----- mobile/lib/shared/views/splash_screen.dart | 2 - .../lib/shared/views/tab_controller_page.dart | 3 - mobile/lib/utils/immich_app_theme.dart | 133 ++++++++++++++++++ mobile/pubspec.yaml | 2 +- .../src/constants/server_version.constant.ts | 2 +- 47 files changed, 536 insertions(+), 307 deletions(-) create mode 100644 mobile/lib/modules/settings/providers/app_settings.provider.dart delete mode 100644 mobile/lib/modules/settings/providers/store_providers_here.txt rename mobile/lib/{shared => modules/settings}/services/app_settings.service.dart (91%) delete mode 100644 mobile/lib/modules/settings/services/store_services_here.txt create mode 100644 mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart create mode 100644 mobile/lib/utils/immich_app_theme.dart diff --git a/mobile/android/fastlane/Fastfile b/mobile/android/fastlane/Fastfile index e90f87aa38..ae84f8dd68 100644 --- a/mobile/android/fastlane/Fastfile +++ b/mobile/android/fastlane/Fastfile @@ -30,8 +30,8 @@ platform :android do task: 'bundle', build_type: 'Release', properties: { - "android.injected.version.code" => 32, - "android.injected.version.name" => "1.22.0", + "android.injected.version.code" => 33, + "android.injected.version.name" => "1.23.0", } ) upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab') diff --git a/mobile/assets/i18n/en-US.json b/mobile/assets/i18n/en-US.json index 14340dfdad..ca4a07b542 100644 --- a/mobile/assets/i18n/en-US.json +++ b/mobile/assets/i18n/en-US.json @@ -48,7 +48,7 @@ "control_bottom_app_bar_delete": "Delete", "create_shared_album_page_share": "Share", "create_shared_album_page_create": "Create", - "create_shared_album_page_share_add_assets": "ADD ASSETS", + "create_shared_album_page_share_add_assets": "ADD PHOTOS", "create_shared_album_page_share_select_photos": "Select Photos", "daily_title_text_date": "E, MMM dd", "daily_title_text_date_year": "E, MMM dd, yyyy", @@ -113,5 +113,14 @@ "library_page_new_album": "New album", "create_album_page_untitled": "Untitled", "share_dialog_preparing": "Preparing...", - "control_bottom_app_bar_share": "Share" + "control_bottom_app_bar_share": "Share", + "setting_pages_app_bar_settings": "Settings", + "theme_setting_theme_title": "Theme", + "theme_setting_theme_subtitle": "Choose the app's theme setting", + "theme_setting_system_theme_switch": "Automatic (Follow system setting)", + "theme_setting_dark_mode_switch": "Dark mode", + "theme_setting_image_viewer_quality_title": "Image viewer quality", + "theme_setting_image_viewer_quality_subtitle": "Adjust the quality of the detail image viewer", + "theme_setting_three_stage_loading_title": "Enable three-stage loading", + "theme_setting_three_stage_loading_subtitle": "The three-stage loading delivers the best quality image in exchange for a slower loading speed" } diff --git a/mobile/ios/fastlane/Fastfile b/mobile/ios/fastlane/Fastfile index 4248335bee..8fb106f1c1 100644 --- a/mobile/ios/fastlane/Fastfile +++ b/mobile/ios/fastlane/Fastfile @@ -19,7 +19,7 @@ platform :ios do desc "iOS Beta" lane :beta do increment_version_number( - version_number: "1.22.0" + version_number: "1.23.0" ) increment_build_number( build_number: latest_testflight_build_number + 1, diff --git a/mobile/lib/constants/immich_colors.dart b/mobile/lib/constants/immich_colors.dart index f93ae3736a..e3f6013581 100644 --- a/mobile/lib/constants/immich_colors.dart +++ b/mobile/lib/constants/immich_colors.dart @@ -1,3 +1,5 @@ import 'package:flutter/material.dart'; -const immichBackgroundColor = Color(0xFFf6f8fe); +Color immichBackgroundColor = const Color(0xFFf6f8fe); +Color immichDarkBackgroundColor = const Color.fromARGB(255, 0, 0, 0); +Color immichDarkThemePrimaryColor = const Color.fromARGB(255, 173, 203, 250); diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index 1a3ba8b194..427d2f4a66 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -7,7 +7,6 @@ import 'package:flutter/services.dart'; import 'package:flutter_displaymode/flutter_displaymode.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/constants/immich_colors.dart'; import 'package:immich_mobile/modules/backup/models/hive_backup_albums.model.dart'; import 'package:immich_mobile/modules/backup/providers/backup.provider.dart'; import 'package:immich_mobile/modules/login/models/hive_saved_login_info.model.dart'; @@ -19,8 +18,10 @@ import 'package:immich_mobile/shared/providers/asset.provider.dart'; import 'package:immich_mobile/shared/providers/release_info.provider.dart'; import 'package:immich_mobile/shared/providers/server_info.provider.dart'; import 'package:immich_mobile/shared/providers/websocket.provider.dart'; +import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; import 'package:immich_mobile/shared/views/immich_loading_overlay.dart'; import 'package:immich_mobile/shared/views/version_announcement_overlay.dart'; +import 'package:immich_mobile/utils/immich_app_theme.dart'; import 'constants/hive_box.dart'; void main() async { @@ -50,8 +51,11 @@ void main() async { Locale('da', 'DK'), Locale('de', 'DE'), Locale('es', 'ES'), + Locale('fi', 'FI'), Locale('fr', 'FR'), Locale('it', 'IT'), + Locale('ja', 'JP'), + Locale('pl', 'PL') ]; if (kReleaseMode && Platform.isAndroid) { @@ -130,7 +134,6 @@ class ImmichAppState extends ConsumerState @override initState() { super.initState(); - initApp().then((_) => debugPrint("App Init Completed")); } @@ -155,23 +158,9 @@ class ImmichAppState extends ConsumerState MaterialApp.router( title: 'Immich', debugShowCheckedModeBanner: false, - theme: ThemeData( - useMaterial3: true, - brightness: Brightness.light, - primarySwatch: Colors.indigo, - fontFamily: 'WorkSans', - snackBarTheme: const SnackBarThemeData( - contentTextStyle: TextStyle(fontFamily: 'WorkSans'), - ), - scaffoldBackgroundColor: immichBackgroundColor, - appBarTheme: const AppBarTheme( - backgroundColor: immichBackgroundColor, - foregroundColor: Colors.indigo, - elevation: 1, - centerTitle: true, - systemOverlayStyle: SystemUiOverlayStyle.dark, - ), - ), + themeMode: ref.watch(immichThemeProvider), + darkTheme: immichDarkTheme, + theme: immichLightTheme, routeInformationParser: router.defaultRouteParser(), routerDelegate: router.delegate( navigatorObservers: () => [TabNavigationObserver(ref: ref)], diff --git a/mobile/lib/modules/album/ui/album_action_outlined_button.dart b/mobile/lib/modules/album/ui/album_action_outlined_button.dart index fdfab59768..928a50794a 100644 --- a/mobile/lib/modules/album/ui/album_action_outlined_button.dart +++ b/mobile/lib/modules/album/ui/album_action_outlined_button.dart @@ -14,6 +14,8 @@ class AlbumActionOutlinedButton extends StatelessWidget { @override Widget build(BuildContext context) { + final isDarkTheme = Theme.of(context).brightness == Brightness.dark; + return Padding( padding: const EdgeInsets.only(right: 8.0), child: OutlinedButton.icon( @@ -22,19 +24,23 @@ class AlbumActionOutlinedButton extends StatelessWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(25), ), - side: const BorderSide( + side: BorderSide( width: 1, - color: Color.fromARGB(255, 215, 215, 215), + color: isDarkTheme + ? const Color.fromARGB(255, 63, 63, 63) + : const Color.fromARGB(255, 206, 206, 206), ), ), - icon: Icon(iconData, size: 15), + icon: Icon( + iconData, + size: 15, + color: Theme.of(context).primaryColor, + ), label: Text( labelText, - style: const TextStyle( - fontSize: 12, - fontWeight: FontWeight.bold, - color: Colors.black87, - ), + style: Theme.of(context).textTheme.labelSmall?.copyWith( + fontWeight: FontWeight.bold, + ), ), onPressed: onPressed, ), diff --git a/mobile/lib/modules/album/ui/album_thumbnail_card.dart b/mobile/lib/modules/album/ui/album_thumbnail_card.dart index 4901376093..51aa598f6c 100644 --- a/mobile/lib/modules/album/ui/album_thumbnail_card.dart +++ b/mobile/lib/modules/album/ui/album_thumbnail_card.dart @@ -52,7 +52,6 @@ class AlbumThumbnailCard extends StatelessWidget { album.albumName, style: const TextStyle( fontWeight: FontWeight.bold, - fontSize: 12, ), ), ), @@ -65,14 +64,14 @@ class AlbumThumbnailCard extends StatelessWidget { ? 'album_thumbnail_card_item' : 'album_thumbnail_card_items', style: const TextStyle( - fontSize: 10, + fontSize: 12, ), ).tr(args: ['${album.assetCount}']), if (album.shared) const Text( 'album_thumbnail_card_shared', style: TextStyle( - fontSize: 10, + fontSize: 12, ), ).tr() ], diff --git a/mobile/lib/modules/album/ui/album_title_text_field.dart b/mobile/lib/modules/album/ui/album_title_text_field.dart index fa7f27471d..83122f791b 100644 --- a/mobile/lib/modules/album/ui/album_title_text_field.dart +++ b/mobile/lib/modules/album/ui/album_title_text_field.dart @@ -19,6 +19,8 @@ class AlbumTitleTextField extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + final isDarkTheme = Theme.of(context).brightness == Brightness.dark; + return TextField( onChanged: (v) { if (v.isEmpty) { @@ -51,7 +53,10 @@ class AlbumTitleTextField extends ConsumerWidget { albumTitleController.clear(); isAlbumTitleEmpty.value = true; }, - icon: const Icon(Icons.cancel_rounded), + icon: Icon( + Icons.cancel_rounded, + color: Theme.of(context).primaryColor, + ), splashRadius: 10, ) : null, @@ -65,7 +70,9 @@ class AlbumTitleTextField extends ConsumerWidget { ), hintText: 'share_add_title'.tr(), focusColor: Colors.grey[300], - fillColor: Colors.grey[200], + fillColor: isDarkTheme + ? const Color.fromARGB(255, 32, 33, 35) + : Colors.grey[200], filled: isAlbumTitleTextFieldFocus.value, ), ); diff --git a/mobile/lib/modules/album/ui/album_viewer_appbar.dart b/mobile/lib/modules/album/ui/album_viewer_appbar.dart index ed7e817c79..edfdcade09 100644 --- a/mobile/lib/modules/album/ui/album_viewer_appbar.dart +++ b/mobile/lib/modules/album/ui/album_viewer_appbar.dart @@ -150,7 +150,7 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget { void _buildBottomSheet() { showModalBottomSheet( - backgroundColor: immichBackgroundColor, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, isScrollControlled: false, context: context, builder: (context) { diff --git a/mobile/lib/modules/album/ui/album_viewer_editable_title.dart b/mobile/lib/modules/album/ui/album_viewer_editable_title.dart index c0a1f148b6..9c9c137c84 100644 --- a/mobile/lib/modules/album/ui/album_viewer_editable_title.dart +++ b/mobile/lib/modules/album/ui/album_viewer_editable_title.dart @@ -18,6 +18,7 @@ class AlbumViewerEditableTitle extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final titleTextEditController = useTextEditingController(text: albumInfo.albumName); + final isDarkTheme = Theme.of(context).brightness == Brightness.dark; void onFocusModeChange() { if (!titleFocusNode.hasFocus && titleTextEditController.text.isEmpty) { @@ -65,7 +66,10 @@ class AlbumViewerEditableTitle extends HookConsumerWidget { onPressed: () { titleTextEditController.clear(); }, - icon: const Icon(Icons.cancel_rounded), + icon: Icon( + Icons.cancel_rounded, + color: Theme.of(context).primaryColor, + ), splashRadius: 10, ) : null, @@ -78,7 +82,9 @@ class AlbumViewerEditableTitle extends HookConsumerWidget { borderRadius: BorderRadius.circular(10), ), focusColor: Colors.grey[300], - fillColor: Colors.grey[200], + fillColor: isDarkTheme + ? const Color.fromARGB(255, 32, 33, 35) + : Colors.grey[200], filled: titleFocusNode.hasFocus, hintText: 'share_add_title'.tr(), ), diff --git a/mobile/lib/modules/album/ui/sharing_sliver_appbar.dart b/mobile/lib/modules/album/ui/sharing_sliver_appbar.dart index 49ac3741fe..9643f1929e 100644 --- a/mobile/lib/modules/album/ui/sharing_sliver_appbar.dart +++ b/mobile/lib/modules/album/ui/sharing_sliver_appbar.dart @@ -35,13 +35,7 @@ class SharingSliverAppBar extends StatelessWidget { Expanded( child: Padding( padding: const EdgeInsets.only(right: 4.0), - child: TextButton.icon( - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - Theme.of(context).primaryColor.withAlpha(20), - ), - // foregroundColor: MaterialStateProperty.all(Colors.white), - ), + child: ElevatedButton.icon( onPressed: () { AutoRouter.of(context) .push(CreateAlbumRoute(isSharedAlbum: true)); @@ -52,8 +46,12 @@ class SharingSliverAppBar extends StatelessWidget { ), label: const Text( "sharing_silver_appbar_create_shared_album", - style: - TextStyle(fontWeight: FontWeight.bold, fontSize: 12), + maxLines: 1, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 11, + // color: Theme.of(context).primaryColor, + ), ).tr(), ), ), @@ -61,13 +59,7 @@ class SharingSliverAppBar extends StatelessWidget { Expanded( child: Padding( padding: const EdgeInsets.only(left: 4.0), - child: TextButton.icon( - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - Theme.of(context).primaryColor.withAlpha(20), - ), - // foregroundColor: MaterialStateProperty.all(Colors.white), - ), + child: ElevatedButton.icon( onPressed: null, icon: const Icon( Icons.swap_horizontal_circle_outlined, @@ -75,8 +67,11 @@ class SharingSliverAppBar extends StatelessWidget { ), label: const Text( "sharing_silver_appbar_share_partner", - style: - TextStyle(fontWeight: FontWeight.bold, fontSize: 12), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 11, + ), + maxLines: 1, ).tr(), ), ), diff --git a/mobile/lib/modules/album/views/album_viewer_page.dart b/mobile/lib/modules/album/views/album_viewer_page.dart index fd8fd2c0e6..237635dd18 100644 --- a/mobile/lib/modules/album/views/album_viewer_page.dart +++ b/mobile/lib/modules/album/views/album_viewer_page.dart @@ -3,7 +3,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/constants/immich_colors.dart'; import 'package:immich_mobile/modules/home/ui/draggable_scrollbar.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; import 'package:immich_mobile/modules/album/models/asset_selection_page_result.model.dart'; @@ -242,7 +241,7 @@ class AlbumViewerPage extends HookConsumerWidget { titleFocusNode.unfocus(); }, child: DraggableScrollbar.semicircle( - backgroundColor: Theme.of(context).primaryColor, + backgroundColor: Theme.of(context).hintColor, controller: scrollController, heightScrollThumb: 48.0, child: CustomScrollView( @@ -255,7 +254,7 @@ class AlbumViewerPage extends HookConsumerWidget { minHeight: 50, maxHeight: 50, child: Container( - color: immichBackgroundColor, + color: Theme.of(context).scaffoldBackgroundColor, child: _buildControlButton(albumInfo), ), ), diff --git a/mobile/lib/modules/album/views/asset_selection_page.dart b/mobile/lib/modules/album/views/asset_selection_page.dart index a8bde660fb..226d6b0285 100644 --- a/mobile/lib/modules/album/views/asset_selection_page.dart +++ b/mobile/lib/modules/album/views/asset_selection_page.dart @@ -43,7 +43,7 @@ class AssetSelectionPage extends HookConsumerWidget { return Stack( children: [ DraggableScrollbar.semicircle( - backgroundColor: Theme.of(context).primaryColor, + backgroundColor: Theme.of(context).hintColor, controller: scrollController, heightScrollThumb: 48.0, child: CustomScrollView( diff --git a/mobile/lib/modules/album/views/create_album_page.dart b/mobile/lib/modules/album/views/create_album_page.dart index c10bd6987f..20cf0c26d5 100644 --- a/mobile/lib/modules/album/views/create_album_page.dart +++ b/mobile/lib/modules/album/views/create_album_page.dart @@ -27,6 +27,7 @@ class CreateAlbumPage extends HookConsumerWidget { final isAlbumTitleEmpty = useState(true); final selectedAssets = ref.watch(assetSelectionProvider).selectedNewAssetsForAlbum; + final isDarkTheme = Theme.of(context).brightness == Brightness.dark; _showSelectUserPage() { AutoRouter.of(context).push(const SelectUserForSharingRoute()); @@ -75,9 +76,12 @@ class CreateAlbumPage extends HookConsumerWidget { return SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.only(top: 200, left: 18), - child: const Text( + child: Text( 'create_shared_album_page_share_add_assets', - style: TextStyle(fontSize: 12), + style: Theme.of(context).textTheme.headline2?.copyWith( + fontSize: 12, + fontWeight: FontWeight.normal, + ), ).tr(), ), ); @@ -96,24 +100,28 @@ class CreateAlbumPage extends HookConsumerWidget { alignment: Alignment.centerLeft, padding: const EdgeInsets.symmetric(vertical: 22, horizontal: 16), - side: const BorderSide( - color: Color.fromARGB(255, 206, 206, 206), + side: BorderSide( + color: isDarkTheme + ? const Color.fromARGB(255, 63, 63, 63) + : const Color.fromARGB(255, 206, 206, 206), ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), ), onPressed: _onSelectPhotosButtonPressed, - icon: const Icon(Icons.add_rounded), + icon: Icon( + Icons.add_rounded, + color: Theme.of(context).primaryColor, + ), label: Padding( padding: const EdgeInsets.only(left: 8.0), child: Text( 'create_shared_album_page_share_select_photos', - style: TextStyle( - fontSize: 16, - color: Colors.grey[700], - fontWeight: FontWeight.bold, - ), + style: Theme.of(context).textTheme.labelLarge?.copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + ), ).tr(), ), ), @@ -190,6 +198,7 @@ class CreateAlbumPage extends HookConsumerWidget { appBar: AppBar( elevation: 0, centerTitle: false, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, leading: IconButton( onPressed: () { ref.watch(assetSelectionProvider.notifier).removeAll(); @@ -197,9 +206,11 @@ class CreateAlbumPage extends HookConsumerWidget { }, icon: const Icon(Icons.close_rounded), ), - title: const Text( + title: Text( 'share_create_album', - style: TextStyle(color: Colors.black), + style: Theme.of(context).textTheme.headline2?.copyWith( + color: Theme.of(context).primaryColor, + ), ).tr(), actions: [ if (isSharedAlbum) @@ -209,8 +220,9 @@ class CreateAlbumPage extends HookConsumerWidget { : null, child: Text( 'create_shared_album_page_share'.tr(), - style: const TextStyle( + style: TextStyle( fontWeight: FontWeight.bold, + color: Theme.of(context).primaryColor, ), ), ), @@ -234,9 +246,9 @@ class CreateAlbumPage extends HookConsumerWidget { child: CustomScrollView( slivers: [ SliverAppBar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, elevation: 5, automaticallyImplyLeading: false, - // leading: Container(), pinned: true, floating: false, bottom: PreferredSize( diff --git a/mobile/lib/modules/album/views/library_page.dart b/mobile/lib/modules/album/views/library_page.dart index 6e5f6edb74..7bb91bc815 100644 --- a/mobile/lib/modules/album/views/library_page.dart +++ b/mobile/lib/modules/album/views/library_page.dart @@ -23,7 +23,7 @@ class LibraryPage extends HookConsumerWidget { ); Widget _buildAppBar() { - return SliverAppBar( + return const SliverAppBar( centerTitle: true, floating: true, pinned: false, @@ -35,7 +35,6 @@ class LibraryPage extends HookConsumerWidget { fontFamily: 'SnowburstOne', fontWeight: FontWeight.bold, fontSize: 22, - color: Theme.of(context).primaryColor, ), ), ); @@ -72,7 +71,6 @@ class LibraryPage extends HookConsumerWidget { child: const Text( 'library_page_new_album', style: TextStyle( - fontSize: 12, fontWeight: FontWeight.bold, ), ).tr(), diff --git a/mobile/lib/modules/album/views/select_user_for_sharing_page.dart b/mobile/lib/modules/album/views/select_user_for_sharing_page.dart index 8f479df498..0d21e06484 100644 --- a/mobile/lib/modules/album/views/select_user_for_sharing_page.dart +++ b/mobile/lib/modules/album/views/select_user_for_sharing_page.dart @@ -136,9 +136,9 @@ class SelectUserForSharingPage extends HookConsumerWidget { return Scaffold( appBar: AppBar( - title: const Text( + title: Text( 'share_invite', - style: TextStyle(color: Colors.black), + style: TextStyle(color: Theme.of(context).primaryColor), ).tr(), elevation: 0, centerTitle: false, @@ -150,11 +150,18 @@ class SelectUserForSharingPage extends HookConsumerWidget { ), actions: [ TextButton( + style: TextButton.styleFrom( + primary: Theme.of(context).primaryColor, + ), onPressed: sharedUsersList.value.isEmpty ? null : _createSharedAlbum, child: const Text( "share_create_album", - style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + // color: Theme.of(context).primaryColor, + ), ).tr(), ) ], diff --git a/mobile/lib/modules/album/views/sharing_page.dart b/mobile/lib/modules/album/views/sharing_page.dart index bc862f4a82..5fb8ee00ce 100644 --- a/mobile/lib/modules/album/views/sharing_page.dart +++ b/mobile/lib/modules/album/views/sharing_page.dart @@ -61,11 +61,9 @@ class SharingPage extends HookConsumerWidget { sharedAlbums[index].albumName, maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.grey.shade800, - ), + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.bold, + ), ), onTap: () { AutoRouter.of(context) @@ -87,7 +85,7 @@ class SharingPage extends HookConsumerWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), // if you need this side: const BorderSide( - color: Colors.black12, + color: Colors.grey, width: 1, ), ), @@ -97,30 +95,26 @@ class SharingPage extends HookConsumerWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: const EdgeInsets.only(left: 5.0, bottom: 5), + const Padding( + padding: EdgeInsets.only(left: 5.0, bottom: 5), child: Icon( Icons.offline_share_outlined, size: 50, - color: Theme.of(context).primaryColor.withAlpha(200), + // color: Theme.of(context).primaryColor, ), ), Padding( padding: const EdgeInsets.all(8.0), child: Text( 'sharing_page_empty_list', - style: TextStyle( - fontSize: 12, - color: Theme.of(context).primaryColor, - fontWeight: FontWeight.bold, - ), + style: Theme.of(context).textTheme.headline3, ).tr(), ), Padding( padding: const EdgeInsets.all(8.0), child: Text( 'sharing_page_description', - style: TextStyle(fontSize: 12, color: Colors.grey[700]), + style: Theme.of(context).textTheme.bodyMedium, ).tr(), ), ], diff --git a/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart b/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart index 602e24ee2a..5b805a48d9 100644 --- a/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart +++ b/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart @@ -11,7 +11,8 @@ import 'package:immich_mobile/modules/asset_viewer/ui/top_control_app_bar.dart'; import 'package:immich_mobile/modules/asset_viewer/views/image_viewer_page.dart'; import 'package:immich_mobile/modules/asset_viewer/views/video_viewer_page.dart'; import 'package:immich_mobile/modules/home/services/asset.service.dart'; -import 'package:immich_mobile/shared/services/app_settings.service.dart'; +import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; +import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; import 'package:openapi/api.dart'; // ignore: must_be_immutable diff --git a/mobile/lib/modules/backup/ui/album_info_card.dart b/mobile/lib/modules/backup/ui/album_info_card.dart index b523c713b1..18a660dcfb 100644 --- a/mobile/lib/modules/backup/ui/album_info_card.dart +++ b/mobile/lib/modules/backup/ui/album_info_card.dart @@ -24,6 +24,7 @@ class AlbumInfoCard extends HookConsumerWidget { ref.watch(backupProvider).selectedBackupAlbums.contains(albumInfo); final bool isExcluded = ref.watch(backupProvider).excludedBackupAlbums.contains(albumInfo); + final isDarkTheme = Theme.of(context).brightness == Brightness.dark; ColorFilter selectedFilter = ColorFilter.mode( Theme.of(context).primaryColor.withAlpha(100), @@ -39,11 +40,11 @@ class AlbumInfoCard extends HookConsumerWidget { return Chip( visualDensity: VisualDensity.compact, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)), - label: const Text( + label: Text( "album_info_card_backup_album_included", style: TextStyle( fontSize: 10, - color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, fontWeight: FontWeight.bold, ), ).tr(), @@ -53,11 +54,11 @@ class AlbumInfoCard extends HookConsumerWidget { return Chip( visualDensity: VisualDensity.compact, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)), - label: const Text( + label: Text( "album_info_card_backup_album_excluded", style: TextStyle( fontSize: 10, - color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, fontWeight: FontWeight.bold, ), ).tr(), @@ -141,8 +142,10 @@ class AlbumInfoCard extends HookConsumerWidget { margin: const EdgeInsets.all(1), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), // if you need this - side: const BorderSide( - color: Color(0xFFC9C9C9), + side: BorderSide( + color: isDarkTheme + ? const Color.fromARGB(255, 37, 35, 35) + : const Color(0xFFC9C9C9), width: 1, ), ), @@ -219,8 +222,9 @@ class AlbumInfoCard extends HookConsumerWidget { ), IconButton( onPressed: () { - AutoRouter.of(context) - .push(AlbumPreviewRoute(album: albumInfo)); + AutoRouter.of(context).push( + AlbumPreviewRoute(album: albumInfo), + ); }, icon: Icon( Icons.image_outlined, diff --git a/mobile/lib/modules/backup/ui/backup_info_card.dart b/mobile/lib/modules/backup/ui/backup_info_card.dart index 6bc832a5d4..697b9795cc 100644 --- a/mobile/lib/modules/backup/ui/backup_info_card.dart +++ b/mobile/lib/modules/backup/ui/backup_info_card.dart @@ -35,7 +35,7 @@ class BackupInfoCard extends StatelessWidget { padding: const EdgeInsets.only(top: 8.0), child: Text( subtitle, - style: const TextStyle(color: Color(0xFF808080), fontSize: 12), + style: const TextStyle(fontSize: 12), ), ), trailing: Column( diff --git a/mobile/lib/modules/backup/views/backup_album_selection_page.dart b/mobile/lib/modules/backup/views/backup_album_selection_page.dart index 50a5be8537..271c70a4be 100644 --- a/mobile/lib/modules/backup/views/backup_album_selection_page.dart +++ b/mobile/lib/modules/backup/views/backup_album_selection_page.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/constants/immich_colors.dart'; import 'package:immich_mobile/modules/backup/providers/backup.provider.dart'; import 'package:immich_mobile/modules/backup/ui/album_info_card.dart'; import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart'; @@ -16,6 +17,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { final availableAlbums = ref.watch(backupProvider).availableAlbums; final selectedBackupAlbums = ref.watch(backupProvider).selectedBackupAlbums; final excludedBackupAlbums = ref.watch(backupProvider).excludedBackupAlbums; + final isDarkTheme = Theme.of(context).brightness == Brightness.dark; useEffect( () { @@ -81,14 +83,16 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { ), label: Text( album.name, - style: const TextStyle( + style: TextStyle( fontSize: 10, - color: Colors.white, + color: Theme.of(context).brightness == Brightness.dark + ? Colors.black + : Colors.white, fontWeight: FontWeight.bold, ), ), backgroundColor: Theme.of(context).primaryColor, - deleteIconColor: Colors.white, + deleteIconColor: isDarkTheme ? Colors.black : Colors.white, deleteIcon: const Icon( Icons.cancel_rounded, size: 15, @@ -119,14 +123,15 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { ), label: Text( album.name, - style: const TextStyle( + style: TextStyle( fontSize: 10, - color: Colors.white, + color: isDarkTheme ? Colors.black : immichBackgroundColor, fontWeight: FontWeight.bold, ), ), backgroundColor: Colors.red[300], - deleteIconColor: Colors.white, + deleteIconColor: + isDarkTheme ? Colors.black : immichBackgroundColor, deleteIcon: const Icon( Icons.cancel_rounded, size: 15, @@ -154,11 +159,16 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { physics: const ClampingScrollPhysics(), children: [ Padding( - padding: - const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), + padding: const EdgeInsets.symmetric( + vertical: 8.0, + horizontal: 16.0, + ), child: const Text( "backup_album_selection_page_selection_info", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + ), ).tr(), ), // Selected Album Chips @@ -178,9 +188,11 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { child: Card( margin: const EdgeInsets.all(0), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5), // if you need this - side: const BorderSide( - color: Color.fromARGB(255, 235, 235, 235), + borderRadius: BorderRadius.circular(5), + side: BorderSide( + color: isDarkTheme + ? const Color.fromARGB(255, 0, 0, 0) + : const Color.fromARGB(255, 235, 235, 235), width: 1, ), ), @@ -190,12 +202,11 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { children: [ ListTile( visualDensity: VisualDensity.compact, - title: Text( + title: const Text( "backup_album_selection_page_total_assets", style: TextStyle( fontWeight: FontWeight.bold, fontSize: 14, - color: Colors.grey[700], ), ).tr(), trailing: Text( @@ -257,11 +268,10 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { content: SingleChildScrollView( child: ListBody( children: [ - Text( + const Text( 'backup_album_selection_page_assets_scatter', style: TextStyle( fontSize: 14, - color: Colors.grey[700], ), ).tr(), ], diff --git a/mobile/lib/modules/backup/views/backup_controller_page.dart b/mobile/lib/modules/backup/views/backup_controller_page.dart index 65377b8538..32ecd8741d 100644 --- a/mobile/lib/modules/backup/views/backup_controller_page.dart +++ b/mobile/lib/modules/backup/views/backup_controller_page.dart @@ -82,7 +82,7 @@ class BackupControllerPage extends HookConsumerWidget { ); } - ListTile _buildBackupController() { + ListTile _buildAutoBackupController() { var backUpOption = authenticationState.deviceInfo.isAutoBackup ? "backup_controller_page_status_on".tr() : "backup_controller_page_status_off".tr(); @@ -114,13 +114,7 @@ class BackupControllerPage extends HookConsumerWidget { ).tr(), Padding( padding: const EdgeInsets.only(top: 8.0), - child: OutlinedButton( - style: OutlinedButton.styleFrom( - side: const BorderSide( - width: 1, - color: Color.fromARGB(255, 220, 220, 220), - ), - ), + child: ElevatedButton( onPressed: () { if (isAutoBackup) { ref @@ -134,7 +128,10 @@ class BackupControllerPage extends HookConsumerWidget { }, child: Text( backupBtnText, - style: const TextStyle(fontWeight: FontWeight.bold), + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 12, + ), ), ), ) @@ -232,33 +229,24 @@ class BackupControllerPage extends HookConsumerWidget { children: [ const Text( "backup_controller_page_to_backup", - style: TextStyle(color: Color(0xFF808080), fontSize: 12), + style: TextStyle(fontSize: 12), ).tr(), _buildSelectedAlbumName(), _buildExcludedAlbumName() ], ), ), - trailing: OutlinedButton( - style: OutlinedButton.styleFrom( - enableFeedback: true, - side: const BorderSide( - width: 1, - color: Color.fromARGB(255, 220, 220, 220), - ), - ), + trailing: ElevatedButton( onPressed: () { AutoRouter.of(context).push(const BackupAlbumSelectionRoute()); }, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 16.0, + child: const Text( + "backup_controller_page_select", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 12, ), - child: const Text( - "backup_controller_page_select", - style: TextStyle(fontWeight: FontWeight.bold), - ).tr(), - ), + ).tr(), ), ), ); @@ -324,14 +312,14 @@ class BackupControllerPage extends HookConsumerWidget { padding: const EdgeInsets.only(top: 8.0), child: Table( border: TableBorder.all( - color: Colors.black12, + color: Theme.of(context).primaryColorLight, width: 1, ), children: [ TableRow( - decoration: BoxDecoration( - color: Colors.grey[100], - ), + decoration: const BoxDecoration( + // color: Colors.grey[100], + ), children: [ TableCell( verticalAlignment: TableCellVerticalAlignment.middle, @@ -355,9 +343,9 @@ class BackupControllerPage extends HookConsumerWidget { ], ), TableRow( - decoration: BoxDecoration( - color: Colors.grey[200], - ), + decoration: const BoxDecoration( + // color: Colors.grey[200], + ), children: [ TableCell( verticalAlignment: TableCellVerticalAlignment.middle, @@ -384,9 +372,9 @@ class BackupControllerPage extends HookConsumerWidget { ], ), TableRow( - decoration: BoxDecoration( - color: Colors.grey[100], - ), + decoration: const BoxDecoration( + // color: Colors.grey[100], + ), children: [ TableCell( child: Padding( @@ -463,7 +451,7 @@ class BackupControllerPage extends HookConsumerWidget { "${backupState.allUniqueAssets.length - backupState.selectedAlbumsBackupAssetsIds.length}", ), const Divider(), - _buildBackupController(), + _buildAutoBackupController(), const Divider(), _buildStorageInformation(), const Divider(), @@ -479,7 +467,7 @@ class BackupControllerPage extends HookConsumerWidget { style: ElevatedButton.styleFrom( primary: Colors.red[300], onPrimary: Colors.grey[50], - padding: const EdgeInsets.all(14), + // padding: const EdgeInsets.all(14), ), onPressed: () { ref.read(backupProvider.notifier).cancelBackup(); @@ -493,11 +481,6 @@ class BackupControllerPage extends HookConsumerWidget { ).tr(), ) : ElevatedButton( - style: ElevatedButton.styleFrom( - primary: Theme.of(context).primaryColor, - onPrimary: Colors.grey[50], - padding: const EdgeInsets.all(14), - ), onPressed: shouldBackup ? startBackup : null, child: const Text( "backup_controller_page_start_backup", diff --git a/mobile/lib/modules/home/ui/control_bottom_app_bar.dart b/mobile/lib/modules/home/ui/control_bottom_app_bar.dart index 8d655a0f54..875647e73c 100644 --- a/mobile/lib/modules/home/ui/control_bottom_app_bar.dart +++ b/mobile/lib/modules/home/ui/control_bottom_app_bar.dart @@ -1,11 +1,9 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart'; import 'package:immich_mobile/modules/home/ui/delete_diaglog.dart'; -import '../../../shared/providers/asset.provider.dart'; -import '../providers/home_page_state.provider.dart'; - class ControlBottomAppBar extends ConsumerWidget { const ControlBottomAppBar({Key? key}) : super(key: key); @@ -19,10 +17,10 @@ class ControlBottomAppBar extends ConsumerWidget { height: MediaQuery.of(context).size.height * 0.15, decoration: BoxDecoration( borderRadius: const BorderRadius.only( - topLeft: Radius.circular(15), - topRight: Radius.circular(15), + topLeft: Radius.circular(8), + topRight: Radius.circular(8), ), - color: Colors.grey[300]?.withOpacity(0.98), + color: Theme.of(context).scaffoldBackgroundColor.withOpacity(0.95), ), child: Column( children: [ diff --git a/mobile/lib/modules/home/ui/daily_title_text.dart b/mobile/lib/modules/home/ui/daily_title_text.dart index ad2532b416..ce12a4b793 100644 --- a/mobile/lib/modules/home/ui/daily_title_text.dart +++ b/mobile/lib/modules/home/ui/daily_title_text.dart @@ -86,7 +86,6 @@ class DailyTitleText extends ConsumerWidget { style: const TextStyle( fontSize: 14, fontWeight: FontWeight.bold, - color: Colors.black87, ), ), const Spacer(), diff --git a/mobile/lib/modules/home/ui/disable_multi_select_button.dart b/mobile/lib/modules/home/ui/disable_multi_select_button.dart index 9a75bd6376..2d450832eb 100644 --- a/mobile/lib/modules/home/ui/disable_multi_select_button.dart +++ b/mobile/lib/modules/home/ui/disable_multi_select_button.dart @@ -14,32 +14,22 @@ class DisableMultiSelectButton extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { return Positioned( - top: 0, + top: 10, left: 0, child: Padding( padding: const EdgeInsets.only(left: 16.0, top: 46), - child: Material( - elevation: 20, - borderRadius: BorderRadius.circular(35), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(35), - color: Colors.grey[100], - ), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 4.0), - child: TextButton.icon( - onPressed: () { - onPressed(); - }, - icon: const Icon(Icons.close_rounded), - label: Text( - '$selectedItemCount', - style: const TextStyle( - fontWeight: FontWeight.w600, - fontSize: 18, - ), - ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 4.0), + child: ElevatedButton.icon( + onPressed: () { + onPressed(); + }, + icon: const Icon(Icons.close_rounded), + label: Text( + '$selectedItemCount', + style: const TextStyle( + fontWeight: FontWeight.w600, + fontSize: 18, ), ), ), diff --git a/mobile/lib/modules/home/ui/immich_sliver_appbar.dart b/mobile/lib/modules/home/ui/immich_sliver_appbar.dart index 7e71cf93f4..cc50af8a5f 100644 --- a/mobile/lib/modules/home/ui/immich_sliver_appbar.dart +++ b/mobile/lib/modules/home/ui/immich_sliver_appbar.dart @@ -30,6 +30,7 @@ class ImmichSliverAppBar extends ConsumerWidget { floating: true, pinned: false, snap: false, + backgroundColor: Theme.of(context).appBarTheme.backgroundColor, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(5)), ), @@ -57,7 +58,7 @@ class ImmichSliverAppBar extends ConsumerWidget { child: GestureDetector( onTap: () => Scaffold.of(context).openDrawer(), child: Material( - color: Colors.grey[200], + // color: Colors.grey[200], elevation: 1, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(50.0), @@ -77,13 +78,12 @@ class ImmichSliverAppBar extends ConsumerWidget { ); }, ), - title: Text( + title: const Text( 'IMMICH', style: TextStyle( fontFamily: 'SnowburstOne', fontWeight: FontWeight.bold, fontSize: 22, - color: Theme.of(context).primaryColor, ), ), actions: [ @@ -112,12 +112,13 @@ class ImmichSliverAppBar extends ConsumerWidget { ? const Icon(Icons.backup_rounded) : Badge( padding: const EdgeInsets.all(4), - elevation: 2, + elevation: 3, position: BadgePosition.bottomEnd(bottom: -4, end: -4), badgeColor: Colors.white, badgeContent: const Icon( Icons.cloud_off_rounded, size: 8, + color: Colors.indigo, ), child: const Icon(Icons.backup_rounded), ), diff --git a/mobile/lib/modules/home/ui/monthly_title_text.dart b/mobile/lib/modules/home/ui/monthly_title_text.dart index f319624604..a68ea69ee5 100644 --- a/mobile/lib/modules/home/ui/monthly_title_text.dart +++ b/mobile/lib/modules/home/ui/monthly_title_text.dart @@ -22,7 +22,7 @@ class MonthlyTitleText extends StatelessWidget { style: TextStyle( fontSize: 26, fontWeight: FontWeight.bold, - color: Theme.of(context).primaryColor, + color: Theme.of(context).textTheme.headline1?.color, ), ), ), diff --git a/mobile/lib/modules/home/ui/profile_drawer/profile_drawer.dart b/mobile/lib/modules/home/ui/profile_drawer/profile_drawer.dart index 136f29b192..d8bb50c329 100644 --- a/mobile/lib/modules/home/ui/profile_drawer/profile_drawer.dart +++ b/mobile/lib/modules/home/ui/profile_drawer/profile_drawer.dart @@ -22,17 +22,16 @@ class ProfileDrawer extends HookConsumerWidget { height: double.infinity, child: Icon( Icons.logout_rounded, - color: Colors.grey[700], + color: Theme.of(context).textTheme.labelMedium?.color, size: 20, ), ), title: Text( "profile_drawer_sign_out", - style: TextStyle( - color: Colors.grey[700], - fontSize: 12, - fontWeight: FontWeight.bold, - ), + style: Theme.of(context) + .textTheme + .labelLarge + ?.copyWith(fontWeight: FontWeight.bold), ).tr(), onTap: () async { bool res = await ref.watch(authenticationProvider.notifier).logout(); @@ -54,17 +53,16 @@ class ProfileDrawer extends HookConsumerWidget { height: double.infinity, child: Icon( Icons.settings_rounded, - color: Colors.grey[700], + color: Theme.of(context).textTheme.labelMedium?.color, size: 20, ), ), title: Text( "profile_drawer_settings", - style: TextStyle( - color: Colors.grey[700], - fontSize: 12, - fontWeight: FontWeight.bold, - ), + style: Theme.of(context) + .textTheme + .labelLarge + ?.copyWith(fontWeight: FontWeight.bold), ).tr(), onTap: () { AutoRouter.of(context).push(const SettingsRoute()); diff --git a/mobile/lib/modules/home/ui/profile_drawer/profile_drawer_header.dart b/mobile/lib/modules/home/ui/profile_drawer/profile_drawer_header.dart index 50e88a7fa5..d8187b8c5e 100644 --- a/mobile/lib/modules/home/ui/profile_drawer/profile_drawer_header.dart +++ b/mobile/lib/modules/home/ui/profile_drawer/profile_drawer_header.dart @@ -23,6 +23,7 @@ class ProfileDrawerHeader extends HookConsumerWidget { final uploadProfileImageStatus = ref.watch(uploadProfileImageProvider).status; var dummmy = Random().nextInt(1024); + final isDarkMode = Theme.of(context).brightness == Brightness.dark; _buildUserProfileImage() { if (authState.profileImagePath.isEmpty) { @@ -104,13 +105,19 @@ class ProfileDrawerHeader extends HookConsumerWidget { ); return DrawerHeader( - decoration: const BoxDecoration( + decoration: BoxDecoration( gradient: LinearGradient( - colors: [ - Color.fromARGB(255, 216, 219, 238), - Color.fromARGB(255, 242, 242, 242), - Colors.white, - ], + colors: isDarkMode + ? [ + const Color.fromARGB(255, 22, 25, 48), + const Color.fromARGB(255, 13, 13, 13), + const Color.fromARGB(255, 0, 0, 0), + ] + : [ + const Color.fromARGB(255, 216, 219, 238), + const Color.fromARGB(255, 242, 242, 242), + Colors.white, + ], begin: Alignment.centerRight, end: Alignment.centerLeft, ), @@ -129,8 +136,8 @@ class ProfileDrawerHeader extends HookConsumerWidget { child: GestureDetector( onTap: _pickUserProfileImage, child: Material( - color: Colors.grey[50], - elevation: 2, + color: Colors.grey[100], + elevation: 3, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(50.0), ), @@ -157,7 +164,7 @@ class ProfileDrawerHeader extends HookConsumerWidget { ), Text( authState.userEmail, - style: TextStyle(color: Colors.grey[800], fontSize: 12), + style: Theme.of(context).textTheme.labelMedium, ) ], ), diff --git a/mobile/lib/modules/home/ui/profile_drawer/server_info_box.dart b/mobile/lib/modules/home/ui/profile_drawer/server_info_box.dart index 1583983434..8cd84fdfce 100644 --- a/mobile/lib/modules/home/ui/profile_drawer/server_info_box.dart +++ b/mobile/lib/modules/home/ui/profile_drawer/server_info_box.dart @@ -38,7 +38,7 @@ class ServerInfoBox extends HookConsumerWidget { padding: const EdgeInsets.all(8.0), child: Card( elevation: 0, - color: Colors.grey[100], + color: Theme.of(context).scaffoldBackgroundColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), // if you need this side: const BorderSide( @@ -65,7 +65,10 @@ class ServerInfoBox extends HookConsumerWidget { ), ), ), - const Divider(), + const Divider( + color: Color.fromARGB(101, 201, 201, 201), + thickness: 1, + ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -87,7 +90,10 @@ class ServerInfoBox extends HookConsumerWidget { ), ], ), - const Divider(), + const Divider( + color: Color.fromARGB(101, 201, 201, 201), + thickness: 1, + ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/mobile/lib/modules/home/views/home_page.dart b/mobile/lib/modules/home/views/home_page.dart index b28036ec50..7bb1dbb828 100644 --- a/mobile/lib/modules/home/views/home_page.dart +++ b/mobile/lib/modules/home/views/home_page.dart @@ -117,9 +117,9 @@ class HomePage extends HookConsumerWidget { ], ), Padding( - padding: const EdgeInsets.only(top: 50.0), + padding: const EdgeInsets.only(top: 60.0, bottom: 30.0), child: DraggableScrollbar.semicircle( - backgroundColor: Theme.of(context).primaryColor, + backgroundColor: Theme.of(context).hintColor, controller: scrollController, heightScrollThumb: 48.0, child: CustomScrollView( diff --git a/mobile/lib/modules/search/ui/thumbnail_with_info.dart b/mobile/lib/modules/search/ui/thumbnail_with_info.dart index d65db0224c..211a72d71f 100644 --- a/mobile/lib/modules/search/ui/thumbnail_with_info.dart +++ b/mobile/lib/modules/search/ui/thumbnail_with_info.dart @@ -26,7 +26,7 @@ class ThumbnailWithInfo extends StatelessWidget { child: Padding( padding: const EdgeInsets.only(right: 8.0), child: SizedBox( - width: MediaQuery.of(context).size.width / 2, + width: MediaQuery.of(context).size.width / 3, child: Stack( alignment: Alignment.bottomCenter, children: [ @@ -58,7 +58,7 @@ class ThumbnailWithInfo extends StatelessWidget { style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, - fontSize: 16, + fontSize: 14, ), ), ), diff --git a/mobile/lib/modules/search/views/search_page.dart b/mobile/lib/modules/search/views/search_page.dart index e29e1d97b9..6254540b84 100644 --- a/mobile/lib/modules/search/views/search_page.dart +++ b/mobile/lib/modules/search/views/search_page.dart @@ -29,6 +29,8 @@ class SearchPage extends HookConsumerWidget { AsyncValue> curatedObjects = ref.watch(getCuratedObjectProvider); + double imageSize = MediaQuery.of(context).size.width / 3; + useEffect( () { searchFocusNode = FocusNode(); @@ -46,15 +48,15 @@ class SearchPage extends HookConsumerWidget { _buildPlaces() { return curatedLocation.when( - loading: () => const SizedBox( - height: 200, - child: Center(child: ImmichLoadingIndicator()), + loading: () => SizedBox( + height: imageSize, + child: const Center(child: ImmichLoadingIndicator()), ), error: (err, stack) => Text('Error: $err'), data: (curatedLocations) { return curatedLocations.isNotEmpty ? SizedBox( - height: MediaQuery.of(context).size.width / 2, + height: imageSize, child: ListView.builder( padding: const EdgeInsets.only(left: 16), scrollDirection: Axis.horizontal, @@ -76,7 +78,7 @@ class SearchPage extends HookConsumerWidget { ), ) : SizedBox( - height: MediaQuery.of(context).size.width / 2, + height: imageSize, child: ListView.builder( padding: const EdgeInsets.only(left: 16), scrollDirection: Axis.horizontal, @@ -105,7 +107,7 @@ class SearchPage extends HookConsumerWidget { data: (objects) { return objects.isNotEmpty ? SizedBox( - height: MediaQuery.of(context).size.width / 2, + height: imageSize, child: ListView.builder( padding: const EdgeInsets.only(left: 16), scrollDirection: Axis.horizontal, @@ -113,7 +115,7 @@ class SearchPage extends HookConsumerWidget { itemBuilder: ((context, index) { var curatedObjectInfo = objects[index]; var thumbnailRequestUrl = - '${box.get(serverEndpointKey)}/asset/file?aid=${curatedObjectInfo.deviceAssetId}&did=${curatedObjectInfo.deviceId}&isThumb=true'; + '${box.get(serverEndpointKey)}/asset/thumbnail/${curatedObjectInfo.id}'; return ThumbnailWithInfo( imageUrl: thumbnailRequestUrl, @@ -131,7 +133,8 @@ class SearchPage extends HookConsumerWidget { ), ) : SizedBox( - height: MediaQuery.of(context).size.width / 2, + // height: imageSize, + width: imageSize, child: ListView.builder( padding: const EdgeInsets.only(left: 16), scrollDirection: Axis.horizontal, @@ -163,12 +166,13 @@ class SearchPage extends HookConsumerWidget { child: Stack( children: [ ListView( + shrinkWrap: true, children: [ Padding( padding: const EdgeInsets.all(16.0), child: const Text( "search_page_places", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14), ).tr(), ), _buildPlaces(), @@ -176,7 +180,7 @@ class SearchPage extends HookConsumerWidget { padding: const EdgeInsets.all(16.0), child: const Text( "search_page_things", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14), ).tr(), ), _buildThings() diff --git a/mobile/lib/modules/search/views/search_result_page.dart b/mobile/lib/modules/search/views/search_result_page.dart index fa81613b57..09f38ffb0f 100644 --- a/mobile/lib/modules/search/views/search_result_page.dart +++ b/mobile/lib/modules/search/views/search_result_page.dart @@ -172,7 +172,7 @@ class SearchResultPage extends HookConsumerWidget { }); return DraggableScrollbar.semicircle( - backgroundColor: Theme.of(context).primaryColor, + backgroundColor: Theme.of(context).hintColor, controller: scrollController, heightScrollThumb: 48.0, child: CustomScrollView( diff --git a/mobile/lib/modules/settings/providers/app_settings.provider.dart b/mobile/lib/modules/settings/providers/app_settings.provider.dart new file mode 100644 index 0000000000..f5d172e4c4 --- /dev/null +++ b/mobile/lib/modules/settings/providers/app_settings.provider.dart @@ -0,0 +1,4 @@ +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; + +final appSettingsServiceProvider = Provider((ref) => AppSettingsService()); diff --git a/mobile/lib/modules/settings/providers/store_providers_here.txt b/mobile/lib/modules/settings/providers/store_providers_here.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/mobile/lib/shared/services/app_settings.service.dart b/mobile/lib/modules/settings/services/app_settings.service.dart similarity index 91% rename from mobile/lib/shared/services/app_settings.service.dart rename to mobile/lib/modules/settings/services/app_settings.service.dart index dca81d00a1..4324c32c1b 100644 --- a/mobile/lib/shared/services/app_settings.service.dart +++ b/mobile/lib/modules/settings/services/app_settings.service.dart @@ -5,7 +5,7 @@ import 'package:immich_mobile/constants/hive_box.dart'; enum AppSettingsEnum { threeStageLoading, // true, false, - themeMode, // "light","dark" + themeMode, // "light","dark","system" } class AppSettingsService { @@ -61,8 +61,8 @@ class AppSettingsService { // Default value of themeMode is "light" if (settingType == AppSettingsEnum.themeMode) { - hiveBox.put(settingKey, "light"); - return "light"; + hiveBox.put(settingKey, "system"); + return "system"; } } @@ -75,5 +75,3 @@ class AppSettingsService { } } } - -final appSettingsServiceProvider = Provider((ref) => AppSettingsService()); diff --git a/mobile/lib/modules/settings/services/store_services_here.txt b/mobile/lib/modules/settings/services/store_services_here.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/mobile/lib/modules/settings/ui/image_viewer_quality_setting/image_viewer_quality_setting.dart b/mobile/lib/modules/settings/ui/image_viewer_quality_setting/image_viewer_quality_setting.dart index 9229ca11d4..861f7efa9b 100644 --- a/mobile/lib/modules/settings/ui/image_viewer_quality_setting/image_viewer_quality_setting.dart +++ b/mobile/lib/modules/settings/ui/image_viewer_quality_setting/image_viewer_quality_setting.dart @@ -1,3 +1,4 @@ +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:immich_mobile/modules/settings/ui/image_viewer_quality_setting/three_stage_loading.dart'; @@ -8,20 +9,21 @@ class ImageViewerQualitySetting extends StatelessWidget { @override Widget build(BuildContext context) { - return const ExpansionTile( - title: Text( - 'Image viewer quality', + return ExpansionTile( + textColor: Theme.of(context).primaryColor, + title: const Text( + 'theme_setting_image_viewer_quality_title', style: TextStyle( fontWeight: FontWeight.bold, ), - ), - subtitle: Text( - 'Adjust the quality of the detail image viewer', + ).tr(), + subtitle: const Text( + 'theme_setting_image_viewer_quality_subtitle', style: TextStyle( fontSize: 13, ), - ), - children: [ + ).tr(), + children: const [ ThreeStageLoading(), ], ); diff --git a/mobile/lib/modules/settings/ui/image_viewer_quality_setting/three_stage_loading.dart b/mobile/lib/modules/settings/ui/image_viewer_quality_setting/three_stage_loading.dart index c1309448d9..24169a7fb8 100644 --- a/mobile/lib/modules/settings/ui/image_viewer_quality_setting/three_stage_loading.dart +++ b/mobile/lib/modules/settings/ui/image_viewer_quality_setting/three_stage_loading.dart @@ -1,7 +1,9 @@ +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/shared/services/app_settings.service.dart'; +import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; +import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; class ThreeStageLoading extends HookConsumerWidget { const ThreeStageLoading({ @@ -35,18 +37,18 @@ class ThreeStageLoading extends HookConsumerWidget { return SwitchListTile.adaptive( title: const Text( - "Enable three stage loading", + "theme_setting_three_stage_loading_title", style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, ), - ), + ).tr(), subtitle: const Text( - "The three-stage loading delivers the best quality image in exchange for a slower loading speed", + "theme_setting_three_stage_loading_subtitle", style: TextStyle( fontSize: 12, ), - ), + ).tr(), value: isEnable.value, onChanged: onSwitchChanged, ); diff --git a/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart b/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart new file mode 100644 index 0000000000..2284a4c322 --- /dev/null +++ b/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart @@ -0,0 +1,107 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; +import 'package:immich_mobile/modules/settings/ui/image_viewer_quality_setting/three_stage_loading.dart'; +import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; +import 'package:immich_mobile/utils/immich_app_theme.dart'; + +class ThemeSetting extends HookConsumerWidget { + const ThemeSetting({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final currentTheme = useState(ThemeMode.system); + + useEffect( + () { + currentTheme.value = ref.read(immichThemeProvider); + return null; + }, + [], + ); + + return ExpansionTile( + textColor: Theme.of(context).primaryColor, + title: const Text( + 'theme_setting_theme_title', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ).tr(), + subtitle: const Text( + 'theme_setting_theme_subtitle', + style: TextStyle( + fontSize: 13, + ), + ).tr(), + children: [ + SwitchListTile.adaptive( + activeColor: Theme.of(context).primaryColor, + title: const Text( + 'theme_setting_system_theme_switch', + style: TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.bold, + ), + ).tr(), + value: currentTheme.value == ThemeMode.system, + onChanged: (bool isSystem) { + var currentSystemBrightness = + MediaQuery.of(context).platformBrightness; + + if (isSystem) { + currentTheme.value = ThemeMode.system; + ref.watch(immichThemeProvider.notifier).state = ThemeMode.system; + ref + .watch(appSettingsServiceProvider) + .setSetting(AppSettingsEnum.themeMode, "system"); + } else { + if (currentSystemBrightness == Brightness.light) { + currentTheme.value = ThemeMode.light; + ref.watch(immichThemeProvider.notifier).state = ThemeMode.light; + ref + .watch(appSettingsServiceProvider) + .setSetting(AppSettingsEnum.themeMode, "light"); + } else if (currentSystemBrightness == Brightness.dark) { + currentTheme.value = ThemeMode.dark; + ref.watch(immichThemeProvider.notifier).state = ThemeMode.dark; + ref + .watch(appSettingsServiceProvider) + .setSetting(AppSettingsEnum.themeMode, "dark"); + } + } + }, + ), + if (currentTheme.value != ThemeMode.system) + SwitchListTile.adaptive( + activeColor: Theme.of(context).primaryColor, + title: const Text( + 'theme_setting_dark_mode_switch', + style: TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.bold, + ), + ).tr(), + value: ref.watch(immichThemeProvider) == ThemeMode.dark, + onChanged: (bool isDark) { + if (isDark) { + ref.watch(immichThemeProvider.notifier).state = ThemeMode.dark; + ref + .watch(appSettingsServiceProvider) + .setSetting(AppSettingsEnum.themeMode, "dark"); + } else { + ref.watch(immichThemeProvider.notifier).state = ThemeMode.light; + ref + .watch(appSettingsServiceProvider) + .setSetting(AppSettingsEnum.themeMode, "light"); + } + }, + ), + ], + ); + } +} diff --git a/mobile/lib/modules/settings/views/settings_page.dart b/mobile/lib/modules/settings/views/settings_page.dart index 387b3a9531..5347999e51 100644 --- a/mobile/lib/modules/settings/views/settings_page.dart +++ b/mobile/lib/modules/settings/views/settings_page.dart @@ -1,6 +1,8 @@ +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/settings/ui/image_viewer_quality_setting/image_viewer_quality_setting.dart'; +import 'package:immich_mobile/modules/settings/ui/theme_setting/theme_setting.dart'; class SettingsPage extends HookConsumerWidget { const SettingsPage({Key? key}) : super(key: key); @@ -20,12 +22,12 @@ class SettingsPage extends HookConsumerWidget { automaticallyImplyLeading: false, centerTitle: false, title: const Text( - 'Settings', + 'setting_pages_app_bar_settings', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), - ), + ).tr(), ), body: ListView( children: [ @@ -33,10 +35,7 @@ class SettingsPage extends HookConsumerWidget { context: context, tiles: [ const ImageViewerQualitySetting(), - const SettingListTile( - title: 'Theme', - subtitle: 'Choose between light and dark theme', - ), + const ThemeSetting(), ], ).toList(), ], @@ -44,38 +43,3 @@ class SettingsPage extends HookConsumerWidget { ); } } - -class SettingListTile extends StatelessWidget { - const SettingListTile({ - required this.title, - required this.subtitle, - Key? key, - }) : super(key: key); - - final String title; - final String subtitle; - - @override - Widget build(BuildContext context) { - return ListTile( - dense: true, - title: Text( - title, - style: const TextStyle( - fontWeight: FontWeight.bold, - ), - ), - subtitle: Text( - subtitle, - style: const TextStyle( - fontSize: 12, - ), - ), - trailing: const Icon( - Icons.keyboard_arrow_right_rounded, - size: 24, - ), - onTap: () {}, - ); - } -} diff --git a/mobile/lib/shared/views/splash_screen.dart b/mobile/lib/shared/views/splash_screen.dart index 23a5456023..e7fc8ae495 100644 --- a/mobile/lib/shared/views/splash_screen.dart +++ b/mobile/lib/shared/views/splash_screen.dart @@ -4,7 +4,6 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/hive_box.dart'; -import 'package:immich_mobile/constants/immich_colors.dart'; import 'package:immich_mobile/modules/backup/providers/backup.provider.dart'; import 'package:immich_mobile/modules/login/models/hive_saved_login_info.model.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; @@ -49,7 +48,6 @@ class SplashScreenPage extends HookConsumerWidget { ); return Scaffold( - backgroundColor: immichBackgroundColor, body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/mobile/lib/shared/views/tab_controller_page.dart b/mobile/lib/shared/views/tab_controller_page.dart index a55aa5937d..51a13fea5a 100644 --- a/mobile/lib/shared/views/tab_controller_page.dart +++ b/mobile/lib/shared/views/tab_controller_page.dart @@ -2,7 +2,6 @@ import 'package:auto_route/auto_route.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/constants/immich_colors.dart'; import 'package:immich_mobile/modules/home/providers/home_page_state.provider.dart'; import 'package:immich_mobile/routing/router.dart'; @@ -36,8 +35,6 @@ class TabControllerPage extends ConsumerWidget { bottomNavigationBar: isMultiSelectEnable ? null : BottomNavigationBar( - type: BottomNavigationBarType.fixed, - backgroundColor: immichBackgroundColor, selectedLabelStyle: const TextStyle( fontSize: 13, fontWeight: FontWeight.w600, diff --git a/mobile/lib/utils/immich_app_theme.dart b/mobile/lib/utils/immich_app_theme.dart new file mode 100644 index 0000000000..64daafe0de --- /dev/null +++ b/mobile/lib/utils/immich_app_theme.dart @@ -0,0 +1,133 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/constants/immich_colors.dart'; +import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; +import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; + +final immichThemeProvider = StateProvider((ref) { + var themeMode = ref + .watch(appSettingsServiceProvider) + .getSetting(AppSettingsEnum.themeMode); + + debugPrint("Current themeMode $themeMode"); + + if (themeMode == "light") { + return ThemeMode.light; + } else if (themeMode == "dark") { + return ThemeMode.dark; + } else { + return ThemeMode.system; + } +}); + +ThemeData immichDarkTheme = ThemeData( + useMaterial3: true, + brightness: Brightness.dark, + primarySwatch: Colors.indigo, + primaryColor: immichDarkThemePrimaryColor, + scaffoldBackgroundColor: immichDarkBackgroundColor, + hintColor: Colors.grey[600], + fontFamily: 'WorkSans', + snackBarTheme: const SnackBarThemeData( + contentTextStyle: TextStyle(fontFamily: 'WorkSans'), + ), + appBarTheme: AppBarTheme( + titleTextStyle: TextStyle( + fontFamily: 'WorkSans', + color: immichDarkThemePrimaryColor, + ), + backgroundColor: const Color.fromARGB(255, 32, 33, 35), + foregroundColor: immichDarkThemePrimaryColor, + elevation: 1, + centerTitle: true, + systemOverlayStyle: SystemUiOverlayStyle.light, + ), + bottomNavigationBarTheme: BottomNavigationBarThemeData( + type: BottomNavigationBarType.fixed, + backgroundColor: const Color.fromARGB(255, 35, 36, 37), + selectedItemColor: immichDarkThemePrimaryColor, + ), + drawerTheme: DrawerThemeData( + backgroundColor: immichDarkBackgroundColor, + scrimColor: Colors.white.withOpacity(0.1), + ), + textTheme: TextTheme( + headline1: const TextStyle( + fontSize: 26, + fontWeight: FontWeight.bold, + color: Color.fromARGB(255, 255, 255, 255), + ), + headline2: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Color.fromARGB(255, 148, 151, 155), + ), + headline3: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: immichDarkThemePrimaryColor, + ), + ), + cardColor: Colors.grey[900], + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + onPrimary: Colors.black87, + primary: immichDarkThemePrimaryColor, + ), + ), +); + +ThemeData immichLightTheme = ThemeData( + useMaterial3: true, + brightness: Brightness.light, + primarySwatch: Colors.indigo, + hintColor: Colors.indigo, + fontFamily: 'WorkSans', + scaffoldBackgroundColor: immichBackgroundColor, + snackBarTheme: const SnackBarThemeData( + contentTextStyle: TextStyle(fontFamily: 'WorkSans'), + ), + appBarTheme: AppBarTheme( + titleTextStyle: const TextStyle( + fontFamily: 'WorkSans', + color: Colors.indigo, + ), + backgroundColor: immichBackgroundColor, + foregroundColor: Colors.indigo, + elevation: 1, + centerTitle: true, + systemOverlayStyle: SystemUiOverlayStyle.dark, + ), + bottomNavigationBarTheme: BottomNavigationBarThemeData( + type: BottomNavigationBarType.fixed, + backgroundColor: immichBackgroundColor, + selectedItemColor: Colors.indigo, + ), + drawerTheme: DrawerThemeData( + backgroundColor: immichBackgroundColor, + ), + textTheme: const TextTheme( + headline1: TextStyle( + fontSize: 26, + fontWeight: FontWeight.bold, + color: Colors.indigo, + ), + headline2: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black87, + ), + headline3: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: Colors.indigo, + ), + ), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + primary: Colors.indigo, + onPrimary: Colors.white, + ), + ), +); diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 7e645f7e84..b3a8750cfb 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -2,7 +2,7 @@ name: immich_mobile description: Immich - selfhosted backup media file on mobile phone publish_to: "none" -version: 1.22.0+32 +version: 1.23.0+33 environment: sdk: ">=2.17.0 <3.0.0" diff --git a/server/apps/immich/src/constants/server_version.constant.ts b/server/apps/immich/src/constants/server_version.constant.ts index a43fb20a88..5552d69d0a 100644 --- a/server/apps/immich/src/constants/server_version.constant.ts +++ b/server/apps/immich/src/constants/server_version.constant.ts @@ -10,7 +10,7 @@ export interface IServerVersion { export const serverVersion: IServerVersion = { major: 1, - minor: 22, + minor: 23, patch: 0, build: 0, };