Skip to content

Commit

Permalink
fix: Top app bar icon color
Browse files Browse the repository at this point in the history
refactor: Add themeMode extensions
refactor: Create theme service data class
  • Loading branch information
github-actions committed Sep 10, 2024
1 parent a53c610 commit d7d0a44
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 70 deletions.
53 changes: 28 additions & 25 deletions lib/src/components/top_app_bar/extended_top_app_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,33 +49,36 @@ class ZetaExtendedAppBarDelegate extends SliverPersistentHeaderDelegate {
constraints: BoxConstraints(minHeight: Zeta.of(context).spacing.xl_9, maxHeight: maxExtent),
child: ColoredBox(
color: Zeta.of(context).colors.surfaceDefault,
child: Stack(
children: [
Positioned(
top: shrinks
? (topMax + (-1 * shrinkOffset)).clamp(
topMin -
(searchController != null && searchController!.isEnabled
? searchBarOffsetTop
: Zeta.of(context).spacing.none),
topMax,
)
: topMax,
left: shrinks ? ((shrinkOffset / maxExtent) * _maxExtent).clamp(leftMin, leftMax) : leftMin,
right: searchController != null && searchController!.isEnabled
? searchBarOffsetRight
: Zeta.of(context).spacing.none,
child: title,
),
if (leading != null)
Positioned(top: Zeta.of(context).spacing.medium, left: Zeta.of(context).spacing.small, child: leading!),
if (actions != null)
child: IconTheme(
data: IconThemeData(color: Zeta.of(context).colors.mainDefault),
child: Stack(
children: [
Positioned(
top: Zeta.of(context).spacing.medium,
right: Zeta.of(context).spacing.small,
child: Row(children: actions!),
top: shrinks
? (topMax + (-1 * shrinkOffset)).clamp(
topMin -
(searchController != null && searchController!.isEnabled
? searchBarOffsetTop
: Zeta.of(context).spacing.none),
topMax,
)
: topMax,
left: shrinks ? ((shrinkOffset / maxExtent) * _maxExtent).clamp(leftMin, leftMax) : leftMin,
right: searchController != null && searchController!.isEnabled
? searchBarOffsetRight
: Zeta.of(context).spacing.none,
child: title,
),
],
if (leading != null)
Positioned(top: Zeta.of(context).spacing.medium, left: Zeta.of(context).spacing.small, child: leading!),
if (actions != null)
Positioned(
top: Zeta.of(context).spacing.medium,
right: Zeta.of(context).spacing.small,
child: Row(children: actions!),
),
],
),
),
),
);
Expand Down
15 changes: 15 additions & 0 deletions lib/src/theme/color_extensions.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:math' as math;
import 'dart:ui';

import 'package:flutter/material.dart';
import '../../zeta_flutter.dart';
Expand Down Expand Up @@ -343,3 +344,17 @@ extension ZetaSemanticColorExtension on ZetaSemanticColors {
onSurface: mainDefault,
);
}

/// Extensions on [ThemeMode] to provide additional functionality.
extension ZetaThemeModeExtension on ThemeMode {
/// Returns true if the theme mode is dark.
bool get isDark =>
this == ThemeMode.system ? PlatformDispatcher.instance.platformBrightness.isDark : this == ThemeMode.dark;

/// Returns the brightness value based on the theme mode.
Brightness get brightness => isDark ? Brightness.dark : Brightness.light;
}

extension on Brightness {
bool get isDark => this == Brightness.dark;
}
70 changes: 50 additions & 20 deletions lib/src/theme/theme_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,28 @@ import 'contrast.dart';
const String _kThemeMode = 'themeMode';
const String _kContrast = 'contrast';
const String _kThemeId = 'theme_id';
const String _kFontFamily = 'fontFamily';

/// `ZetaThemeData` is a class that holds the theme data to be stored with the theme service.
class ZetaThemeServiceData {
/// Constructs a [ZetaThemeServiceData].
///
/// All fields are optional. If null, defaults will be used.
ZetaThemeServiceData({this.themeId, this.themeMode, this.contrast, this.fontFamily});

/// The unique identifier for the custom theme data.
final String? themeId;

/// The theme mode of the Zeta theme.
final ThemeMode? themeMode;

/// The contrast of the Zeta theme.
final ZetaContrast? contrast;

/// The font family of the Zeta theme.
final String? fontFamily;
}

// TODO(colors): Re-add custom font somewhere (not here)
// TODO(colors): Add tests
/// `ZetaThemeService` is an abstract class.
Expand All @@ -27,8 +49,8 @@ abstract class ZetaThemeService {
///
/// `ZetaContrast` defines different contrast styles to use across the application.
///
/// Returns a Future `(ZetaThemeData?, ThemeMode?, ZetaContrast?)`.
Future<(ThemeMode?, ZetaContrast?, String?)> loadTheme();
/// Returns a Future [ZetaThemeServiceData].
Future<ZetaThemeServiceData> loadTheme();

/// Saves the provided theme data as the application's theme.
///
Expand All @@ -38,11 +60,7 @@ abstract class ZetaThemeService {
///
/// Returns a `Future` that completes when the theme data has been successfully saved.
Future<void> saveTheme({
required ThemeMode themeMode,
required ZetaContrast contrast,
required String? themeId,
});
Future<void> saveTheme({required ZetaThemeServiceData themeData});
}

/// A default implementation of `ZetaThemeService` that uses `SharedPreferences` to store the theme data.
Expand All @@ -51,7 +69,7 @@ class ZetaDefaultThemeService extends ZetaThemeService {
const ZetaDefaultThemeService();

@override
Future<(ThemeMode?, ZetaContrast?, String?)> loadTheme() async {
Future<ZetaThemeServiceData> loadTheme() async {
final preferences = await SharedPreferences.getInstance();

final modeString = preferences.getString(_kThemeMode);
Expand All @@ -66,21 +84,33 @@ class ZetaDefaultThemeService extends ZetaThemeService {
final contrast = contrastString == ZetaContrast.aaa.name ? ZetaContrast.aaa : ZetaContrast.aa;

final themeId = preferences.getString(_kThemeId);

return (themeMode, contrast, themeId);
final fontFamily = preferences.getString(_kFontFamily);

return ZetaThemeServiceData(
themeMode: themeMode,
contrast: contrast,
themeId: themeId,
fontFamily: fontFamily,
);
}

@override
Future<void> saveTheme({
required ThemeMode themeMode,
required ZetaContrast contrast,
required String? themeId,
}) async {
Future<void> saveTheme({required ZetaThemeServiceData themeData}) async {
final preferences = await SharedPreferences.getInstance();

await preferences.setString(_kThemeMode, themeMode.name);
await preferences.setString(_kContrast, contrast.name);

if (themeId != null) await preferences.setString(_kThemeId, themeId);
final List<Future<void>> futures = [];

if (themeData.fontFamily != null) {
futures.add(preferences.setString(_kFontFamily, themeData.fontFamily!));
}
if (themeData.themeMode != null) {
futures.add(preferences.setString(_kThemeMode, themeData.themeMode!.name));
}
if (themeData.contrast != null) {
futures.add(preferences.setString(_kContrast, themeData.contrast!.name));
}
if (themeData.themeId != null) {
futures.add(preferences.setString(_kThemeId, themeData.themeId!));
}
await Future.wait(futures);
}
}
12 changes: 1 addition & 11 deletions lib/src/utils/zeta.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';

import '../../zeta_flutter.dart';

Expand Down Expand Up @@ -66,16 +65,7 @@ class Zeta extends InheritedWidget {
/// If the theme mode is set to 'system', it will return the brightness that ties with the device's system theme setting.
/// If the theme mode is set to 'light', it always returns `Brightness.light`.
/// If neither, it returns `Brightness.dark` by default (i.e., when the theme mode is 'dark').
Brightness get brightness {
if (themeMode == ThemeMode.system) {
return SchedulerBinding
.instance.platformDispatcher.platformBrightness; // Return the current system brightness setting
} else if (themeMode == ThemeMode.light) {
return Brightness.light; // Return the light mode brightness
} else {
return Brightness.dark; // Default: Return the dark mode brightness
}
}
Brightness get brightness => themeMode.brightness;

/// Gets the radius values based on the tokens.
ZetaRadiiSemantics get radius => semantics.radii;
Expand Down
29 changes: 15 additions & 14 deletions lib/src/utils/zeta_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,15 @@ class ZetaProviderState extends State<ZetaProvider> with Diagnosticable, Widgets

/// Retrieves the theme values from the shared preferences.
Future<void> getThemeValuesFromPreferences() async {
final (themeMode, contrast, themeId) = await widget.themeService.loadTheme();
final ZetaThemeServiceData themeServiceData = await widget.themeService.loadTheme();

// Set the initial theme mode.
_themeMode = themeMode ?? widget.initialThemeMode ?? ThemeMode.system;
_themeMode = themeServiceData.themeMode ?? widget.initialThemeMode ?? ThemeMode.system;

// Set the initial contrast.
_contrast = contrast ?? widget.initialContrast ?? ZetaContrast.aa;
_contrast = themeServiceData.contrast ?? widget.initialContrast ?? ZetaContrast.aa;

final loadedTheme = _customThemes[widget.initialTheme ?? themeId];
final loadedTheme = _customThemes[themeServiceData.themeId ?? widget.initialTheme];

if (loadedTheme != null) {
_customTheme = loadedTheme;
Expand Down Expand Up @@ -319,9 +319,11 @@ class ZetaProviderState extends State<ZetaProvider> with Diagnosticable, Widgets
void _saveThemeChange() {
unawaited(
widget.themeService.saveTheme(
themeMode: _themeMode,
contrast: _contrast,
themeId: _customTheme?.id,
themeData: ZetaThemeServiceData(
themeMode: _themeMode,
contrast: _contrast,
themeId: _customTheme?.id,
),
),
);
}
Expand Down Expand Up @@ -356,7 +358,6 @@ class _InternalProvider extends StatefulWidget {
/// Represents the late initialization of the ZetaContrast value.
final ZetaContrast contrast;

/// Represents the late initialization of the ThemeMode value.
final ThemeMode themeMode;

final bool rounded;
Expand Down Expand Up @@ -389,14 +390,14 @@ class _InternalProviderState extends State<_InternalProvider> {
themeMode: widget.themeMode,
contrast: widget.contrast,
rounded: widget.rounded,
customPrimitives: widget.themeMode == ThemeMode.light
? ZetaPrimitivesLight(
primary: widget.customTheme?.primary,
secondary: widget.customTheme?.secondary,
)
: ZetaPrimitivesDark(
customPrimitives: widget.themeMode.isDark
? ZetaPrimitivesDark(
primary: widget.customTheme?.primaryDark,
secondary: widget.customTheme?.secondaryDark,
)
: ZetaPrimitivesLight(
primary: widget.customTheme?.primary,
secondary: widget.customTheme?.secondary,
),
child: Builder(
builder: (context) {
Expand Down

0 comments on commit d7d0a44

Please sign in to comment.