Added material you
This commit is contained in:
parent
baf654be40
commit
6697346628
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
250
lib/main.dart
250
lib/main.dart
|
@ -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,
|
||||||
|
|
|
@ -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))
|
||||||
])))));
|
])))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
]))),
|
]))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
]))),
|
]))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
|
|
|
@ -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)!
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue