Added material you

This commit is contained in:
JHubi1 2024-06-13 20:51:22 +02:00
parent baf654be40
commit 6697346628
No known key found for this signature in database
GPG Key ID: 7BF82570CBBBD050
13 changed files with 347 additions and 143 deletions

View File

@ -368,6 +368,36 @@
"description": "Text displayed for cancel button, should be capitalized", "description": "Text displayed for cancel button, should be capitalized",
"context": "Visible in the settings view" "context": "Visible in the settings view"
}, },
"settingsThemeDevice": "Gerät",
"@settingsThemeDevice": {
"description": "Text displayed as description for device theme option",
"context": "Visible in the settings view"
},
"settingsThemeOllama": "Ollama",
"@settingsThemeOllama": {
"description": "Text displayed as description for Ollama theme option",
"context": "Visible in the settings view"
},
"settingsThemeRestartTitle": "Neustart Erforderlich",
"@settingsThemeRestartTitle": {
"description": "Title of the restart required dialog",
"context": "Visible in the settings view"
},
"settingsThemeRestartDescription": "Das Ändern des Themas erfordert einen Neustart.\nMöchtest du jetzt neu starten oder die Aktion abbrechen?",
"@settingsThemeRestartDescription": {
"description": "Description of the restart required dialog",
"context": "Visible in the settings view"
},
"settingsThemeRestartRestart": "Neustarten",
"@settingsThemeRestartRestart": {
"description": "Text displayed for restart button, should be capitalized",
"context": "Visible in the settings view"
},
"settingsThemeRestartCancel": "Abbrechen",
"@settingsThemeRestartCancel": {
"description": "Text displayed for cancel button, should be capitalized",
"context": "Visible in the settings view"
},
"settingsVoicePermissionLoading": "Lade Sprachberechtigungen ...", "settingsVoicePermissionLoading": "Lade Sprachberechtigungen ...",
"@settingsVoicePermissionLoading": { "@settingsVoicePermissionLoading": {
"description": "Text displayed while loading voice permissions", "description": "Text displayed while loading voice permissions",

View File

@ -368,6 +368,36 @@
"description": "Text displayed for cancel button, should be capitalized", "description": "Text displayed for cancel button, should be capitalized",
"context": "Visible in the settings view" "context": "Visible in the settings view"
}, },
"settingsThemeDevice": "Device",
"@settingsThemeDevice": {
"description": "Text displayed as description for device theme option",
"context": "Visible in the settings view"
},
"settingsThemeOllama": "Ollama",
"@settingsThemeOllama": {
"description": "Text displayed as description for Ollama theme option",
"context": "Visible in the settings view"
},
"settingsThemeRestartTitle": "Restart Required",
"@settingsThemeRestartTitle": {
"description": "Title of the restart required dialog",
"context": "Visible in the settings view"
},
"settingsThemeRestartDescription": "Changing the theme requires a restart.\nDo you want to restart now or cancel the action?",
"@settingsThemeRestartDescription": {
"description": "Description of the restart required dialog",
"context": "Visible in the settings view"
},
"settingsThemeRestartRestart": "Restart",
"@settingsThemeRestartRestart": {
"description": "Text displayed for restart button, should be capitalized",
"context": "Visible in the settings view"
},
"settingsThemeRestartCancel": "Cancel",
"@settingsThemeRestartCancel": {
"description": "Text displayed for cancel button, should be capitalized",
"context": "Visible in the settings view"
},
"settingsVoicePermissionLoading": "Loading voice permissions ...", "settingsVoicePermissionLoading": "Loading voice permissions ...",
"@settingsVoicePermissionLoading": { "@settingsVoicePermissionLoading": {
"description": "Text displayed while loading voice permissions", "description": "Text displayed while loading voice permissions",

View File

@ -32,6 +32,7 @@ import 'package:flutter_displaymode/flutter_displaymode.dart';
import 'package:speech_to_text/speech_to_text.dart'; import 'package:speech_to_text/speech_to_text.dart';
import 'package:flutter_tts/flutter_tts.dart'; import 'package:flutter_tts/flutter_tts.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:dynamic_color/dynamic_color.dart';
// client configuration // client configuration
@ -127,63 +128,109 @@ class _AppState extends State<App> {
} }
load(); load();
WidgetsBinding.instance.addPostFrameCallback(
(timeStamp) {
if (!(prefs?.getBool("useDeviceTheme") ?? false)) {
theme = ThemeData.from(
colorScheme: const ColorScheme(
brightness: Brightness.light,
primary: Colors.black,
onPrimary: Colors.white,
secondary: Colors.white,
onSecondary: Colors.black,
error: Colors.red,
onError: Colors.white,
surface: Colors.white,
onSurface: Colors.black));
themeDark = ThemeData.from(
colorScheme: const ColorScheme(
brightness: Brightness.dark,
primary: Colors.white,
onPrimary: Colors.black,
secondary: Colors.black,
onSecondary: Colors.white,
error: Colors.red,
onError: Colors.black,
surface: Colors.black,
onSurface: Colors.white));
setState(() {});
}
},
);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return DynamicColorBuilder(
localizationsDelegates: AppLocalizations.localizationsDelegates, builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) {
supportedLocales: AppLocalizations.supportedLocales, if ((prefs?.getBool("useDeviceTheme") ?? false) &&
localeListResolutionCallback: (deviceLocales, supportedLocales) { lightDynamic != null &&
if (deviceLocales != null) { darkDynamic != null) {
for (final locale in deviceLocales) { theme = ThemeData.from(colorScheme: lightDynamic);
var newLocale = Locale(locale.languageCode); themeDark = ThemeData.from(colorScheme: darkDynamic);
if (supportedLocales.contains(newLocale)) { } else {
return locale; theme = ThemeData.from(
colorScheme: const ColorScheme(
brightness: Brightness.light,
primary: Colors.black,
onPrimary: Colors.white,
secondary: Colors.white,
onSecondary: Colors.black,
error: Colors.red,
onError: Colors.white,
surface: Colors.white,
onSurface: Colors.black));
themeDark = ThemeData.from(
colorScheme: const ColorScheme(
brightness: Brightness.dark,
primary: Colors.white,
onPrimary: Colors.black,
secondary: Colors.black,
onSecondary: Colors.white,
error: Colors.red,
onError: Colors.black,
surface: Colors.black,
onSurface: Colors.white));
}
WidgetsBinding.instance.addPostFrameCallback((_) {
WidgetsBinding.instance.platformDispatcher.onPlatformBrightnessChanged =
() {
// invert colors used, because brightness not updated yet
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor:
(prefs?.getString("brightness") ?? "system") == "system"
? ((MediaQuery.of(context).platformBrightness ==
Brightness.light)
? (themeDark ?? ThemeData.dark()).colorScheme.surface
: (theme ?? ThemeData()).colorScheme.surface)
: (prefs?.getString("brightness") == "dark"
? (themeDark ?? ThemeData()).colorScheme.surface
: (theme ?? ThemeData.dark()).colorScheme.surface),
systemNavigationBarIconBrightness:
(((prefs?.getString("brightness") ?? "system") == "system" &&
MediaQuery.of(context).platformBrightness ==
Brightness.dark) ||
prefs?.getString("brightness") == "light")
? Brightness.dark
: Brightness.light));
};
// brightness changed function not run at first startup
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor:
(prefs?.getString("brightness") ?? "system") == "system"
? ((MediaQuery.of(context).platformBrightness ==
Brightness.light)
? (theme ?? ThemeData.dark()).colorScheme.surface
: (themeDark ?? ThemeData()).colorScheme.surface)
: (prefs?.getString("brightness") == "dark"
? (themeDark ?? ThemeData()).colorScheme.surface
: (theme ?? ThemeData.dark()).colorScheme.surface),
systemNavigationBarIconBrightness:
(((prefs?.getString("brightness") ?? "system") == "system" &&
MediaQuery.of(context).platformBrightness ==
Brightness.light) ||
prefs?.getString("brightness") == "light")
? Brightness.dark
: Brightness.light));
});
return MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
localeListResolutionCallback: (deviceLocales, supportedLocales) {
if (deviceLocales != null) {
for (final locale in deviceLocales) {
var newLocale = Locale(locale.languageCode);
if (supportedLocales.contains(newLocale)) {
return locale;
}
} }
} }
} return const Locale("en");
return const Locale("en"); },
}, title: "Ollama",
title: "Ollama", theme: theme,
theme: theme, darkTheme: themeDark,
darkTheme: themeDark, themeMode: ((prefs?.getString("brightness") ?? "system") == "system")
themeMode: ((prefs?.getString("brightness") ?? "system") == "system") ? ThemeMode.system
? ThemeMode.system : ((prefs!.getString("brightness") == "dark")
: ((prefs!.getString("brightness") == "dark") ? ThemeMode.dark
? ThemeMode.dark : ThemeMode.light),
: ThemeMode.light), home: const MainApp());
home: const MainApp()); });
} }
} }
@ -541,54 +588,6 @@ class _MainAppState extends State<MainApp> {
})); }));
} }
void setBrightness() {
WidgetsBinding
.instance.platformDispatcher.onPlatformBrightnessChanged = () {
// invert colors used, because brightness not updated yet
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor:
(prefs!.getString("brightness") ?? "system") == "system"
? ((MediaQuery.of(context).platformBrightness ==
Brightness.light)
? (themeDark ?? ThemeData.dark())
.colorScheme
.surface
: (theme ?? ThemeData()).colorScheme.surface)
: (prefs!.getString("brightness") == "dark"
? (themeDark ?? ThemeData()).colorScheme.surface
: (theme ?? ThemeData.dark()).colorScheme.surface),
systemNavigationBarIconBrightness:
(((prefs!.getString("brightness") ?? "system") ==
"system" &&
MediaQuery.of(context).platformBrightness ==
Brightness.dark) ||
prefs!.getString("brightness") == "light")
? Brightness.dark
: Brightness.light));
};
// brightness changed function not run at first startup
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor:
(prefs!.getString("brightness") ?? "system") == "system"
? ((MediaQuery.of(context).platformBrightness ==
Brightness.light)
? (theme ?? ThemeData.dark()).colorScheme.surface
: (themeDark ?? ThemeData()).colorScheme.surface)
: (prefs!.getString("brightness") == "dark"
? (themeDark ?? ThemeData()).colorScheme.surface
: (theme ?? ThemeData.dark()).colorScheme.surface),
systemNavigationBarIconBrightness:
(((prefs!.getString("brightness") ?? "system") == "system" &&
MediaQuery.of(context).platformBrightness ==
Brightness.light) ||
prefs!.getString("brightness") == "light")
? Brightness.dark
: Brightness.light));
}
setBrightness();
// prefs!.remove("welcomeFinished"); // prefs!.remove("welcomeFinished");
if (!(prefs!.getBool("welcomeFinished") ?? false) && allowSettings) { if (!(prefs!.getBool("welcomeFinished") ?? false) && allowSettings) {
// ignore: use_build_context_synchronously // ignore: use_build_context_synchronously
@ -761,14 +760,16 @@ class _MainAppState extends State<MainApp> {
]), ]),
actions: [ actions: [
TextButton( TextButton(
onPressed: () {selectionHaptic(); onPressed: () {
selectionHaptic();
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: Text(AppLocalizations.of( child: Text(AppLocalizations.of(
context)! context)!
.deleteDialogCancel)), .deleteDialogCancel)),
TextButton( TextButton(
onPressed: () {selectionHaptic(); onPressed: () {
selectionHaptic();
Navigator.of(context).pop(); Navigator.of(context).pop();
for (var i = 0; for (var i = 0;
@ -1227,7 +1228,8 @@ class _MainAppState extends State<MainApp> {
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: OutlinedButton.icon( child: OutlinedButton.icon(
onPressed: () async {selectionHaptic(); onPressed: () async {
selectionHaptic();
Navigator.of(context) Navigator.of(context)
.pop(); .pop();
setMainState = setState; setMainState = setState;
@ -1248,7 +1250,8 @@ class _MainAppState extends State<MainApp> {
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: OutlinedButton.icon( child: OutlinedButton.icon(
onPressed: () async {selectionHaptic(); onPressed: () async {
selectionHaptic();
Navigator.of(context) Navigator.of(context)
.pop(); .pop();
@ -1300,7 +1303,8 @@ class _MainAppState extends State<MainApp> {
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: OutlinedButton.icon( child: OutlinedButton.icon(
onPressed: () async {selectionHaptic(); onPressed: () async {
selectionHaptic();
Navigator.of(context) Navigator.of(context)
.pop(); .pop();
@ -1379,17 +1383,26 @@ class _MainAppState extends State<MainApp> {
attachmentButtonIcon: !multimodal attachmentButtonIcon: !multimodal
? (prefs?.getBool("voiceModeEnabled") ?? ? (prefs?.getBool("voiceModeEnabled") ??
false) false)
? const Icon(Icons.headphones_rounded) ? Icon(Icons.headphones_rounded,
color:
Theme.of(context).iconTheme.color)
: null : null
: const Icon(Icons.add_a_photo_rounded), : Icon(Icons.add_a_photo_rounded,
color: Theme.of(context).iconTheme.color),
sendButtonIcon: SizedBox( sendButtonIcon: SizedBox(
height: 24, height: 24,
child: CircleAvatar( child: CircleAvatar(
backgroundColor: backgroundColor:
Theme.of(context).colorScheme.primary, Theme.of(context).iconTheme.color,
radius: 12, radius: 12,
child: child: Icon(Icons.arrow_upward_rounded,
const Icon(Icons.arrow_upward_rounded)), color:
(prefs?.getBool("useDeviceTheme") ??
false)
? Theme.of(context)
.colorScheme
.surface
: null)),
), ),
sendButtonMargin: EdgeInsets.zero, sendButtonMargin: EdgeInsets.zero,
attachmentButtonMargin: EdgeInsets.zero, attachmentButtonMargin: EdgeInsets.zero,
@ -1414,8 +1427,7 @@ class _MainAppState extends State<MainApp> {
Platform.isMacOS)) Platform.isMacOS))
? 0 ? 0
: 8), : 8),
messageMaxWidth: (MediaQuery.of(context).size.width >= messageMaxWidth: (MediaQuery.of(context).size.width >= 1000)
1000)
? (MediaQuery.of(context).size.width >= 1600) ? (MediaQuery.of(context).size.width >= 1600)
? (MediaQuery.of(context).size.width >= 2200) ? (MediaQuery.of(context).size.width >= 2200)
? 1900 ? 1900
@ -1428,17 +1440,23 @@ class _MainAppState extends State<MainApp> {
secondaryColor: (themeDark ?? ThemeData.dark()).colorScheme.primary.withAlpha(20), secondaryColor: (themeDark ?? ThemeData.dark()).colorScheme.primary.withAlpha(20),
attachmentButtonIcon: !multimodal attachmentButtonIcon: !multimodal
? (prefs?.getBool("voiceModeEnabled") ?? false) ? (prefs?.getBool("voiceModeEnabled") ?? false)
? const Icon(Icons.headphones_rounded) ? Icon(Icons.headphones_rounded, color: Theme.of(context).iconTheme.color)
: null : null
: const Icon(Icons.add_a_photo_rounded), : Icon(Icons.add_a_photo_rounded, color: Theme.of(context).iconTheme.color),
sendButtonIcon: SizedBox( sendButtonIcon: SizedBox(
height: 24, height: 24,
child: CircleAvatar( child: CircleAvatar(
backgroundColor: backgroundColor:
Theme.of(context).colorScheme.primary, Theme.of(context).iconTheme.color,
radius: 12, radius: 12,
child: child: Icon(Icons.arrow_upward_rounded,
const Icon(Icons.arrow_upward_rounded)), color:
(prefs?.getBool("useDeviceTheme") ??
false)
? Theme.of(context)
.colorScheme
.surface
: null)),
), ),
sendButtonMargin: EdgeInsets.zero, sendButtonMargin: EdgeInsets.zero,
attachmentButtonMargin: EdgeInsets.zero, attachmentButtonMargin: EdgeInsets.zero,

View File

@ -17,6 +17,7 @@ import 'settings/about.dart';
import 'package:dartx/dartx.dart'; import 'package:dartx/dartx.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:dynamic_color/dynamic_color.dart';
Widget toggle(BuildContext context, String text, bool value, Widget toggle(BuildContext context, String text, bool value,
Function(bool value) onChanged, Function(bool value) onChanged,
@ -81,11 +82,22 @@ Widget toggle(BuildContext context, String text, bool value,
} }
} }
: onChanged, : onChanged,
activeTrackColor: disabled
? Theme.of(context).colorScheme.primary.withAlpha(50)
: null,
trackOutlineColor: disabled trackOutlineColor: disabled
? const WidgetStatePropertyAll(Colors.grey) ? WidgetStatePropertyAll(Theme.of(context)
.colorScheme
.primary
.withAlpha(150)
.harmonizeWith(
Theme.of(context).colorScheme.primary))
: null, : null,
thumbColor: disabled thumbColor: disabled
? const WidgetStatePropertyAll(Colors.grey) ? WidgetStatePropertyAll(Theme.of(context)
.colorScheme
.primary
.withAlpha(150))
: null))) : null)))
]), ]),
]), ]),
@ -364,8 +376,12 @@ class _ScreenSettingsState extends State<ScreenSettings> {
splashFactory: NoSplash.splashFactory, splashFactory: NoSplash.splashFactory,
child: Row( child: Row(
children: [ children: [
const Icon(Icons.error_rounded, Icon(Icons.error_rounded,
color: Colors.red), color: Colors.red
.harmonizeWith(
Theme.of(context)
.colorScheme
.primary)),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
AppLocalizations.of(context)! AppLocalizations.of(context)!
@ -373,8 +389,12 @@ class _ScreenSettingsState extends State<ScreenSettings> {
hostInvalidHost hostInvalidHost
? "host" ? "host"
: "url"), : "url"),
style: const TextStyle( style: TextStyle(
color: Colors.red)) color: Colors.red
.harmonizeWith(
Theme.of(context)
.colorScheme
.primary)))
], ],
)) ))
: null, : null,
@ -402,15 +422,24 @@ class _ScreenSettingsState extends State<ScreenSettings> {
) )
: Row( : Row(
children: [ children: [
const Icon(Icons.check_rounded, Icon(Icons.check_rounded,
color: Colors.green), color: Colors.green
.harmonizeWith(
Theme.of(context)
.colorScheme
.primary)),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
AppLocalizations.of( AppLocalizations.of(
context)! context)!
.settingsHostValid, .settingsHostValid,
style: const TextStyle( style: TextStyle(
color: Colors.green, color: Colors.green
.harmonizeWith(
Theme.of(
context)
.colorScheme
.primary),
fontFamily: fontFamily:
"monospace")) "monospace"))
], ],
@ -481,7 +510,8 @@ class _ScreenSettingsState extends State<ScreenSettings> {
.settingsSavedAutomatically, .settingsSavedAutomatically,
Icons.info_rounded, Icons.info_rounded,
null, null,
color: Colors.grey) color: Colors.grey.harmonizeWith(
Theme.of(context).colorScheme.primary))
]))))); ])))));
} }
} }

View File

@ -8,6 +8,7 @@ import '../screen_settings.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:dynamic_color/dynamic_color.dart';
class ScreenSettingsBehavior extends StatefulWidget { class ScreenSettingsBehavior extends StatefulWidget {
const ScreenSettingsBehavior({super.key}); const ScreenSettingsBehavior({super.key});
@ -116,7 +117,8 @@ class _ScreenSettingsBehaviorState extends State<ScreenSettingsBehavior> {
.settingsBehaviorNotUpdatedForOlderChats, .settingsBehaviorNotUpdatedForOlderChats,
Icons.info_rounded, Icons.info_rounded,
null, null,
color: Colors.grey) color: Colors.grey
.harmonizeWith(Theme.of(context).colorScheme.primary))
]))), ]))),
); );
} }

View File

@ -11,6 +11,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:dynamic_color/dynamic_color.dart';
class ScreenSettingsExport extends StatefulWidget { class ScreenSettingsExport extends StatefulWidget {
const ScreenSettingsExport({super.key}); const ScreenSettingsExport({super.key});
@ -169,10 +170,12 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
const SizedBox(height: 16), const SizedBox(height: 16),
button(AppLocalizations.of(context)!.settingsExportInfo, button(AppLocalizations.of(context)!.settingsExportInfo,
Icons.info_rounded, null, Icons.info_rounded, null,
color: Colors.grey), color: Colors.grey
.harmonizeWith(Theme.of(context).colorScheme.primary)),
button(AppLocalizations.of(context)!.settingsExportWarning, button(AppLocalizations.of(context)!.settingsExportWarning,
Icons.warning_rounded, null, Icons.warning_rounded, null,
color: Colors.orange) color: Colors.orange
.harmonizeWith(Theme.of(context).colorScheme.primary))
]))), ]))),
); );
} }

View File

@ -1,7 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../main.dart'; import '../main.dart';
import '../worker/haptic.dart'; import '../worker/haptic.dart';
@ -367,6 +366,72 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
}); });
}); });
}), }),
const SizedBox(height: 8),
SegmentedButton(
segments: [
ButtonSegment(
value: "device",
label: Text(AppLocalizations.of(context)!
.settingsThemeDevice),
icon: const Icon(Icons.devices_rounded)),
ButtonSegment(
value: "ollama",
label: Text(AppLocalizations.of(context)!
.settingsThemeOllama),
icon: const ImageIcon(
AssetImage("assets/logo512.png")))
],
selected: {
(prefs?.getBool("useDeviceTheme") ?? false)
? "device"
: "ollama"
},
onSelectionChanged: (p0) {
selectionHaptic();
showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setLocalState) {
return AlertDialog(
title: Text(AppLocalizations.of(context)!
.settingsThemeRestartTitle),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(AppLocalizations.of(context)!
.settingsThemeRestartDescription),
]),
actions: [
TextButton(
onPressed: () {
selectionHaptic();
Navigator.of(context).pop();
},
child: Text(AppLocalizations.of(
context)!
.settingsThemeRestartCancel)),
TextButton(
onPressed: () async {
selectionHaptic();
await prefs!.setBool(
"useDeviceTheme",
p0.elementAt(0) == "device");
if (Platform.isWindows ||
Platform.isLinux ||
Platform.isMacOS) {
exit(0);
} else {
Restart.restartApp();
}
},
child: Text(AppLocalizations.of(
context)!
.settingsThemeRestartRestart))
]);
});
});
}),
const SizedBox(height: 16) const SizedBox(height: 16)
]), ]),
) )

View File

@ -10,6 +10,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:dynamic_color/dynamic_color.dart';
class ScreenSettingsVoice extends StatefulWidget { class ScreenSettingsVoice extends StatefulWidget {
const ScreenSettingsVoice({super.key}); const ScreenSettingsVoice({super.key});
@ -329,7 +330,9 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
.settingsExperimentalBetaFeature, .settingsExperimentalBetaFeature,
Icons.warning_rounded, Icons.warning_rounded,
null, null,
color: Colors.orange, onLongTap: () { color: Colors.orange
.harmonizeWith(Theme.of(context).colorScheme.primary),
onLongTap: () {
selectionHaptic(); selectionHaptic();
ScaffoldMessenger.of(context).showSnackBar(SnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(AppLocalizations.of(context)! content: Text(AppLocalizations.of(context)!

View File

@ -164,7 +164,10 @@ void setModel(BuildContext context, Function setState) {
? const Icon(Icons ? const Icon(Icons
.collections_rounded) .collections_rounded)
: null)), : null)),
checkmarkColor: (usedIndex == index) checkmarkColor: (usedIndex == index &&
!(prefs?.getBool(
"useDeviceTheme") ??
false))
? ((MediaQuery.of(context) ? ((MediaQuery.of(context)
.platformBrightness == .platformBrightness ==
Brightness.light) Brightness.light)
@ -175,7 +178,10 @@ void setModel(BuildContext context, Function setState) {
.colorScheme .colorScheme
.secondary) .secondary)
: null, : null,
labelStyle: (usedIndex == index) labelStyle: (usedIndex == index &&
!(prefs?.getBool(
"useDeviceTheme") ??
false))
? TextStyle( ? TextStyle(
color: (MediaQuery.of(context) color: (MediaQuery.of(context)
.platformBrightness == .platformBrightness ==
@ -188,15 +194,19 @@ void setModel(BuildContext context, Function setState) {
.colorScheme .colorScheme
.secondary) .secondary)
: null, : null,
selectedColor: (MediaQuery.of(context) selectedColor: (prefs
.platformBrightness == ?.getBool("useDeviceTheme") ??
Brightness.light) false)
? (theme ?? ThemeData()) ? null
.colorScheme : (MediaQuery.of(context)
.primary .platformBrightness ==
: (themeDark ?? ThemeData.dark()) Brightness.light)
.colorScheme ? (theme ?? ThemeData())
.primary, .colorScheme
.primary
: (themeDark ?? ThemeData.dark())
.colorScheme
.primary,
onSelected: (bool selected) { onSelected: (bool selected) {
selectionHaptic(); selectionHaptic();
if (addIndex == index) { if (addIndex == index) {

View File

@ -153,6 +153,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
dynamic_color:
dependency: "direct main"
description:
name: dynamic_color
sha256: eae98052fa6e2826bdac3dd2e921c6ce2903be15c6b7f8b6d8a5d49b5086298d
url: "https://pub.dev"
source: hosted
version: "1.7.0"
equatable: equatable:
dependency: transitive dependency: transitive
description: description:

View File

@ -42,6 +42,7 @@ dependencies:
flutter_tts: ^4.0.2 flutter_tts: ^4.0.2
permission_handler: ^11.3.1 permission_handler: ^11.3.1
datetime_loop: ^1.2.0 datetime_loop: ^1.2.0
dynamic_color: ^1.7.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@ -7,6 +7,7 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <bitsdojo_window_windows/bitsdojo_window_plugin.h> #include <bitsdojo_window_windows/bitsdojo_window_plugin.h>
#include <dynamic_color/dynamic_color_plugin_c_api.h>
#include <file_selector_windows/file_selector_windows.h> #include <file_selector_windows/file_selector_windows.h>
#include <flutter_tts/flutter_tts_plugin.h> #include <flutter_tts/flutter_tts_plugin.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h>
@ -15,6 +16,8 @@
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
BitsdojoWindowPluginRegisterWithRegistrar( BitsdojoWindowPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("BitsdojoWindowPlugin")); registry->GetRegistrarForPlugin("BitsdojoWindowPlugin"));
DynamicColorPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
FileSelectorWindowsRegisterWithRegistrar( FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows")); registry->GetRegistrarForPlugin("FileSelectorWindows"));
FlutterTtsPluginRegisterWithRegistrar( FlutterTtsPluginRegisterWithRegistrar(

View File

@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
bitsdojo_window_windows bitsdojo_window_windows
dynamic_color
file_selector_windows file_selector_windows
flutter_tts flutter_tts
permission_handler_windows permission_handler_windows