parent
6c84f51267
commit
0629a8c0b5
|
|
@ -1,7 +1,6 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:ollama_app/worker/theme.dart';
|
|
||||||
|
|
||||||
import 'main.dart';
|
import 'main.dart';
|
||||||
import 'worker/haptic.dart';
|
import 'worker/haptic.dart';
|
||||||
|
|
@ -29,9 +28,8 @@ Widget toggle(BuildContext context, String text, bool value,
|
||||||
void Function()? onDisabledTap,
|
void Function()? onDisabledTap,
|
||||||
void Function()? onLongTap,
|
void Function()? onLongTap,
|
||||||
void Function()? onDoubleTap,
|
void Function()? onDoubleTap,
|
||||||
Widget? icon}) {
|
Widget? icon,
|
||||||
var space = ""; // Invisible character: U+2063
|
bool? iconAfterwards}) {
|
||||||
var spacePlus = " $space";
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
enableFeedback: false,
|
enableFeedback: false,
|
||||||
splashFactory: NoSplash.splashFactory,
|
splashFactory: NoSplash.splashFactory,
|
||||||
|
|
@ -51,65 +49,66 @@ Widget toggle(BuildContext context, String text, bool value,
|
||||||
onDoubleTap: onDoubleTap,
|
onDoubleTap: onDoubleTap,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(top: 4, bottom: 4),
|
padding: const EdgeInsets.only(top: 4, bottom: 4),
|
||||||
child: Stack(children: [
|
child: Row(children: [
|
||||||
|
Expanded(
|
||||||
|
child: LayoutBuilder(builder: (context, constraints) {
|
||||||
|
return Row(mainAxisSize: MainAxisSize.max, children: [
|
||||||
|
(icon != null && !(iconAfterwards ?? false))
|
||||||
|
? Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8),
|
||||||
|
child: icon,
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
maxWidth: constraints.maxWidth - (icon != null ? 32 : 0)),
|
||||||
|
child: Text(text,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
|
style: TextStyle(color: disabled ? Colors.grey : null)),
|
||||||
|
),
|
||||||
|
(icon != null && (iconAfterwards ?? false))
|
||||||
|
? Transform.translate(
|
||||||
|
offset: const Offset(0, 1),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 8),
|
||||||
|
child: icon,
|
||||||
|
))
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 16),
|
||||||
|
child: Divider(color: Theme.of(context).dividerColor)),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}),
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: const EdgeInsets.only(left: 16),
|
||||||
left: (icon == null) ? 16 : 32, right: 16, top: 12),
|
child: Switch(
|
||||||
child: Divider(color: Theme.of(context).dividerColor)),
|
value: value,
|
||||||
Row(mainAxisSize: MainAxisSize.max, children: [
|
onChanged: disabled
|
||||||
(icon != null)
|
? (onDisabledTap != null)
|
||||||
? Padding(
|
? (p0) {
|
||||||
padding: const EdgeInsets.only(right: 8),
|
selectionHaptic();
|
||||||
child: icon,
|
onDisabledTap();
|
||||||
)
|
}
|
||||||
: const SizedBox.shrink(),
|
: null
|
||||||
Expanded(
|
: onChanged,
|
||||||
child: Text(text + spacePlus,
|
activeTrackColor: disabled
|
||||||
overflow: TextOverflow.ellipsis,
|
? Theme.of(context).colorScheme.primary.withAlpha(50)
|
||||||
maxLines: 1,
|
: null,
|
||||||
style: TextStyle(
|
trackOutlineColor: disabled
|
||||||
color: disabled ? Colors.grey : null,
|
? WidgetStatePropertyAll(
|
||||||
backgroundColor:
|
Theme.of(context).colorScheme.primary.withAlpha(150))
|
||||||
(Theme.of(context).brightness == Brightness.light)
|
: null,
|
||||||
? themeLight().colorScheme.surface
|
thumbColor: disabled
|
||||||
: themeDark().colorScheme.surface))),
|
? WidgetStatePropertyAll(
|
||||||
Container(
|
Theme.of(context).colorScheme.primary.withAlpha(150))
|
||||||
padding: const EdgeInsets.only(left: 16),
|
: !(prefs?.getBool("useDeviceTheme") ?? false) && value
|
||||||
color: (Theme.of(context).brightness == Brightness.light)
|
? WidgetStatePropertyAll(
|
||||||
? themeLight().colorScheme.surface
|
Theme.of(context).colorScheme.secondary)
|
||||||
: themeDark().colorScheme.surface,
|
: null))
|
||||||
child: SizedBox(
|
|
||||||
height: 40,
|
|
||||||
child: Switch(
|
|
||||||
value: value,
|
|
||||||
onChanged: disabled
|
|
||||||
? (onDisabledTap != null)
|
|
||||||
? (p0) {
|
|
||||||
selectionHaptic();
|
|
||||||
onDisabledTap();
|
|
||||||
}
|
|
||||||
: null
|
|
||||||
: onChanged,
|
|
||||||
activeTrackColor: disabled
|
|
||||||
? Theme.of(context).colorScheme.primary.withAlpha(50)
|
|
||||||
: null,
|
|
||||||
trackOutlineColor: disabled
|
|
||||||
? WidgetStatePropertyAll(Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.primary
|
|
||||||
.withAlpha(150))
|
|
||||||
: null,
|
|
||||||
thumbColor: disabled
|
|
||||||
? WidgetStatePropertyAll(Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.primary
|
|
||||||
.withAlpha(150))
|
|
||||||
: !(prefs?.getBool("useDeviceTheme") ?? false) &&
|
|
||||||
value
|
|
||||||
? WidgetStatePropertyAll(
|
|
||||||
Theme.of(context).colorScheme.secondary)
|
|
||||||
: null)))
|
|
||||||
]),
|
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -160,6 +159,7 @@ Widget button(String text, IconData? icon, void Function()? onPressed,
|
||||||
bool alwaysMobileDescription = false,
|
bool alwaysMobileDescription = false,
|
||||||
String? badge,
|
String? badge,
|
||||||
String? iconBadge,
|
String? iconBadge,
|
||||||
|
bool? iconAfterwards,
|
||||||
void Function()? onDisabledTap,
|
void Function()? onDisabledTap,
|
||||||
void Function()? onLongTap,
|
void Function()? onLongTap,
|
||||||
void Function()? onDoubleTap}) {
|
void Function()? onDoubleTap}) {
|
||||||
|
|
@ -177,6 +177,10 @@ Widget button(String text, IconData? icon, void Function()? onPressed,
|
||||||
: EdgeInsets.zero,
|
: EdgeInsets.zero,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
enableFeedback: false,
|
enableFeedback: false,
|
||||||
|
// disable hint that clickable, other tap functions still functional
|
||||||
|
splashFactory: (onPressed == null) ? NoSplash.splashFactory : null,
|
||||||
|
highlightColor: (onPressed == null) ? Colors.transparent : null,
|
||||||
|
hoverColor: (onPressed == null) ? Colors.transparent : null,
|
||||||
onTap: disabled
|
onTap: disabled
|
||||||
? () {
|
? () {
|
||||||
selectionHaptic();
|
selectionHaptic();
|
||||||
|
|
@ -208,67 +212,99 @@ Widget button(String text, IconData? icon, void Function()? onPressed,
|
||||||
var iconContent = (icon != null || replaceIconIfNull)
|
var iconContent = (icon != null || replaceIconIfNull)
|
||||||
? replaceIconIfNull
|
? replaceIconIfNull
|
||||||
? ImageIcon(MemoryImage(kTransparentImage))
|
? ImageIcon(MemoryImage(kTransparentImage))
|
||||||
: Icon(icon, color: disabled ? Colors.grey : color)
|
: Icon(icon,
|
||||||
|
color: disabled || (iconAfterwards ?? false)
|
||||||
|
? Colors.grey
|
||||||
|
: color)
|
||||||
: const SizedBox.shrink();
|
: const SizedBox.shrink();
|
||||||
return Row(children: [
|
return Row(
|
||||||
(iconBadge == null)
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
? iconContent
|
children: [
|
||||||
: Badge(
|
!(iconAfterwards ?? false)
|
||||||
label: (iconBadge != "") ? Text(iconBadge) : null,
|
? (iconBadge == null)
|
||||||
child: iconContent),
|
? iconContent
|
||||||
(icon != null || replaceIconIfNull)
|
: Badge(
|
||||||
? const SizedBox(width: 16, height: 42)
|
label: (iconBadge != "") ? Text(iconBadge) : null,
|
||||||
: const SizedBox.shrink(),
|
child: iconContent)
|
||||||
Expanded(child: Builder(builder: (context) {
|
: const SizedBox.shrink(),
|
||||||
Widget textWidget = Text(text,
|
(icon != null || replaceIconIfNull)
|
||||||
style: TextStyle(color: disabled ? Colors.grey : color));
|
? SizedBox(
|
||||||
if (badge != null) {
|
width: !(iconAfterwards ?? false) ? 16 : null,
|
||||||
textWidget = Badge(
|
height: 42)
|
||||||
label: Text(badge),
|
: const SizedBox.shrink(),
|
||||||
offset: const Offset(20, -4),
|
Expanded(child: Builder(builder: (context) {
|
||||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
Widget textWidget = Text(text,
|
||||||
textColor: Theme.of(context).colorScheme.onPrimary,
|
style:
|
||||||
child: textWidget);
|
TextStyle(color: disabled ? Colors.grey : color));
|
||||||
}
|
if (badge != null) {
|
||||||
if (description == null || description!.startsWith("\n")) {
|
textWidget = Badge(
|
||||||
description = description?.removePrefix("\n");
|
label: Text(badge),
|
||||||
return Column(
|
offset: const Offset(20, -4),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
backgroundColor:
|
||||||
mainAxisSize: MainAxisSize.min,
|
Theme.of(context).colorScheme.primary,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
textColor: Theme.of(context).colorScheme.onPrimary,
|
||||||
children: [
|
child: textWidget);
|
||||||
textWidget,
|
}
|
||||||
(description != null &&
|
if (iconAfterwards ?? false) {
|
||||||
!alwaysMobileDescription &&
|
return Row(
|
||||||
(desktopLayoutNotRequired(context) ||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
!onlyDesktopDescription))
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
? Text(description!,
|
children: [
|
||||||
style: const TextStyle(
|
textWidget,
|
||||||
color: Colors.grey,
|
// same info distance as [toggle]
|
||||||
overflow: TextOverflow.ellipsis))
|
const SizedBox(width: 8),
|
||||||
: const SizedBox.shrink()
|
Transform.translate(
|
||||||
]);
|
offset: const Offset(0, 1),
|
||||||
} else {
|
child: (iconBadge == null)
|
||||||
return Row(
|
? iconContent
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
: Badge(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
label: (iconBadge != "")
|
||||||
children: [
|
? Text(iconBadge)
|
||||||
textWidget,
|
: null,
|
||||||
(description != null &&
|
child: iconContent)),
|
||||||
!alwaysMobileDescription &&
|
]);
|
||||||
(desktopLayoutNotRequired(context) ||
|
} else {
|
||||||
!onlyDesktopDescription))
|
if (description == null ||
|
||||||
? Expanded(
|
description!.startsWith("\n")) {
|
||||||
child: Text(description!,
|
description = description?.removePrefix("\n");
|
||||||
style: const TextStyle(
|
return Column(
|
||||||
color: Colors.grey,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
overflow: TextOverflow.ellipsis)),
|
mainAxisSize: MainAxisSize.min,
|
||||||
)
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
: const SizedBox.shrink()
|
children: [
|
||||||
]);
|
textWidget,
|
||||||
}
|
(description != null &&
|
||||||
}))
|
!alwaysMobileDescription &&
|
||||||
]);
|
(desktopLayoutNotRequired(context) ||
|
||||||
|
!onlyDesktopDescription))
|
||||||
|
? Text(description!,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.grey,
|
||||||
|
overflow: TextOverflow.ellipsis))
|
||||||
|
: const SizedBox.shrink()
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
textWidget,
|
||||||
|
(description != null &&
|
||||||
|
!alwaysMobileDescription &&
|
||||||
|
(desktopLayoutNotRequired(context) ||
|
||||||
|
!onlyDesktopDescription))
|
||||||
|
? Expanded(
|
||||||
|
child: Text(description!,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.grey,
|
||||||
|
overflow: TextOverflow.ellipsis)),
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
]);
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,9 @@ class _ScreenSettingsBehaviorState extends State<ScreenSettingsBehavior> {
|
||||||
prefs!.setBool("useSystem", value);
|
prefs!.setBool("useSystem", value);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.info_outline_rounded),
|
icon: const Icon(Icons.info_rounded,
|
||||||
|
color: Colors.grey),
|
||||||
|
iconAfterwards: true,
|
||||||
onLongTap: () {
|
onLongTap: () {
|
||||||
selectionHaptic();
|
selectionHaptic();
|
||||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
|
|
|
||||||
|
|
@ -290,8 +290,9 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
||||||
button(
|
button(
|
||||||
AppLocalizations.of(context)!
|
AppLocalizations.of(context)!
|
||||||
.settingsTimeoutMultiplier,
|
.settingsTimeoutMultiplier,
|
||||||
Icons.info_outline_rounded,
|
Icons.info_rounded,
|
||||||
null,
|
null,
|
||||||
|
iconAfterwards: true,
|
||||||
context: context,
|
context: context,
|
||||||
alwaysMobileDescription: true,
|
alwaysMobileDescription: true,
|
||||||
description:
|
description:
|
||||||
|
|
@ -380,7 +381,9 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
||||||
setMainAppState!(() {});
|
setMainAppState!(() {});
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}),
|
}),
|
||||||
const SizedBox(height: 8),
|
AnimatedContainer(
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
height: desktopLayoutNotRequired(context) ? 16 : 8),
|
||||||
(colorSchemeLight != null && colorSchemeDark != null)
|
(colorSchemeLight != null && colorSchemeDark != null)
|
||||||
? SegmentedButton(
|
? SegmentedButton(
|
||||||
segments: [
|
segments: [
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue