1
0
mirror of https://github.com/immich-app/immich.git synced 2025-07-16 07:24:40 +02:00

feat(mobile): add support for material themes (#11560)

* feat(mobile): add support for material themes

Added support for custom theming and updated all elements accordingly.

* fix(mobile): Restored immich brand colors to default theme

* fix(mobile): make ListTile titles bold in settings main page

* feat(mobile): update bottom nav and appbar colors

* small tweaks

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
Pruthvi Bugidi
2024-08-06 19:50:27 +05:30
committed by GitHub
parent 20262209ce
commit 0eacdf93eb
65 changed files with 944 additions and 563 deletions

View File

@ -1,12 +1,12 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class AlbumActionOutlinedButton extends StatelessWidget {
class AlbumActionFilledButton extends StatelessWidget {
final VoidCallback? onPressed;
final String labelText;
final IconData iconData;
const AlbumActionOutlinedButton({
const AlbumActionFilledButton({
super.key,
this.onPressed,
required this.labelText,
@ -17,18 +17,13 @@ class AlbumActionOutlinedButton extends StatelessWidget {
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(right: 16.0),
child: OutlinedButton.icon(
style: OutlinedButton.styleFrom(
child: FilledButton.icon(
style: FilledButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
side: BorderSide(
width: 1,
color: context.isDarkTheme
? const Color.fromARGB(255, 63, 63, 63)
: const Color.fromARGB(255, 206, 206, 206),
),
backgroundColor: context.colorScheme.surfaceContainerHigh,
),
icon: Icon(
iconData,

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/entities/album.entity.dart';
import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
class AlbumThumbnailCard extends StatelessWidget {
@ -23,8 +24,6 @@ class AlbumThumbnailCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
var isDarkTheme = context.isDarkTheme;
return LayoutBuilder(
builder: (context, constraints) {
var cardSize = constraints.maxWidth;
@ -34,12 +33,13 @@ class AlbumThumbnailCard extends StatelessWidget {
height: cardSize,
width: cardSize,
decoration: BoxDecoration(
color: isDarkTheme ? Colors.grey[800] : Colors.grey[200],
color: context.colorScheme.surfaceContainerHigh,
),
child: Center(
child: Icon(
Icons.no_photography,
size: cardSize * .15,
color: context.colorScheme.primary,
),
),
);
@ -65,6 +65,9 @@ class AlbumThumbnailCard extends StatelessWidget {
return RichText(
overflow: TextOverflow.fade,
text: TextSpan(
style: context.textTheme.bodyMedium?.copyWith(
color: context.colorScheme.onSurfaceSecondary,
),
children: [
TextSpan(
text: album.assetCount == 1
@ -72,14 +75,9 @@ class AlbumThumbnailCard extends StatelessWidget {
.tr(args: ['${album.assetCount}'])
: 'album_thumbnail_card_items'
.tr(args: ['${album.assetCount}']),
style: context.textTheme.bodyMedium,
),
if (owner != null) const TextSpan(text: ' · '),
if (owner != null)
TextSpan(
text: owner,
style: context.textTheme.bodyMedium,
),
if (owner != null) TextSpan(text: owner),
],
),
);
@ -112,7 +110,7 @@ class AlbumThumbnailCard extends StatelessWidget {
album.name,
overflow: TextOverflow.ellipsis,
style: context.textTheme.bodyMedium?.copyWith(
color: context.primaryColor,
color: context.colorScheme.onSurface,
fontWeight: FontWeight.w500,
),
),

View File

@ -20,8 +20,6 @@ class AlbumTitleTextField extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final isDarkTheme = context.isDarkTheme;
return TextField(
onChanged: (v) {
if (v.isEmpty) {
@ -35,7 +33,7 @@ class AlbumTitleTextField extends ConsumerWidget {
focusNode: albumTitleTextFieldFocusNode,
style: TextStyle(
fontSize: 28,
color: isDarkTheme ? Colors.grey[300] : Colors.grey[700],
color: context.colorScheme.onSurface,
fontWeight: FontWeight.bold,
),
controller: albumTitleController,
@ -61,24 +59,18 @@ class AlbumTitleTextField extends ConsumerWidget {
splashRadius: 10,
)
: null,
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.circular(10),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.circular(10),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
hintText: 'share_add_title'.tr(),
hintStyle: TextStyle(
hintStyle: context.themeData.inputDecorationTheme.hintStyle?.copyWith(
fontSize: 28,
color: isDarkTheme ? Colors.grey[300] : Colors.grey[700],
fontWeight: FontWeight.bold,
),
focusColor: Colors.grey[300],
fillColor: isDarkTheme
? const Color.fromARGB(255, 32, 33, 35)
: Colors.grey[200],
fillColor: context.scaffoldBackgroundColor,
filled: isAlbumTitleTextFieldFocus.value,
),
);

View File

@ -95,7 +95,7 @@ class AlbumViewerAppbar extends HookConsumerWidget
'action_common_confirm',
style: TextStyle(
fontWeight: FontWeight.bold,
color: !context.isDarkTheme ? Colors.red : Colors.red[300],
color: context.colorScheme.error,
),
).tr(),
),

View File

@ -73,24 +73,18 @@ class AlbumViewerEditableTitle extends HookConsumerWidget {
splashRadius: 10,
)
: null,
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.circular(10),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.circular(10),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
focusColor: Colors.grey[300],
fillColor: context.isDarkTheme
? const Color.fromARGB(255, 32, 33, 35)
: Colors.grey[200],
fillColor: context.scaffoldBackgroundColor,
filled: titleFocusNode.hasFocus,
hintText: 'share_add_title'.tr(),
hintStyle: TextStyle(
hintStyle: context.themeData.inputDecorationTheme.hintStyle?.copyWith(
fontSize: 28,
color: context.isDarkTheme ? Colors.grey[300] : Colors.grey[700],
fontWeight: FontWeight.bold,
),
),
),

View File

@ -281,7 +281,7 @@ class ControlBottomAppBar extends HookConsumerWidget {
ScrollController scrollController,
) {
return Card(
color: context.isDarkTheme ? Colors.grey[900] : Colors.grey[100],
color: context.colorScheme.surfaceContainerLow,
surfaceTintColor: Colors.transparent,
elevation: 18.0,
shape: const RoundedRectangleBorder(

View File

@ -22,12 +22,15 @@ class DisableMultiSelectButton extends ConsumerWidget {
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: ElevatedButton.icon(
onPressed: () => onPressed(),
icon: const Icon(Icons.close_rounded),
icon: Icon(
Icons.close_rounded,
color: context.colorScheme.onPrimary,
),
label: Text(
'$selectedItemCount',
style: context.textTheme.titleMedium?.copyWith(
height: 2.5,
color: context.isDarkTheme ? Colors.black : Colors.white,
color: context.colorScheme.onPrimary,
),
),
),

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
import 'package:immich_mobile/providers/app_settings.provider.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
@ -74,9 +75,9 @@ class GroupDividerTitle extends HookConsumerWidget {
Icons.check_circle_rounded,
color: context.primaryColor,
)
: const Icon(
: Icon(
Icons.check_circle_outline_rounded,
color: Colors.grey,
color: context.colorScheme.onSurfaceSecondary,
),
),
],

View File

@ -11,6 +11,7 @@ import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/collection_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/providers/asset_viewer/scroll_notifier.provider.dart';
import 'package:immich_mobile/widgets/asset_grid/asset_drag_region.dart';
import 'package:immich_mobile/widgets/asset_grid/thumbnail_image.dart';
@ -266,7 +267,9 @@ class ImmichAssetGridViewState extends ConsumerState<ImmichAssetGridView> {
scrollStateListener: dragScrolling,
itemPositionsListener: _itemPositionsListener,
controller: _itemScrollController,
backgroundColor: context.themeData.hintColor,
backgroundColor: context.isDarkTheme
? context.colorScheme.primary.darken(amount: .5)
: context.colorScheme.primary,
labelTextBuilder: _labelBuilder,
padding: appBarOffset()
? const EdgeInsets.only(top: 60)

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
import 'package:immich_mobile/utils/storage_indicator.dart';
import 'package:isar/isar.dart';
@ -42,8 +43,8 @@ class ThumbnailImage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final assetContainerColor = context.isDarkTheme
? Colors.blueGrey
: context.themeData.primaryColorLight;
? context.primaryColor.darken(amount: 0.6)
: context.primaryColor.lighten(amount: 0.8);
// 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;
@ -192,8 +193,8 @@ class ThumbnailImage extends ConsumerWidget {
bottom: 5,
child: Icon(
storageIcon(asset),
color: Colors.white,
size: 18,
color: Colors.white.withOpacity(.8),
size: 16,
),
),
if (asset.isFavorite)

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
class ThumbnailPlaceholder extends StatelessWidget {
final EdgeInsets margin;
@ -13,25 +14,20 @@ class ThumbnailPlaceholder extends StatelessWidget {
this.height = 250,
});
static const _brightColors = [
Color(0xFFF1F3F4),
Color(0xFFB4B6B8),
];
static const _darkColors = [
Color(0xFF3B3F42),
Color(0xFF2B2F32),
];
@override
Widget build(BuildContext context) {
var gradientColors = [
context.colorScheme.surfaceContainer,
context.colorScheme.surfaceContainer.darken(amount: .1),
];
return Container(
width: width,
height: height,
margin: margin,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: context.isDarkTheme ? _darkColors : _brightColors,
colors: gradientColors,
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),

View File

@ -5,6 +5,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/entities/exif_info.entity.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/services/asset_description.service.dart';
import 'package:immich_mobile/widgets/common/immich_toast.dart';
@ -23,7 +24,6 @@ class DescriptionInput extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final textColor = context.isDarkTheme ? Colors.white : Colors.black;
final controller = useTextEditingController();
final focusNode = useFocusNode();
final isFocus = useState(false);
@ -71,7 +71,7 @@ class DescriptionInput extends HookConsumerWidget {
},
icon: Icon(
Icons.cancel_rounded,
color: Colors.grey[500],
color: context.colorScheme.onSurfaceSecondary,
),
splashRadius: 10,
);
@ -100,9 +100,6 @@ class DescriptionInput extends HookConsumerWidget {
decoration: InputDecoration(
hintText: 'description_input_hint_text'.tr(),
border: InputBorder.none,
hintStyle: context.textTheme.labelLarge?.copyWith(
color: textColor.withOpacity(0.5),
),
suffixIcon: suffixIcon,
),
);

View File

@ -22,7 +22,7 @@ class ExifBottomSheet extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final assetWithExif = ref.watch(assetDetailProvider(asset));
var textColor = context.isDarkTheme ? Colors.white : Colors.black;
var textColor = context.colorScheme.onSurface;
final ExifInfo? exifInfo = (assetWithExif.value ?? asset).exifInfo;
// Format the date time with the timezone
final (dt, timeZone) =

View File

@ -178,6 +178,7 @@ class TopControlAppBar extends HookConsumerWidget {
actionsIconTheme: const IconThemeData(
size: iconSize,
),
shape: const Border(),
actions: [
if (asset.isRemote && isOwner) buildFavoriteButton(a),
if (asset.livePhotoVideoId != null) buildLivePhotoButton(),

View File

@ -47,22 +47,22 @@ class AlbumInfoListTile extends HookConsumerWidget {
buildIcon() {
if (isSelected) {
return const Icon(
return Icon(
Icons.check_circle_rounded,
color: Colors.green,
color: context.colorScheme.primary,
);
}
if (isExcluded) {
return const Icon(
return Icon(
Icons.remove_circle_rounded,
color: Colors.red,
color: context.colorScheme.error,
);
}
return Icon(
Icons.circle,
color: context.isDarkTheme ? Colors.grey[400] : Colors.black45,
color: context.colorScheme.surfaceContainerHighest,
);
}

View File

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
class BackupInfoCard extends StatelessWidget {
final String title;
@ -19,9 +20,7 @@ class BackupInfoCard extends StatelessWidget {
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20), // if you need this
side: BorderSide(
color: context.isDarkTheme
? const Color.fromARGB(255, 56, 56, 56)
: Colors.black12,
color: context.colorScheme.outlineVariant,
width: 1,
),
),
@ -38,7 +37,9 @@ class BackupInfoCard extends StatelessWidget {
padding: const EdgeInsets.only(top: 4.0, right: 18.0),
child: Text(
subtitle,
style: context.textTheme.bodyMedium,
style: context.textTheme.bodyMedium?.copyWith(
color: context.colorScheme.onSurfaceSecondary,
),
),
),
trailing: Column(

View File

@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/models/backup/backup_state.model.dart';
import 'package:immich_mobile/providers/backup/backup.provider.dart';
import 'package:immich_mobile/providers/backup/error_backup_list.provider.dart';
@ -82,22 +83,20 @@ class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
Widget buildAssetInfoTable() {
return Table(
border: TableBorder.all(
color: context.themeData.primaryColorLight,
color: context.colorScheme.outlineVariant,
width: 1,
),
children: [
TableRow(
decoration: const BoxDecoration(
// color: Colors.grey[100],
),
children: [
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: const Text(
child: Text(
'backup_controller_page_filename',
style: TextStyle(
color: context.colorScheme.onSurfaceSecondary,
fontWeight: FontWeight.bold,
fontSize: 10.0,
),
@ -109,17 +108,15 @@ class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
],
),
TableRow(
decoration: const BoxDecoration(
// color: Colors.grey[200],
),
children: [
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: const Text(
child: Text(
"backup_controller_page_created",
style: TextStyle(
color: context.colorScheme.onSurfaceSecondary,
fontWeight: FontWeight.bold,
fontSize: 10.0,
),
@ -131,16 +128,14 @@ class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
],
),
TableRow(
decoration: const BoxDecoration(
// color: Colors.grey[100],
),
children: [
TableCell(
child: Padding(
padding: const EdgeInsets.all(6.0),
child: const Text(
child: Text(
"backup_controller_page_id",
style: TextStyle(
color: context.colorScheme.onSurfaceSecondary,
fontWeight: FontWeight.bold,
fontSize: 10.0,
),
@ -181,8 +176,7 @@ class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
child: LinearProgressIndicator(
minHeight: 10.0,
value: uploadProgress / 100.0,
backgroundColor: Colors.grey,
color: context.primaryColor,
borderRadius: const BorderRadius.all(Radius.circular(10.0)),
),
),
Text(
@ -214,8 +208,7 @@ class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
child: LinearProgressIndicator(
minHeight: 10.0,
value: uploadProgress / 100.0,
backgroundColor: Colors.grey,
color: context.primaryColor,
borderRadius: const BorderRadius.all(Radius.circular(10.0)),
),
),
Text(

View File

@ -57,6 +57,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
? 'assets/immich-text-dark.png'
: 'assets/immich-text-light.png',
height: 16,
color: context.primaryColor,
),
),
],
@ -88,7 +89,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
buildSettingButton() {
return buildActionButton(
Icons.settings_rounded,
Icons.settings_outlined,
"profile_drawer_settings",
() => context.pushRoute(const SettingsRoute()),
);
@ -146,9 +147,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
child: Container(
padding: const EdgeInsets.symmetric(vertical: 4),
decoration: BoxDecoration(
color: context.isDarkTheme
? context.scaffoldBackgroundColor
: const Color.fromARGB(255, 225, 229, 240),
color: context.colorScheme.surface,
),
child: ListTile(
minLeadingWidth: 50,
@ -171,10 +170,10 @@ class ImmichAppBarDialog extends HookConsumerWidget {
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: LinearProgressIndicator(
minHeight: 5.0,
minHeight: 10.0,
value: percentage,
backgroundColor: Colors.grey,
color: theme.primaryColor,
borderRadius:
const BorderRadius.all(Radius.circular(10.0)),
),
),
Padding(
@ -248,7 +247,6 @@ class ImmichAppBarDialog extends HookConsumerWidget {
right: horizontalPadding,
bottom: isHorizontal ? 20 : 100,
),
backgroundColor: theme.cardColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:image_picker/image_picker.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/providers/upload_profile_image.provider.dart';
import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/providers/user.provider.dart';
@ -79,9 +80,7 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: context.isDarkTheme
? context.scaffoldBackgroundColor
: const Color.fromARGB(255, 225, 229, 240),
color: context.colorScheme.surface,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
@ -99,9 +98,7 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
bottom: -5,
right: -8,
child: Material(
color: context.isDarkTheme
? Colors.blueGrey[800]
: Colors.white,
color: context.colorScheme.surfaceContainerHighest,
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0),
@ -129,7 +126,7 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
subtitle: Text(
authState.userEmail,
style: context.textTheme.bodySmall?.copyWith(
color: context.textTheme.bodySmall?.color?.withAlpha(200),
color: context.colorScheme.onSurfaceSecondary,
),
),
),

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/models/server_info/server_info.model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:immich_mobile/providers/server_info.provider.dart';
@ -42,9 +43,7 @@ class AppBarServerInfo extends HookConsumerWidget {
padding: const EdgeInsets.only(left: 10.0, right: 10.0, bottom: 10.0),
child: Container(
decoration: BoxDecoration(
color: context.isDarkTheme
? context.scaffoldBackgroundColor
: const Color.fromARGB(255, 225, 229, 240),
color: context.colorScheme.surface,
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
@ -71,10 +70,7 @@ class AppBarServerInfo extends HookConsumerWidget {
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Divider(
color: Color.fromARGB(101, 201, 201, 201),
thickness: 1,
),
child: Divider(thickness: 1),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -100,8 +96,7 @@ class AppBarServerInfo extends HookConsumerWidget {
"${appInfo.value["version"]} build.${appInfo.value["buildNumber"]}",
style: TextStyle(
fontSize: contentFontSize,
color: context.textTheme.labelSmall?.color
?.withOpacity(0.5),
color: context.colorScheme.onSurfaceSecondary,
fontWeight: FontWeight.bold,
),
),
@ -111,10 +106,7 @@ class AppBarServerInfo extends HookConsumerWidget {
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Divider(
color: Color.fromARGB(101, 201, 201, 201),
thickness: 1,
),
child: Divider(thickness: 1),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -142,8 +134,7 @@ class AppBarServerInfo extends HookConsumerWidget {
: "--",
style: TextStyle(
fontSize: contentFontSize,
color: context.textTheme.labelSmall?.color
?.withOpacity(0.5),
color: context.colorScheme.onSurfaceSecondary,
fontWeight: FontWeight.bold,
),
),
@ -153,10 +144,7 @@ class AppBarServerInfo extends HookConsumerWidget {
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Divider(
color: Color.fromARGB(101, 201, 201, 201),
thickness: 1,
),
child: Divider(thickness: 1),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -197,8 +185,7 @@ class AppBarServerInfo extends HookConsumerWidget {
getServerUrl() ?? '--',
style: TextStyle(
fontSize: contentFontSize,
color: context.textTheme.labelSmall?.color
?.withOpacity(0.5),
color: context.colorScheme.onSurfaceSecondary,
fontWeight: FontWeight.bold,
overflow: TextOverflow.ellipsis,
),
@ -211,10 +198,7 @@ class AppBarServerInfo extends HookConsumerWidget {
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Divider(
color: Color.fromARGB(101, 201, 201, 201),
thickness: 1,
),
child: Divider(thickness: 1),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -255,8 +239,7 @@ class AppBarServerInfo extends HookConsumerWidget {
: "--",
style: TextStyle(
fontSize: contentFontSize,
color: context.textTheme.labelSmall?.color
?.withOpacity(0.5),
color: context.colorScheme.onSurfaceSecondary,
fontWeight: FontWeight.bold,
),
),

View File

@ -47,7 +47,7 @@ class ConfirmDialog extends StatelessWidget {
child: Text(
ok,
style: TextStyle(
color: Colors.red[400],
color: context.colorScheme.error,
fontWeight: FontWeight.bold,
),
).tr(),

View File

@ -111,7 +111,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
buildBackupIndicator() {
final indicatorIcon = getBackupBadgeIcon();
final badgeBackground = isDarkTheme ? Colors.blueGrey[800] : Colors.white;
final badgeBackground = context.colorScheme.surfaceContainer;
return InkWell(
onTap: () => context.pushRoute(const BackupControllerRoute()),
@ -123,7 +123,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
decoration: BoxDecoration(
color: badgeBackground,
border: Border.all(
color: isDarkTheme ? Colors.black : Colors.grey,
color: context.colorScheme.outline.withOpacity(.3),
),
borderRadius: BorderRadius.circular(widgetSize / 2),
),

View File

@ -21,6 +21,7 @@ class ImmichTitleText extends StatelessWidget {
),
width: fontSize * 4,
filterQuality: FilterQuality.high,
color: context.primaryColor,
);
}
}

View File

@ -51,9 +51,9 @@ class ImmichToast {
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: context.isDarkTheme ? Colors.grey[900] : Colors.grey[50],
color: context.colorScheme.surfaceContainer,
border: Border.all(
color: Colors.black12,
color: context.colorScheme.outline.withOpacity(.5),
width: 1,
),
),

View File

@ -51,7 +51,7 @@ class ChangePasswordForm extends HookConsumerWidget {
),
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
color: context.colorScheme.onSurface,
fontWeight: FontWeight.w600,
),
),
@ -191,9 +191,6 @@ class ChangePasswordButton extends ConsumerWidget {
return ElevatedButton(
style: ElevatedButton.styleFrom(
visualDensity: VisualDensity.standard,
backgroundColor: context.primaryColor,
foregroundColor: Colors.grey[50],
elevation: 2,
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 25),
),
onPressed: onPressed,

View File

@ -70,6 +70,7 @@ class _MapThemeOverideState extends ConsumerState<MapThemeOveride>
Widget build(BuildContext context) {
_theme = widget.themeMode ??
ref.watch(mapStateNotifierProvider.select((v) => v.themeMode));
var appTheme = ref.watch(immichThemeProvider);
useValueChanged<ThemeMode, void>(_theme, (_, __) {
if (_theme == ThemeMode.system) {
@ -83,7 +84,9 @@ class _MapThemeOverideState extends ConsumerState<MapThemeOveride>
});
return Theme(
data: _isDarkTheme ? immichDarkTheme : immichLightTheme,
data: _isDarkTheme
? getThemeData(colorScheme: appTheme.dark)
: getThemeData(colorScheme: appTheme.light),
child: widget.mapBuilder.call(
ref.watch(
mapStateNotifierProvider.select(

View File

@ -1,6 +1,5 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/constants/immich_colors.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class MemoryEpilogue extends StatefulWidget {
@ -49,24 +48,26 @@ class _MemoryEpilogueState extends State<MemoryEpilogue>
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icon(
Icons.check_circle_outline_sharp,
color: immichDarkThemePrimaryColor,
color: context.isDarkTheme
? context.colorScheme.primary
: context.colorScheme.inversePrimary,
size: 64.0,
),
const SizedBox(height: 16.0),
Text(
"memories_all_caught_up",
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
color: Colors.white,
),
style: context.textTheme.headlineMedium?.copyWith(
color: Colors.white,
),
).tr(),
const SizedBox(height: 16.0),
Text(
"memories_check_back_tomorrow",
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Colors.white,
),
style: context.textTheme.bodyMedium?.copyWith(
color: Colors.white,
),
).tr(),
const SizedBox(height: 16.0),
TextButton(
@ -74,7 +75,9 @@ class _MemoryEpilogueState extends State<MemoryEpilogue>
child: Text(
"memories_start_over",
style: context.textTheme.displayMedium?.copyWith(
color: immichDarkThemePrimaryColor,
color: context.isDarkTheme
? context.colorScheme.primary
: context.colorScheme.inversePrimary,
),
).tr(),
),
@ -108,9 +111,9 @@ class _MemoryEpilogueState extends State<MemoryEpilogue>
),
Text(
"memories_swipe_to_close",
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Colors.white,
),
style: context.textTheme.bodyMedium?.copyWith(
color: Colors.white,
),
).tr(),
],
),

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/constants/immich_colors.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class MemoryProgressIndicator extends StatelessWidget {
/// The number of ticks in the progress indicator
@ -25,8 +25,11 @@ class MemoryProgressIndicator extends StatelessWidget {
children: [
LinearProgressIndicator(
value: value,
backgroundColor: Colors.grey[600],
color: immichDarkThemePrimaryColor,
borderRadius: const BorderRadius.all(Radius.circular(10.0)),
backgroundColor: Colors.grey[800],
color: context.isDarkTheme
? context.colorScheme.primary
: context.colorScheme.inversePrimary,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,

View File

@ -22,9 +22,9 @@ class SearchFilterChip extends StatelessWidget {
onTap: onTap,
child: Card(
elevation: 0,
color: context.primaryColor.withAlpha(25),
color: context.primaryColor.withOpacity(.5),
shape: StadiumBorder(
side: BorderSide(color: context.primaryColor),
side: BorderSide(color: context.colorScheme.secondaryContainer),
),
child: Padding(
padding:
@ -47,8 +47,9 @@ class SearchFilterChip extends StatelessWidget {
onTap: onTap,
child: Card(
elevation: 0,
shape:
StadiumBorder(side: BorderSide(color: Colors.grey.withAlpha(100))),
shape: StadiumBorder(
side: BorderSide(color: context.colorScheme.outline.withOpacity(.5)),
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 14.0),
child: Row(

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
class ThumbnailWithInfoContainer extends StatelessWidget {
const ThumbnailWithInfoContainer({
@ -25,7 +26,14 @@ class ThumbnailWithInfoContainer extends StatelessWidget {
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius),
color: context.isDarkTheme ? Colors.grey[900] : Colors.grey[100],
gradient: LinearGradient(
colors: [
context.colorScheme.surfaceContainer,
context.colorScheme.surfaceContainer.darken(amount: .1),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
foregroundDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius),
@ -34,7 +42,7 @@ class ThumbnailWithInfoContainer extends StatelessWidget {
begin: FractionalOffset.topCenter,
end: FractionalOffset.bottomCenter,
colors: [
Colors.grey.withOpacity(0.0),
Colors.transparent,
label == ''
? Colors.black.withOpacity(0.1)
: Colors.black.withOpacity(0.5),

View File

@ -2,6 +2,7 @@ import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/routing/router.dart';
class CustomeProxyHeaderSettings extends StatelessWidget {
@ -20,8 +21,8 @@ class CustomeProxyHeaderSettings extends StatelessWidget {
),
subtitle: Text(
"headers_settings_tile_subtitle".tr(),
style: const TextStyle(
fontSize: 14,
style: context.textTheme.bodyMedium?.copyWith(
color: context.colorScheme.onSurfaceSecondary,
),
),
onTap: () => context.pushRoute(const HeaderSettingsRoute()),

View File

@ -40,9 +40,7 @@ class LanguageSettings extends HookConsumerWidget {
),
),
backgroundColor: WidgetStatePropertyAll<Color>(
context.isDarkTheme
? Colors.grey[900]!
: context.scaffoldBackgroundColor,
context.colorScheme.surfaceContainer,
),
),
menuHeight: context.height * 0.5,

View File

@ -4,6 +4,7 @@ import 'package:flutter_hooks/flutter_hooks.dart' show useEffect, useState;
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/entities/duplicated_asset.entity.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/providers/db.provider.dart';
class LocalStorageSettings extends HookConsumerWidget {
@ -35,10 +36,10 @@ class LocalStorageSettings extends HookConsumerWidget {
fontWeight: FontWeight.w500,
),
).tr(args: ["${cacheItemCount.value}"]),
subtitle: const Text(
subtitle: Text(
"cache_settings_duplicated_assets_subtitle",
style: TextStyle(
fontSize: 14,
style: context.textTheme.bodyMedium?.copyWith(
color: context.colorScheme.onSurfaceSecondary,
),
).tr(),
trailing: TextButton(

View File

@ -15,6 +15,9 @@ class PreferenceSetting extends StatelessWidget {
HapticSetting(),
];
return const SettingsSubPageScaffold(settings: preferenceSettings);
return const SettingsSubPageScaffold(
settings: preferenceSettings,
showDivider: true,
);
}
}

View File

@ -0,0 +1,221 @@
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/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/utils/immich_app_theme.dart';
import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart';
class PrimaryColorSetting extends HookConsumerWidget {
const PrimaryColorSetting({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final themeProvider = ref.read(immichThemeProvider);
final primaryColorSetting =
useAppSettingsState(AppSettingsEnum.primaryColor);
final systemPrimaryColorSetting =
useAppSettingsState(AppSettingsEnum.dynamicTheme);
final currentPreset = useValueNotifier(ref.read(immichThemePresetProvider));
const tileSize = 55.0;
useValueChanged(
primaryColorSetting.value,
(_, __) => currentPreset.value = ImmichColorPreset.values
.firstWhere((e) => e.name == primaryColorSetting.value),
);
void popBottomSheet() {
Future.delayed(const Duration(milliseconds: 200), () {
Navigator.pop(context);
});
}
onUseSystemColorChange(bool newValue) {
systemPrimaryColorSetting.value = newValue;
ref.watch(dynamicThemeSettingProvider.notifier).state = newValue;
ref.invalidate(immichThemeProvider);
popBottomSheet();
}
onPrimaryColorChange(ImmichColorPreset colorPreset) {
primaryColorSetting.value = colorPreset.name;
ref.watch(immichThemePresetProvider.notifier).state = colorPreset;
ref.invalidate(immichThemeProvider);
//turn off system color setting
if (systemPrimaryColorSetting.value) {
onUseSystemColorChange(false);
} else {
popBottomSheet();
}
}
buildPrimaryColorTile({
required Color topColor,
required Color bottomColor,
required double tileSize,
required bool showSelector,
}) {
return Container(
margin: const EdgeInsets.all(4.0),
child: Stack(
children: [
Container(
height: tileSize,
width: tileSize,
decoration: BoxDecoration(
color: bottomColor,
borderRadius: const BorderRadius.all(Radius.circular(100)),
),
),
Container(
height: tileSize / 2,
width: tileSize,
decoration: BoxDecoration(
color: topColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(100),
topRight: Radius.circular(100),
),
),
),
if (showSelector)
Positioned(
left: 0,
right: 0,
top: 0,
bottom: 0,
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(100)),
color: Colors.grey[900]?.withOpacity(.4),
),
child: const Padding(
padding: EdgeInsets.all(3),
child: Icon(
Icons.check_rounded,
color: Colors.white,
size: 25,
),
),
),
),
],
),
);
}
bottomSheetContent() {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Align(
alignment: Alignment.center,
child: Text(
"theme_setting_primary_color_title".tr(),
style: context.textTheme.titleLarge,
),
),
if (isDynamicThemeAvailable)
Container(
padding: const EdgeInsets.symmetric(horizontal: 20),
margin: const EdgeInsets.only(top: 10),
child: SwitchListTile.adaptive(
contentPadding:
const EdgeInsets.symmetric(vertical: 6, horizontal: 20),
dense: true,
activeColor: context.primaryColor,
tileColor: context.colorScheme.surfaceContainerHigh,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
title: Text(
'theme_setting_system_primary_color_title'.tr(),
style: context.textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.w500,
height: 1.5,
),
),
value: systemPrimaryColorSetting.value,
onChanged: onUseSystemColorChange,
),
),
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
children: ImmichColorPreset.values.map((themePreset) {
var theme = themePreset.getTheme();
return GestureDetector(
onTap: () => onPrimaryColorChange(themePreset),
child: buildPrimaryColorTile(
topColor: theme.light.primary,
bottomColor: theme.dark.primary,
tileSize: tileSize,
showSelector: currentPreset.value == themePreset &&
!systemPrimaryColorSetting.value,
),
);
}).toList(),
),
),
],
);
}
return ListTile(
onTap: () => showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext ctx) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 0),
child: bottomSheetContent(),
);
},
),
contentPadding: const EdgeInsets.symmetric(horizontal: 20),
title: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"theme_setting_primary_color_title".tr(),
style: context.textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.w500,
),
),
Text(
"theme_setting_primary_color_subtitle".tr(),
style: context.textTheme.bodyMedium
?.copyWith(color: context.colorScheme.onSurfaceSecondary),
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 8.0),
child: buildPrimaryColorTile(
topColor: themeProvider.light.primary,
bottomColor: themeProvider.dark.primary,
tileSize: 42.0,
showSelector: false,
),
),
],
),
);
}
}

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/widgets/settings/preference_settings/primary_color_setting.dart';
import 'package:immich_mobile/widgets/settings/settings_sub_title.dart';
import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart';
import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart';
@ -16,11 +17,16 @@ class ThemeSetting extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final currentThemeString = useAppSettingsState(AppSettingsEnum.themeMode);
final currentTheme = useValueNotifier(ref.read(immichThemeProvider));
final currentTheme = useValueNotifier(ref.read(immichThemeModeProvider));
final isDarkTheme = useValueNotifier(currentTheme.value == ThemeMode.dark);
final isSystemTheme =
useValueNotifier(currentTheme.value == ThemeMode.system);
final applyThemeToBackgroundSetting =
useAppSettingsState(AppSettingsEnum.colorfulInterface);
final applyThemeToBackgroundProvider =
useValueNotifier(ref.read(colorfulInterfaceSettingProvider));
useValueChanged(
currentThemeString.value,
(_, __) => currentTheme.value = switch (currentThemeString.value) {
@ -30,12 +36,18 @@ class ThemeSetting extends HookConsumerWidget {
},
);
useValueChanged(
applyThemeToBackgroundSetting.value,
(_, __) => applyThemeToBackgroundProvider.value =
applyThemeToBackgroundSetting.value,
);
void onThemeChange(bool isDark) {
if (isDark) {
ref.watch(immichThemeProvider.notifier).state = ThemeMode.dark;
ref.watch(immichThemeModeProvider.notifier).state = ThemeMode.dark;
currentThemeString.value = "dark";
} else {
ref.watch(immichThemeProvider.notifier).state = ThemeMode.light;
ref.watch(immichThemeModeProvider.notifier).state = ThemeMode.light;
currentThemeString.value = "light";
}
}
@ -44,7 +56,7 @@ class ThemeSetting extends HookConsumerWidget {
if (isSystem) {
currentThemeString.value = "system";
isSystemTheme.value = true;
ref.watch(immichThemeProvider.notifier).state = ThemeMode.system;
ref.watch(immichThemeModeProvider.notifier).state = ThemeMode.system;
} else {
final currentSystemBrightness =
MediaQuery.platformBrightnessOf(context);
@ -52,14 +64,20 @@ class ThemeSetting extends HookConsumerWidget {
isDarkTheme.value = currentSystemBrightness == Brightness.dark;
if (currentSystemBrightness == Brightness.light) {
currentThemeString.value = "light";
ref.watch(immichThemeProvider.notifier).state = ThemeMode.light;
ref.watch(immichThemeModeProvider.notifier).state = ThemeMode.light;
} else if (currentSystemBrightness == Brightness.dark) {
currentThemeString.value = "dark";
ref.watch(immichThemeProvider.notifier).state = ThemeMode.dark;
ref.watch(immichThemeModeProvider.notifier).state = ThemeMode.dark;
}
}
}
void onSurfaceColorSettingChange(bool useColorfulInterface) {
applyThemeToBackgroundSetting.value = useColorfulInterface;
ref.watch(colorfulInterfaceSettingProvider.notifier).state =
useColorfulInterface;
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -75,6 +93,13 @@ class ThemeSetting extends HookConsumerWidget {
title: 'theme_setting_dark_mode_switch'.tr(),
onChanged: onThemeChange,
),
const PrimaryColorSetting(),
SettingsSwitchListTile(
valueNotifier: applyThemeToBackgroundProvider,
title: "theme_setting_colorful_interface_title".tr(),
subtitle: 'theme_setting_colorful_interface_subtitle'.tr(),
onChanged: onSurfaceColorSettingChange,
),
],
);
}

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
class SettingsButtonListTile extends StatelessWidget {
final IconData icon;
@ -39,7 +40,12 @@ class SettingsButtonListTile extends StatelessWidget {
children: [
if (subtileText != null) const SizedBox(height: 4),
if (subtileText != null)
Text(subtileText!, style: context.textTheme.bodyMedium),
Text(
subtileText!,
style: context.textTheme.bodyMedium?.copyWith(
color: context.colorScheme.onSurfaceSecondary,
),
),
if (subtitle != null) subtitle!,
const SizedBox(height: 6),
ElevatedButton(onPressed: onButtonTap, child: Text(buttonText)),

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
class SettingsSwitchListTile extends StatelessWidget {
final ValueNotifier<bool> valueNotifier;
@ -54,7 +55,9 @@ class SettingsSwitchListTile extends StatelessWidget {
? Text(
subtitle!,
style: context.textTheme.bodyMedium?.copyWith(
color: enabled ? null : context.themeData.disabledColor,
color: enabled
? context.colorScheme.onSurfaceSecondary
: context.themeData.disabledColor,
),
)
: null,

View File

@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/utils/http_ssl_cert_override.dart';
class SslClientCertSettings extends StatefulWidget {
@ -40,7 +41,9 @@ class _SslClientCertSettingsState extends State<SslClientCertSettings> {
children: [
Text(
"client_cert_subtitle".tr(),
style: context.textTheme.bodyMedium,
style: context.textTheme.bodyMedium?.copyWith(
color: context.colorScheme.onSurfaceSecondary,
),
),
const SizedBox(
height: 6,

View File

@ -65,8 +65,8 @@ class SharedLinkItem extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final themeData = context.themeData;
final isDarkMode = themeData.brightness == Brightness.dark;
final colorScheme = context.colorScheme;
final isDarkMode = colorScheme.brightness == Brightness.dark;
final thumbnailUrl = sharedLink.thumbAssetId != null
? getThumbnailUrlForRemoteId(sharedLink.thumbAssetId!)
: null;
@ -159,7 +159,7 @@ class SharedLinkItem extends ConsumerWidget {
return Padding(
padding: const EdgeInsets.only(right: 10),
child: Chip(
backgroundColor: themeData.primaryColor,
backgroundColor: colorScheme.primary,
label: Text(
labelText,
style: TextStyle(
@ -240,7 +240,7 @@ class SharedLinkItem extends ConsumerWidget {
child: Tooltip(
verticalOffset: 0,
decoration: BoxDecoration(
color: themeData.primaryColor.withOpacity(0.9),
color: colorScheme.primary.withOpacity(0.9),
borderRadius: BorderRadius.circular(10),
),
textStyle: TextStyle(
@ -253,7 +253,7 @@ class SharedLinkItem extends ConsumerWidget {
child: Text(
sharedLink.title,
style: TextStyle(
color: themeData.primaryColor,
color: colorScheme.primary,
fontWeight: FontWeight.bold,
overflow: TextOverflow.ellipsis,
),
@ -268,7 +268,7 @@ class SharedLinkItem extends ConsumerWidget {
child: Tooltip(
verticalOffset: 0,
decoration: BoxDecoration(
color: themeData.primaryColor.withOpacity(0.9),
color: colorScheme.primary.withOpacity(0.9),
borderRadius: BorderRadius.circular(10),
),
textStyle: TextStyle(