diff --git a/app/lib/theme.dart b/app/lib/theme.dart index 7cc17b39..16ee8d7b 100644 --- a/app/lib/theme.dart +++ b/app/lib/theme.dart @@ -55,33 +55,6 @@ extension ThemeExtension on ThemeData { tileMode: TileMode.clamp, ); } - - /// Apply surface tint to [color] based on the [elevation] level - /// - /// This function is a temporary workaround for widgets not yet fully - /// supported Material 3 - Color elevate(Color color, int elevation) { - final double tintOpacity; - switch (elevation) { - case 1: - tintOpacity = 0.05; - break; - case 2: - tintOpacity = 0.08; - break; - case 3: - tintOpacity = 0.11; - break; - case 4: - tintOpacity = 0.12; - break; - case 5: - default: - tintOpacity = 0.14; - break; - } - return Color.lerp(color, colorScheme.surfaceTint, tintOpacity)!; - } } class DarkModeSwitchTheme extends StatelessWidget { diff --git a/app/lib/widget/changelog.dart b/app/lib/widget/changelog.dart index 325d00d5..fc82cd01 100644 --- a/app/lib/widget/changelog.dart +++ b/app/lib/widget/changelog.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/app_localizations.dart'; -import 'package:nc_photos/theme.dart'; import 'package:np_codegen/np_codegen.dart'; +import 'package:np_ui/np_ui.dart'; part 'changelog.g.dart'; part 'changelog/changelog_550.dart'; diff --git a/app/lib/widget/home_photos/view.dart b/app/lib/widget/home_photos/view.dart index d7d8c927..a16bb8c3 100644 --- a/app/lib/widget/home_photos/view.dart +++ b/app/lib/widget/home_photos/view.dart @@ -309,8 +309,10 @@ class _ScrollLabel extends StatelessWidget { return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: DefaultTextStyle( - style: Theme.of(context).textTheme.titleMedium!.copyWith( - color: Theme.of(context).colorScheme.onSecondaryContainer), + style: Theme.of(context).textStyleColored( + (textTheme) => textTheme.titleMedium, + (colorScheme) => colorScheme.onSecondaryContainer, + )!, child: Text(text), ), ); diff --git a/app/lib/widget/map_browser.dart b/app/lib/widget/map_browser.dart index 01e517b7..e74fb272 100644 --- a/app/lib/widget/map_browser.dart +++ b/app/lib/widget/map_browser.dart @@ -27,7 +27,6 @@ import 'package:nc_photos/np_api_util.dart'; import 'package:nc_photos/snack_bar_manager.dart'; import 'package:nc_photos/stream_extension.dart'; import 'package:nc_photos/stream_util.dart'; -import 'package:nc_photos/theme.dart'; import 'package:nc_photos/theme/dimension.dart'; import 'package:nc_photos/widget/collection_browser.dart'; import 'package:nc_photos/widget/measure.dart'; @@ -37,6 +36,7 @@ import 'package:np_codegen/np_codegen.dart'; import 'package:np_common/object_util.dart'; import 'package:np_datetime/np_datetime.dart'; import 'package:np_gps_map/np_gps_map.dart'; +import 'package:np_ui/np_ui.dart'; import 'package:to_string/to_string.dart'; part 'map_browser.g.dart'; diff --git a/app/lib/widget/protected_page_password_auth_dialog.dart b/app/lib/widget/protected_page_password_auth_dialog.dart index 1c7cb54b..cfc61b10 100644 --- a/app/lib/widget/protected_page_password_auth_dialog.dart +++ b/app/lib/widget/protected_page_password_auth_dialog.dart @@ -10,6 +10,7 @@ import 'package:nc_photos/k.dart' as k; import 'package:np_codegen/np_codegen.dart'; import 'package:np_common/unique.dart'; import 'package:np_string/np_string.dart'; +import 'package:np_ui/np_ui.dart'; import 'package:to_string/to_string.dart'; part 'protected_page_password_auth_dialog.g.dart'; diff --git a/app/lib/widget/protected_page_password_auth_dialog/view.dart b/app/lib/widget/protected_page_password_auth_dialog/view.dart index 96ddfecb..d0a16e13 100644 --- a/app/lib/widget/protected_page_password_auth_dialog/view.dart +++ b/app/lib/widget/protected_page_password_auth_dialog/view.dart @@ -100,9 +100,10 @@ class _ErrorNoticeState extends State<_ErrorNotice> (t) => Offset(tremblingTransform(3, t) * .05, 0))), child: Text( widget.text, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: Theme.of(context).colorScheme.error, - ), + style: Theme.of(context).textStyleColored( + (textTheme) => textTheme.bodySmall, + (colorScheme) => colorScheme.error, + ), ), ), ); diff --git a/app/lib/widget/settings/app_lock_settings.dart b/app/lib/widget/settings/app_lock_settings.dart index b9771aae..30c06f02 100644 --- a/app/lib/widget/settings/app_lock_settings.dart +++ b/app/lib/widget/settings/app_lock_settings.dart @@ -12,6 +12,7 @@ import 'package:nc_photos/widget/protected_page_password_auth_dialog.dart'; import 'package:nc_photos/widget/protected_page_pin_auth_dialog.dart'; import 'package:np_codegen/np_codegen.dart'; import 'package:np_string/np_string.dart'; +import 'package:np_ui/np_ui.dart'; import 'package:to_string/to_string.dart'; part 'app_lock/bloc.dart'; @@ -71,11 +72,12 @@ class _WrappedAppLockSettings extends StatelessWidget { ? L10n.global().disabledText : L10n.global().enabledText, textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleSmall!.copyWith( - color: appLockType == null - ? Theme.of(context).colorScheme.error - : Theme.of(context).colorScheme.primary, - ), + style: Theme.of(context).textStyleColored( + (textTheme) => textTheme.titleSmall, + (colorScheme) => appLockType == null + ? colorScheme.error + : colorScheme.primary, + ), ), ), ), diff --git a/app/lib/widget/settings/settings_list_caption.dart b/app/lib/widget/settings/settings_list_caption.dart index 6f99eabd..318a6836 100644 --- a/app/lib/widget/settings/settings_list_caption.dart +++ b/app/lib/widget/settings/settings_list_caption.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:np_ui/np_ui.dart'; class SettingsListCaption extends StatelessWidget { const SettingsListCaption({ @@ -12,9 +13,10 @@ class SettingsListCaption extends StatelessWidget { padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), child: Text( label, - style: Theme.of(context).textTheme.titleMedium!.copyWith( - color: Theme.of(context).colorScheme.primary, - ), + style: Theme.of(context).textStyleColored( + (textTheme) => textTheme.titleMedium, + (colorScheme) => colorScheme.primary, + ), ), ); } diff --git a/app/lib/widget/video_viewer.dart b/app/lib/widget/video_viewer.dart index ec247957..09601344 100644 --- a/app/lib/widget/video_viewer.dart +++ b/app/lib/widget/video_viewer.dart @@ -211,9 +211,10 @@ class _VideoViewerState extends State valueListenable: _controller, builder: (context, VideoPlayerValue value, child) => Text( _durationToString(value.position), - style: Theme.of(context).textTheme.labelLarge!.copyWith( - color: Theme.of(context).colorScheme.onSurface, - ), + style: Theme.of(context).textStyleColored( + (textTheme) => textTheme.labelLarge, + (colorScheme) => colorScheme.onSurface, + ), ), ), const SizedBox(width: 8), @@ -235,9 +236,10 @@ class _VideoViewerState extends State if (_controller.value.duration != Duration.zero) Text( _durationToString(_controller.value.duration), - style: Theme.of(context).textTheme.labelLarge!.copyWith( - color: Theme.of(context).colorScheme.onSurface, - ), + style: Theme.of(context).textStyleColored( + (textTheme) => textTheme.labelLarge, + (colorScheme) => colorScheme.onSurface, + ), ), const SizedBox(width: 4), if (widget.canLoop) _LoopToggle(controller: _controller), diff --git a/np_ui/lib/np_ui.dart b/np_ui/lib/np_ui.dart index 1f05109d..74af8db0 100644 --- a/np_ui/lib/np_ui.dart +++ b/np_ui/lib/np_ui.dart @@ -9,5 +9,6 @@ export 'src/pixel_image_provider.dart'; export 'src/shimmer.dart'; export 'src/stateful_slider.dart'; export 'src/switch_form_field.dart'; +export 'src/theme_util.dart'; export 'src/translucent_sliver_app_bar.dart'; export 'src/unbounded_list_tile.dart'; diff --git a/np_ui/lib/src/theme_util.dart b/np_ui/lib/src/theme_util.dart new file mode 100644 index 00000000..b47d34fd --- /dev/null +++ b/np_ui/lib/src/theme_util.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; + +extension ThemeDataExtension on ThemeData { + /// Apply surface tint to [color] based on the [elevation] level + /// + /// This function is a temporary workaround for widgets not yet fully + /// supported Material 3 + Color elevate(Color color, int elevation) { + final double tintOpacity; + switch (elevation) { + case 1: + tintOpacity = 0.05; + break; + case 2: + tintOpacity = 0.08; + break; + case 3: + tintOpacity = 0.11; + break; + case 4: + tintOpacity = 0.12; + break; + case 5: + default: + tintOpacity = 0.14; + break; + } + return Color.lerp(color, colorScheme.surfaceTint, tintOpacity)!; + } + + TextStyle? textStyleColored( + TextStyle? Function(TextTheme textTheme) textStyleBuilder, + Color? Function(ColorScheme colorScheme) colorBuilder, + ) { + return textStyleBuilder(textTheme)?.copyWith( + color: colorBuilder(colorScheme), + ); + } +}