Skip to content

Commit 8c84c3a

Browse files
committed
feat: update theme handling and improve UI consistency across various screens
1 parent f5c8894 commit 8c84c3a

16 files changed

Lines changed: 156 additions & 210 deletions

client/lib/app/app.dart

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,6 @@ class _BorneoAppState extends State<BorneoApp> {
106106

107107
@override
108108
Widget build(BuildContext context) {
109-
/*
110-
theme: ThemeData(
111-
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xff493b72), brightness: Brightness.light),
112-
useMaterial3: true, // 推荐使用 Material 3
113-
),
114-
darkTheme: ThemeData(
115-
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xff493b72), brightness: Brightness.dark),
116-
useMaterial3: true, // 推荐使用 Material 3
117-
),
118-
*/
119109
return MultiProvider(
120110
providers: [
121111
Provider<EventBus>(create: (_) => widget.globalEventBus),
@@ -126,8 +116,16 @@ class _BorneoAppState extends State<BorneoApp> {
126116
return MaterialApp(
127117
title: 'Borneo Aqua',
128118
navigatorKey: _navigatorKey,
129-
theme: BorneoTheme(Theme.of(context).textTheme).light(),
130-
darkTheme: BorneoTheme(Theme.of(context).textTheme).dark(),
119+
//theme: BorneoTheme(Theme.of(context).textTheme).light(),
120+
//darkTheme: BorneoTheme(Theme.of(context).textTheme).dark(),
121+
theme: ThemeData(
122+
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xff493b72), brightness: Brightness.light),
123+
useMaterial3: true, // 推荐使用 Material 3
124+
),
125+
darkTheme: ThemeData(
126+
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xff493b72), brightness: Brightness.dark),
127+
useMaterial3: true, // 推荐使用 Material 3
128+
),
131129
themeMode: _themeMode,
132130
locale: _locale,
133131
supportedLocales: kSupportedLocales,
@@ -150,10 +148,13 @@ class _BorneoAppState extends State<BorneoApp> {
150148
SystemChrome.setSystemUIOverlayStyle(
151149
SystemUiOverlayStyle(
152150
statusBarColor: Colors.transparent,
153-
statusBarIconBrightness: Brightness.dark,
154-
systemNavigationBarColor: effectiveBrightness == Brightness.light
151+
statusBarIconBrightness: theme.brightness,
152+
systemNavigationBarColor: theme.colorScheme.surfaceContainer,
153+
/*
154+
effectiveBrightness == Brightness.light
155155
? Colors.white
156-
: theme.colorScheme.surfaceContainerHighest,
156+
: theme.colorScheme.surfaceContainer,
157+
*/
157158
systemNavigationBarIconBrightness: effectiveBrightness == Brightness.light
158159
? Brightness.dark
159160
: Brightness.light,

client/lib/devices/borneo/lyfi/manifest.dart

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,16 @@ class LyfiDeviceModuleMetadata extends DeviceModuleMetadata {
5656
}
5757

5858
static List<Widget> _secondaryStatesBuilder(BuildContext context, AbstractDeviceSummaryViewModel vm) {
59-
final modeWidget = Selector<AbstractDeviceSummaryViewModel, LyfiMode?>(
60-
selector: (_, vm) => (vm as LyfiSummaryDeviceViewModel).ledMode,
61-
builder: (context, mode, child) => Text(_modeText(context, mode), style: Theme.of(context).textTheme.labelSmall),
62-
);
6359
final stateWidget = Selector<AbstractDeviceSummaryViewModel, LyfiState?>(
6460
selector: (_, vm) => (vm as LyfiSummaryDeviceViewModel).ledState,
6561
builder: (context, state, child) =>
6662
Text(_stateText(context, state), style: Theme.of(context).textTheme.labelSmall),
6763
);
68-
return [modeWidget, stateWidget];
64+
final modeWidget = Selector<AbstractDeviceSummaryViewModel, LyfiMode?>(
65+
selector: (_, vm) => (vm as LyfiSummaryDeviceViewModel).ledMode,
66+
builder: (context, mode, child) => Text(_modeText(context, mode), style: Theme.of(context).textTheme.labelSmall),
67+
);
68+
return [stateWidget, modeWidget];
6969
}
7070

7171
/// Custom card center: bar chart of per-channel brightness.
@@ -115,20 +115,13 @@ class LyfiDeviceModuleMetadata extends DeviceModuleMetadata {
115115
}
116116
}
117117

118-
static String _stateText(BuildContext context, LyfiState? state) {
119-
switch (state) {
120-
case LyfiState.normal:
121-
return context.translate('NORM');
122-
case LyfiState.dimming:
123-
return context.translate('DIMM');
124-
case LyfiState.temporary:
125-
return context.translate('TEMP');
126-
case LyfiState.preview:
127-
return context.translate('PREV');
128-
default:
129-
return '-';
130-
}
131-
}
118+
static String _stateText(BuildContext context, LyfiState? state) => switch (state) {
119+
LyfiState.normal => context.translate('NORM'),
120+
LyfiState.dimming => context.translate('DIMM'),
121+
LyfiState.temporary => context.translate('TEMP'),
122+
LyfiState.preview => context.translate('PREV'),
123+
_ => '-',
124+
};
132125

133126
static Future<WotThing> _createWotThing(
134127
DeviceEntity device,
@@ -161,7 +154,7 @@ class _LyfiBrightnessChart extends StatelessWidget {
161154
final fraction = (value / kLyfiBrightnessMax).clamp(0.0, 1.0).toDouble();
162155
final pct = (fraction * 100).round();
163156
final primaryColor = HexColor.fromHex(ch.color);
164-
final trackColor = Theme.of(context).colorScheme.surfaceContainerLow;
157+
final trackColor = Theme.of(context).colorScheme.surfaceContainerHigh;
165158
return Center(
166159
child: LayoutBuilder(
167160
builder: (context, constraints) {

client/lib/devices/borneo/lyfi/views/brightness_slider_list.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ class BrightnessSliderList<TEditor extends IEditor> extends StatelessWidget {
3939
SizedBox(height: 4),
4040
Text(
4141
'${(channelValue / kLyfiBrightnessMax * 100.0).toStringAsFixed(1).padLeft(5, '\u2007')}%',
42-
style: Theme.of(context).textTheme.labelMedium?.copyWith(fontFeatures: [FontFeature.tabularFigures()]),
42+
style: Theme.of(context).textTheme.labelMedium?.copyWith(
43+
color: Theme.of(context).colorScheme.onSurface,
44+
fontFeatures: [FontFeature.tabularFigures()],
45+
),
4346
),
4447
],
4548
),
@@ -57,7 +60,7 @@ class BrightnessSliderList<TEditor extends IEditor> extends StatelessWidget {
5760
padding: EdgeInsets.zero,
5861
itemCount: editor.availableChannelCount,
5962
itemBuilder: (context, index) => sliders[index],
60-
separatorBuilder: (context, index) => Divider(height: 1, color: Theme.of(context).dividerColor),
63+
separatorBuilder: (context, index) => Divider(height: 1, color: Theme.of(context).dividerTheme.color, indent: 16),
6164
);
6265
}
6366
}

client/lib/devices/borneo/lyfi/views/brightness_slider_list_tile.dart

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ class BrightnessSliderListTile extends StatelessWidget {
2727
@override
2828
Widget build(BuildContext context) {
2929
final handlerSize = 24.0;
30+
final trackBarBorder = Border.all(color: Theme.of(context).colorScheme.surfaceContainerHigh, width: 1.5);
3031
return ListTile(
3132
dense: true,
32-
tileColor: Theme.of(context).colorScheme.surfaceContainerHigh,
3333
minVerticalPadding: 0,
3434
contentPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 0),
3535
title: FlutterSlider(
@@ -46,7 +46,7 @@ class BrightnessSliderListTile extends StatelessWidget {
4646
child: Center(
4747
child: Icon(
4848
Icons.circle,
49-
color: disabled ? color : color.withValues(alpha: 0.38),
49+
color: disabled ? color.withValues(alpha: 0.38) : color,
5050
size: handlerSize * 0.60,
5151
),
5252
),
@@ -66,15 +66,10 @@ class BrightnessSliderListTile extends StatelessWidget {
6666
trackBar: FlutterSliderTrackBar(
6767
activeTrackBarHeight: 8,
6868
inactiveTrackBarHeight: 8,
69-
activeTrackBar: BoxDecoration(
70-
border: Border.all(color: Theme.of(context).colorScheme.surfaceDim, width: 1.5),
71-
color: disabled ? color.withValues(alpha: 0.38) : color,
72-
borderRadius: BorderRadius.circular(3),
73-
),
74-
inactiveTrackBar: BoxDecoration(
75-
color: Theme.of(context).colorScheme.surfaceDim,
76-
borderRadius: BorderRadius.circular(3),
77-
),
69+
activeDisabledTrackBarColor: color.withValues(alpha: 0.15),
70+
inactiveDisabledTrackBarColor: color.withValues(alpha: 0.15),
71+
activeTrackBar: BoxDecoration(border: trackBarBorder, color: color),
72+
inactiveTrackBar: BoxDecoration(border: trackBarBorder, color: color.withValues(alpha: 0.24)),
7873
),
7974
onDragging: (index, low, _) => onChanged(low.toInt()),
8075
onDragCompleted: (index, low, _) => onChanged(low.toInt()),

client/lib/devices/borneo/lyfi/views/dashboard/dashboard_acclimation_tile.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ class DashboardAcclimationTile extends StatelessWidget {
146146
child: Icon(
147147
Icons.calendar_month_outlined,
148148
size: 64,
149-
color: theme.colorScheme.onSurface.withValues(alpha: 0.15),
149+
color: theme.colorScheme.inversePrimary.withValues(alpha: 0.24),
150150
),
151151
),
152152
],

client/lib/devices/borneo/lyfi/views/dashboard/dashboard_settings_tile.dart

Lines changed: 23 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -32,57 +32,33 @@ class DashboardSettingsTile extends StatelessWidget {
3232
Widget tile = DashboardTile(
3333
disabled: isDisabled,
3434
onPressed: isDisabled ? null : () => _openSettings(context, gt),
35-
child: Row(
36-
crossAxisAlignment: CrossAxisAlignment.center,
37-
children: [
38-
Icon(Icons.settings, size: 32, color: effectiveIconColor),
39-
const SizedBox(width: 8),
40-
Expanded(
41-
child: Column(
42-
mainAxisAlignment: MainAxisAlignment.center,
43-
crossAxisAlignment: CrossAxisAlignment.start,
44-
children: [
45-
Text(
46-
context.translate("Settings"),
47-
style: theme.textTheme.titleMedium?.copyWith(color: effectiveFgColor),
48-
),
49-
],
35+
child: Badge(
36+
key: Key('settings_red_dot'),
37+
largeSize: 12,
38+
smallSize: 12,
39+
isLabelVisible: showDot,
40+
child: Row(
41+
crossAxisAlignment: CrossAxisAlignment.center,
42+
children: [
43+
Icon(Icons.settings, size: 32, color: effectiveIconColor),
44+
const SizedBox(width: 8),
45+
Expanded(
46+
child: Column(
47+
mainAxisAlignment: MainAxisAlignment.center,
48+
crossAxisAlignment: CrossAxisAlignment.start,
49+
children: [
50+
Text(
51+
context.translate("Settings"),
52+
style: theme.textTheme.titleMedium?.copyWith(color: effectiveFgColor),
53+
),
54+
],
55+
),
5056
),
51-
),
52-
],
57+
],
58+
),
5359
),
5460
);
5561

56-
if (showDot) {
57-
// use a tiny notification-style badge rather than a huge circle.
58-
// typical apps use something like 6–10px diameter with a white border.
59-
const double dotDiameter = 10.0;
60-
const double borderWidth = 1.5;
61-
// keep the badge fully inside the tile so it doesn't hit siblings on
62-
// large screens. Use a small inset relative to corner radius.
63-
final double inset = DashboardTile.cornerRadius / 4;
64-
tile = Stack(
65-
clipBehavior: Clip.none,
66-
children: [
67-
tile,
68-
Positioned(
69-
top: inset,
70-
right: inset,
71-
child: Container(
72-
key: const Key('settings_red_dot'),
73-
width: dotDiameter,
74-
height: dotDiameter,
75-
decoration: BoxDecoration(
76-
color: Theme.of(context).colorScheme.error,
77-
shape: BoxShape.circle,
78-
border: Border.all(color: Theme.of(context).scaffoldBackgroundColor, width: borderWidth),
79-
),
80-
),
81-
),
82-
],
83-
);
84-
}
85-
8662
return tile;
8763
},
8864
);

client/lib/devices/borneo/lyfi/views/dashboard/dashboard_temporary_tile.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class DashboardTemporaryTile extends StatelessWidget {
108108
child: Icon(
109109
Icons.flashlight_on,
110110
size: 64,
111-
color: theme.colorScheme.onSurface.withValues(alpha: 0.15),
111+
color: theme.colorScheme.inversePrimary.withValues(alpha: 0.24),
112112
),
113113
),
114114
],

client/lib/devices/borneo/lyfi/views/editor/schedule_editor_view.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ class ScheduleEditorView extends StatelessWidget {
160160
// Bottom buttons
161161
Consumer<ScheduleEditorViewModel>(
162162
builder: (context, vm, child) => ScreenTopRoundedContainer(
163-
color: Theme.of(context).colorScheme.surfaceContainerHighest,
163+
color: Theme.of(context).colorScheme.surfaceContainer,
164164
padding: const EdgeInsets.fromLTRB(8, 24, 8, 8),
165165
child: Row(
166166
mainAxisAlignment: MainAxisAlignment.spaceEvenly,

client/lib/devices/borneo/lyfi/views/moon_screen.dart

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ class MoonScreen extends StatelessWidget {
3939
create: (cb) => vm,
4040
builder: (context, child) {
4141
return Scaffold(
42-
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
4342
appBar: AppBar(
4443
title: Text(context.translate('Moonlight')),
4544
actions: [
@@ -67,22 +66,17 @@ class MoonScreen extends StatelessWidget {
6766
return Column(
6867
mainAxisSize: MainAxisSize.max,
6968
children: [
70-
Container(
71-
color: Theme.of(context).scaffoldBackgroundColor,
72-
padding: const EdgeInsets.all(0),
73-
child: AspectRatio(
74-
aspectRatio: 1.5,
75-
child: Consumer<MoonViewModel>(builder: (context, vm, _) => buildGraph(context, vm)),
76-
),
69+
AspectRatio(
70+
aspectRatio: 1.5,
71+
child: Consumer<MoonViewModel>(builder: (context, vm, _) => buildGraph(context, vm)),
7772
),
7873
const SizedBox(height: 24),
7974
Expanded(
8075
child: Consumer<MoonViewModel>(
8176
builder: (context, vm, _) => ScreenTopRoundedContainer(
82-
color: Theme.of(context).colorScheme.surfaceContainerHighest,
83-
child: SingleChildScrollView(
84-
child: BrightnessSliderList(vm.editor, disabled: !vm.enabled || !vm.canEdit),
85-
),
77+
color: Theme.of(context).colorScheme.surfaceContainer,
78+
padding: EdgeInsets.fromLTRB(0, 24, 0, 24),
79+
child: BrightnessSliderList(vm.editor, disabled: !vm.enabled || !vm.canEdit),
8680
),
8781
),
8882
),

client/lib/features/devices/views/device_card.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class DeviceCard extends StatelessWidget {
3030
selector: (_, vm) => (isOnline: vm.isOnline, isPowerOn: vm.isPowerOn, name: vm.deviceEntity.name),
3131
builder: (context, status, _) {
3232
final colorScheme = Theme.of(context).colorScheme;
33-
final bgColor = colorScheme.surfaceContainer;
33+
final bgColor = colorScheme.surfaceContainerHighest;
3434
final fgColor = colorScheme.onSurface;
3535

3636
return ClipRRect(
@@ -84,7 +84,7 @@ class DeviceCard extends StatelessWidget {
8484
),
8585
),
8686
),
87-
const SizedBox(height: 2),
87+
const SizedBox(height: 4),
8888
// Status row
8989
Padding(
9090
padding: const EdgeInsets.only(right: 8),
@@ -172,7 +172,8 @@ class DeviceCard extends StatelessWidget {
172172
if (i > 0)
173173
SizedBox(
174174
height: 12,
175-
child: VerticalDivider(thickness: 1.5, width: 8, color: fgColor.withValues(alpha: 0.38)),
175+
width: 12,
176+
child: Icon(Icons.circle, size: 4, color: fgColor.withValues(alpha: 0.38)),
176177
),
177178
widgets[i],
178179
],
@@ -226,6 +227,7 @@ class DeviceCard extends StatelessWidget {
226227
case 'change-group':
227228
final groupEntities = parentVM.groups.where((gvm) => !gvm.isDummy).map((gvm) => gvm.model).toList();
228229
showModalBottomSheet(
230+
backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
229231
context: context,
230232
builder: (BuildContext ctx) => DeviceGroupSelectionSheet(
231233
availableGroups: groupEntities,

0 commit comments

Comments
 (0)