Make the custom accent-color picker actually retint the app
NooColors (the color source for nearly the whole redesigned UI) only had two states: the fixed violet palette, or a Material You dynamic scheme when "Match wallpaper" was on. The 5-swatch custom accent picker still wrote to SettingsController.seedColor, but nothing read it back into NooColors - it only reached the underlying Material ColorScheme, which the Noo-styled UI doesn't use, so every custom swatch looked identically purple. Add NooColors.fromSeed, which retints just the accent/accentText/ accentSoft roles from a chosen seed color via ColorScheme.fromSeed (bg/surface/fg etc. stay the fixed warm-neutral palette, unlike dynamic color which reshapes everything to match the wallpaper), and wire it into AppTheme.light/dark. Add a "Default" (Noo violet) swatch to the picker, and move SettingsController's initial seed color to that same violet so a fresh install - or any device without dynamic color - keeps today's look instead of picking up the leftover Nextcloud-blue default from before seed colors did anything visible.
This commit is contained in:
@@ -5,6 +5,15 @@ import 'design_tokens.dart';
|
||||
class AppTheme {
|
||||
static const Color defaultNextcloudBlue = Color(0xFF0082C9);
|
||||
|
||||
/// The design system's own fixed violet - [NooColors.light]/`.dark`'s
|
||||
/// `accent`, and the accent picker's "Default" swatch. Also
|
||||
/// [SettingsController]'s initial [SettingsController.seedColor], so a
|
||||
/// fresh install (or any device without Material You dynamic color) keeps
|
||||
/// today's violet look rather than picking up the leftover
|
||||
/// [defaultNextcloudBlue] default from before seed colors actually did
|
||||
/// anything to the Noo-styled UI (see [NooColors.fromSeed]).
|
||||
static const Color defaultAccent = Color(0xFF8D0DE3);
|
||||
|
||||
// Flutter's Material 3 default (ZoomPageTransitionsBuilder) doesn't
|
||||
// implement Android's predictive-back gesture at all. Opting into
|
||||
// PredictiveBackPageTransitionsBuilder here (Android only) is required —
|
||||
@@ -24,6 +33,7 @@ class AppTheme {
|
||||
static const _sliderTheme = SliderThemeData(year2023: false);
|
||||
|
||||
static const List<Color> seedColors = [
|
||||
defaultAccent, // Default (Noo Violet)
|
||||
Color(0xFF0082C9), // Nextcloud Blue
|
||||
Color(0xFF009688), // Ocean Teal
|
||||
Color(0xFF6750A4), // Deep Purple
|
||||
@@ -87,7 +97,7 @@ class AppTheme {
|
||||
);
|
||||
final nooColors = (useDynamicColor && dynamicScheme != null)
|
||||
? NooColors.fromDynamicScheme(dynamicScheme)
|
||||
: NooColors.light;
|
||||
: NooColors.fromSeed(seedColor, Brightness.light);
|
||||
|
||||
return ThemeData(
|
||||
useMaterial3: true,
|
||||
@@ -131,7 +141,7 @@ class AppTheme {
|
||||
);
|
||||
var nooColors = (useDynamicColor && dynamicScheme != null)
|
||||
? NooColors.fromDynamicScheme(dynamicScheme)
|
||||
: NooColors.dark;
|
||||
: NooColors.fromSeed(seedColor, Brightness.dark);
|
||||
|
||||
if (amoled) {
|
||||
// True OLED black across every surface tone Material 3 hands out -
|
||||
|
||||
@@ -7,13 +7,13 @@ import 'package:google_fonts/google_fonts.dart';
|
||||
/// `Theme.of(context).extension<NooColors>()!` (or a `context.nooColors`
|
||||
/// getter, once one exists) instead of the Material [ColorScheme] roles.
|
||||
///
|
||||
/// Two independent sources feed this, matching the app's color settings:
|
||||
/// the fixed [light]/[dark] palettes below (the design system's own
|
||||
/// default look), or [NooColors.fromDynamicScheme] when the user has
|
||||
/// Material You dynamic color turned on - there's no third option (no
|
||||
/// custom accent picker), since the design system explicitly rules out
|
||||
/// "add new colors". [withAmoled] layers on top of either source when the
|
||||
/// user's AMOLED toggle is on.
|
||||
/// Three sources feed this, matching the app's color settings: the fixed
|
||||
/// [light]/[dark] palettes below (the design system's own default look,
|
||||
/// also what the accent picker's "Default" violet swatch selects),
|
||||
/// [NooColors.fromDynamicScheme] when the user has Material You dynamic
|
||||
/// color turned on, or [NooColors.fromSeed] for a custom accent-picker
|
||||
/// swatch. [withAmoled] layers on top of any of the three when the user's
|
||||
/// AMOLED toggle is on.
|
||||
@immutable
|
||||
class NooColors extends ThemeExtension<NooColors> {
|
||||
final Color bg;
|
||||
@@ -161,6 +161,34 @@ class NooColors extends ThemeExtension<NooColors> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Derives an accent-only variant of the fixed [light]/[dark] palette for
|
||||
/// a user-chosen custom seed color (Settings' accent-color picker) -
|
||||
/// unlike [fromDynamicScheme], only the accent roles change; bg/surface/
|
||||
/// fg etc. stay the Noo warm-neutral palette, since picking a named
|
||||
/// accent ("Ocean Teal") is meant to retint the brand color, not reshape
|
||||
/// the whole surface to match a wallpaper the way dynamic color does.
|
||||
/// [seedColor] equal to the fixed palette's own accent (the picker's
|
||||
/// "Default" violet swatch) returns the untouched fixed palette, so the
|
||||
/// out-of-box look stays pixel-identical rather than going through
|
||||
/// [ColorScheme.fromSeed]'s tonal-palette math for no reason.
|
||||
factory NooColors.fromSeed(Color seedColor, Brightness brightness) {
|
||||
final fixed = brightness == Brightness.dark ? dark : light;
|
||||
if (seedColor == light.accent) return fixed;
|
||||
final cs = ColorScheme.fromSeed(
|
||||
seedColor: seedColor,
|
||||
brightness: brightness,
|
||||
);
|
||||
return fixed.copyWith(
|
||||
accent: seedColor,
|
||||
// Light accentText matches accent exactly, same as the fixed
|
||||
// palette - dark needs a lighter, desaturated tint for contrast
|
||||
// against a dark surface, which is exactly what Material's tonal
|
||||
// primary (tone ~80 in dark mode) is designed to give.
|
||||
accentText: brightness == Brightness.dark ? cs.primary : seedColor,
|
||||
accentSoft: cs.primaryContainer,
|
||||
);
|
||||
}
|
||||
|
||||
/// True OLED black across every surface tone - not just [bg] - so cards,
|
||||
/// bars and sheets all go black too instead of the dark palette's warm
|
||||
/// dark-grey tones. Mirrors the AMOLED handling this replaces in
|
||||
@@ -391,10 +419,8 @@ class NooText {
|
||||
fontWeight: FontWeight.w400,
|
||||
);
|
||||
|
||||
static TextStyle get label => GoogleFonts.instrumentSans(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
);
|
||||
static TextStyle get label =>
|
||||
GoogleFonts.instrumentSans(fontSize: 13, fontWeight: FontWeight.w600);
|
||||
|
||||
static TextStyle get meta => GoogleFonts.instrumentSans(
|
||||
fontSize: 13,
|
||||
|
||||
Reference in New Issue
Block a user