Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 46 additions & 41 deletions system_theme/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,51 +22,56 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return SystemThemeBuilder(builder: (context, color) {
final colors = [
color.lightest,
color.lighter,
color.light,
color.accent,
color.dark,
color.darker,
color.darkest,
];
return Scaffold(
body: SafeArea(
child: Column(children: [
Text(
'Accent color: ${defaultTargetPlatform.supportsAccentColor ? 'supported' : 'not supported'}'),
...colors.map((color) {
return Expanded(
child: Container(
color: color,
alignment: Alignment.center,
child: Text(
[
'Lightest',
'Lighter',
'Light',
'Default',
'Dark',
'Darker',
'Darkest',
][colors.indexOf(color)] +
'\n${color.toHex()}',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
return SystemThemeBuilder(
builder: (context, color) {
final colors = [
color.lightest,
color.lighter,
color.light,
color.accent,
color.dark,
color.darker,
color.darkest,
];
return Scaffold(
body: SafeArea(
child: Column(
children: [
Text(
'Accent color: ${defaultTargetPlatform.supportsAccentColor ? 'supported' : 'not supported'}',
),
...colors.map((color) {
return Expanded(
child: Container(
color: color,
alignment: Alignment.center,
child: Text(
[
'Lightest',
'Lighter',
'Light',
'Default',
'Dark',
'Darker',
'Darkest',
][colors.indexOf(color)] +
'\n${color.toHex()}',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: color.computeLuminance() >= 0.5
? Colors.black
: Colors.white,
),
textAlign: TextAlign.center,
),
),
);
}).toList(),
]),
),
);
});
textAlign: TextAlign.center,
),
),
);
}).toList(),
Comment on lines +43 to +68

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation uses indexOf to determine the label for each color. This logic is flawed because if multiple shades have the same color value (which occurs when the platform doesn't provide specific variants and autoAdjustLightness is disabled or results in the same color), indexOf will always return the index of the first occurrence, leading to incorrect labels in the UI. Additionally, the variable name color in the map function shadows the color variable from the SystemThemeBuilder scope. Using asMap().entries allows for a reliable index and avoids shadowing.

                ...colors.asMap().entries.map((entry) {
                  final index = entry.key;
                  final itemColor = entry.value;
                  return Expanded(
                    child: Container(
                      color: itemColor,
                      alignment: Alignment.center,
                      child: Text(
                        [
                              'Lightest',
                              'Lighter',
                              'Light',
                              'Default',
                              'Dark',
                              'Darker',
                              'Darkest',
                            ][index] +
                            '\n${itemColor.toHex()}',
                        style: Theme.of(context).textTheme.titleLarge?.copyWith(
                          color: itemColor.computeLuminance() >= 0.5
                              ? Colors.black
                              : Colors.white,
                        ),
                        textAlign: TextAlign.center,
                      ),
                    ),
                  );
                }).toList(),

],
),
),
);
},
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion system_theme/lib/system_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class SystemAccentColor {
}

SystemAccentColor._fromMap(dynamic colors)
: defaultAccentColor = SystemTheme.fallbackColor {
: defaultAccentColor = SystemTheme.fallbackColor {
_retrieveFromColors(colors);
}

Expand Down
6 changes: 2 additions & 4 deletions system_theme/lib/system_theme_builder.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import 'package:flutter/widgets.dart';
import 'package:system_theme/system_theme.dart';

typedef ThemeWidgetBuilder = Widget Function(
BuildContext context,
SystemAccentColor accent,
);
typedef ThemeWidgetBuilder =
Widget Function(BuildContext context, SystemAccentColor accent);

/// A widget that rebuilds when the system theme changes.
///
Expand Down
60 changes: 31 additions & 29 deletions system_theme/test/system_theme_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ void main() {
final List<MethodCall> log = <MethodCall>[];

// Helper to create a color map in the format the plugin expects
Map<String, dynamic> createColorMap(
{int r = 0, int g = 0, int b = 0, int a = 255}) {
Map<String, dynamic> createColorMap({
int r = 0,
int g = 0,
int b = 0,
int a = 255,
}) {
return {'R': r, 'G': g, 'B': b, 'A': a};
}

Expand All @@ -35,14 +39,12 @@ void main() {

TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
log.add(methodCall);
if (methodCall.method == 'SystemTheme.accentColor') {
return {
'accent': createColorMap(r: 0, g: 0, b: 255),
};
}
return null;
});
log.add(methodCall);
if (methodCall.method == 'SystemTheme.accentColor') {
return {'accent': createColorMap(r: 0, g: 0, b: 255)};
}
return null;
});
});

tearDown(() {
Expand All @@ -63,11 +65,15 @@ void main() {
test('Check platform support for listening to changes', () {
debugDefaultTargetPlatformOverride = TargetPlatform.windows;
expect(
defaultTargetPlatform.supportsListeningToAccentColorChanges, isTrue);
defaultTargetPlatform.supportsListeningToAccentColorChanges,
isTrue,
);

debugDefaultTargetPlatformOverride = TargetPlatform.android;
expect(
defaultTargetPlatform.supportsListeningToAccentColorChanges, isFalse);
defaultTargetPlatform.supportsListeningToAccentColorChanges,
isFalse,
);
});

test('Loads accent color correctly (Singleton)', () async {
Expand All @@ -82,8 +88,8 @@ void main() {
test('Handles MissingPluginException gracefully', () async {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
throw MissingPluginException();
});
throw MissingPluginException();
});

final testTheme = SystemAccentColor(kDefaultFallbackColor);

Expand All @@ -97,8 +103,8 @@ void main() {

TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
return null;
});
return null;
});

final testTheme = SystemAccentColor(customFallback);

Expand All @@ -114,10 +120,8 @@ void main() {

TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
return {
'accent': createColorMap(r: 0, g: 0, b: 255),
};
});
return {'accent': createColorMap(r: 0, g: 0, b: 255)};
});

final testTheme = SystemAccentColor(kDefaultFallbackColor);
await testTheme.load();
Expand All @@ -134,11 +138,11 @@ void main() {

TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
return {
'accent': createColorMap(r: 0, g: 0, b: 255),
'light': createColorMap(r: 0, g: 255, b: 0),
};
});
return {
'accent': createColorMap(r: 0, g: 0, b: 255),
'light': createColorMap(r: 0, g: 255, b: 0),
};
});

final testTheme = SystemAccentColor(kDefaultFallbackColor);
await testTheme.load();
Expand All @@ -151,10 +155,8 @@ void main() {

TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
return {
'accent': createColorMap(r: 0, g: 0, b: 255),
};
});
return {'accent': createColorMap(r: 0, g: 0, b: 255)};
});

final testTheme = SystemAccentColor(kDefaultFallbackColor);
await testTheme.load();
Expand Down
Loading