diff --git a/mobile/lib/constants/immich_colors.dart b/mobile/lib/constants/immich_colors.dart deleted file mode 100644 index e3f601358..000000000 --- a/mobile/lib/constants/immich_colors.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:flutter/material.dart'; - -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/modules/album/ui/album_thumbnail_card.dart b/mobile/lib/modules/album/ui/album_thumbnail_card.dart index f37751e3e..d261dbc6c 100644 --- a/mobile/lib/modules/album/ui/album_thumbnail_card.dart +++ b/mobile/lib/modules/album/ui/album_thumbnail_card.dart @@ -28,25 +28,33 @@ class AlbumThumbnailCard extends StatelessWidget { var cardSize = constraints.maxWidth; buildEmptyThumbnail() { - return Container( + return SizedBox( height: cardSize, width: cardSize, - decoration: BoxDecoration( - color: isDarkMode ? Colors.grey[800] : Colors.grey[200], - ), - child: Center( - child: Icon( - Icons.no_photography, - size: cardSize * .15, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20.0), + ), + child: Center( + child: Icon( + Icons.no_photography, + size: cardSize * .15, + ), ), ), ); } - buildAlbumThumbnail() => ImmichImage( - album.thumbnail.value, - width: cardSize, - height: cardSize, + buildAlbumThumbnail() => Card( + clipBehavior: Clip.hardEdge, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + child: ImmichImage( + album.thumbnail.value, + width: cardSize, + height: cardSize, + ), ); buildAlbumTextRow() { diff --git a/mobile/lib/modules/album/ui/album_thumbnail_listtile.dart b/mobile/lib/modules/album/ui/album_thumbnail_listtile.dart index c9237ea27..db86f9891 100644 --- a/mobile/lib/modules/album/ui/album_thumbnail_listtile.dart +++ b/mobile/lib/modules/album/ui/album_thumbnail_listtile.dart @@ -21,39 +21,48 @@ class AlbumThumbnailListTile extends StatelessWidget { @override Widget build(BuildContext context) { var cardSize = 68.0; - var isDarkMode = Theme.of(context).brightness == Brightness.dark; buildEmptyThumbnail() { - return Container( - decoration: BoxDecoration( - color: isDarkMode ? Colors.grey[800] : Colors.grey[200], - ), - child: SizedBox( - height: cardSize, - width: cardSize, - child: const Center( - child: Icon(Icons.no_photography), + return SizedBox( + height: cardSize, + width: cardSize, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20.0), + ), + child: Center( + child: Icon( + Icons.no_photography, + size: cardSize * .15, + ), ), ), ); } buildAlbumThumbnail() { - return CachedNetworkImage( - width: cardSize, - height: cardSize, - fit: BoxFit.cover, - fadeInDuration: const Duration(milliseconds: 200), - imageUrl: getAlbumThumbnailUrl( - album, - type: ThumbnailFormat.JPEG, + return Card( + clipBehavior: Clip.hardEdge, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + child: CachedNetworkImage( + width: cardSize, + height: cardSize, + fit: BoxFit.cover, + fadeInDuration: const Duration(milliseconds: 200), + imageUrl: getAlbumThumbnailUrl( + album, + type: ThumbnailFormat.JPEG, + ), + httpHeaders: { + "Authorization": "Bearer ${Store.get(StoreKey.accessToken)}", + }, + cacheKey: + getAlbumThumbNailCacheKey(album, type: ThumbnailFormat.JPEG), + errorWidget: (context, url, error) => + const Icon(Icons.image_not_supported_outlined), ), - httpHeaders: { - "Authorization": "Bearer ${Store.get(StoreKey.accessToken)}", - }, - cacheKey: getAlbumThumbNailCacheKey(album, type: ThumbnailFormat.JPEG), - errorWidget: (context, url, error) => - const Icon(Icons.image_not_supported_outlined), ); } diff --git a/mobile/lib/modules/album/views/album_viewer_page.dart b/mobile/lib/modules/album/views/album_viewer_page.dart index dc30b3718..1ce33e1df 100644 --- a/mobile/lib/modules/album/views/album_viewer_page.dart +++ b/mobile/lib/modules/album/views/album_viewer_page.dart @@ -151,7 +151,7 @@ class AlbumViewerPage extends HookConsumerWidget { titleFocusNode: titleFocusNode, ) : Padding( - padding: const EdgeInsets.only(left: 8.0), + padding: const EdgeInsets.only(left: 8.0, bottom: 20.0), child: Text( album.name, style: const TextStyle( diff --git a/mobile/lib/modules/album/views/library_page.dart b/mobile/lib/modules/album/views/library_page.dart index 90d095640..029e90226 100644 --- a/mobile/lib/modules/album/views/library_page.dart +++ b/mobile/lib/modules/album/views/library_page.dart @@ -21,7 +21,6 @@ class LibraryPage extends HookConsumerWidget { final trashEnabled = ref.watch(serverInfoProvider.select((v) => v.serverFeatures.trash)); final albums = ref.watch(albumProvider); - var isDarkMode = Theme.of(context).brightness == Brightness.dark; var settings = ref.watch(appSettingsServiceProvider); useEffect( @@ -138,51 +137,55 @@ class LibraryPage extends HookConsumerWidget { } Widget buildCreateAlbumButton() { - return GestureDetector( - onTap: () { - AutoRouter.of(context).push(CreateAlbumRoute(isSharedAlbum: false)); + return LayoutBuilder( + builder: (context, constraints) { + var cardSize = constraints.maxWidth; + + return GestureDetector( + onTap: () { + AutoRouter.of(context) + .push(CreateAlbumRoute(isSharedAlbum: false)); + }, + child: Padding( + padding: const EdgeInsets.only(bottom: 32), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: cardSize, + width: cardSize, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20.0), + ), + child: Center( + child: Icon( + Icons.add_rounded, + size: 28, + color: Theme.of(context).primaryColor, + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only( + top: 8.0, + bottom: 16, + left: 8.0, + ), + child: const Text( + 'library_page_new_album', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ).tr(), + ), + ], + ), + ), + ); }, - child: Padding( - padding: const EdgeInsets.only(bottom: 32), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Container( - decoration: BoxDecoration( - border: Border.all( - color: isDarkMode - ? const Color.fromARGB(255, 53, 53, 53) - : const Color.fromARGB(255, 203, 203, 203), - ), - color: isDarkMode ? Colors.grey[900] : Colors.grey[50], - borderRadius: BorderRadius.circular(20), - ), - child: Center( - child: Icon( - Icons.add_rounded, - size: 28, - color: Theme.of(context).primaryColor, - ), - ), - ), - ), - Padding( - padding: const EdgeInsets.only( - top: 8.0, - bottom: 16, - ), - child: const Text( - 'library_page_new_album', - style: TextStyle( - fontWeight: FontWeight.bold, - ), - ).tr(), - ), - ], - ), - ), ); } @@ -192,30 +195,19 @@ class LibraryPage extends HookConsumerWidget { Function() onClick, ) { return Expanded( - child: OutlinedButton.icon( + child: ElevatedButton.icon( onPressed: onClick, label: Padding( padding: const EdgeInsets.only(left: 8.0), child: Text( label, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 13.0, - color: isDarkMode ? Colors.white : Colors.grey[800], + ), + ), + style: Theme.of(context).elevatedButtonTheme.style?.copyWith( + alignment: Alignment.centerLeft, ), - ), - ), - style: OutlinedButton.styleFrom( - padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), - backgroundColor: isDarkMode ? Colors.grey[900] : Colors.grey[50], - side: BorderSide( - color: isDarkMode ? Colors.grey[800]! : Colors.grey[300]!, - ), - alignment: Alignment.centerLeft, - ), icon: Icon( icon, - color: Theme.of(context).primaryColor, ), ), ); @@ -293,7 +285,6 @@ class LibraryPage extends HookConsumerWidget { sliver: SliverGrid( gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 250, - mainAxisSpacing: 12, crossAxisSpacing: 12, childAspectRatio: .7, ), diff --git a/mobile/lib/modules/album/views/sharing_page.dart b/mobile/lib/modules/album/views/sharing_page.dart index 5e74aef67..4f26c58b0 100644 --- a/mobile/lib/modules/album/views/sharing_page.dart +++ b/mobile/lib/modules/album/views/sharing_page.dart @@ -134,13 +134,12 @@ class SharingPage extends HookConsumerWidget { Icons.photo_album_outlined, size: 20, ), + style: Theme.of(context).elevatedButtonTheme.style?.copyWith( + alignment: Alignment.centerLeft, + ), label: const Text( "sharing_silver_appbar_create_shared_album", maxLines: 1, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 11, - ), ).tr(), ), ), @@ -153,12 +152,11 @@ class SharingPage extends HookConsumerWidget { Icons.link, size: 20, ), + style: Theme.of(context).elevatedButtonTheme.style?.copyWith( + alignment: Alignment.centerLeft, + ), label: const Text( "sharing_silver_appbar_shared_links", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 11, - ), maxLines: 1, ).tr(), ), @@ -198,7 +196,10 @@ class SharingPage extends HookConsumerWidget { padding: const EdgeInsets.all(8.0), child: Text( 'sharing_page_empty_list', - style: Theme.of(context).textTheme.displaySmall, + style: Theme.of(context) + .textTheme + .displaySmall + ?.copyWith(color: Theme.of(context).primaryColor), ).tr(), ), Padding( 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 9e4118038..b7151f5dc 100644 --- a/mobile/lib/modules/backup/views/backup_album_selection_page.dart +++ b/mobile/lib/modules/backup/views/backup_album_selection_page.dart @@ -4,7 +4,6 @@ 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/modules/backup/ui/album_info_list_tile.dart'; @@ -148,13 +147,12 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { album.name, style: TextStyle( fontSize: 10, - color: isDarkTheme ? Colors.black : immichBackgroundColor, + color: Theme.of(context).colorScheme.surface, fontWeight: FontWeight.bold, ), ), backgroundColor: Colors.red[300], - deleteIconColor: - isDarkTheme ? Colors.black : immichBackgroundColor, + deleteIconColor: Theme.of(context).colorScheme.surface, deleteIcon: const Icon( Icons.cancel_rounded, size: 15, diff --git a/mobile/lib/modules/home/ui/asset_grid/disable_multi_select_button.dart b/mobile/lib/modules/home/ui/asset_grid/disable_multi_select_button.dart index 98f932ab2..f0c3a0a22 100644 --- a/mobile/lib/modules/home/ui/asset_grid/disable_multi_select_button.dart +++ b/mobile/lib/modules/home/ui/asset_grid/disable_multi_select_button.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -class DisableMultiSelectButton extends ConsumerWidget { +class DisableMultiSelectButton extends StatelessWidget { const DisableMultiSelectButton({ Key? key, required this.onPressed, @@ -12,25 +11,29 @@ class DisableMultiSelectButton extends ConsumerWidget { final int selectedItemCount; @override - Widget build(BuildContext context, WidgetRef ref) { + Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.only(left: 16.0, top: 16.0), - 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, - ), + padding: const EdgeInsets.only(left: 16.0, top: 16.0), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 4.0), + child: ElevatedButton.icon( + style: ElevatedButton.styleFrom( + foregroundColor: Theme.of(context).colorScheme.surface, + backgroundColor: Theme.of(context).colorScheme.primary, + ), + 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/asset_grid/draggable_scrollbar_custom.dart b/mobile/lib/modules/home/ui/asset_grid/draggable_scrollbar_custom.dart index d28d825c9..2c98bf520 100644 --- a/mobile/lib/modules/home/ui/asset_grid/draggable_scrollbar_custom.dart +++ b/mobile/lib/modules/home/ui/asset_grid/draggable_scrollbar_custom.dart @@ -6,6 +6,7 @@ import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; /// Build the Scroll Thumb and label using the current configuration typedef ScrollThumbBuilder = Widget Function( Color backgroundColor, + Color foregroundColor, Animation thumbAnimation, Animation labelAnimation, double height, { @@ -33,6 +34,9 @@ class DraggableScrollbar extends StatefulWidget { /// The background color of the label and thumb final Color backgroundColor; + /// The foreground color of the arrows in the thumb + final Color foregroundColor; + /// The amount of padding that should surround the thumb final EdgeInsetsGeometry? padding; @@ -66,6 +70,7 @@ class DraggableScrollbar extends StatefulWidget { required this.scrollStateListener, this.heightScrollThumb = 48.0, this.backgroundColor = Colors.white, + this.foregroundColor = Colors.white, this.padding, this.scrollbarAnimationDuration = const Duration(milliseconds: 300), this.scrollbarTimeToFade = const Duration(milliseconds: 600), @@ -85,6 +90,7 @@ class DraggableScrollbar extends StatefulWidget { static buildScrollThumbAndLabel({ required Widget scrollThumb, required Color backgroundColor, + required Color foregroundColor, required Animation? thumbAnimation, required Animation? labelAnimation, required Text? labelText, @@ -123,6 +129,7 @@ class DraggableScrollbar extends StatefulWidget { ) { return ( Color backgroundColor, + Color foregroundColor, Animation thumbAnimation, Animation labelAnimation, double height, { @@ -131,7 +138,7 @@ class DraggableScrollbar extends StatefulWidget { }) { final scrollThumb = CustomPaint( key: scrollThumbKey, - foregroundPainter: ArrowCustomPainter(Colors.white), + foregroundPainter: ArrowCustomPainter(foregroundColor), child: Material( elevation: 4.0, color: backgroundColor, @@ -150,6 +157,7 @@ class DraggableScrollbar extends StatefulWidget { return buildScrollThumbAndLabel( scrollThumb: scrollThumb, backgroundColor: backgroundColor, + foregroundColor: foregroundColor, thumbAnimation: thumbAnimation, labelAnimation: labelAnimation, labelText: labelText, @@ -286,6 +294,7 @@ class DraggableScrollbarState extends State padding: widget.padding, child: widget.scrollThumbBuilder( widget.backgroundColor, + widget.foregroundColor, _thumbAnimation, _labelAnimation, widget.heightScrollThumb, diff --git a/mobile/lib/modules/home/ui/asset_grid/group_divider_title.dart b/mobile/lib/modules/home/ui/asset_grid/group_divider_title.dart index d63b0631e..334fffb36 100644 --- a/mobile/lib/modules/home/ui/asset_grid/group_divider_title.dart +++ b/mobile/lib/modules/home/ui/asset_grid/group_divider_title.dart @@ -53,9 +53,12 @@ class GroupDividerTitle extends ConsumerWidget { Icons.check_circle_rounded, color: Theme.of(context).primaryColor, ) - : const Icon( + : Icon( Icons.check_circle_outline_rounded, - color: Colors.grey, + color: Theme.of(context) + .colorScheme + .onBackground + .withAlpha(100), ), ), ], diff --git a/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart b/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart index 3b900a5f1..afaf1655d 100644 --- a/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart +++ b/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart @@ -221,11 +221,7 @@ class ImmichAssetGridViewState extends State { padding: const EdgeInsets.only(left: 12.0, top: 24.0), child: Text( title, - style: TextStyle( - fontSize: 26, - fontWeight: FontWeight.bold, - color: Theme.of(context).textTheme.displayLarge?.color, - ), + style: Theme.of(context).textTheme.titleLarge, ), ); } @@ -243,7 +239,7 @@ class ImmichAssetGridViewState extends State { bottom: widget.margin, right: i + 1 == num ? 0.0 : widget.margin, ), - color: Colors.grey, + color: Theme.of(context).colorScheme.surfaceVariant, ), ], ); @@ -328,8 +324,8 @@ class ImmichAssetGridViewState extends State { return Text( DateFormat.yMMMM().format(date), - style: const TextStyle( - color: Colors.white, + style: TextStyle( + color: Theme.of(context).colorScheme.onPrimary, fontWeight: FontWeight.bold, ), ); @@ -372,7 +368,8 @@ class ImmichAssetGridViewState extends State { scrollStateListener: dragScrolling, itemPositionsListener: _itemPositionsListener, controller: _itemScrollController, - backgroundColor: Theme.of(context).hintColor, + backgroundColor: Theme.of(context).colorScheme.primary, + foregroundColor: Theme.of(context).colorScheme.onPrimary, labelTextBuilder: _labelBuilder, labelConstraints: const BoxConstraints(maxHeight: 28), scrollbarAnimationDuration: const Duration(milliseconds: 300), diff --git a/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart b/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart index 16423b3b4..e0f2a323a 100644 --- a/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart +++ b/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart @@ -43,9 +43,6 @@ class ThumbnailImage extends StatelessWidget { @override Widget build(BuildContext context) { - final isDarkTheme = Theme.of(context).brightness == Brightness.dark; - final assetContainerColor = - isDarkTheme ? Colors.blueGrey : Theme.of(context).primaryColorLight; // Assets from response DTOs do not have an isar id, querying which would give us the default autoIncrement id final isFromDto = asset.id == Isar.autoIncrement; @@ -54,11 +51,13 @@ class ThumbnailImage extends StatelessWidget { return Container( decoration: BoxDecoration( shape: BoxShape.circle, - color: assetContainerColor, + color: Theme.of(context).colorScheme.surfaceVariant, ), child: Icon( Icons.check_circle_rounded, - color: Theme.of(context).primaryColor, + color: onDeselect == null + ? Theme.of(context).colorScheme.primary.withAlpha(120) + : Theme.of(context).colorScheme.primary, ), ); } else { @@ -132,9 +131,10 @@ class ThumbnailImage extends StatelessWidget { } Widget buildImage() { - final image = SizedBox( + final image = Container( width: 300, height: 300, + color: Theme.of(context).colorScheme.surfaceVariant, child: Hero( tag: isFromDto ? '${asset.remoteId}-$heroOffset' @@ -153,9 +153,9 @@ class ThumbnailImage extends StatelessWidget { decoration: BoxDecoration( border: Border.all( width: 0, - color: onDeselect == null ? Colors.grey : assetContainerColor, + color: Theme.of(context).colorScheme.surfaceVariant, ), - color: onDeselect == null ? Colors.grey : assetContainerColor, + color: Theme.of(context).colorScheme.surfaceVariant, ), child: ClipRRect( borderRadius: const BorderRadius.only( @@ -197,14 +197,14 @@ class ThumbnailImage extends StatelessWidget { }, child: Stack( children: [ - Container( + AnimatedContainer( + duration: const Duration(milliseconds: 300), + curve: Curves.decelerate, decoration: BoxDecoration( border: multiselectEnabled && isSelected ? Border.all( - color: onDeselect == null - ? Colors.grey - : assetContainerColor, - width: 8, + color: Theme.of(context).colorScheme.surfaceVariant, + width: 12, ) : const Border(), ), 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 4f6e2706d..97de80bfc 100644 --- a/mobile/lib/modules/home/ui/control_bottom_app_bar.dart +++ b/mobile/lib/modules/home/ui/control_bottom_app_bar.dart @@ -42,7 +42,6 @@ class ControlBottomAppBar extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - var isDarkMode = Theme.of(context).brightness == Brightness.dark; var hasRemote = selectionAssetState.hasRemote || selectionAssetState.hasMerged; var hasLocal = selectionAssetState.hasLocal; @@ -128,8 +127,6 @@ class ControlBottomAppBar extends ConsumerWidget { ScrollController scrollController, ) { return Card( - color: isDarkMode ? Colors.grey[900] : Colors.grey[100], - surfaceTintColor: Colors.transparent, elevation: 18.0, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.only( diff --git a/mobile/lib/modules/login/ui/login_form.dart b/mobile/lib/modules/login/ui/login_form.dart index 58c7feec2..d30ba1593 100644 --- a/mobile/lib/modules/login/ui/login_form.dart +++ b/mobile/lib/modules/login/ui/login_form.dart @@ -127,9 +127,9 @@ class LoginForm extends HookConsumerWidget { ); populateTestLoginInfo() { - usernameController.text = 'testuser@email.com'; - passwordController.text = 'password'; - serverEndpointController.text = 'http://10.1.15.216:2283/api'; + usernameController.text = 'demo@immich.app'; + passwordController.text = 'demo'; + serverEndpointController.text = 'https://demo.immich.app'; } login() async { @@ -303,7 +303,10 @@ class LoginForm extends HookConsumerWidget { children: [ Text( serverEndpointController.text, - style: Theme.of(context).textTheme.displaySmall, + style: Theme.of(context) + .textTheme + .displaySmall + ?.copyWith(color: Theme.of(context).primaryColor), textAlign: TextAlign.center, ), if (isPasswordLoginEnable.value) ...[ diff --git a/mobile/lib/modules/map/views/map_page.dart b/mobile/lib/modules/map/views/map_page.dart index ffa18d37a..379219b8e 100644 --- a/mobile/lib/modules/map/views/map_page.dart +++ b/mobile/lib/modules/map/views/map_page.dart @@ -120,6 +120,7 @@ class MapPageState extends ConsumerState { final selectedAssets = useState({}); final showLoadingIndicator = useState(false); final refetchMarkers = useState(true); + final themeData = isDarkTheme ? immichDarkTheme : immichLightTheme; if (refetchMarkers.value) { mapMarkerData.value = ref.watch(mapMarkersProvider).when( @@ -189,7 +190,7 @@ class MapPageState extends ConsumerState { showDialog( context: context, builder: (context) => Theme( - data: isDarkTheme ? immichDarkTheme : immichLightTheme, + data: themeData, child: LocationServiceDisabledDialog(), ), ); @@ -203,7 +204,7 @@ class MapPageState extends ConsumerState { shouldRequestPermission = await showDialog( context: context, builder: (context) => Theme( - data: isDarkTheme ? immichDarkTheme : immichLightTheme, + data: themeData, child: LocationPermissionDisabledDialog(), ), ); @@ -438,7 +439,7 @@ class MapPageState extends ConsumerState { ), child: Theme( // Override app theme based on map theme - data: isDarkTheme ? immichDarkTheme : immichLightTheme, + data: themeData, child: Scaffold( appBar: MapAppBar( isDarkTheme: isDarkTheme, diff --git a/mobile/lib/modules/memories/ui/memory_lane.dart b/mobile/lib/modules/memories/ui/memory_lane.dart index dcd803651..43bb906d4 100644 --- a/mobile/lib/modules/memories/ui/memory_lane.dart +++ b/mobile/lib/modules/memories/ui/memory_lane.dart @@ -17,7 +17,7 @@ class MemoryLane extends HookConsumerWidget { .whenData( (memories) => memories != null ? Container( - margin: const EdgeInsets.only(top: 10), + margin: const EdgeInsets.only(top: 10, left: 10), height: 200, child: ListView.builder( scrollDirection: Axis.horizontal, diff --git a/mobile/lib/modules/partner/views/partner_page.dart b/mobile/lib/modules/partner/views/partner_page.dart index 61c639746..c82da9d76 100644 --- a/mobile/lib/modules/partner/views/partner_page.dart +++ b/mobile/lib/modules/partner/views/partner_page.dart @@ -118,6 +118,7 @@ class PartnerPage extends HookConsumerWidget { Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 8), @@ -126,12 +127,15 @@ class PartnerPage extends HookConsumerWidget { style: TextStyle(fontSize: 14), ).tr(), ), - ElevatedButton.icon( - onPressed: availableUsers.whenOrNull( - data: (data) => addNewUsersHandler, + Align( + alignment: Alignment.center, + child: ElevatedButton.icon( + onPressed: availableUsers.whenOrNull( + data: (data) => addNewUsersHandler, + ), + icon: const Icon(Icons.person_add), + label: const Text("partner_page_add_partner").tr(), ), - icon: const Icon(Icons.person_add), - label: const Text("partner_page_add_partner").tr(), ), ], ), diff --git a/mobile/lib/modules/search/ui/curated_people_row.dart b/mobile/lib/modules/search/ui/curated_people_row.dart index 8a65c25f7..2988bfc4c 100644 --- a/mobile/lib/modules/search/ui/curated_people_row.dart +++ b/mobile/lib/modules/search/ui/curated_people_row.dart @@ -30,8 +30,8 @@ class CuratedPeopleRow extends StatelessWidget { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: SizedBox( - width: imageSize, - height: imageSize, + width: 120, + height: 120, child: ThumbnailWithInfo( textInfo: '', onTap: () {}, diff --git a/mobile/lib/modules/search/ui/thumbnail_with_info.dart b/mobile/lib/modules/search/ui/thumbnail_with_info.dart index bbb7e6834..c4b94ec5d 100644 --- a/mobile/lib/modules/search/ui/thumbnail_with_info.dart +++ b/mobile/lib/modules/search/ui/thumbnail_with_info.dart @@ -22,8 +22,6 @@ class ThumbnailWithInfo extends StatelessWidget { @override Widget build(BuildContext context) { - var isDarkMode = Theme.of(context).brightness == Brightness.dark; - var textAndIconColor = isDarkMode ? Colors.grey[100] : Colors.grey[700]; return GestureDetector( onTap: () { onTap(); @@ -34,7 +32,7 @@ class ThumbnailWithInfo extends StatelessWidget { Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(borderRadius), - color: isDarkMode ? Colors.grey[900] : Colors.grey[100], + color: Theme.of(context).colorScheme.surfaceVariant, ), child: imageUrl != null ? ClipRRect( @@ -43,6 +41,17 @@ class ThumbnailWithInfo extends StatelessWidget { width: double.infinity, height: double.infinity, fit: BoxFit.cover, + placeholder: (context, url) { + return SizedBox.square( + dimension: 250, + child: DecoratedBox( + decoration: BoxDecoration( + color: + Theme.of(context).colorScheme.surfaceVariant, + ), + ), + ); + }, imageUrl: imageUrl!, httpHeaders: { "Authorization": @@ -55,7 +64,7 @@ class ThumbnailWithInfo extends StatelessWidget { : Center( child: Icon( noImageIcon ?? Icons.not_listed_location, - color: textAndIconColor, + color: Theme.of(context).primaryColor, ), ), ), @@ -67,10 +76,10 @@ class ThumbnailWithInfo extends StatelessWidget { begin: FractionalOffset.topCenter, end: FractionalOffset.bottomCenter, colors: [ - Colors.grey.withOpacity(0.0), + Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.0), textInfo == '' - ? Colors.black.withOpacity(0.1) - : Colors.black.withOpacity(0.5), + ? Theme.of(context).colorScheme.surface.withOpacity(0.1) + : Theme.of(context).colorScheme.surface.withOpacity(0.6), ], stops: const [0.0, 1.0], ), diff --git a/mobile/lib/modules/settings/ui/advanced_settings/advanced_settings.dart b/mobile/lib/modules/settings/ui/advanced_settings/advanced_settings.dart index 3c8d47d1e..98eea94f5 100644 --- a/mobile/lib/modules/settings/ui/advanced_settings/advanced_settings.dart +++ b/mobile/lib/modules/settings/ui/advanced_settings/advanced_settings.dart @@ -86,7 +86,6 @@ class AdvancedSettings extends HookConsumerWidget { min: 1.0, divisions: 7, label: logLevel, - activeColor: Theme.of(context).primaryColor, ), ), SettingsSwitchListTile( diff --git a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart index 8ff719da3..32175a09b 100644 --- a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart +++ b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart @@ -50,7 +50,6 @@ class LayoutSettings extends HookConsumerWidget { return Column( children: [ SwitchListTile.adaptive( - activeColor: Theme.of(context).primaryColor, title: Text( "asset_list_layout_settings_dynamic_layout_title", style: Theme.of(context) @@ -75,7 +74,6 @@ class LayoutSettings extends HookConsumerWidget { ).tr(), ), RadioListTile( - activeColor: Theme.of(context).primaryColor, title: Text( "asset_list_layout_settings_group_by_month_day", style: Theme.of(context).textTheme.labelLarge, @@ -86,7 +84,6 @@ class LayoutSettings extends HookConsumerWidget { controlAffinity: ListTileControlAffinity.trailing, ), RadioListTile( - activeColor: Theme.of(context).primaryColor, title: Text( "asset_list_layout_settings_group_by_month", style: Theme.of(context).textTheme.labelLarge, @@ -97,7 +94,6 @@ class LayoutSettings extends HookConsumerWidget { controlAffinity: ListTileControlAffinity.trailing, ), RadioListTile( - activeColor: Theme.of(context).primaryColor, title: Text( "asset_list_layout_settings_group_automatically", style: Theme.of(context).textTheme.labelLarge, diff --git a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart index ae0e02148..7761567e8 100644 --- a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart +++ b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart @@ -33,7 +33,6 @@ class StorageIndicator extends HookConsumerWidget { ); return SwitchListTile.adaptive( - activeColor: Theme.of(context).primaryColor, title: Text( "theme_setting_asset_list_storage_indicator_title", style: Theme.of(context) diff --git a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart index 89ac79133..e6f6e6ac3 100644 --- a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart +++ b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart @@ -51,7 +51,6 @@ class TilesPerRow extends HookConsumerWidget { max: 6, divisions: 4, label: "${itemsValue.value.toInt()}", - activeColor: Theme.of(context).primaryColor, ), ], ); diff --git a/mobile/lib/modules/settings/ui/notification_setting/notification_setting.dart b/mobile/lib/modules/settings/ui/notification_setting/notification_setting.dart index 5f00cd0d9..233c1abd4 100644 --- a/mobile/lib/modules/settings/ui/notification_setting/notification_setting.dart +++ b/mobile/lib/modules/settings/ui/notification_setting/notification_setting.dart @@ -149,7 +149,6 @@ class NotificationSetting extends HookConsumerWidget { max: 5.0, divisions: 5, label: formattedValue, - activeColor: Theme.of(context).primaryColor, ), ), ], diff --git a/mobile/lib/modules/settings/ui/settings_switch_list_tile.dart b/mobile/lib/modules/settings/ui/settings_switch_list_tile.dart index c6fff19f6..5f7917a79 100644 --- a/mobile/lib/modules/settings/ui/settings_switch_list_tile.dart +++ b/mobile/lib/modules/settings/ui/settings_switch_list_tile.dart @@ -23,29 +23,31 @@ class SettingsSwitchListTile extends StatelessWidget { @override Widget build(BuildContext context) { return SwitchListTile.adaptive( - selectedTileColor: enabled ? null : Theme.of(context).disabledColor, value: valueNotifier.value, - onChanged: (bool value) { - if (enabled) { - valueNotifier.value = value; - appSettingService.setSetting(settingsEnum, value); - } - if (onChanged != null) { - onChanged!(value); - } - }, - activeColor: enabled - ? Theme.of(context).primaryColor - : Theme.of(context).disabledColor, + onChanged: enabled + ? (bool value) { + valueNotifier.value = value; + appSettingService.setSetting(settingsEnum, value); + if (onChanged != null) { + onChanged!(value); + } + } + : null, dense: true, title: Text( title, - style: Theme.of(context) - .textTheme - .labelLarge - ?.copyWith(fontWeight: FontWeight.bold), + style: Theme.of(context).textTheme.labelLarge?.copyWith( + fontWeight: FontWeight.bold, + color: enabled + ? null + : Theme.of(context).colorScheme.onSurface.withAlpha(100), + ), ), - subtitle: subtitle != null ? Text(subtitle!) : null, + subtitle: subtitle != null + ? Text( + subtitle!, + ) + : null, ); } } diff --git a/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart b/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart index 2e3b7134c..9db6f2802 100644 --- a/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart +++ b/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart @@ -24,7 +24,6 @@ class ThemeSetting extends HookConsumerWidget { ); return ExpansionTile( - textColor: Theme.of(context).primaryColor, title: const Text( 'theme_setting_theme_title', style: TextStyle( @@ -39,7 +38,6 @@ class ThemeSetting extends HookConsumerWidget { ).tr(), children: [ SwitchListTile.adaptive( - activeColor: Theme.of(context).primaryColor, title: Text( 'theme_setting_system_theme_switch', style: Theme.of(context) @@ -77,7 +75,6 @@ class ThemeSetting extends HookConsumerWidget { ), if (currentTheme.value != ThemeMode.system) SwitchListTile.adaptive( - activeColor: Theme.of(context).primaryColor, title: Text( 'theme_setting_dark_mode_switch', style: Theme.of(context) diff --git a/mobile/lib/shared/ui/app_bar_dialog/app_bar_dialog.dart b/mobile/lib/shared/ui/app_bar_dialog/app_bar_dialog.dart index ede113837..f8e7514c2 100644 --- a/mobile/lib/shared/ui/app_bar_dialog/app_bar_dialog.dart +++ b/mobile/lib/shared/ui/app_bar_dialog/app_bar_dialog.dart @@ -23,7 +23,6 @@ class ImmichAppBarDialog extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { BackUpState backupState = ref.watch(backupProvider); final theme = Theme.of(context); - bool isDarkTheme = theme.brightness == Brightness.dark; bool isHorizontal = MediaQuery.of(context).size.width > 600; final horizontalPadding = isHorizontal ? 100.0 : 20.0; final user = ref.watch(currentUserProvider); @@ -135,11 +134,8 @@ class ImmichAppBarDialog extends HookConsumerWidget { padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 3), child: Container( padding: const EdgeInsets.symmetric(vertical: 4), - decoration: BoxDecoration( - color: isDarkTheme - ? Theme.of(context).scaffoldBackgroundColor - : const Color.fromARGB(255, 225, 229, 240), - ), + decoration: + BoxDecoration(color: Theme.of(context).colorScheme.surface), child: ListTile( minLeadingWidth: 50, leading: Icon( @@ -161,7 +157,8 @@ class ImmichAppBarDialog extends HookConsumerWidget { child: LinearProgressIndicator( minHeight: 5.0, value: backupState.serverInfo.diskUsagePercentage / 100.0, - backgroundColor: Colors.grey, + backgroundColor: + Theme.of(context).colorScheme.onSurface.withAlpha(50), color: theme.primaryColor, ), ), diff --git a/mobile/lib/shared/ui/app_bar_dialog/app_bar_profile_info.dart b/mobile/lib/shared/ui/app_bar_dialog/app_bar_profile_info.dart index d58699d5c..f050f4d4b 100644 --- a/mobile/lib/shared/ui/app_bar_dialog/app_bar_profile_info.dart +++ b/mobile/lib/shared/ui/app_bar_dialog/app_bar_profile_info.dart @@ -18,7 +18,6 @@ class AppBarProfileInfoBox extends HookConsumerWidget { AuthenticationState authState = ref.watch(authenticationProvider); final uploadProfileImageStatus = ref.watch(uploadProfileImageProvider).status; - final isDarkMode = Theme.of(context).brightness == Brightness.dark; final user = Store.tryGet(StoreKey.currentUser); buildUserProfileImage() { @@ -91,9 +90,7 @@ class AppBarProfileInfoBox extends HookConsumerWidget { child: Container( width: double.infinity, decoration: BoxDecoration( - color: Theme.of(context).brightness == Brightness.dark - ? Theme.of(context).scaffoldBackgroundColor - : const Color.fromARGB(255, 225, 229, 240), + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.only( topLeft: Radius.circular(10), topRight: Radius.circular(10), @@ -111,7 +108,7 @@ class AppBarProfileInfoBox extends HookConsumerWidget { bottom: -5, right: -8, child: Material( - color: isDarkMode ? Colors.blueGrey[800] : Colors.white, + color: Theme.of(context).colorScheme.primaryContainer, elevation: 3, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(50.0), diff --git a/mobile/lib/shared/ui/app_bar_dialog/app_bar_server_info.dart b/mobile/lib/shared/ui/app_bar_dialog/app_bar_server_info.dart index fa4a73536..0c4590305 100644 --- a/mobile/lib/shared/ui/app_bar_dialog/app_bar_server_info.dart +++ b/mobile/lib/shared/ui/app_bar_dialog/app_bar_server_info.dart @@ -39,9 +39,7 @@ class AppBarServerInfo extends HookConsumerWidget { padding: const EdgeInsets.only(left: 10.0, right: 10.0, bottom: 10.0), child: Container( decoration: BoxDecoration( - color: Theme.of(context).brightness == Brightness.dark - ? Theme.of(context).scaffoldBackgroundColor - : const Color.fromARGB(255, 225, 229, 240), + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10), @@ -139,7 +137,7 @@ class AppBarServerInfo extends HookConsumerWidget { child: Text( serverInfoState.serverVersion.major > 0 ? "${serverInfoState.serverVersion.major}.${serverInfoState.serverVersion.minor}.${serverInfoState.serverVersion.patch}" - : "?", + : "--", style: TextStyle( fontSize: 11, color: Theme.of(context) @@ -190,9 +188,7 @@ class AppBarServerInfo extends HookConsumerWidget { borderRadius: BorderRadius.circular(10), ), textStyle: TextStyle( - color: Theme.of(context).brightness == Brightness.dark - ? Colors.black - : Colors.white, + color: Theme.of(context).colorScheme.onPrimary, fontWeight: FontWeight.bold, ), message: getServerUrl() ?? '--', diff --git a/mobile/lib/shared/ui/drag_sheet.dart b/mobile/lib/shared/ui/drag_sheet.dart index 574962cc0..0da8a7e69 100644 --- a/mobile/lib/shared/ui/drag_sheet.dart +++ b/mobile/lib/shared/ui/drag_sheet.dart @@ -9,7 +9,7 @@ class CustomDraggingHandle extends StatelessWidget { height: 5, width: 30, decoration: BoxDecoration( - color: Colors.grey[500], + color: Theme.of(context).dividerColor, borderRadius: BorderRadius.circular(16), ), ); diff --git a/mobile/lib/shared/ui/immich_app_bar.dart b/mobile/lib/shared/ui/immich_app_bar.dart index 3510931f6..debeb9596 100644 --- a/mobile/lib/shared/ui/immich_app_bar.dart +++ b/mobile/lib/shared/ui/immich_app_bar.dart @@ -28,7 +28,6 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget { final ServerInfo serverInfoState = ref.watch(serverInfoProvider); AuthenticationState authState = ref.watch(authenticationProvider); final user = Store.tryGet(StoreKey.currentUser); - final isDarkMode = Theme.of(context).brightness == Brightness.dark; const widgetSize = 30.0; buildProfileIndicator() { @@ -69,9 +68,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget { ); } - getBackupBadgeIcon() { - final iconColor = isDarkMode ? Colors.white : Colors.black; - + Widget? getBackupBadgeIcon() { if (isEnableAutoBackup) { if (backupState.backupProgress == BackUpProgressEnum.inProgress) { return Container( @@ -79,7 +76,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget { child: CircularProgressIndicator( strokeWidth: 2, strokeCap: StrokeCap.round, - valueColor: AlwaysStoppedAnimation(iconColor), + color: Theme.of(context).colorScheme.onSurfaceVariant, ), ); } else if (backupState.backupProgress != @@ -88,7 +85,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget { return Icon( Icons.check_outlined, size: 9, - color: iconColor, + color: Theme.of(context).colorScheme.onSurfaceVariant, ); } } @@ -97,14 +94,14 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget { return Icon( Icons.cloud_off_rounded, size: 9, - color: iconColor, + color: Theme.of(context).colorScheme.onSurfaceVariant, ); } + return null; } buildBackupIndicator() { final indicatorIcon = getBackupBadgeIcon(); - final badgeBackground = isDarkMode ? Colors.blueGrey[800] : Colors.white; return InkWell( onTap: () => AutoRouter.of(context).push(const BackupControllerRoute()), @@ -114,11 +111,11 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget { width: widgetSize / 2, height: widgetSize / 2, decoration: BoxDecoration( - color: badgeBackground, border: Border.all( - color: isDarkMode ? Colors.black : Colors.grey, + color: Theme.of(context).colorScheme.surface, ), borderRadius: BorderRadius.circular(widgetSize / 2), + color: Theme.of(context).colorScheme.surfaceVariant, ), child: indicatorIcon, ), @@ -126,10 +123,9 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget { alignment: Alignment.bottomRight, isLabelVisible: indicatorIcon != null, offset: const Offset(2, 2), - child: Icon( + child: const Icon( Icons.backup_rounded, size: widgetSize, - color: Theme.of(context).primaryColor, ), ), ); @@ -158,12 +154,13 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget { ), Container( margin: const EdgeInsets.only(left: 10), - child: const Text( + child: Text( 'IMMICH', style: TextStyle( fontFamily: 'SnowburstOne', fontWeight: FontWeight.bold, fontSize: 24, + color: Theme.of(context).primaryColor, ), ), ), diff --git a/mobile/lib/shared/ui/immich_image.dart b/mobile/lib/shared/ui/immich_image.dart index 8b505f556..362291227 100644 --- a/mobile/lib/shared/ui/immich_image.dart +++ b/mobile/lib/shared/ui/immich_image.dart @@ -32,8 +32,8 @@ class ImmichImage extends StatelessWidget { Widget build(BuildContext context) { if (this.asset == null) { return Container( - decoration: const BoxDecoration( - color: Colors.grey, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceVariant, ), child: SizedBox( width: width, @@ -60,10 +60,12 @@ class ImmichImage extends StatelessWidget { return Stack( children: [ if (useGrayBoxPlaceholder) - const SizedBox.square( + SizedBox.square( dimension: 250, child: DecoratedBox( - decoration: BoxDecoration(color: Colors.grey), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceVariant, + ), ), ), if (useProgressIndicator) @@ -109,10 +111,12 @@ class ImmichImage extends StatelessWidget { return Stack( children: [ if (useGrayBoxPlaceholder) - const SizedBox.square( + SizedBox.square( dimension: 250, child: DecoratedBox( - decoration: BoxDecoration(color: Colors.grey), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceVariant, + ), ), ), if (useProgressIndicator) diff --git a/mobile/lib/shared/ui/photo_view/src/photo_view_default_widgets.dart b/mobile/lib/shared/ui/photo_view/src/photo_view_default_widgets.dart index 339463b3f..73c1b0ff1 100644 --- a/mobile/lib/shared/ui/photo_view/src/photo_view_default_widgets.dart +++ b/mobile/lib/shared/ui/photo_view/src/photo_view_default_widgets.dart @@ -13,7 +13,7 @@ class PhotoViewDefaultError extends StatelessWidget { child: Center( child: Icon( Icons.broken_image, - color: Colors.grey[400], + color: Theme.of(context).primaryColor, size: 40.0, ), ), diff --git a/mobile/lib/shared/views/splash_screen.dart b/mobile/lib/shared/views/splash_screen.dart index bd419bc02..a17df06e6 100644 --- a/mobile/lib/shared/views/splash_screen.dart +++ b/mobile/lib/shared/views/splash_screen.dart @@ -79,8 +79,9 @@ class SplashScreenPage extends HookConsumerWidget { [], ); - return const Scaffold( - body: Center( + return Scaffold( + appBar: AppBar(), + body: const Center( child: Image( image: AssetImage('assets/immich-logo-no-outline.png'), width: 80, diff --git a/mobile/lib/shared/views/tab_controller_page.dart b/mobile/lib/shared/views/tab_controller_page.dart index 8e72ce900..e62ec0deb 100644 --- a/mobile/lib/shared/views/tab_controller_page.dart +++ b/mobile/lib/shared/views/tab_controller_page.dart @@ -24,7 +24,7 @@ class TabControllerPage extends HookConsumerWidget { children: [ icon, Positioned( - right: -14, + right: -16, child: SizedBox( height: 12, width: 12, @@ -114,9 +114,8 @@ class TabControllerPage extends HookConsumerWidget { Icons.photo_library_outlined, ), selectedIcon: buildIcon( - Icon( + const Icon( Icons.photo_library, - color: Theme.of(context).primaryColor, ), ), ), @@ -125,9 +124,8 @@ class TabControllerPage extends HookConsumerWidget { icon: const Icon( Icons.search_rounded, ), - selectedIcon: Icon( + selectedIcon: const Icon( Icons.search, - color: Theme.of(context).primaryColor, ), ), NavigationDestination( @@ -135,9 +133,8 @@ class TabControllerPage extends HookConsumerWidget { icon: const Icon( Icons.group_outlined, ), - selectedIcon: Icon( + selectedIcon: const Icon( Icons.group, - color: Theme.of(context).primaryColor, ), ), NavigationDestination( @@ -146,9 +143,8 @@ class TabControllerPage extends HookConsumerWidget { Icons.photo_album_outlined, ), selectedIcon: buildIcon( - Icon( + const Icon( Icons.photo_album_rounded, - color: Theme.of(context).primaryColor, ), ), ), diff --git a/mobile/lib/utils/immich_app_theme.dart b/mobile/lib/utils/immich_app_theme.dart index 670a7660d..957242c34 100644 --- a/mobile/lib/utils/immich_app_theme.dart +++ b/mobile/lib/utils/immich_app_theme.dart @@ -1,6 +1,5 @@ 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/settings/providers/app_settings.provider.dart'; import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; @@ -20,259 +19,157 @@ final immichThemeProvider = StateProvider((ref) { } }); -ThemeData base = ThemeData( - chipTheme: const ChipThemeData( - side: BorderSide.none, - ), - sliderTheme: const SliderThemeData( - thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7), - trackHeight: 2.0, - ), -); - -ThemeData immichLightTheme = ThemeData( - useMaterial3: true, +ColorScheme _lightColorScheme = const ColorScheme( brightness: Brightness.light, - primarySwatch: Colors.indigo, - primaryColor: Colors.indigo, - hintColor: Colors.indigo, - focusColor: Colors.indigo, - splashColor: Colors.indigo.withOpacity(0.15), - fontFamily: 'WorkSans', - scaffoldBackgroundColor: immichBackgroundColor, - snackBarTheme: const SnackBarThemeData( - contentTextStyle: TextStyle( - fontFamily: 'WorkSans', - color: Colors.indigo, - fontWeight: FontWeight.bold, - ), - backgroundColor: Colors.white, - ), - appBarTheme: AppBarTheme( - titleTextStyle: const TextStyle( - fontFamily: 'WorkSans', - color: Colors.indigo, - fontWeight: FontWeight.bold, - fontSize: 18, - ), - backgroundColor: immichBackgroundColor, - foregroundColor: Colors.indigo, - elevation: 0, - scrolledUnderElevation: 0, - centerTitle: true, - ), - bottomNavigationBarTheme: BottomNavigationBarThemeData( - type: BottomNavigationBarType.fixed, - backgroundColor: immichBackgroundColor, - selectedItemColor: Colors.indigo, - ), - cardTheme: const CardTheme( - surfaceTintColor: Colors.transparent, - ), - drawerTheme: DrawerThemeData( - backgroundColor: immichBackgroundColor, - ), - textTheme: const TextTheme( - displayLarge: TextStyle( - fontSize: 26, - fontWeight: FontWeight.bold, - color: Colors.indigo, - ), - displayMedium: TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black87, - ), - displaySmall: TextStyle( - fontSize: 12, - fontWeight: FontWeight.bold, - color: Colors.indigo, - ), - titleSmall: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - ), - titleMedium: TextStyle( - fontSize: 18.0, - fontWeight: FontWeight.bold, - ), - titleLarge: TextStyle( - fontSize: 26.0, - fontWeight: FontWeight.bold, - ), - ), - elevatedButtonTheme: ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - backgroundColor: Colors.indigo, - foregroundColor: Colors.white, - ), - ), - chipTheme: base.chipTheme, - sliderTheme: base.sliderTheme, - popupMenuTheme: const PopupMenuThemeData( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(10)), - ), - surfaceTintColor: Colors.transparent, - color: Colors.white, - ), - navigationBarTheme: NavigationBarThemeData( - indicatorColor: Colors.indigo.withOpacity(0.15), - iconTheme: MaterialStatePropertyAll( - IconThemeData(color: Colors.grey[700]), - ), - backgroundColor: immichBackgroundColor, - surfaceTintColor: Colors.transparent, - labelTextStyle: MaterialStatePropertyAll( - TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Colors.grey[700], - ), - ), - ), - dialogTheme: const DialogTheme( - surfaceTintColor: Colors.transparent, - ), - inputDecorationTheme: const InputDecorationTheme( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Colors.indigo, - ), - ), - labelStyle: TextStyle( - color: Colors.indigo, - ), - hintStyle: TextStyle( - fontSize: 14.0, - fontWeight: FontWeight.normal, - ), - ), - textSelectionTheme: const TextSelectionThemeData( - cursorColor: Colors.indigo, - ), + primary: Color(0xff4755b5), + onPrimary: Color(0xffffffff), + primaryContainer: Color(0xffdfe0ff), + onPrimaryContainer: Color(0xff000d60), + secondary: Color(0xff5b5d72), + onSecondary: Color(0xffffffff), + secondaryContainer: Color(0xFFD6D8FF), + onSecondaryContainer: Color(0xff181a2c), + tertiary: Color(0xff77536c), + onTertiary: Color(0xffffffff), + tertiaryContainer: Color(0xffffd7f0), + onTertiaryContainer: Color(0xff2d1127), + error: Color(0xffba1a1a), + onError: Color(0xffffffff), + errorContainer: Color(0xffffdad6), + onErrorContainer: Color(0xff410002), + background: Color(0xfff9f6fc), + onBackground: Color(0xff1b1b1f), + surface: Color(0xfff9f6fc), + onSurface: Color(0xff1b1b1f), + surfaceVariant: Color(0xffdeddea), + onSurfaceVariant: Color(0xff46464f), + outline: Color(0xff777680), + outlineVariant: Color(0xffc7c5d0), + shadow: Color(0xff000000), + scrim: Color(0xff000000), + inverseSurface: Color(0xff303137), + onInverseSurface: Color(0xfff3f0f4), + inversePrimary: Color(0xffbcc3ff), + surfaceTint: Color(0xff4755b5), ); -ThemeData immichDarkTheme = ThemeData( - useMaterial3: true, +ColorScheme _darkColorScheme = const ColorScheme( brightness: Brightness.dark, - primarySwatch: Colors.indigo, - primaryColor: immichDarkThemePrimaryColor, - scaffoldBackgroundColor: immichDarkBackgroundColor, - hintColor: Colors.grey[600], - fontFamily: 'WorkSans', - snackBarTheme: SnackBarThemeData( - contentTextStyle: TextStyle( - fontFamily: 'WorkSans', - color: immichDarkThemePrimaryColor, - fontWeight: FontWeight.bold, - ), - backgroundColor: Colors.grey[900], - ), - textButtonTheme: TextButtonThemeData( - style: TextButton.styleFrom( - foregroundColor: immichDarkThemePrimaryColor, - ), - ), - appBarTheme: AppBarTheme( - titleTextStyle: TextStyle( - fontFamily: 'WorkSans', - color: immichDarkThemePrimaryColor, - fontWeight: FontWeight.bold, - fontSize: 18, - ), - backgroundColor: const Color.fromARGB(255, 32, 33, 35), - foregroundColor: immichDarkThemePrimaryColor, - elevation: 0, - scrolledUnderElevation: 0, - centerTitle: true, - ), - 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( - displayLarge: const TextStyle( - fontSize: 26, - fontWeight: FontWeight.bold, - color: Color.fromARGB(255, 255, 255, 255), - ), - displayMedium: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, - color: Color.fromARGB(255, 255, 255, 255), - ), - displaySmall: TextStyle( - fontSize: 12, - fontWeight: FontWeight.bold, - color: immichDarkThemePrimaryColor, - ), - titleSmall: const TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - ), - titleMedium: const TextStyle( - fontSize: 18.0, - fontWeight: FontWeight.bold, - ), - titleLarge: const TextStyle( - fontSize: 26.0, - fontWeight: FontWeight.bold, - ), - ), - cardColor: Colors.grey[900], - elevatedButtonTheme: ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - foregroundColor: Colors.black87, - backgroundColor: immichDarkThemePrimaryColor, - ), - ), - chipTheme: base.chipTheme, - sliderTheme: base.sliderTheme, - popupMenuTheme: const PopupMenuThemeData( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(10)), - ), - surfaceTintColor: Colors.transparent, - ), - navigationBarTheme: NavigationBarThemeData( - indicatorColor: immichDarkThemePrimaryColor.withOpacity(0.4), - iconTheme: MaterialStatePropertyAll( - IconThemeData(color: Colors.grey[500]), - ), - backgroundColor: Colors.grey[900], - surfaceTintColor: Colors.transparent, - labelTextStyle: MaterialStatePropertyAll( - TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Colors.grey[500], - ), - ), - ), - dialogTheme: const DialogTheme( - surfaceTintColor: Colors.transparent, - ), - inputDecorationTheme: InputDecorationTheme( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: immichDarkThemePrimaryColor, - ), - ), - labelStyle: TextStyle( - color: immichDarkThemePrimaryColor, - ), - hintStyle: const TextStyle( - fontSize: 14.0, - fontWeight: FontWeight.normal, - ), - ), - textSelectionTheme: TextSelectionThemeData( - cursorColor: immichDarkThemePrimaryColor, - ), + primary: Color(0xffa4c8ff), + onPrimary: Color(0xff00315e), + primaryContainer: Color(0xFF182C40), + onPrimaryContainer: Color(0xffd4e3ff), + secondary: Color(0xffbcc7dc), + onSecondary: Color(0xff37474f), + secondaryContainer: Color(0xff3d4758), + onSecondaryContainer: Color(0xffd8e3f8), + tertiary: Color(0xffdabde2), + onTertiary: Color(0xff3d2946), + tertiaryContainer: Color(0xff543f5e), + onTertiaryContainer: Color(0xfff6d9ff), + error: Color(0xffffb4ab), + onError: Color(0xff690005), + errorContainer: Color(0xff93000a), + onErrorContainer: Color(0xffffb4ab), + background: Color(0xff101214), + onBackground: Color(0xffe2e2e5), + surface: Color(0xff101214), + onSurface: Color(0xffe2e2e5), + surfaceVariant: Color(0xff363c42), + onSurfaceVariant: Color(0xffc1c7ce), + outline: Color(0xff8b9198), + outlineVariant: Color(0xff41474d), + shadow: Color(0xff000000), + scrim: Color(0xff000000), + inverseSurface: Color(0xffeeeef1), + onInverseSurface: Color(0xff2e3133), + inversePrimary: Color(0xff1c5fa5), + surfaceTint: Color(0xff90caf9), ); + +ThemeData getThemeForScheme(ColorScheme scheme) { + return ThemeData( + useMaterial3: true, + brightness: scheme.brightness, + colorScheme: scheme, + primaryColor: scheme.primary, + scaffoldBackgroundColor: scheme.background, + fontFamily: 'WorkSans', + appBarTheme: AppBarTheme( + iconTheme: IconThemeData(color: scheme.primary), + titleTextStyle: TextStyle( + fontSize: 18.0, + fontWeight: FontWeight.bold, + color: scheme.primary, + ), + ), + cardTheme: const CardTheme(elevation: 2.0), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + visualDensity: VisualDensity.standard, + textStyle: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 11, + ), + shadowColor: scheme.shadow, + foregroundColor: scheme.onPrimary, + backgroundColor: scheme.primary, + ), + ), + navigationBarTheme: NavigationBarThemeData( + iconTheme: MaterialStateProperty.resolveWith((states) { + if (states.contains(MaterialState.selected)) { + return IconThemeData(color: scheme.primary); + } + return null; + }), + ), + textTheme: TextTheme( + displayLarge: TextStyle( + fontSize: 26, + fontWeight: FontWeight.bold, + color: scheme.primary, + ), + displayMedium: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), + displaySmall: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + ), + titleSmall: const TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + titleMedium: const TextStyle( + fontSize: 18.0, + fontWeight: FontWeight.bold, + ), + titleLarge: TextStyle( + fontSize: 26.0, + fontWeight: FontWeight.bold, + color: scheme.primary, + ), + ), + chipTheme: const ChipThemeData( + side: BorderSide.none, + ), + sliderTheme: const SliderThemeData( + thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7), + trackHeight: 2.0, + ), + inputDecorationTheme: InputDecorationTheme( + labelStyle: TextStyle( + color: scheme.primary, + ), + hintStyle: const TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.normal, + ), + ), + ); +} + +ThemeData immichLightTheme = getThemeForScheme(_lightColorScheme); +ThemeData immichDarkTheme = getThemeForScheme(_darkColorScheme);