Added timeout multiplicator
This commit is contained in:
parent
a9fed3e36d
commit
20dbce2f34
|
@ -398,6 +398,21 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"settingsTimeoutMultiplier": "Timeout multiplier",
|
||||
"@settingsTimeoutMultiplier": {
|
||||
"description": "Text displayed as title for the timeout multiplier section",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsTimeoutMultiplierDescription": "Select the multiplier that is applied to every timeout value in the app. Can be useful with a slow internet connection or a slow host.",
|
||||
"@settingsTimeoutMultiplierDescription": {
|
||||
"description": "Description of the timeout multiplier section",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsTimeoutMultiplierExample": "E.g. message timeout:",
|
||||
"@settingsTimeoutMultiplierExample": {
|
||||
"description": "Example for the timeout multiplier",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsEnableHapticFeedback": "Enable haptic feedback",
|
||||
"@settingsEnableHapticFeedback": {
|
||||
"description": "Text displayed as description for enable haptic feedback toggle",
|
||||
|
@ -423,26 +438,6 @@
|
|||
"description": "Text displayed as description for dark brightness option",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsBrightnessRestartTitle": "Restart Required",
|
||||
"@settingsBrightnessRestartTitle": {
|
||||
"description": "Title of the restart required dialog",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsBrightnessRestartDescription": "Changing the theme requires a restart.\nDo you want to restart now or cancel the action?",
|
||||
"@settingsBrightnessRestartDescription": {
|
||||
"description": "Description of the restart required dialog",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsBrightnessRestartRestart": "Restart",
|
||||
"@settingsBrightnessRestartRestart": {
|
||||
"description": "Text displayed for restart button, should be capitalized",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsBrightnessRestartCancel": "Cancel",
|
||||
"@settingsBrightnessRestartCancel": {
|
||||
"description": "Text displayed for cancel button, should be capitalized",
|
||||
"context": "Visible in the settings view"
|
||||
},
|
||||
"settingsThemeDevice": "Device",
|
||||
"@settingsThemeDevice": {
|
||||
"description": "Text displayed as description for device theme option",
|
||||
|
@ -453,26 +448,6 @@
|
|||
"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"
|
||||
},
|
||||
"settingsTemporaryFixes": "Temporary interface fixes",
|
||||
"@settingsTemporaryFixes": {
|
||||
"description": "Text displayed as description for temporary fixes section",
|
||||
|
|
|
@ -122,7 +122,7 @@ Widget title(String text, {double top = 16, double bottom = 16}) {
|
|||
Padding(
|
||||
padding: const EdgeInsets.only(left: 24, right: 24),
|
||||
child: Text(text)),
|
||||
const Expanded(child: Divider(height: 1))
|
||||
const Expanded(child: Divider())
|
||||
]));
|
||||
}
|
||||
|
||||
|
@ -155,16 +155,21 @@ Widget button(String text, IconData? icon, void Function()? onPressed,
|
|||
bool disabled = false,
|
||||
bool replaceIconIfNull = false,
|
||||
String? description,
|
||||
bool onlyDesktopDescription = true,
|
||||
bool alwaysMobileDescription = false,
|
||||
String? badge,
|
||||
void Function()? onDisabledTap,
|
||||
void Function()? onLongTap,
|
||||
void Function()? onDoubleTap}) {
|
||||
if (description != null &&
|
||||
(context != null && desktopLayoutNotRequired(context)) &&
|
||||
((context != null && desktopLayoutNotRequired(context)) ||
|
||||
!onlyDesktopDescription) &&
|
||||
!alwaysMobileDescription &&
|
||||
!description.startsWith("\n")) {
|
||||
description = " • $description";
|
||||
}
|
||||
return Padding(
|
||||
return AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
padding: (context != null && desktopLayoutNotRequired(context))
|
||||
? const EdgeInsets.only(top: 8, bottom: 8)
|
||||
: EdgeInsets.zero,
|
||||
|
@ -183,9 +188,11 @@ Widget button(String text, IconData? icon, void Function()? onPressed,
|
|||
}
|
||||
: onPressed,
|
||||
onLongPress: (description != null && context != null)
|
||||
? desktopLayoutNotRequired(context)
|
||||
? (desktopLayoutNotRequired(context) && !alwaysMobileDescription) ||
|
||||
!onlyDesktopDescription
|
||||
? null
|
||||
: () {
|
||||
selectionHaptic();
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(description!.trim()),
|
||||
showCloseIcon: true));
|
||||
|
@ -223,9 +230,14 @@ Widget button(String text, IconData? icon, void Function()? onPressed,
|
|||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
textWidget,
|
||||
(description != null && desktopLayoutNotRequired(context))
|
||||
(description != null &&
|
||||
!alwaysMobileDescription &&
|
||||
(desktopLayoutNotRequired(context) ||
|
||||
!onlyDesktopDescription))
|
||||
? Text(description!,
|
||||
style: const TextStyle(color: Colors.grey))
|
||||
style: const TextStyle(
|
||||
color: Colors.grey,
|
||||
overflow: TextOverflow.ellipsis))
|
||||
: const SizedBox.shrink()
|
||||
]);
|
||||
} else {
|
||||
|
@ -234,9 +246,16 @@ Widget button(String text, IconData? icon, void Function()? onPressed,
|
|||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
textWidget,
|
||||
(description != null && desktopLayoutNotRequired(context))
|
||||
? Text(description!,
|
||||
style: const TextStyle(color: Colors.grey))
|
||||
(description != null &&
|
||||
!alwaysMobileDescription &&
|
||||
(desktopLayoutNotRequired(context) ||
|
||||
!onlyDesktopDescription))
|
||||
? Expanded(
|
||||
child: Text(description!,
|
||||
style: const TextStyle(
|
||||
color: Colors.grey,
|
||||
overflow: TextOverflow.ellipsis)),
|
||||
)
|
||||
: const SizedBox.shrink()
|
||||
]);
|
||||
}
|
||||
|
@ -286,9 +305,11 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
.cast<String, String>(),
|
||||
)
|
||||
..followRedirects = false;
|
||||
request = await http.Response.fromStream(await requestBase
|
||||
.send()
|
||||
.timeout(const Duration(seconds: 5), onTimeout: () {
|
||||
request = await http.Response.fromStream(await requestBase.send().timeout(
|
||||
Duration(
|
||||
milliseconds:
|
||||
(5000.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0))
|
||||
.round()), onTimeout: () {
|
||||
return http.StreamedResponse(const Stream.empty(), 408);
|
||||
}));
|
||||
client.close();
|
||||
|
|
|
@ -118,7 +118,9 @@ class _ScreenVoiceState extends State<ScreenVoice> {
|
|||
"Add punctuation and syntax to the following sentence. You must not change order of words or a word in itself! You must not add any word or phrase or remove one! Do not change between formal and personal form, keep the original one!\n\n$text",
|
||||
keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")),
|
||||
)
|
||||
.timeout(const Duration(seconds: 10));
|
||||
.timeout(Duration(
|
||||
seconds: (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0))
|
||||
.round()));
|
||||
setState(() {
|
||||
text = generated.response!;
|
||||
});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:dartx/dartx.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
|
@ -21,6 +22,25 @@ class ScreenSettingsInterface extends StatefulWidget {
|
|||
_ScreenSettingsInterfaceState();
|
||||
}
|
||||
|
||||
String secondsBeautify(double seconds) {
|
||||
String? endString;
|
||||
int? endMinutes;
|
||||
int? endSeconds;
|
||||
|
||||
if (seconds > 60) {
|
||||
endSeconds = seconds.toInt() % 60;
|
||||
endMinutes = (seconds - endSeconds) ~/ 60;
|
||||
|
||||
endString = "${endMinutes}m";
|
||||
if (endSeconds > 0) {
|
||||
endString += " ${endSeconds}s";
|
||||
}
|
||||
return "($endString)";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -258,6 +278,37 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
});
|
||||
}),
|
||||
titleDivider(context: context),
|
||||
button(
|
||||
AppLocalizations.of(context)!
|
||||
.settingsTimeoutMultiplier,
|
||||
Icons.info_outline_rounded,
|
||||
null,
|
||||
context: context,
|
||||
alwaysMobileDescription: true,
|
||||
description:
|
||||
"\n${AppLocalizations.of(context)!.settingsTimeoutMultiplierDescription}"),
|
||||
Slider(
|
||||
value: (prefs!.getDouble("timeoutMultiplier") ?? 1),
|
||||
min: 0.5,
|
||||
divisions: 19,
|
||||
max: 10,
|
||||
label: (prefs!.getDouble("timeoutMultiplier") ?? 1)
|
||||
.toString()
|
||||
.removeSuffix(".0"),
|
||||
onChanged: (value) {
|
||||
selectionHaptic();
|
||||
prefs!.setDouble("timeoutMultiplier", value);
|
||||
setState(() {});
|
||||
}),
|
||||
button(
|
||||
AppLocalizations.of(context)!
|
||||
.settingsTimeoutMultiplierExample,
|
||||
Icons.calculate_rounded,
|
||||
null,
|
||||
onlyDesktopDescription: false,
|
||||
description:
|
||||
"\n${(prefs!.getDouble("timeoutMultiplier") ?? 1)} x 30s = ${((prefs!.getDouble("timeoutMultiplier") ?? 1) * 30).round()}s ${secondsBeautify((prefs!.getDouble("timeoutMultiplier") ?? 1) * 30)}"),
|
||||
titleDivider(context: context),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!
|
||||
|
|
|
@ -99,9 +99,11 @@ Future<String> getTitleAi(List history) async {
|
|||
],
|
||||
keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")),
|
||||
)
|
||||
.timeout(const Duration(seconds: 10));
|
||||
.timeout(Duration(
|
||||
seconds:
|
||||
(10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0)).round()));
|
||||
var title = generated.message.content;
|
||||
title = title.replaceAll("\n", " ").trim();
|
||||
title = title.replaceAll("\n", " ");
|
||||
|
||||
var terms = [
|
||||
"\"",
|
||||
|
@ -127,13 +129,13 @@ Future<String> getTitleAi(List history) async {
|
|||
|
||||
title = title.replaceAll(RegExp(r'<.*?>', dotAll: true), "");
|
||||
if (title.split(":").length == 2) {
|
||||
title = title.split(":")[1].trim();
|
||||
title = title.split(":")[1];
|
||||
}
|
||||
|
||||
while (title.contains(" ")) {
|
||||
title = title.replaceAll(" ", " ");
|
||||
}
|
||||
return title;
|
||||
return title.trim();
|
||||
}
|
||||
|
||||
Future<void> setTitleAi(List history) async {
|
||||
|
@ -231,7 +233,9 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
messages: history,
|
||||
keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")),
|
||||
)
|
||||
.timeout(const Duration(seconds: 30));
|
||||
.timeout(Duration(
|
||||
seconds: (30.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0))
|
||||
.round()));
|
||||
|
||||
await for (final res in stream) {
|
||||
text += (res.message.content);
|
||||
|
@ -263,7 +267,9 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
messages: history,
|
||||
keepAlive: int.parse(prefs!.getString("keepAlive") ?? "300")),
|
||||
)
|
||||
.timeout(const Duration(seconds: 30));
|
||||
.timeout(Duration(
|
||||
seconds: (30.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0))
|
||||
.round()));
|
||||
if (chatAllowed) return "";
|
||||
messages.insert(
|
||||
0,
|
||||
|
|
|
@ -35,7 +35,9 @@ void setModel(BuildContext context, Function setState) {
|
|||
.cast<String, String>(),
|
||||
baseUrl: "$host/api")
|
||||
.listModels()
|
||||
.timeout(const Duration(seconds: 10));
|
||||
.timeout(Duration(
|
||||
seconds: (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0))
|
||||
.round()));
|
||||
for (var i = 0; i < list.models!.length; i++) {
|
||||
models.add(list.models![i].model!.split(":")[0]);
|
||||
modelsReal.add(list.models![i].model!);
|
||||
|
@ -125,7 +127,10 @@ void setModel(BuildContext context, Function setState) {
|
|||
int.parse(prefs!.getString("keepAlive") ?? "300")
|
||||
}),
|
||||
)
|
||||
.timeout(const Duration(seconds: 15));
|
||||
.timeout(Duration(
|
||||
seconds: (10.0 *
|
||||
(prefs!.getDouble("timeoutMultiplier") ?? 1.0))
|
||||
.round()));
|
||||
} catch (_) {
|
||||
// ignore: use_build_context_synchronously
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
|
@ -420,7 +425,7 @@ Future<bool> deleteChatDialog(BuildContext context, Function setState,
|
|||
uuid ??= chatUuid;
|
||||
|
||||
bool returnValue = false;
|
||||
void delete() {
|
||||
void delete(BuildContext context) {
|
||||
returnValue = true;
|
||||
if (takeAction) {
|
||||
for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) {
|
||||
|
@ -468,7 +473,7 @@ Future<bool> deleteChatDialog(BuildContext context, Function setState,
|
|||
onPressed: () {
|
||||
selectionHaptic();
|
||||
Navigator.of(context).pop();
|
||||
delete();
|
||||
delete(context);
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.deleteDialogDelete))
|
||||
|
@ -476,7 +481,7 @@ Future<bool> deleteChatDialog(BuildContext context, Function setState,
|
|||
});
|
||||
});
|
||||
} else {
|
||||
delete();
|
||||
delete(context);
|
||||
}
|
||||
setState(() {});
|
||||
return returnValue;
|
||||
|
|
|
@ -6,6 +6,8 @@ import 'package:ollama_app/worker/desktop.dart';
|
|||
import 'haptic.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import '../main.dart';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:install_referrer/install_referrer.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
|
@ -87,7 +89,10 @@ void checkUpdate(Function setState) async {
|
|||
var request = await http
|
||||
.get(Uri.parse(
|
||||
"https://api.github.com/repos/${repo[3]}/${repo[4]}/releases"))
|
||||
.timeout(const Duration(seconds: 5));
|
||||
.timeout(Duration(
|
||||
milliseconds:
|
||||
(5000.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0))
|
||||
.round()));
|
||||
if (request.statusCode == 403) {
|
||||
setState(() {
|
||||
updateStatus = "rateLimit";
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
"settingsUseSystem",
|
||||
"settingsUseSystemDescription",
|
||||
"settingsPreloadModels",
|
||||
"settingsTimeoutMultiplier",
|
||||
"settingsTimeoutMultiplierDescription",
|
||||
"settingsTimeoutMultiplierExample",
|
||||
"settingsTemporaryFixes",
|
||||
"settingsTemporaryFixesDescription",
|
||||
"settingsTemporaryFixesInstructions",
|
||||
|
@ -32,6 +35,9 @@
|
|||
"settingsUseSystem",
|
||||
"settingsUseSystemDescription",
|
||||
"settingsPreloadModels",
|
||||
"settingsTimeoutMultiplier",
|
||||
"settingsTimeoutMultiplierDescription",
|
||||
"settingsTimeoutMultiplierExample",
|
||||
"settingsTemporaryFixes",
|
||||
"settingsTemporaryFixesDescription",
|
||||
"settingsTemporaryFixesInstructions",
|
||||
|
@ -54,6 +60,9 @@
|
|||
"settingsUseSystem",
|
||||
"settingsUseSystemDescription",
|
||||
"settingsPreloadModels",
|
||||
"settingsTimeoutMultiplier",
|
||||
"settingsTimeoutMultiplierDescription",
|
||||
"settingsTimeoutMultiplierExample",
|
||||
"settingsTemporaryFixes",
|
||||
"settingsTemporaryFixesDescription",
|
||||
"settingsTemporaryFixesInstructions",
|
||||
|
@ -76,6 +85,9 @@
|
|||
"settingsUseSystem",
|
||||
"settingsUseSystemDescription",
|
||||
"settingsPreloadModels",
|
||||
"settingsTimeoutMultiplier",
|
||||
"settingsTimeoutMultiplierDescription",
|
||||
"settingsTimeoutMultiplierExample",
|
||||
"settingsTemporaryFixes",
|
||||
"settingsTemporaryFixesDescription",
|
||||
"settingsTemporaryFixesInstructions",
|
||||
|
|
Loading…
Reference in New Issue