Formatting and Restructure
This commit is contained in:
parent
519fc27f26
commit
58437ad377
|
@ -1 +1,47 @@
|
|||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
# Imports and Declarations
|
||||
- combinators_ordering
|
||||
- directives_ordering
|
||||
- omit_local_variable_types
|
||||
- prefer_relative_imports
|
||||
- sort_unnamed_constructors_first
|
||||
- use_named_constants
|
||||
- avoid_setters_without_getters
|
||||
|
||||
# Formatting
|
||||
- avoid_escaping_inner_quotes
|
||||
- avoid_multiple_declarations_per_line
|
||||
- eol_at_end_of_file
|
||||
- leading_newlines_in_multiline_strings
|
||||
- unnecessary_breaks
|
||||
- unnecessary_final
|
||||
- unnecessary_lambdas
|
||||
- unnecessary_parenthesis
|
||||
|
||||
# Async, Errors, Null Safety
|
||||
- avoid_catching_errors
|
||||
- avoid_null_checks_in_equality_operators
|
||||
- avoid_void_async
|
||||
- cancel_subscriptions
|
||||
- cast_nullable_to_non_nullable
|
||||
- unnecessary_await_in_return
|
||||
- use_if_null_to_convert_nulls_to_bools
|
||||
- use_to_and_as_if_applicable
|
||||
|
||||
# Usage Patterns
|
||||
- cascade_invocations
|
||||
- prefer_foreach
|
||||
- prefer_null_aware_method_calls
|
||||
- sized_box_shrink_expand
|
||||
- use_colored_box
|
||||
- use_decorated_box
|
||||
- use_is_even_rather_than_modulo
|
||||
|
||||
# Documentation
|
||||
- deprecated_consistency
|
||||
- document_ignores
|
||||
- prefer_asserts_with_message
|
||||
- provide_deprecation_message
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
arb-dir: lib/l10n
|
||||
template-arb-file: app_en.arb
|
||||
preferred-supported-locales: en
|
||||
output-localization-file: app_localizations.dart
|
||||
output-dir: lib/l10n/gen
|
||||
preferred-supported-locales: [ en ]
|
||||
untranslated-messages-file: untranslated_messages.json
|
||||
synthetic-package: false
|
||||
output-dir: lib/l10n/gen
|
||||
nullable-getter: false
|
||||
format: true
|
||||
|
|
|
@ -66,15 +66,17 @@ import 'app_localizations_zh.dart';
|
|||
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
|
||||
/// property.
|
||||
abstract class AppLocalizations {
|
||||
AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
||||
AppLocalizations(String locale)
|
||||
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
||||
|
||||
final String localeName;
|
||||
|
||||
static AppLocalizations? of(BuildContext context) {
|
||||
return Localizations.of<AppLocalizations>(context, AppLocalizations);
|
||||
static AppLocalizations of(BuildContext context) {
|
||||
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
|
||||
}
|
||||
|
||||
static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();
|
||||
static const LocalizationsDelegate<AppLocalizations> delegate =
|
||||
_AppLocalizationsDelegate();
|
||||
|
||||
/// A list of this localizations delegate along with the default localizations
|
||||
/// delegates.
|
||||
|
@ -86,7 +88,8 @@ abstract class AppLocalizations {
|
|||
/// Additional delegates can be added by appending to this list in
|
||||
/// MaterialApp. This list does not have to be used at all if a custom list
|
||||
/// of delegates is preferred or required.
|
||||
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = <LocalizationsDelegate<dynamic>>[
|
||||
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
|
||||
<LocalizationsDelegate<dynamic>>[
|
||||
delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
|
@ -986,7 +989,8 @@ abstract class AppLocalizations {
|
|||
String settingsVersion(String version);
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
|
||||
class _AppLocalizationsDelegate
|
||||
extends LocalizationsDelegate<AppLocalizations> {
|
||||
const _AppLocalizationsDelegate();
|
||||
|
||||
@override
|
||||
|
@ -995,29 +999,39 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations>
|
|||
}
|
||||
|
||||
@override
|
||||
bool isSupported(Locale locale) => <String>['de', 'en', 'fa', 'it', 'tr', 'zh'].contains(locale.languageCode);
|
||||
bool isSupported(Locale locale) => <String>[
|
||||
'de',
|
||||
'en',
|
||||
'fa',
|
||||
'it',
|
||||
'tr',
|
||||
'zh'
|
||||
].contains(locale.languageCode);
|
||||
|
||||
@override
|
||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||
}
|
||||
|
||||
AppLocalizations lookupAppLocalizations(Locale locale) {
|
||||
|
||||
|
||||
// Lookup logic when only language code is specified.
|
||||
switch (locale.languageCode) {
|
||||
case 'de': return AppLocalizationsDe();
|
||||
case 'en': return AppLocalizationsEn();
|
||||
case 'fa': return AppLocalizationsFa();
|
||||
case 'it': return AppLocalizationsIt();
|
||||
case 'tr': return AppLocalizationsTr();
|
||||
case 'zh': return AppLocalizationsZh();
|
||||
case 'de':
|
||||
return AppLocalizationsDe();
|
||||
case 'en':
|
||||
return AppLocalizationsEn();
|
||||
case 'fa':
|
||||
return AppLocalizationsFa();
|
||||
case 'it':
|
||||
return AppLocalizationsIt();
|
||||
case 'tr':
|
||||
return AppLocalizationsTr();
|
||||
case 'zh':
|
||||
return AppLocalizationsZh();
|
||||
}
|
||||
|
||||
throw FlutterError(
|
||||
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
|
||||
'an issue with the localizations generation tool. Please file an issue '
|
||||
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
||||
'that was used.'
|
||||
);
|
||||
'that was used.');
|
||||
}
|
||||
|
|
|
@ -87,7 +87,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get noModelSelected => 'Kein Modell ausgewählt';
|
||||
|
||||
@override
|
||||
String get noHostSelected => 'Kein Host ausgewählt, öffne zum Auswählen die Einstellungen';
|
||||
String get noHostSelected =>
|
||||
'Kein Host ausgewählt, öffne zum Auswählen die Einstellungen';
|
||||
|
||||
@override
|
||||
String get noSelectedModel => '<selektor>';
|
||||
|
@ -102,7 +103,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get modelDialogAddPromptTitle => 'Neues Modell hinzufügen';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptDescription => 'Das kann entweder ein normaler Name (z.B. \'llama3\') oder Name und Tag (z.B. \'llama3:70b\') sein.';
|
||||
String get modelDialogAddPromptDescription =>
|
||||
'Das kann entweder ein normaler Name (z.B. \'llama3\') oder Name und Tag (z.B. \'llama3:70b\') sein.';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptAlreadyExists => 'Modell existiert bereits';
|
||||
|
@ -114,7 +116,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get modelDialogAddAllowanceTitle => 'Proxy erlauben';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceDescription => 'Ollama App muss überprüfen, ob das eingegebene Modell gültig ist. Dafür senden wir normalerweise eine Webanfrage an die Ollama-Modellliste und überprüfen den Statuscode, aber da gerade der Webclient verwendet wird, können wir das nicht direkt tun. Stattdessen sendet die App die Anfrage an eine andere API, gehostet von JHubi1, um dies für uns zu überprüfen.\nDies ist eine einmalige Anfrage und wird nur gesendet, wenn du ein neues Modell hinzufügst.\nIhre IP-Adresse wird mit der Anfrage gesendet und kann bis zu zehn Minuten gespeichert werden, um Spamming mit potenziell schädlichen Absichten zu verhindern.\nWenn du zustimmst, wird deine Auswahl für die Zukunft gespeichert; wenn nicht, wird nichts gesendet und das Modell wird nicht hinzugefügt.';
|
||||
String get modelDialogAddAllowanceDescription =>
|
||||
'Ollama App muss überprüfen, ob das eingegebene Modell gültig ist. Dafür senden wir normalerweise eine Webanfrage an die Ollama-Modellliste und überprüfen den Statuscode, aber da gerade der Webclient verwendet wird, können wir das nicht direkt tun. Stattdessen sendet die App die Anfrage an eine andere API, gehostet von JHubi1, um dies für uns zu überprüfen.\nDies ist eine einmalige Anfrage und wird nur gesendet, wenn du ein neues Modell hinzufügst.\nIhre IP-Adresse wird mit der Anfrage gesendet und kann bis zu zehn Minuten gespeichert werden, um Spamming mit potenziell schädlichen Absichten zu verhindern.\nWenn du zustimmst, wird deine Auswahl für die Zukunft gespeichert; wenn nicht, wird nichts gesendet und das Modell wird nicht hinzugefügt.';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceAllow => 'Erlauben';
|
||||
|
@ -156,7 +159,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get deleteDialogTitle => 'Chat löschen';
|
||||
|
||||
@override
|
||||
String get deleteDialogDescription => 'Bist du sicher, dass du fortfahren möchtest? Dies wird alle Erinnerungen dieses Chats löschen und kann nicht rückgängig gemacht werden.\nUm diesen Dialog zu deaktivieren, besuche die Einstellungen.';
|
||||
String get deleteDialogDescription =>
|
||||
'Bist du sicher, dass du fortfahren möchtest? Dies wird alle Erinnerungen dieses Chats löschen und kann nicht rückgängig gemacht werden.\nUm diesen Dialog zu deaktivieren, besuche die Einstellungen.';
|
||||
|
||||
@override
|
||||
String get deleteDialogDelete => 'Löschen';
|
||||
|
@ -174,61 +178,73 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get settingsTitleBehavior => 'Verhalten';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionBehavior => 'Ändere das Verhalten der KI nach deinen Wünschen.';
|
||||
String get settingsDescriptionBehavior =>
|
||||
'Ändere das Verhalten der KI nach deinen Wünschen.';
|
||||
|
||||
@override
|
||||
String get settingsTitleInterface => 'Oberfläche';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionInterface => 'Bearbeite das Aussehen und Verhalten von Ollama App.';
|
||||
String get settingsDescriptionInterface =>
|
||||
'Bearbeite das Aussehen und Verhalten von Ollama App.';
|
||||
|
||||
@override
|
||||
String get settingsTitleVoice => 'Voice';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionVoice => 'Voice Mode aktivieren und Spracheinstellungen anpassen.';
|
||||
String get settingsDescriptionVoice =>
|
||||
'Voice Mode aktivieren und Spracheinstellungen anpassen.';
|
||||
|
||||
@override
|
||||
String get settingsTitleExport => 'Exportieren';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionExport => 'Exportiere und importiere deinen Chat-Verlauf.';
|
||||
String get settingsDescriptionExport =>
|
||||
'Exportiere und importiere deinen Chat-Verlauf.';
|
||||
|
||||
@override
|
||||
String get settingsTitleAbout => 'Über';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionAbout => 'Suche nach Updates und erfahre mehr über Ollama App.';
|
||||
String get settingsDescriptionAbout =>
|
||||
'Suche nach Updates und erfahre mehr über Ollama App.';
|
||||
|
||||
@override
|
||||
String get settingsSavedAutomatically => 'Einstellungen werden automatisch gespeichert';
|
||||
String get settingsSavedAutomatically =>
|
||||
'Einstellungen werden automatisch gespeichert';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlpha => 'alpha';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaDescription => 'Diese Funktion befindet sich im Alpha-Status und funktioniert möglicherweise nicht wie beabsichtigt oder erwartet.\nKritische Probleme und/oder dauerhafte kritische Schäden am Gerät und/oder den verwendeten Diensten können nicht ausgeschlossen werden.\nBenutzung auf eigene Gefahr. Keine Haftung seitens des App-Autors.';
|
||||
String get settingsExperimentalAlphaDescription =>
|
||||
'Diese Funktion befindet sich im Alpha-Status und funktioniert möglicherweise nicht wie beabsichtigt oder erwartet.\nKritische Probleme und/oder dauerhafte kritische Schäden am Gerät und/oder den verwendeten Diensten können nicht ausgeschlossen werden.\nBenutzung auf eigene Gefahr. Keine Haftung seitens des App-Autors.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaFeature => 'Alpha-Funktion, halte, um mehr zu erfahren';
|
||||
String get settingsExperimentalAlphaFeature =>
|
||||
'Alpha-Funktion, halte, um mehr zu erfahren';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBeta => 'beta';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaDescription => 'Diese Funktion befindet sich im Beta-Test und funktioniert möglicherweise nicht wie beabsichtigt oder erwartet.\nWeniger schwerwiegende Probleme können auftreten oder auch nicht. Schäden sollten nicht kritisch sein.\nVerwendung auf eigene Gefahr.';
|
||||
String get settingsExperimentalBetaDescription =>
|
||||
'Diese Funktion befindet sich im Beta-Test und funktioniert möglicherweise nicht wie beabsichtigt oder erwartet.\nWeniger schwerwiegende Probleme können auftreten oder auch nicht. Schäden sollten nicht kritisch sein.\nVerwendung auf eigene Gefahr.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaFeature => 'Beta-Funktion, halte, um mehr zu erfahren';
|
||||
String get settingsExperimentalBetaFeature =>
|
||||
'Beta-Funktion, halte, um mehr zu erfahren';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecated => 'veraltet';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedDescription => 'Diese Funktion ist veraltet und wird in einer zukünftigen Version entfernt werden.\nEs funktioniert möglicherweise nicht wie beabsichtigt oder erwartet. Benutzung auf eigenes Gefahr.';
|
||||
String get settingsExperimentalDeprecatedDescription =>
|
||||
'Diese Funktion ist veraltet und wird in einer zukünftigen Version entfernt werden.\nEs funktioniert möglicherweise nicht wie beabsichtigt oder erwartet. Benutzung auf eigenes Gefahr.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedFeature => 'Veraltete Funktion, halte, um mehr zu erfahren';
|
||||
String get settingsExperimentalDeprecatedFeature =>
|
||||
'Veraltete Funktion, halte, um mehr zu erfahren';
|
||||
|
||||
@override
|
||||
String get settingsHost => 'Host';
|
||||
|
@ -258,15 +274,18 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get settingsHostHeaderTitle => 'Host-Header festlegen';
|
||||
|
||||
@override
|
||||
String get settingsHostHeaderInvalid => 'Der eingegebene Text ist kein gültiges Header-JSON-Objekt';
|
||||
String get settingsHostHeaderInvalid =>
|
||||
'Der eingegebene Text ist kein gültiges Header-JSON-Objekt';
|
||||
|
||||
@override
|
||||
String settingsHostInvalidDetailed(String type) {
|
||||
String _temp0 = intl.Intl.selectLogic(
|
||||
type,
|
||||
{
|
||||
'url': 'Die eingegebene URL ist ungültig. Es handelt sich nicht um ein standardisiertes URL-Format.',
|
||||
'other': 'Der eingegebene Host ist ungültig. Er kann nicht erreicht werden. Bitte überprüfe den Host und versuche es erneut.',
|
||||
'url':
|
||||
'Die eingegebene URL ist ungültig. Es handelt sich nicht um ein standardisiertes URL-Format.',
|
||||
'other':
|
||||
'Der eingegebene Host ist ungültig. Er kann nicht erreicht werden. Bitte überprüfe den Host und versuche es erneut.',
|
||||
},
|
||||
);
|
||||
return '$_temp0';
|
||||
|
@ -279,13 +298,15 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get settingsUseSystem => 'Systemnachricht verwenden';
|
||||
|
||||
@override
|
||||
String get settingsUseSystemDescription => 'Deaktiviere das Setzen der obigen Systemnachricht und benutze stattdessen die des Modells. Kann nützlich für Modelle mit Model-Files sein';
|
||||
String get settingsUseSystemDescription =>
|
||||
'Deaktiviere das Setzen der obigen Systemnachricht und benutze stattdessen die des Modells. Kann nützlich für Modelle mit Model-Files sein';
|
||||
|
||||
@override
|
||||
String get settingsDisableMarkdown => 'Markdown deaktivieren';
|
||||
|
||||
@override
|
||||
String get settingsBehaviorNotUpdatedForOlderChats => 'Verhaltenseinstellungen werden nicht für ältere Chats aktualisiert';
|
||||
String get settingsBehaviorNotUpdatedForOlderChats =>
|
||||
'Verhaltenseinstellungen werden nicht für ältere Chats aktualisiert';
|
||||
|
||||
@override
|
||||
String get settingsShowModelTags => 'Model-Tags anzeigen';
|
||||
|
@ -321,7 +342,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get settingsKeepModelLoadedNever => 'Modell nicht dauerhaft laden';
|
||||
|
||||
@override
|
||||
String get settingsKeepModelLoadedFor => 'Bestimmte Modell-Ladedauer festlegen';
|
||||
String get settingsKeepModelLoadedFor =>
|
||||
'Bestimmte Modell-Ladedauer festlegen';
|
||||
|
||||
@override
|
||||
String settingsKeepModelLoadedSet(String minutes) {
|
||||
|
@ -332,7 +354,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get settingsTimeoutMultiplier => 'Timeout Multiplikator';
|
||||
|
||||
@override
|
||||
String get settingsTimeoutMultiplierDescription => 'Wähle den Multiplikator aus, der auf jeden Timeout-Wert in der App angewendet wird. Kann bei einer langsamen Internetverbindung oder einem langsamen Host nützlich sein.';
|
||||
String get settingsTimeoutMultiplierDescription =>
|
||||
'Wähle den Multiplikator aus, der auf jeden Timeout-Wert in der App angewendet wird. Kann bei einer langsamen Internetverbindung oder einem langsamen Host nützlich sein.';
|
||||
|
||||
@override
|
||||
String get settingsTimeoutMultiplierExample => 'Z.b. Nachrichten-Timeout:';
|
||||
|
@ -362,10 +385,12 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get settingsTemporaryFixes => 'Temporäre Interface Korrekturen';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesDescription => 'Temporäre Korrekturen für Interface-Probleme aktivieren.\nDrücke lange auf die einzelnen Optionen, um mehr zu erfahren.';
|
||||
String get settingsTemporaryFixesDescription =>
|
||||
'Temporäre Korrekturen für Interface-Probleme aktivieren.\nDrücke lange auf die einzelnen Optionen, um mehr zu erfahren.';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesInstructions => 'Aktiviere keine dieser Einstellungen, solltest du nicht wissen, was sie machen! Die gegebene Lösung funktioniert möglicherweise nicht wie erwartet.\nSie können nicht als final gesehen werden und sollten nicht als dieses bewertet werden. Probleme können auftreten.';
|
||||
String get settingsTemporaryFixesInstructions =>
|
||||
'Aktiviere keine dieser Einstellungen, solltest du nicht wissen, was sie machen! Die gegebene Lösung funktioniert möglicherweise nicht wie erwartet.\nSie können nicht als final gesehen werden und sollten nicht als dieses bewertet werden. Probleme können auftreten.';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesNoFixes => 'Keine Korrekturen verfügbar';
|
||||
|
@ -377,7 +402,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get settingsVoiceTtsNotSupported => 'Sprachausgabe nicht unterstützt';
|
||||
|
||||
@override
|
||||
String get settingsVoiceTtsNotSupportedDescription => 'Sprachausgabedienste sind nicht für die ausgewählte Sprache verfügbar. Wähle eine andere Sprache im Sprachwähler, um diese wieder zu aktivieren.\nAndere Dienste, wie Spracherkennung und KI-Denken werden noch immer wie gewohnt funktionieren, doch die Interaktion könnte möglicherweise nicht gleich fließend sein.';
|
||||
String get settingsVoiceTtsNotSupportedDescription =>
|
||||
'Sprachausgabedienste sind nicht für die ausgewählte Sprache verfügbar. Wähle eine andere Sprache im Sprachwähler, um diese wieder zu aktivieren.\nAndere Dienste, wie Spracherkennung und KI-Denken werden noch immer wie gewohnt funktionieren, doch die Interaktion könnte möglicherweise nicht gleich fließend sein.';
|
||||
|
||||
@override
|
||||
String get settingsVoicePermissionNot => 'Berechtigungen nicht erteilt';
|
||||
|
@ -413,7 +439,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get settingsImportChatsTitle => 'Importieren';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsDescription => 'Der folgende Schritt importiert die Chats aus der ausgewählten Datei. Dadurch werden alle aktuell verfügbaren Chats überschrieben.\nMöchtest du fortfahren?';
|
||||
String get settingsImportChatsDescription =>
|
||||
'Der folgende Schritt importiert die Chats aus der ausgewählten Datei. Dadurch werden alle aktuell verfügbaren Chats überschrieben.\nMöchtest du fortfahren?';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsImport => 'Importieren und Löschen';
|
||||
|
@ -425,10 +452,12 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get settingsImportChatsSuccess => 'Chats erfolgreich importiert';
|
||||
|
||||
@override
|
||||
String get settingsExportInfo => 'Diese Optionen ermöglichen es dir, deinen Chat-Verlauf zu exportieren und zu importieren. Dies kann nützlich sein, wenn du deinen Chat-Verlauf auf ein anderes Gerät übertragen oder deinen Chat-Verlauf sichern möchtest';
|
||||
String get settingsExportInfo =>
|
||||
'Diese Optionen ermöglichen es dir, deinen Chat-Verlauf zu exportieren und zu importieren. Dies kann nützlich sein, wenn du deinen Chat-Verlauf auf ein anderes Gerät übertragen oder deinen Chat-Verlauf sichern möchtest';
|
||||
|
||||
@override
|
||||
String get settingsExportWarning => 'Mehrere Chatverläufe werden nicht zusammengeführt! Du verlierst deinen aktuellen Chatverlauf, wenn du einen neuen importierst';
|
||||
String get settingsExportWarning =>
|
||||
'Mehrere Chatverläufe werden nicht zusammengeführt! Du verlierst deinen aktuellen Chatverlauf, wenn du einen neuen importierst';
|
||||
|
||||
@override
|
||||
String get settingsUpdateCheck => 'Nach Updates suchen';
|
||||
|
@ -454,7 +483,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get settingsUpdateDialogTitle => 'Neue Version verfügbar';
|
||||
|
||||
@override
|
||||
String get settingsUpdateDialogDescription => 'Eine neue Version von Ollama ist verfügbar. Möchtest du sie jetzt herunterladen und installieren?';
|
||||
String get settingsUpdateDialogDescription =>
|
||||
'Eine neue Version von Ollama ist verfügbar. Möchtest du sie jetzt herunterladen und installieren?';
|
||||
|
||||
@override
|
||||
String get settingsUpdateChangeLog => 'Versionshinweise';
|
||||
|
|
|
@ -102,7 +102,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get modelDialogAddPromptTitle => 'Add new model';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptDescription => 'This can have either be a normal name (e.g. \'llama3\') or name and tag (e.g. \'llama3:70b\').';
|
||||
String get modelDialogAddPromptDescription =>
|
||||
'This can have either be a normal name (e.g. \'llama3\') or name and tag (e.g. \'llama3:70b\').';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptAlreadyExists => 'Model already exists';
|
||||
|
@ -114,7 +115,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get modelDialogAddAllowanceTitle => 'Allow Proxy';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceDescription => 'Ollama App must check if the entered model is valid. For that, we normally send a web request to the Ollama model list and check the status code, but because you\'re using the web client, we can\'t do that directly. Instead, the app will send the request to a different api, hosted by JHubi1, to check for us.\nThis is a one-time request and will only be sent when you add a new model.\nYour IP address will be sent with the request and might be stored for up to ten minutes to prevent spamming with potential harmful intentions.\nIf you accept, your selection will be remembered in the future; if not, nothing will be sent and the model won\'t be added.';
|
||||
String get modelDialogAddAllowanceDescription =>
|
||||
'Ollama App must check if the entered model is valid. For that, we normally send a web request to the Ollama model list and check the status code, but because you\'re using the web client, we can\'t do that directly. Instead, the app will send the request to a different api, hosted by JHubi1, to check for us.\nThis is a one-time request and will only be sent when you add a new model.\nYour IP address will be sent with the request and might be stored for up to ten minutes to prevent spamming with potential harmful intentions.\nIf you accept, your selection will be remembered in the future; if not, nothing will be sent and the model won\'t be added.';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceAllow => 'Allow';
|
||||
|
@ -156,7 +158,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get deleteDialogTitle => 'Delete Chat';
|
||||
|
||||
@override
|
||||
String get deleteDialogDescription => 'Are you sure you want to continue? This will wipe all memory of this chat and cannot be undone.\nTo disable this dialog, visit the settings.';
|
||||
String get deleteDialogDescription =>
|
||||
'Are you sure you want to continue? This will wipe all memory of this chat and cannot be undone.\nTo disable this dialog, visit the settings.';
|
||||
|
||||
@override
|
||||
String get deleteDialogDelete => 'Delete';
|
||||
|
@ -174,31 +177,36 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get settingsTitleBehavior => 'Behavior';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionBehavior => 'Change the behavior of the AI to your liking.';
|
||||
String get settingsDescriptionBehavior =>
|
||||
'Change the behavior of the AI to your liking.';
|
||||
|
||||
@override
|
||||
String get settingsTitleInterface => 'Interface';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionInterface => 'Edit how Ollama App looks and behaves.';
|
||||
String get settingsDescriptionInterface =>
|
||||
'Edit how Ollama App looks and behaves.';
|
||||
|
||||
@override
|
||||
String get settingsTitleVoice => 'Voice';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionVoice => 'Enable voice mode and configure voice settings.';
|
||||
String get settingsDescriptionVoice =>
|
||||
'Enable voice mode and configure voice settings.';
|
||||
|
||||
@override
|
||||
String get settingsTitleExport => 'Export';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionExport => 'Export and import your chat history.';
|
||||
String get settingsDescriptionExport =>
|
||||
'Export and import your chat history.';
|
||||
|
||||
@override
|
||||
String get settingsTitleAbout => 'About';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionAbout => 'Check for updates and learn more about Ollama App.';
|
||||
String get settingsDescriptionAbout =>
|
||||
'Check for updates and learn more about Ollama App.';
|
||||
|
||||
@override
|
||||
String get settingsSavedAutomatically => 'Settings are saved automatically';
|
||||
|
@ -207,28 +215,34 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get settingsExperimentalAlpha => 'alpha';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaDescription => 'This feature is in alpha and may not work as intended or expected.\nCritical issues and/or permanent critical damage to device and/or used services cannot be ruled out.\nUse at your own risk. No liability on the part of the app author.';
|
||||
String get settingsExperimentalAlphaDescription =>
|
||||
'This feature is in alpha and may not work as intended or expected.\nCritical issues and/or permanent critical damage to device and/or used services cannot be ruled out.\nUse at your own risk. No liability on the part of the app author.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaFeature => 'Alpha feature, hold to learn more';
|
||||
String get settingsExperimentalAlphaFeature =>
|
||||
'Alpha feature, hold to learn more';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBeta => 'beta';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaDescription => 'This feature is in beta and may not work intended or expected.\nLess severe issues may or may not occur. Damage shouldn\'t be critical.\nUse at your own risk.';
|
||||
String get settingsExperimentalBetaDescription =>
|
||||
'This feature is in beta and may not work intended or expected.\nLess severe issues may or may not occur. Damage shouldn\'t be critical.\nUse at your own risk.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaFeature => 'Beta feature, hold to learn more';
|
||||
String get settingsExperimentalBetaFeature =>
|
||||
'Beta feature, hold to learn more';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecated => 'deprecated';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedDescription => 'This feature is deprecated and will be removed in a future version.\nIt may not work as intended or expected. Use at your own risk.';
|
||||
String get settingsExperimentalDeprecatedDescription =>
|
||||
'This feature is deprecated and will be removed in a future version.\nIt may not work as intended or expected. Use at your own risk.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedFeature => 'Deprecated feature, hold to learn more';
|
||||
String get settingsExperimentalDeprecatedFeature =>
|
||||
'Deprecated feature, hold to learn more';
|
||||
|
||||
@override
|
||||
String get settingsHost => 'Host';
|
||||
|
@ -258,15 +272,18 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get settingsHostHeaderTitle => 'Set host header';
|
||||
|
||||
@override
|
||||
String get settingsHostHeaderInvalid => 'The entered text isn\'t a valid header JSON object';
|
||||
String get settingsHostHeaderInvalid =>
|
||||
'The entered text isn\'t a valid header JSON object';
|
||||
|
||||
@override
|
||||
String settingsHostInvalidDetailed(String type) {
|
||||
String _temp0 = intl.Intl.selectLogic(
|
||||
type,
|
||||
{
|
||||
'url': 'The URL you entered is invalid. It isn\'t an a standardized URL format.',
|
||||
'other': 'The host you entered is invalid. It cannot be reached. Please check the host and try again.',
|
||||
'url':
|
||||
'The URL you entered is invalid. It isn\'t an a standardized URL format.',
|
||||
'other':
|
||||
'The host you entered is invalid. It cannot be reached. Please check the host and try again.',
|
||||
},
|
||||
);
|
||||
return '$_temp0';
|
||||
|
@ -279,13 +296,15 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get settingsUseSystem => 'Use system message';
|
||||
|
||||
@override
|
||||
String get settingsUseSystemDescription => 'Disables setting the system message above and use the one of the model instead. Can be useful for models with model files';
|
||||
String get settingsUseSystemDescription =>
|
||||
'Disables setting the system message above and use the one of the model instead. Can be useful for models with model files';
|
||||
|
||||
@override
|
||||
String get settingsDisableMarkdown => 'Disable markdown';
|
||||
|
||||
@override
|
||||
String get settingsBehaviorNotUpdatedForOlderChats => 'Behavior settings are not updated for older chats';
|
||||
String get settingsBehaviorNotUpdatedForOlderChats =>
|
||||
'Behavior settings are not updated for older chats';
|
||||
|
||||
@override
|
||||
String get settingsShowModelTags => 'Show model tags';
|
||||
|
@ -321,7 +340,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get settingsKeepModelLoadedNever => 'Don\'t keep model loaded';
|
||||
|
||||
@override
|
||||
String get settingsKeepModelLoadedFor => 'Set specific time to keep model loaded';
|
||||
String get settingsKeepModelLoadedFor =>
|
||||
'Set specific time to keep model loaded';
|
||||
|
||||
@override
|
||||
String settingsKeepModelLoadedSet(String minutes) {
|
||||
|
@ -332,7 +352,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get settingsTimeoutMultiplier => 'Timeout multiplier';
|
||||
|
||||
@override
|
||||
String get 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.';
|
||||
String get 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.';
|
||||
|
||||
@override
|
||||
String get settingsTimeoutMultiplierExample => 'E.g. message timeout:';
|
||||
|
@ -362,10 +383,12 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get settingsTemporaryFixes => 'Temporary interface fixes';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesDescription => 'Enable temporary fixes for interface issues.\nLong press on the individual options to learn more.';
|
||||
String get settingsTemporaryFixesDescription =>
|
||||
'Enable temporary fixes for interface issues.\nLong press on the individual options to learn more.';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesInstructions => 'Do not toggle any of these settings unless you know what you are doing! The given solutions might not work as expected.\nThey cannot be seen as final or should be judged as such. Issues might occur.';
|
||||
String get settingsTemporaryFixesInstructions =>
|
||||
'Do not toggle any of these settings unless you know what you are doing! The given solutions might not work as expected.\nThey cannot be seen as final or should be judged as such. Issues might occur.';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesNoFixes => 'No fixes available';
|
||||
|
@ -377,7 +400,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get settingsVoiceTtsNotSupported => 'Text-to-speech not supported';
|
||||
|
||||
@override
|
||||
String get settingsVoiceTtsNotSupportedDescription => 'Text-to-speech services are not supported for the selected language. Select a different language in the language drawer to reenable them.\nOther services like voice recognition and AI thinking will still work as usual, but interaction might not be as fluent.';
|
||||
String get settingsVoiceTtsNotSupportedDescription =>
|
||||
'Text-to-speech services are not supported for the selected language. Select a different language in the language drawer to reenable them.\nOther services like voice recognition and AI thinking will still work as usual, but interaction might not be as fluent.';
|
||||
|
||||
@override
|
||||
String get settingsVoicePermissionNot => 'Permissions not granted';
|
||||
|
@ -413,7 +437,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get settingsImportChatsTitle => 'Import';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsDescription => 'The following step will import the chats from the selected file. This will overwrite all currently available chats.\nDo you want to continue?';
|
||||
String get settingsImportChatsDescription =>
|
||||
'The following step will import the chats from the selected file. This will overwrite all currently available chats.\nDo you want to continue?';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsImport => 'Import and Erase';
|
||||
|
@ -425,10 +450,12 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get settingsImportChatsSuccess => 'Chats imported successfully';
|
||||
|
||||
@override
|
||||
String get settingsExportInfo => 'This options allows you to export and import your chat history. This can be useful if you want to transfer your chat history to another device or backup your chat history';
|
||||
String get settingsExportInfo =>
|
||||
'This options allows you to export and import your chat history. This can be useful if you want to transfer your chat history to another device or backup your chat history';
|
||||
|
||||
@override
|
||||
String get settingsExportWarning => 'Multiple chat histories won\'t be merged! You\'ll loose your current chat history if you import a new one';
|
||||
String get settingsExportWarning =>
|
||||
'Multiple chat histories won\'t be merged! You\'ll loose your current chat history if you import a new one';
|
||||
|
||||
@override
|
||||
String get settingsUpdateCheck => 'Check for updates';
|
||||
|
@ -454,7 +481,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get settingsUpdateDialogTitle => 'New version available';
|
||||
|
||||
@override
|
||||
String get settingsUpdateDialogDescription => 'A new version of Ollama is available. Do you want to download and install it now?';
|
||||
String get settingsUpdateDialogDescription =>
|
||||
'A new version of Ollama is available. Do you want to download and install it now?';
|
||||
|
||||
@override
|
||||
String get settingsUpdateChangeLog => 'Change Log';
|
||||
|
|
|
@ -102,7 +102,8 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get modelDialogAddPromptTitle => 'Add new model';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptDescription => 'This can have either be a normal name (e.g. \'llama3\') or name and tag (e.g. \'llama3:70b\').';
|
||||
String get modelDialogAddPromptDescription =>
|
||||
'This can have either be a normal name (e.g. \'llama3\') or name and tag (e.g. \'llama3:70b\').';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptAlreadyExists => 'Model already exists';
|
||||
|
@ -114,7 +115,8 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get modelDialogAddAllowanceTitle => 'Allow Proxy';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceDescription => 'Ollama App must check if the entered model is valid. For that, we normally send a web request to the Ollama model list and check the status code, but because you\'re using the web client, we can\'t do that directly. Instead, the app will send the request to a different api, hosted by JHubi1, to check for us.\nThis is a one-time request and will only be sent when you add a new model.\nYour IP address will be sent with the request and might be stored for up to ten minutes to prevent spamming with potential harmful intentions.\nIf you accept, your selection will be remembered in the future; if not, nothing will be sent and the model won\'t be added.';
|
||||
String get modelDialogAddAllowanceDescription =>
|
||||
'Ollama App must check if the entered model is valid. For that, we normally send a web request to the Ollama model list and check the status code, but because you\'re using the web client, we can\'t do that directly. Instead, the app will send the request to a different api, hosted by JHubi1, to check for us.\nThis is a one-time request and will only be sent when you add a new model.\nYour IP address will be sent with the request and might be stored for up to ten minutes to prevent spamming with potential harmful intentions.\nIf you accept, your selection will be remembered in the future; if not, nothing will be sent and the model won\'t be added.';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceAllow => 'Allow';
|
||||
|
@ -156,7 +158,8 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get deleteDialogTitle => 'Delete Chat';
|
||||
|
||||
@override
|
||||
String get deleteDialogDescription => 'Are you sure you want to continue? This will wipe all memory of this chat and cannot be undone.\nTo disable this dialog, visit the settings.';
|
||||
String get deleteDialogDescription =>
|
||||
'Are you sure you want to continue? This will wipe all memory of this chat and cannot be undone.\nTo disable this dialog, visit the settings.';
|
||||
|
||||
@override
|
||||
String get deleteDialogDelete => 'Delete';
|
||||
|
@ -174,31 +177,36 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get settingsTitleBehavior => 'Behavior';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionBehavior => 'Change the behavior of the AI to your liking.';
|
||||
String get settingsDescriptionBehavior =>
|
||||
'Change the behavior of the AI to your liking.';
|
||||
|
||||
@override
|
||||
String get settingsTitleInterface => 'Interface';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionInterface => 'Edit how Ollama App looks and behaves.';
|
||||
String get settingsDescriptionInterface =>
|
||||
'Edit how Ollama App looks and behaves.';
|
||||
|
||||
@override
|
||||
String get settingsTitleVoice => 'Voice';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionVoice => 'Enable voice mode and configure voice settings.';
|
||||
String get settingsDescriptionVoice =>
|
||||
'Enable voice mode and configure voice settings.';
|
||||
|
||||
@override
|
||||
String get settingsTitleExport => 'Export';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionExport => 'Export and import your chat history.';
|
||||
String get settingsDescriptionExport =>
|
||||
'Export and import your chat history.';
|
||||
|
||||
@override
|
||||
String get settingsTitleAbout => 'About';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionAbout => 'Check for updates and learn more about Ollama App.';
|
||||
String get settingsDescriptionAbout =>
|
||||
'Check for updates and learn more about Ollama App.';
|
||||
|
||||
@override
|
||||
String get settingsSavedAutomatically => 'Settings are saved automatically';
|
||||
|
@ -207,28 +215,34 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get settingsExperimentalAlpha => 'alpha';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaDescription => 'This feature is in alpha and may not work as intended or expected.\nCritical issues and/or permanent critical damage to device and/or used services cannot be ruled out.\nUse at your own risk. No liability on the part of the app author.';
|
||||
String get settingsExperimentalAlphaDescription =>
|
||||
'This feature is in alpha and may not work as intended or expected.\nCritical issues and/or permanent critical damage to device and/or used services cannot be ruled out.\nUse at your own risk. No liability on the part of the app author.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaFeature => 'Alpha feature, hold to learn more';
|
||||
String get settingsExperimentalAlphaFeature =>
|
||||
'Alpha feature, hold to learn more';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBeta => 'beta';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaDescription => 'This feature is in beta and may not work intended or expected.\nLess severe issues may or may not occur. Damage shouldn\'t be critical.\nUse at your own risk.';
|
||||
String get settingsExperimentalBetaDescription =>
|
||||
'This feature is in beta and may not work intended or expected.\nLess severe issues may or may not occur. Damage shouldn\'t be critical.\nUse at your own risk.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaFeature => 'Beta feature, hold to learn more';
|
||||
String get settingsExperimentalBetaFeature =>
|
||||
'Beta feature, hold to learn more';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecated => 'deprecated';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedDescription => 'This feature is deprecated and will be removed in a future version.\nIt may not work as intended or expected. Use at your own risk.';
|
||||
String get settingsExperimentalDeprecatedDescription =>
|
||||
'This feature is deprecated and will be removed in a future version.\nIt may not work as intended or expected. Use at your own risk.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedFeature => 'Deprecated feature, hold to learn more';
|
||||
String get settingsExperimentalDeprecatedFeature =>
|
||||
'Deprecated feature, hold to learn more';
|
||||
|
||||
@override
|
||||
String get settingsHost => 'Host';
|
||||
|
@ -258,15 +272,18 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get settingsHostHeaderTitle => 'Set host header';
|
||||
|
||||
@override
|
||||
String get settingsHostHeaderInvalid => 'The entered text isn\'t a valid header JSON object';
|
||||
String get settingsHostHeaderInvalid =>
|
||||
'The entered text isn\'t a valid header JSON object';
|
||||
|
||||
@override
|
||||
String settingsHostInvalidDetailed(String type) {
|
||||
String _temp0 = intl.Intl.selectLogic(
|
||||
type,
|
||||
{
|
||||
'url': 'The URL you entered is invalid. It isn\'t an a standardized URL format.',
|
||||
'other': 'The host you entered is invalid. It cannot be reached. Please check the host and try again.',
|
||||
'url':
|
||||
'The URL you entered is invalid. It isn\'t an a standardized URL format.',
|
||||
'other':
|
||||
'The host you entered is invalid. It cannot be reached. Please check the host and try again.',
|
||||
},
|
||||
);
|
||||
return '$_temp0';
|
||||
|
@ -279,13 +296,15 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get settingsUseSystem => 'Use system message';
|
||||
|
||||
@override
|
||||
String get settingsUseSystemDescription => 'Disables setting the system message above and use the one of the model instead. Can be useful for models with model files';
|
||||
String get settingsUseSystemDescription =>
|
||||
'Disables setting the system message above and use the one of the model instead. Can be useful for models with model files';
|
||||
|
||||
@override
|
||||
String get settingsDisableMarkdown => 'Disable markdown';
|
||||
|
||||
@override
|
||||
String get settingsBehaviorNotUpdatedForOlderChats => 'Behavior settings are not updated for older chats';
|
||||
String get settingsBehaviorNotUpdatedForOlderChats =>
|
||||
'Behavior settings are not updated for older chats';
|
||||
|
||||
@override
|
||||
String get settingsShowModelTags => 'Show model tags';
|
||||
|
@ -321,7 +340,8 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get settingsKeepModelLoadedNever => 'Don\'t keep model loaded';
|
||||
|
||||
@override
|
||||
String get settingsKeepModelLoadedFor => 'Set specific time to keep model loaded';
|
||||
String get settingsKeepModelLoadedFor =>
|
||||
'Set specific time to keep model loaded';
|
||||
|
||||
@override
|
||||
String settingsKeepModelLoadedSet(String minutes) {
|
||||
|
@ -332,7 +352,8 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get settingsTimeoutMultiplier => 'Timeout multiplier';
|
||||
|
||||
@override
|
||||
String get 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.';
|
||||
String get 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.';
|
||||
|
||||
@override
|
||||
String get settingsTimeoutMultiplierExample => 'E.g. message timeout:';
|
||||
|
@ -362,10 +383,12 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get settingsTemporaryFixes => 'Temporary interface fixes';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesDescription => 'Enable temporary fixes for interface issues.\nLong press on the individual options to learn more.';
|
||||
String get settingsTemporaryFixesDescription =>
|
||||
'Enable temporary fixes for interface issues.\nLong press on the individual options to learn more.';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesInstructions => 'Do not toggle any of these settings unless you know what you are doing! The given solutions might not work as expected.\nThey cannot be seen as final or should be judged as such. Issues might occur.';
|
||||
String get settingsTemporaryFixesInstructions =>
|
||||
'Do not toggle any of these settings unless you know what you are doing! The given solutions might not work as expected.\nThey cannot be seen as final or should be judged as such. Issues might occur.';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesNoFixes => 'No fixes available';
|
||||
|
@ -377,7 +400,8 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get settingsVoiceTtsNotSupported => 'Text-to-speech not supported';
|
||||
|
||||
@override
|
||||
String get settingsVoiceTtsNotSupportedDescription => 'Text-to-speech services are not supported for the selected language. Select a different language in the language drawer to reenable them.\nOther services like voice recognition and AI thinking will still work as usual, but interaction might not be as fluent.';
|
||||
String get settingsVoiceTtsNotSupportedDescription =>
|
||||
'Text-to-speech services are not supported for the selected language. Select a different language in the language drawer to reenable them.\nOther services like voice recognition and AI thinking will still work as usual, but interaction might not be as fluent.';
|
||||
|
||||
@override
|
||||
String get settingsVoicePermissionNot => 'Permissions not granted';
|
||||
|
@ -413,7 +437,8 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get settingsImportChatsTitle => 'Import';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsDescription => 'The following step will import the chats from the selected file. This will overwrite all currently available chats.\nDo you want to continue?';
|
||||
String get settingsImportChatsDescription =>
|
||||
'The following step will import the chats from the selected file. This will overwrite all currently available chats.\nDo you want to continue?';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsImport => 'Import and Erase';
|
||||
|
@ -425,10 +450,12 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get settingsImportChatsSuccess => 'Chats imported successfully';
|
||||
|
||||
@override
|
||||
String get settingsExportInfo => 'This options allows you to export and import your chat history. This can be useful if you want to transfer your chat history to another device or backup your chat history';
|
||||
String get settingsExportInfo =>
|
||||
'This options allows you to export and import your chat history. This can be useful if you want to transfer your chat history to another device or backup your chat history';
|
||||
|
||||
@override
|
||||
String get settingsExportWarning => 'Multiple chat histories won\'t be merged! You\'ll loose your current chat history if you import a new one';
|
||||
String get settingsExportWarning =>
|
||||
'Multiple chat histories won\'t be merged! You\'ll loose your current chat history if you import a new one';
|
||||
|
||||
@override
|
||||
String get settingsUpdateCheck => 'Check for updates';
|
||||
|
@ -454,7 +481,8 @@ class AppLocalizationsFa extends AppLocalizations {
|
|||
String get settingsUpdateDialogTitle => 'New version available';
|
||||
|
||||
@override
|
||||
String get settingsUpdateDialogDescription => 'A new version of Ollama is available. Do you want to download and install it now?';
|
||||
String get settingsUpdateDialogDescription =>
|
||||
'A new version of Ollama is available. Do you want to download and install it now?';
|
||||
|
||||
@override
|
||||
String get settingsUpdateChangeLog => 'Change Log';
|
||||
|
|
|
@ -36,7 +36,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get tip2 => 'Puoi cambiare il tema dalle impostazioni';
|
||||
|
||||
@override
|
||||
String get tip3 => 'Seleziona un modello multimodale per inserire le immagini';
|
||||
String get tip3 =>
|
||||
'Seleziona un modello multimodale per inserire le immagini';
|
||||
|
||||
@override
|
||||
String get tip4 => 'Le chat sono state automaticamente salvate';
|
||||
|
@ -87,7 +88,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get noModelSelected => 'Nessun modello selezionato';
|
||||
|
||||
@override
|
||||
String get noHostSelected => 'Nessun host selezionato, apri le impostazioni per farlo';
|
||||
String get noHostSelected =>
|
||||
'Nessun host selezionato, apri le impostazioni per farlo';
|
||||
|
||||
@override
|
||||
String get noSelectedModel => '<modelli>';
|
||||
|
@ -102,7 +104,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get modelDialogAddPromptTitle => 'Aggiungi nuovo modello';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptDescription => 'Questo può essere un nome normale (ad es. \'llama3\') o nome e tag (ad es. \'llama3:70b\').';
|
||||
String get modelDialogAddPromptDescription =>
|
||||
'Questo può essere un nome normale (ad es. \'llama3\') o nome e tag (ad es. \'llama3:70b\').';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptAlreadyExists => 'Il modello esiste già';
|
||||
|
@ -114,7 +117,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get modelDialogAddAllowanceTitle => 'Abilita Proxy';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceDescription => 'Ollama App deve controllare se il modello inserito è valido. Per questo, normalmente inviamo una richiesta web alla lista dei modelli Ollama e controlliamo il codice di stato, ma perché stai usando il web client, non possiamo farlo direttamente. Invece, l\'app invierà la richiesta a un altro api, ospitato da JHubi1, per eseguire il controllo.\nQuesta è una richiesta verrà inviata solo quando aggiungi un nuovo modello.\nIl tuo indirizzo IP verrà inviato con la richiesta e potrebbe essere memorizzato per un massimo di dieci minuti per evitare lo spamming con potenziali intenzioni nocive.\nSe accetti, la tua selezione sarà ricordata in futuro; in caso contrario, non verrà inviato nulla e il modello non verrà aggiunto.';
|
||||
String get modelDialogAddAllowanceDescription =>
|
||||
'Ollama App deve controllare se il modello inserito è valido. Per questo, normalmente inviamo una richiesta web alla lista dei modelli Ollama e controlliamo il codice di stato, ma perché stai usando il web client, non possiamo farlo direttamente. Invece, l\'app invierà la richiesta a un altro api, ospitato da JHubi1, per eseguire il controllo.\nQuesta è una richiesta verrà inviata solo quando aggiungi un nuovo modello.\nIl tuo indirizzo IP verrà inviato con la richiesta e potrebbe essere memorizzato per un massimo di dieci minuti per evitare lo spamming con potenziali intenzioni nocive.\nSe accetti, la tua selezione sarà ricordata in futuro; in caso contrario, non verrà inviato nulla e il modello non verrà aggiunto.';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceAllow => 'Consenti';
|
||||
|
@ -150,13 +154,15 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get modelDialogAddDownloadFailed => 'Disconnesso, riprova';
|
||||
|
||||
@override
|
||||
String get modelDialogAddDownloadSuccess => 'Download completato con successo';
|
||||
String get modelDialogAddDownloadSuccess =>
|
||||
'Download completato con successo';
|
||||
|
||||
@override
|
||||
String get deleteDialogTitle => 'Elimina Chat';
|
||||
|
||||
@override
|
||||
String get deleteDialogDescription => 'Sei sicuro di voler continuare? Tale operazione cancellerà tutta questa chat e non potrà essere annullata.\nPer disattivare questa finestra di dialogo, vai alle impostazioni.';
|
||||
String get deleteDialogDescription =>
|
||||
'Sei sicuro di voler continuare? Tale operazione cancellerà tutta questa chat e non potrà essere annullata.\nPer disattivare questa finestra di dialogo, vai alle impostazioni.';
|
||||
|
||||
@override
|
||||
String get deleteDialogDelete => 'Elimina';
|
||||
|
@ -174,61 +180,73 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get settingsTitleBehavior => 'Comportamento';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionBehavior => 'Modifica il comportamento dell\'AI a tuo piacimento.';
|
||||
String get settingsDescriptionBehavior =>
|
||||
'Modifica il comportamento dell\'AI a tuo piacimento.';
|
||||
|
||||
@override
|
||||
String get settingsTitleInterface => 'Interfaccia';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionInterface => 'Modifica l\'aspetto e il comportamento dell\'app Ollama.';
|
||||
String get settingsDescriptionInterface =>
|
||||
'Modifica l\'aspetto e il comportamento dell\'app Ollama.';
|
||||
|
||||
@override
|
||||
String get settingsTitleVoice => 'Voce';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionVoice => 'Abilita la modalità vocale e configura le impostazioni vocali.';
|
||||
String get settingsDescriptionVoice =>
|
||||
'Abilita la modalità vocale e configura le impostazioni vocali.';
|
||||
|
||||
@override
|
||||
String get settingsTitleExport => 'Esporta';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionExport => 'Esporta e importa la cronologia delle tue chat.';
|
||||
String get settingsDescriptionExport =>
|
||||
'Esporta e importa la cronologia delle tue chat.';
|
||||
|
||||
@override
|
||||
String get settingsTitleAbout => 'Informazioni';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionAbout => 'Controlla gli aggiornamenti e scopri di più su Ollama App.';
|
||||
String get settingsDescriptionAbout =>
|
||||
'Controlla gli aggiornamenti e scopri di più su Ollama App.';
|
||||
|
||||
@override
|
||||
String get settingsSavedAutomatically => 'Le impostazioni vengono salvate automaticamente';
|
||||
String get settingsSavedAutomatically =>
|
||||
'Le impostazioni vengono salvate automaticamente';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlpha => 'alpha';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaDescription => 'Questa funzionalità è in versione alpha e potrebbe non funzionare come previsto o previsto.\nNon si possono escludere problemi critici e/o danni critici permanenti al dispositivo e/o ai servizi utilizzati.\nL\'utilizzo è a proprio rischio. Nessuna responsabilità da parte dell\'autore dell\'app.';
|
||||
String get settingsExperimentalAlphaDescription =>
|
||||
'Questa funzionalità è in versione alpha e potrebbe non funzionare come previsto o previsto.\nNon si possono escludere problemi critici e/o danni critici permanenti al dispositivo e/o ai servizi utilizzati.\nL\'utilizzo è a proprio rischio. Nessuna responsabilità da parte dell\'autore dell\'app.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaFeature => 'Funzione Alpha, tieni premuto per saperne di più';
|
||||
String get settingsExperimentalAlphaFeature =>
|
||||
'Funzione Alpha, tieni premuto per saperne di più';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBeta => 'beta';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaDescription => 'Questa funzionalità è in versione beta e potrebbe non funzionare come previsto o previsto.\nPotrebbero verificarsi o meno problemi meno gravi. I danni non dovrebbero essere critici.\nUtilizza a tuo rischio e pericolo.';
|
||||
String get settingsExperimentalBetaDescription =>
|
||||
'Questa funzionalità è in versione beta e potrebbe non funzionare come previsto o previsto.\nPotrebbero verificarsi o meno problemi meno gravi. I danni non dovrebbero essere critici.\nUtilizza a tuo rischio e pericolo.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaFeature => 'Funzione Beta, tieni premuto per saperne di più';
|
||||
String get settingsExperimentalBetaFeature =>
|
||||
'Funzione Beta, tieni premuto per saperne di più';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecated => 'deprecato';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedDescription => 'Questa funzionalità è deprecata e verrà rimossa in una versione futura.\nPotrebbe non funzionare come previsto o atteso. Usare a proprio rischio.';
|
||||
String get settingsExperimentalDeprecatedDescription =>
|
||||
'Questa funzionalità è deprecata e verrà rimossa in una versione futura.\nPotrebbe non funzionare come previsto o atteso. Usare a proprio rischio.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedFeature => 'Funzionalità deprecata, tenere premuto per saperne di più';
|
||||
String get settingsExperimentalDeprecatedFeature =>
|
||||
'Funzionalità deprecata, tenere premuto per saperne di più';
|
||||
|
||||
@override
|
||||
String get settingsHost => 'Host';
|
||||
|
@ -258,15 +276,18 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get settingsHostHeaderTitle => 'Imposta header host';
|
||||
|
||||
@override
|
||||
String get settingsHostHeaderInvalid => 'Il testo immesso non è un valido oggetto JSON';
|
||||
String get settingsHostHeaderInvalid =>
|
||||
'Il testo immesso non è un valido oggetto JSON';
|
||||
|
||||
@override
|
||||
String settingsHostInvalidDetailed(String type) {
|
||||
String _temp0 = intl.Intl.selectLogic(
|
||||
type,
|
||||
{
|
||||
'url': 'L\'URL inserito non è valido. Non è un formato URL standardizzato.',
|
||||
'other': 'L\'host inserito non è valido. Non può essere raggiunto. Controlla l\'host e riprova.',
|
||||
'url':
|
||||
'L\'URL inserito non è valido. Non è un formato URL standardizzato.',
|
||||
'other':
|
||||
'L\'host inserito non è valido. Non può essere raggiunto. Controlla l\'host e riprova.',
|
||||
},
|
||||
);
|
||||
return '$_temp0';
|
||||
|
@ -279,13 +300,15 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get settingsUseSystem => 'Usa Messaggio di sistema';
|
||||
|
||||
@override
|
||||
String get settingsUseSystemDescription => 'Disabilita l\'impostazione del messaggio di sistema sopra e utilizza invece quello del modello. Può essere utile per i modelli con file di modello';
|
||||
String get settingsUseSystemDescription =>
|
||||
'Disabilita l\'impostazione del messaggio di sistema sopra e utilizza invece quello del modello. Può essere utile per i modelli con file di modello';
|
||||
|
||||
@override
|
||||
String get settingsDisableMarkdown => 'Disabilita markdown';
|
||||
|
||||
@override
|
||||
String get settingsBehaviorNotUpdatedForOlderChats => 'Le impostazioni sul comportamento non vengono aggiornate per le chat meno recenti';
|
||||
String get settingsBehaviorNotUpdatedForOlderChats =>
|
||||
'Le impostazioni sul comportamento non vengono aggiornate per le chat meno recenti';
|
||||
|
||||
@override
|
||||
String get settingsShowModelTags => 'Visualizza tags modello';
|
||||
|
@ -315,13 +338,16 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get settingsShowTips => 'Mostra suggerimenti nella barra laterale';
|
||||
|
||||
@override
|
||||
String get settingsKeepModelLoadedAlways => 'Mantieni modello sempre caricato';
|
||||
String get settingsKeepModelLoadedAlways =>
|
||||
'Mantieni modello sempre caricato';
|
||||
|
||||
@override
|
||||
String get settingsKeepModelLoadedNever => 'Non mantenere modello sempre caricato';
|
||||
String get settingsKeepModelLoadedNever =>
|
||||
'Non mantenere modello sempre caricato';
|
||||
|
||||
@override
|
||||
String get settingsKeepModelLoadedFor => 'Imposta un tempo specifico per mantenere il modello caricato';
|
||||
String get settingsKeepModelLoadedFor =>
|
||||
'Imposta un tempo specifico per mantenere il modello caricato';
|
||||
|
||||
@override
|
||||
String settingsKeepModelLoadedSet(String minutes) {
|
||||
|
@ -332,7 +358,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get settingsTimeoutMultiplier => 'Moltiplicatore di timeout';
|
||||
|
||||
@override
|
||||
String get settingsTimeoutMultiplierDescription => 'Seleziona il moltiplicatore che viene applicato a ogni valore di timeout nell\'applicazione. Può essere utile con una connessione internet lenta o un host lento.';
|
||||
String get settingsTimeoutMultiplierDescription =>
|
||||
'Seleziona il moltiplicatore che viene applicato a ogni valore di timeout nell\'applicazione. Può essere utile con una connessione internet lenta o un host lento.';
|
||||
|
||||
@override
|
||||
String get settingsTimeoutMultiplierExample => 'Es. messaggio di timeout:';
|
||||
|
@ -359,13 +386,16 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get settingsThemeOllama => 'Ollama';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixes => 'Aggiustamenti temporanei dell\'interfaccia';
|
||||
String get settingsTemporaryFixes =>
|
||||
'Aggiustamenti temporanei dell\'interfaccia';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesDescription => 'Abilita correzioni temporanee per problemi dell\'interfaccia.\nPremi a lungo sulle opzioni individuali per saperne di più.';
|
||||
String get settingsTemporaryFixesDescription =>
|
||||
'Abilita correzioni temporanee per problemi dell\'interfaccia.\nPremi a lungo sulle opzioni individuali per saperne di più.';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesInstructions => 'Non attivare nessuna di queste impostazioni a meno che tu non sappia cosa stai facendo! Le soluzioni fornite potrebbero non funzionare come previsto. \nNon possono essere considerate definitive o giudicate come tali. Potrebbero verificarsi problemi.';
|
||||
String get settingsTemporaryFixesInstructions =>
|
||||
'Non attivare nessuna di queste impostazioni a meno che tu non sappia cosa stai facendo! Le soluzioni fornite potrebbero non funzionare come previsto. \nNon possono essere considerate definitive o giudicate come tali. Potrebbero verificarsi problemi.';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesNoFixes => 'Nessuna correzione disponibile';
|
||||
|
@ -377,7 +407,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get settingsVoiceTtsNotSupported => 'Text-to-speech non supportato';
|
||||
|
||||
@override
|
||||
String get settingsVoiceTtsNotSupportedDescription => 'I servizi di text-to-speech non sono supportati per la lingua selezionata. Seleziona una lingua diversa nel menu a discesa delle lingue per riattivarli.\nAltri servizi come il riconoscimento vocale e il pensiero dell\'IA funzioneranno comunque normalmente, ma l\'interazione potrebbe non essere fluida.';
|
||||
String get settingsVoiceTtsNotSupportedDescription =>
|
||||
'I servizi di text-to-speech non sono supportati per la lingua selezionata. Seleziona una lingua diversa nel menu a discesa delle lingue per riattivarli.\nAltri servizi come il riconoscimento vocale e il pensiero dell\'IA funzioneranno comunque normalmente, ma l\'interazione potrebbe non essere fluida.';
|
||||
|
||||
@override
|
||||
String get settingsVoicePermissionNot => 'Permessi non concessi';
|
||||
|
@ -413,7 +444,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get settingsImportChatsTitle => 'Importa';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsDescription => 'Il passaggio successivo importerà le chat dal file selezionato. Ciò sovrascriverà tutte le chat attualmente disponibili.\nVuoi continuare?';
|
||||
String get settingsImportChatsDescription =>
|
||||
'Il passaggio successivo importerà le chat dal file selezionato. Ciò sovrascriverà tutte le chat attualmente disponibili.\nVuoi continuare?';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsImport => 'Importa e cancella';
|
||||
|
@ -425,10 +457,12 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get settingsImportChatsSuccess => 'Chats importate con successo';
|
||||
|
||||
@override
|
||||
String get settingsExportInfo => 'Questa opzione ti consente di esportare e importare la cronologia chat. Questo può essere utile se desideri trasferire la cronologia chat su un altro dispositivo o eseguire il backup della cronologia chat';
|
||||
String get settingsExportInfo =>
|
||||
'Questa opzione ti consente di esportare e importare la cronologia chat. Questo può essere utile se desideri trasferire la cronologia chat su un altro dispositivo o eseguire il backup della cronologia chat';
|
||||
|
||||
@override
|
||||
String get settingsExportWarning => 'Più cronologie di chat non verranno unite! Perderai la cronologia chat attuale se ne importi una nuova';
|
||||
String get settingsExportWarning =>
|
||||
'Più cronologie di chat non verranno unite! Perderai la cronologia chat attuale se ne importi una nuova';
|
||||
|
||||
@override
|
||||
String get settingsUpdateCheck => 'Controlla aggiornamenti';
|
||||
|
@ -445,7 +479,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
}
|
||||
|
||||
@override
|
||||
String get settingsUpdateRateLimit => 'Impossibile verificare, limite di accesso API superato';
|
||||
String get settingsUpdateRateLimit =>
|
||||
'Impossibile verificare, limite di accesso API superato';
|
||||
|
||||
@override
|
||||
String get settingsUpdateIssue => 'Si è verificato un errore';
|
||||
|
@ -454,7 +489,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get settingsUpdateDialogTitle => 'Nuova versione disponibile';
|
||||
|
||||
@override
|
||||
String get settingsUpdateDialogDescription => 'È disponibile una nuova versione di Ollama. Vuoi scaricarla e installarla adesso?';
|
||||
String get settingsUpdateDialogDescription =>
|
||||
'È disponibile una nuova versione di Ollama. Vuoi scaricarla e installarla adesso?';
|
||||
|
||||
@override
|
||||
String get settingsUpdateChangeLog => 'Cambiamenti';
|
||||
|
@ -466,7 +502,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get settingsUpdateDialogCancel => 'Annulla';
|
||||
|
||||
@override
|
||||
String get settingsCheckForUpdates => 'Controlla gli aggiornamenti all\'apertura';
|
||||
String get settingsCheckForUpdates =>
|
||||
'Controlla gli aggiornamenti all\'apertura';
|
||||
|
||||
@override
|
||||
String get settingsGithub => 'GitHub';
|
||||
|
|
|
@ -87,7 +87,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get noModelSelected => 'Model seçilmedi';
|
||||
|
||||
@override
|
||||
String get noHostSelected => 'Ana bilgisayar seçilmedi, ayarları açıp bir tane belirleyin';
|
||||
String get noHostSelected =>
|
||||
'Ana bilgisayar seçilmedi, ayarları açıp bir tane belirleyin';
|
||||
|
||||
@override
|
||||
String get noSelectedModel => '<seçici>';
|
||||
|
@ -102,7 +103,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get modelDialogAddPromptTitle => 'Yeni model ekle';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptDescription => 'Bu normal bir isim (örneğin \'llama3\') ya da isim ve etiket (örneğin \'llama3:70b\') olabilir.';
|
||||
String get modelDialogAddPromptDescription =>
|
||||
'Bu normal bir isim (örneğin \'llama3\') ya da isim ve etiket (örneğin \'llama3:70b\') olabilir.';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptAlreadyExists => 'Model zaten mevcut';
|
||||
|
@ -114,7 +116,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get modelDialogAddAllowanceTitle => 'Proxy\'e İzin Ver';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceDescription => 'Ollama Uygulaması, girilen modelin geçerli olup olmadığını kontrol etmelidir. Bunun için normalde Ollama model listesine bir web isteği gönderir ve durum kodunu kontrol ederiz, ancak siz web istemcisini kullandığınız için bunu doğrudan yapamayız. Bunun yerine, uygulama bizim için kontrol etmek amacıyla JHubi1 tarafından barındırılan farklı bir API\'ye istek gönderecek. \nBu, yalnızca bir kez yapılan bir istektir ve yalnızca yeni bir model eklediğinizde gönderilecektir. \nIP adresiniz istekle birlikte gönderilecek ve olası zararlı niyetlerle spam yapılmasını önlemek amacıyla on dakikaya kadar saklanabilir. \nKabul ederseniz, seçiminiz gelecekte hatırlanacaktır; kabul etmezseniz, hiçbir şey gönderilmeyecek ve model eklenmeyecektir.';
|
||||
String get modelDialogAddAllowanceDescription =>
|
||||
'Ollama Uygulaması, girilen modelin geçerli olup olmadığını kontrol etmelidir. Bunun için normalde Ollama model listesine bir web isteği gönderir ve durum kodunu kontrol ederiz, ancak siz web istemcisini kullandığınız için bunu doğrudan yapamayız. Bunun yerine, uygulama bizim için kontrol etmek amacıyla JHubi1 tarafından barındırılan farklı bir API\'ye istek gönderecek. \nBu, yalnızca bir kez yapılan bir istektir ve yalnızca yeni bir model eklediğinizde gönderilecektir. \nIP adresiniz istekle birlikte gönderilecek ve olası zararlı niyetlerle spam yapılmasını önlemek amacıyla on dakikaya kadar saklanabilir. \nKabul ederseniz, seçiminiz gelecekte hatırlanacaktır; kabul etmezseniz, hiçbir şey gönderilmeyecek ve model eklenmeyecektir.';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceAllow => 'İzin ver';
|
||||
|
@ -147,7 +150,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
}
|
||||
|
||||
@override
|
||||
String get modelDialogAddDownloadFailed => 'Bağlantı kesildi, yeniden deneyin';
|
||||
String get modelDialogAddDownloadFailed =>
|
||||
'Bağlantı kesildi, yeniden deneyin';
|
||||
|
||||
@override
|
||||
String get modelDialogAddDownloadSuccess => 'İndirme tamamlandı';
|
||||
|
@ -156,7 +160,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get deleteDialogTitle => 'Sohbeti Sil';
|
||||
|
||||
@override
|
||||
String get deleteDialogDescription => 'Devam etmek istediğinizden emin misiniz? Bu işlem, bu sohbetin tüm hafızasını silecek ve geri alınamaz.\nBu dialogu devre dışı bırakmak için ayarları ziyaret edin.';
|
||||
String get deleteDialogDescription =>
|
||||
'Devam etmek istediğinizden emin misiniz? Bu işlem, bu sohbetin tüm hafızasını silecek ve geri alınamaz.\nBu dialogu devre dışı bırakmak için ayarları ziyaret edin.';
|
||||
|
||||
@override
|
||||
String get deleteDialogDelete => 'Sil';
|
||||
|
@ -174,31 +179,36 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsTitleBehavior => 'Davranış';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionBehavior => 'Yapay zekanın davranışını istediğiniz gibi değiştirin.';
|
||||
String get settingsDescriptionBehavior =>
|
||||
'Yapay zekanın davranışını istediğiniz gibi değiştirin.';
|
||||
|
||||
@override
|
||||
String get settingsTitleInterface => 'Arayüz';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionInterface => 'Ollama Uygulamasının görünümünü ve davranışını düzenleyin.';
|
||||
String get settingsDescriptionInterface =>
|
||||
'Ollama Uygulamasının görünümünü ve davranışını düzenleyin.';
|
||||
|
||||
@override
|
||||
String get settingsTitleVoice => 'Ses';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionVoice => 'Ses modunu etkinleştirin ve ses ayarlarını yapılandırın.';
|
||||
String get settingsDescriptionVoice =>
|
||||
'Ses modunu etkinleştirin ve ses ayarlarını yapılandırın.';
|
||||
|
||||
@override
|
||||
String get settingsTitleExport => 'Dışa Aktar';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionExport => 'Sohbet geçmişinizi dışa ve içe aktarın.';
|
||||
String get settingsDescriptionExport =>
|
||||
'Sohbet geçmişinizi dışa ve içe aktarın.';
|
||||
|
||||
@override
|
||||
String get settingsTitleAbout => 'Hakkında';
|
||||
|
||||
@override
|
||||
String get settingsDescriptionAbout => 'Güncellemeleri kontrol edin ve Ollama Uygulaması hakkında daha fazla bilgi edinin.';
|
||||
String get settingsDescriptionAbout =>
|
||||
'Güncellemeleri kontrol edin ve Ollama Uygulaması hakkında daha fazla bilgi edinin.';
|
||||
|
||||
@override
|
||||
String get settingsSavedAutomatically => 'Ayarlar otomatik olarak kaydedilir';
|
||||
|
@ -207,28 +217,34 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsExperimentalAlpha => 'alfa';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaDescription => 'Bu özellik alfa aşamasındadır ve beklendiği gibi çalışmayabilir.\nKritik sorunlar ve/veya cihaza ve/veya kullanılan hizmetlere kalıcı kritik hasar verilebilme ihtimali göz ardı edilemez.\nKendi sorumluluğunuzda kullanın. Uygulama yazarının hiçbir sorumluluğu yoktur.';
|
||||
String get settingsExperimentalAlphaDescription =>
|
||||
'Bu özellik alfa aşamasındadır ve beklendiği gibi çalışmayabilir.\nKritik sorunlar ve/veya cihaza ve/veya kullanılan hizmetlere kalıcı kritik hasar verilebilme ihtimali göz ardı edilemez.\nKendi sorumluluğunuzda kullanın. Uygulama yazarının hiçbir sorumluluğu yoktur.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaFeature => 'Alfa özelliği, daha fazla bilgi için basılı tutun';
|
||||
String get settingsExperimentalAlphaFeature =>
|
||||
'Alfa özelliği, daha fazla bilgi için basılı tutun';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBeta => 'beta';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaDescription => 'Bu özellik beta aşamasındadır ve beklendiği gibi çalışmayabilir.\nDaha az ciddi sorunlar ortaya çıkabilir. Hasar kritik olmamalıdır.\nKendi sorumluluğunuzda kullanın.';
|
||||
String get settingsExperimentalBetaDescription =>
|
||||
'Bu özellik beta aşamasındadır ve beklendiği gibi çalışmayabilir.\nDaha az ciddi sorunlar ortaya çıkabilir. Hasar kritik olmamalıdır.\nKendi sorumluluğunuzda kullanın.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaFeature => 'Beta özelliği, daha fazla bilgi için basılı tutun';
|
||||
String get settingsExperimentalBetaFeature =>
|
||||
'Beta özelliği, daha fazla bilgi için basılı tutun';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecated => 'kullanım dışı';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedDescription => 'Bu özellik kullanımdan kaldırılmıştır ve gelecekteki bir sürümde kaldırılacaktır.\nAmaçlandığı veya beklendiği gibi çalışmayabilir. Kullanım riski size aittir.';
|
||||
String get settingsExperimentalDeprecatedDescription =>
|
||||
'Bu özellik kullanımdan kaldırılmıştır ve gelecekteki bir sürümde kaldırılacaktır.\nAmaçlandığı veya beklendiği gibi çalışmayabilir. Kullanım riski size aittir.';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedFeature => 'Kullanımdan kaldırılan özellik, daha fazla bilgi için bekleyin';
|
||||
String get settingsExperimentalDeprecatedFeature =>
|
||||
'Kullanımdan kaldırılan özellik, daha fazla bilgi için bekleyin';
|
||||
|
||||
@override
|
||||
String get settingsHost => 'Ana bilgisayar';
|
||||
|
@ -258,7 +274,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsHostHeaderTitle => 'Ana bilgisayar başlığını ayarla';
|
||||
|
||||
@override
|
||||
String get settingsHostHeaderInvalid => 'Girilen metin geçerli bir başlık JSON nesnesi değil';
|
||||
String get settingsHostHeaderInvalid =>
|
||||
'Girilen metin geçerli bir başlık JSON nesnesi değil';
|
||||
|
||||
@override
|
||||
String settingsHostInvalidDetailed(String type) {
|
||||
|
@ -266,7 +283,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
type,
|
||||
{
|
||||
'url': 'Girdiğiniz URL geçersiz. Standart bir URL formatında değil.',
|
||||
'other': 'Girdiğiniz ana bilgisayar geçersiz. Ulaşılamıyor. Lütfen ana bilgisayarı kontrol edin ve tekrar deneyin.',
|
||||
'other':
|
||||
'Girdiğiniz ana bilgisayar geçersiz. Ulaşılamıyor. Lütfen ana bilgisayarı kontrol edin ve tekrar deneyin.',
|
||||
},
|
||||
);
|
||||
return '$_temp0';
|
||||
|
@ -279,13 +297,15 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsUseSystem => 'Sistem mesajını kullan';
|
||||
|
||||
@override
|
||||
String get settingsUseSystemDescription => 'Yukarıdaki sistem mesajını ayarlamayı devre dışı bırakır ve bunun yerine modelin mesajını kullanır. Model dosyaları olan modeller için yararlı olabilir';
|
||||
String get settingsUseSystemDescription =>
|
||||
'Yukarıdaki sistem mesajını ayarlamayı devre dışı bırakır ve bunun yerine modelin mesajını kullanır. Model dosyaları olan modeller için yararlı olabilir';
|
||||
|
||||
@override
|
||||
String get settingsDisableMarkdown => 'Markdown\'\'ı devre dışı bırak';
|
||||
|
||||
@override
|
||||
String get settingsBehaviorNotUpdatedForOlderChats => 'Davranış ayarları eski sohbetler için güncellenmez';
|
||||
String get settingsBehaviorNotUpdatedForOlderChats =>
|
||||
'Davranış ayarları eski sohbetler için güncellenmez';
|
||||
|
||||
@override
|
||||
String get settingsShowModelTags => 'Model etiketlerini göster';
|
||||
|
@ -321,7 +341,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsKeepModelLoadedNever => 'Modeli yüklü tutma';
|
||||
|
||||
@override
|
||||
String get settingsKeepModelLoadedFor => 'Modelin yüklü kalacağı belirli bir süre ayarla';
|
||||
String get settingsKeepModelLoadedFor =>
|
||||
'Modelin yüklü kalacağı belirli bir süre ayarla';
|
||||
|
||||
@override
|
||||
String settingsKeepModelLoadedSet(String minutes) {
|
||||
|
@ -332,13 +353,15 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsTimeoutMultiplier => 'Zaman aşımı çarpanı';
|
||||
|
||||
@override
|
||||
String get settingsTimeoutMultiplierDescription => 'Uygulamadaki her zaman aşımı değerine uygulanacak çarpanı seçin. Yavaş bir internet bağlantısı veya yavaş bir ana bilgisayar ile yararlı olabilir.';
|
||||
String get settingsTimeoutMultiplierDescription =>
|
||||
'Uygulamadaki her zaman aşımı değerine uygulanacak çarpanı seçin. Yavaş bir internet bağlantısı veya yavaş bir ana bilgisayar ile yararlı olabilir.';
|
||||
|
||||
@override
|
||||
String get settingsTimeoutMultiplierExample => 'Örn. mesaj zaman aşımı:';
|
||||
|
||||
@override
|
||||
String get settingsEnableHapticFeedback => 'Dokunsal geri bildirimi etkinleştir';
|
||||
String get settingsEnableHapticFeedback =>
|
||||
'Dokunsal geri bildirimi etkinleştir';
|
||||
|
||||
@override
|
||||
String get settingsMaximizeOnStart => 'Başlangıçta maksimize et';
|
||||
|
@ -362,13 +385,16 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsTemporaryFixes => 'Geçici arayüz düzeltmeleri';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesDescription => 'Arayüz sorunları için geçici düzeltmeleri etkinleştirin. \nDaha fazla bilgi edinmek için tek tek seçeneklere uzun basın.';
|
||||
String get settingsTemporaryFixesDescription =>
|
||||
'Arayüz sorunları için geçici düzeltmeleri etkinleştirin. \nDaha fazla bilgi edinmek için tek tek seçeneklere uzun basın.';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesInstructions => 'Ne yaptığınızı bilmiyorsanız bu ayarlardan herhangi birini değiştirmeyin! Verilen çözümler beklendiği gibi çalışmayabilir.\nBunlar nihai olarak görülemez veya bu şekilde değerlendirilmemelidir. Sorunlar ortaya çıkabilir.';
|
||||
String get settingsTemporaryFixesInstructions =>
|
||||
'Ne yaptığınızı bilmiyorsanız bu ayarlardan herhangi birini değiştirmeyin! Verilen çözümler beklendiği gibi çalışmayabilir.\nBunlar nihai olarak görülemez veya bu şekilde değerlendirilmemelidir. Sorunlar ortaya çıkabilir.';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesNoFixes => 'Herhangi bir düzeltme mevcut değil';
|
||||
String get settingsTemporaryFixesNoFixes =>
|
||||
'Herhangi bir düzeltme mevcut değil';
|
||||
|
||||
@override
|
||||
String get settingsVoicePermissionLoading => 'Ses izinleri yükleniyor ...';
|
||||
|
@ -377,7 +403,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsVoiceTtsNotSupported => 'Metinden sese desteklenmiyor';
|
||||
|
||||
@override
|
||||
String get settingsVoiceTtsNotSupportedDescription => 'Metinden sese hizmetleri seçilen dil için desteklenmiyor. Bunları yeniden etkinleştirmek için dil çekmecesinde farklı bir dil seçin.\nSes tanıma ve yapay zeka ile düşünme gibi diğer hizmetler her zamanki gibi çalışmaya devam eder, ancak etkileşim o kadar akıcı olmayabilir.';
|
||||
String get settingsVoiceTtsNotSupportedDescription =>
|
||||
'Metinden sese hizmetleri seçilen dil için desteklenmiyor. Bunları yeniden etkinleştirmek için dil çekmecesinde farklı bir dil seçin.\nSes tanıma ve yapay zeka ile düşünme gibi diğer hizmetler her zamanki gibi çalışmaya devam eder, ancak etkileşim o kadar akıcı olmayabilir.';
|
||||
|
||||
@override
|
||||
String get settingsVoicePermissionNot => 'İzinler verilmedi';
|
||||
|
@ -398,7 +425,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsVoiceLimitLanguage => 'Seçili dille sınırla';
|
||||
|
||||
@override
|
||||
String get settingsVoicePunctuation => 'Yapay zeka noktalama işaretlerini etkinleştir';
|
||||
String get settingsVoicePunctuation =>
|
||||
'Yapay zeka noktalama işaretlerini etkinleştir';
|
||||
|
||||
@override
|
||||
String get settingsExportChats => 'Sohbetleri dışa aktar';
|
||||
|
@ -413,7 +441,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsImportChatsTitle => 'İçe Aktar';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsDescription => 'Sonraki adım, seçilen dosyadan sohbetleri içe aktaracaktır. Bu işlem, şu anda mevcut olan tüm sohbetlerin üzerine yazacaktır.\nDevam etmek istiyor musunuz?';
|
||||
String get settingsImportChatsDescription =>
|
||||
'Sonraki adım, seçilen dosyadan sohbetleri içe aktaracaktır. Bu işlem, şu anda mevcut olan tüm sohbetlerin üzerine yazacaktır.\nDevam etmek istiyor musunuz?';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsImport => 'İçe Aktar ve Sil';
|
||||
|
@ -425,10 +454,12 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsImportChatsSuccess => 'Sohbetler başarıyla içe aktarıldı';
|
||||
|
||||
@override
|
||||
String get settingsExportInfo => 'Bu seçenekler, sohbet geçmişinizi dışa ve içe aktarmanıza olanak tanır. Bu, sohbet geçmişinizi başka bir cihaza aktarmak veya yedeklemek istediğinizde kullanışlı olabilir';
|
||||
String get settingsExportInfo =>
|
||||
'Bu seçenekler, sohbet geçmişinizi dışa ve içe aktarmanıza olanak tanır. Bu, sohbet geçmişinizi başka bir cihaza aktarmak veya yedeklemek istediğinizde kullanışlı olabilir';
|
||||
|
||||
@override
|
||||
String get settingsExportWarning => 'Birden fazla sohbet geçmişi birleştirilmeyecek! Yeni bir sohbet geçmişi içe aktarırsanız mevcut sohbet geçmişinizi kaybedeceksiniz';
|
||||
String get settingsExportWarning =>
|
||||
'Birden fazla sohbet geçmişi birleştirilmeyecek! Yeni bir sohbet geçmişi içe aktarırsanız mevcut sohbet geçmişinizi kaybedeceksiniz';
|
||||
|
||||
@override
|
||||
String get settingsUpdateCheck => 'Güncellemeleri kontrol et';
|
||||
|
@ -445,7 +476,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
}
|
||||
|
||||
@override
|
||||
String get settingsUpdateRateLimit => 'Kontrol edilemiyor, API hız sınırı aşıldı';
|
||||
String get settingsUpdateRateLimit =>
|
||||
'Kontrol edilemiyor, API hız sınırı aşıldı';
|
||||
|
||||
@override
|
||||
String get settingsUpdateIssue => 'Bir sorun oluştu';
|
||||
|
@ -454,7 +486,8 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String get settingsUpdateDialogTitle => 'Yeni sürüm mevcut';
|
||||
|
||||
@override
|
||||
String get settingsUpdateDialogDescription => 'Ollama\'\'nın yeni bir sürümü mevcut. Şimdi indirip kurmak istiyor musunuz?';
|
||||
String get settingsUpdateDialogDescription =>
|
||||
'Ollama\'\'nın yeni bir sürümü mevcut. Şimdi indirip kurmak istiyor musunuz?';
|
||||
|
||||
@override
|
||||
String get settingsUpdateChangeLog => 'Değişiklik Günlüğü';
|
||||
|
|
|
@ -102,7 +102,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get modelDialogAddPromptTitle => '添加新模型';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptDescription => '可以是一个普通名称(如:\'llama3\'),也可以是名称加标签(如:\'llama3:70b\')。';
|
||||
String get modelDialogAddPromptDescription =>
|
||||
'可以是一个普通名称(如:\'llama3\'),也可以是名称加标签(如:\'llama3:70b\')。';
|
||||
|
||||
@override
|
||||
String get modelDialogAddPromptAlreadyExists => '模型已存在';
|
||||
|
@ -114,7 +115,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get modelDialogAddAllowanceTitle => '允许代理服务器';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceDescription => 'Ollama 应用程序必须检查输入的模型是否有效。 为此,我们通常向Ollama模型列表发送一个网络请求并检查状态。 由于您正在使用 Web 客户端,我们不能直接做到这一点。 因此,应用将把请求发送到另一个由 JHubi 1 部署的api 上进行检查。\n这是一个一次性请求,只有当您添加一个新模型时才会发送。\n您的IP地址将与请求一起发送,可能会被存储长达10分钟,以防止潜在的有害故障。\n如果您接受,您的选择将在将来被记住;如果不接受,将不会发送任何内容,也不会添加模型。';
|
||||
String get modelDialogAddAllowanceDescription =>
|
||||
'Ollama 应用程序必须检查输入的模型是否有效。 为此,我们通常向Ollama模型列表发送一个网络请求并检查状态。 由于您正在使用 Web 客户端,我们不能直接做到这一点。 因此,应用将把请求发送到另一个由 JHubi 1 部署的api 上进行检查。\n这是一个一次性请求,只有当您添加一个新模型时才会发送。\n您的IP地址将与请求一起发送,可能会被存储长达10分钟,以防止潜在的有害故障。\n如果您接受,您的选择将在将来被记住;如果不接受,将不会发送任何内容,也不会添加模型。';
|
||||
|
||||
@override
|
||||
String get modelDialogAddAllowanceAllow => '允许';
|
||||
|
@ -156,7 +158,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get deleteDialogTitle => '删除聊天';
|
||||
|
||||
@override
|
||||
String get deleteDialogDescription => '您确定要继续吗?这将删除此聊天的所有记录,且无法撤消。\n要禁用此对话框,请访问设置。';
|
||||
String get deleteDialogDescription =>
|
||||
'您确定要继续吗?这将删除此聊天的所有记录,且无法撤消。\n要禁用此对话框,请访问设置。';
|
||||
|
||||
@override
|
||||
String get deleteDialogDelete => '删除';
|
||||
|
@ -207,7 +210,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get settingsExperimentalAlpha => 'alpha';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaDescription => '此功能处于 Alpha 测试阶段,可能无法按预期工作。\n无法排除会对设备、服务造成严重问题或永久性重大损害。\n使用需自行承担风险。应用作者不承担任何责任。';
|
||||
String get settingsExperimentalAlphaDescription =>
|
||||
'此功能处于 Alpha 测试阶段,可能无法按预期工作。\n无法排除会对设备、服务造成严重问题或永久性重大损害。\n使用需自行承担风险。应用作者不承担任何责任。';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalAlphaFeature => 'Alpha功能,按住以了解更多';
|
||||
|
@ -216,7 +220,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get settingsExperimentalBeta => 'beta';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaDescription => '此功能处于 Beta 测试阶段,可能无法按预期工作。\n可能会出现较轻微的问题,损害预期不严重。\n使用需自行承担风险。';
|
||||
String get settingsExperimentalBetaDescription =>
|
||||
'此功能处于 Beta 测试阶段,可能无法按预期工作。\n可能会出现较轻微的问题,损害预期不严重。\n使用需自行承担风险。';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalBetaFeature => 'Beta测试版功能,按住以了解更多';
|
||||
|
@ -225,7 +230,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get settingsExperimentalDeprecated => '已弃用';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedDescription => '此功能已被弃用,并将在将来的版本中删除。\n它可能无法像预期的那样工作。请自行承担风险。';
|
||||
String get settingsExperimentalDeprecatedDescription =>
|
||||
'此功能已被弃用,并将在将来的版本中删除。\n它可能无法像预期的那样工作。请自行承担风险。';
|
||||
|
||||
@override
|
||||
String get settingsExperimentalDeprecatedFeature => '已弃用的功能,按住以了解更多';
|
||||
|
@ -278,7 +284,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get settingsUseSystem => '使用系统信息';
|
||||
|
||||
@override
|
||||
String get settingsUseSystemDescription => '使用模型内嵌代替系统级别的消息。对于具有模型描述文件的模型可能会有用。';
|
||||
String get settingsUseSystemDescription =>
|
||||
'使用模型内嵌代替系统级别的消息。对于具有模型描述文件的模型可能会有用。';
|
||||
|
||||
@override
|
||||
String get settingsDisableMarkdown => '禁用Markdown';
|
||||
|
@ -331,7 +338,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get settingsTimeoutMultiplier => '超时时间倍倍数';
|
||||
|
||||
@override
|
||||
String get settingsTimeoutMultiplierDescription => '选择应用程序中每个超时时间的倍数。适用于较慢的网络连接或远程主机。';
|
||||
String get settingsTimeoutMultiplierDescription =>
|
||||
'选择应用程序中每个超时时间的倍数。适用于较慢的网络连接或远程主机。';
|
||||
|
||||
@override
|
||||
String get settingsTimeoutMultiplierExample => '例如:消息超时:';
|
||||
|
@ -364,7 +372,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get settingsTemporaryFixesDescription => '启用界面问题的临时修复。\n长按选项以了解更多信息。';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesInstructions => '不要切换这些设置,除非你知道自己在做什么!描述的行为可能不会按照预期工作。\n它们不能被视为最终结果。可能会导致一些问题。';
|
||||
String get settingsTemporaryFixesInstructions =>
|
||||
'不要切换这些设置,除非你知道自己在做什么!描述的行为可能不会按照预期工作。\n它们不能被视为最终结果。可能会导致一些问题。';
|
||||
|
||||
@override
|
||||
String get settingsTemporaryFixesNoFixes => '没有可用的修复';
|
||||
|
@ -376,7 +385,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get settingsVoiceTtsNotSupported => '不支持文本转语音';
|
||||
|
||||
@override
|
||||
String get settingsVoiceTtsNotSupportedDescription => '所选的语言不支持文字转语音服务,您可能需要选择其他语言以启用该功能。\n语音识别和 AI 等其他服务仍可正常工作,但交互可能无法流畅运行。';
|
||||
String get settingsVoiceTtsNotSupportedDescription =>
|
||||
'所选的语言不支持文字转语音服务,您可能需要选择其他语言以启用该功能。\n语音识别和 AI 等其他服务仍可正常工作,但交互可能无法流畅运行。';
|
||||
|
||||
@override
|
||||
String get settingsVoicePermissionNot => '未授予权限';
|
||||
|
@ -412,7 +422,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get settingsImportChatsTitle => '导入';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsDescription => '以下步骤将从所选文件导入聊天记录。这将覆盖所有当前的聊天记录。\n您要继续吗?';
|
||||
String get settingsImportChatsDescription =>
|
||||
'以下步骤将从所选文件导入聊天记录。这将覆盖所有当前的聊天记录。\n您要继续吗?';
|
||||
|
||||
@override
|
||||
String get settingsImportChatsImport => '导入并删除';
|
||||
|
@ -424,7 +435,8 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String get settingsImportChatsSuccess => '聊天记录导入成功';
|
||||
|
||||
@override
|
||||
String get settingsExportInfo => '这个选项允许您导出和导入您的聊天记录。如果您想将聊天记录转移到另一台设备或备份您的聊天记录,这可能会很有用。';
|
||||
String get settingsExportInfo =>
|
||||
'这个选项允许您导出和导入您的聊天记录。如果您想将聊天记录转移到另一台设备或备份您的聊天记录,这可能会很有用。';
|
||||
|
||||
@override
|
||||
String get settingsExportWarning => '多个聊天记录将不会合并!如果导入新的聊天记录,您将丢失当前的聊天记录';
|
||||
|
|
181
lib/main.dart
181
lib/main.dart
|
@ -2,43 +2,41 @@ import 'dart:convert';
|
|||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:ollama_app/l10n/gen/app_localizations.dart';
|
||||
|
||||
import 'screen_settings.dart';
|
||||
import 'screen_voice.dart';
|
||||
import 'screen_welcome.dart';
|
||||
import 'worker/setter.dart';
|
||||
import 'worker/haptic.dart';
|
||||
import 'worker/sender.dart';
|
||||
import 'worker/desktop.dart';
|
||||
import 'worker/theme.dart';
|
||||
import 'worker/update.dart';
|
||||
import 'worker/clients.dart';
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
|
||||
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:visibility_detector/visibility_detector.dart';
|
||||
import 'package:flutter_displaymode/flutter_displaymode.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:flutter_tts/flutter_tts.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:markdown/markdown.dart' as md;
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:flutter_displaymode/flutter_displaymode.dart';
|
||||
import 'package:speech_to_text/speech_to_text.dart';
|
||||
import 'package:flutter_tts/flutter_tts.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:version/version.dart';
|
||||
import 'package:pwa_install/pwa_install.dart' as pwa;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:speech_to_text/speech_to_text.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:version/version.dart';
|
||||
import 'package:visibility_detector/visibility_detector.dart';
|
||||
|
||||
import 'l10n/gen/app_localizations.dart';
|
||||
import 'screens/settings.dart';
|
||||
import 'screens/voice.dart';
|
||||
import 'screens/welcome.dart';
|
||||
import 'services/clients.dart';
|
||||
import 'services/desktop.dart';
|
||||
import 'services/haptic.dart';
|
||||
import 'services/sender.dart';
|
||||
import 'services/setter.dart';
|
||||
import 'services/theme.dart';
|
||||
import 'services/update.dart';
|
||||
|
||||
// client configuration
|
||||
|
||||
|
@ -128,13 +126,13 @@ class _AppState extends State<App> {
|
|||
void initState() {
|
||||
super.initState();
|
||||
|
||||
void load() async {
|
||||
Future<void> load() async {
|
||||
try {
|
||||
await FlutterDisplayMode.setHighRefreshRate();
|
||||
} catch (_) {}
|
||||
|
||||
SharedPreferences.setPrefix("ollama.");
|
||||
SharedPreferences tmp = await SharedPreferences.getInstance();
|
||||
var tmp = await SharedPreferences.getInstance();
|
||||
setState(() {
|
||||
prefs = tmp;
|
||||
});
|
||||
|
@ -169,7 +167,7 @@ class _AppState extends State<App> {
|
|||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
localeListResolutionCallback: (deviceLocales, supportedLocales) {
|
||||
if (deviceLocales != null) {
|
||||
for (final locale in deviceLocales) {
|
||||
for (var locale in deviceLocales) {
|
||||
var newLocale = Locale(locale.languageCode);
|
||||
if (supportedLocales.contains(newLocale)) {
|
||||
return locale;
|
||||
|
@ -179,7 +177,7 @@ class _AppState extends State<App> {
|
|||
return const Locale("en");
|
||||
},
|
||||
onGenerateTitle: (context) {
|
||||
return AppLocalizations.of(context)!.appTitle;
|
||||
return AppLocalizations.of(context).appTitle;
|
||||
},
|
||||
theme: themeLight(),
|
||||
darkTheme: themeDark(),
|
||||
|
@ -244,7 +242,7 @@ class _MainAppState extends State<MainApp> {
|
|||
child: const ImageIcon(
|
||||
AssetImage("assets/logo512.png")))),
|
||||
Expanded(
|
||||
child: Text(AppLocalizations.of(context)!.appTitle,
|
||||
child: Text(AppLocalizations.of(context).appTitle,
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.fade,
|
||||
style:
|
||||
|
@ -259,7 +257,7 @@ class _MainAppState extends State<MainApp> {
|
|||
color: desktopLayout(context)
|
||||
? Theme.of(context).colorScheme.onSurface.withAlpha(20)
|
||||
: null),
|
||||
(allowMultipleChats)
|
||||
allowMultipleChats
|
||||
? (Padding(
|
||||
padding: padding,
|
||||
child: InkWell(
|
||||
|
@ -284,7 +282,7 @@ class _MainAppState extends State<MainApp> {
|
|||
child: Icon(Icons.add_rounded)),
|
||||
Expanded(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.optionNewChat,
|
||||
AppLocalizations.of(context).optionNewChat,
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.fade,
|
||||
style:
|
||||
|
@ -293,7 +291,7 @@ class _MainAppState extends State<MainApp> {
|
|||
const SizedBox(width: 16),
|
||||
])))))
|
||||
: const SizedBox.shrink(),
|
||||
(allowSettings)
|
||||
allowSettings
|
||||
? (Padding(
|
||||
padding: padding,
|
||||
child: InkWell(
|
||||
|
@ -327,7 +325,7 @@ class _MainAppState extends State<MainApp> {
|
|||
: const Icon(Icons.dns_rounded)),
|
||||
Expanded(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.optionSettings,
|
||||
AppLocalizations.of(context).optionSettings,
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.fade,
|
||||
style:
|
||||
|
@ -368,7 +366,7 @@ class _MainAppState extends State<MainApp> {
|
|||
: const Icon(Icons.install_mobile_rounded)),
|
||||
Expanded(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.optionInstallPwa,
|
||||
AppLocalizations.of(context).optionInstallPwa,
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.fade,
|
||||
style:
|
||||
|
@ -392,9 +390,7 @@ class _MainAppState extends State<MainApp> {
|
|||
enableFeedback: false,
|
||||
customBorder: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(50))),
|
||||
onTap: () {
|
||||
selectionHaptic();
|
||||
},
|
||||
onTap: selectionHaptic,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 16, bottom: 16),
|
||||
child: Row(children: [
|
||||
|
@ -404,7 +400,7 @@ class _MainAppState extends State<MainApp> {
|
|||
color: Colors.grey)),
|
||||
Expanded(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.optionNoChatFound,
|
||||
AppLocalizations.of(context).optionNoChatFound,
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.fade,
|
||||
style: const TextStyle(
|
||||
|
@ -414,15 +410,15 @@ class _MainAppState extends State<MainApp> {
|
|||
const SizedBox(width: 16),
|
||||
]))))),
|
||||
Builder(builder: (context) {
|
||||
String tip = (tipId == 0)
|
||||
? AppLocalizations.of(context)!.tip0
|
||||
var tip = (tipId == 0)
|
||||
? AppLocalizations.of(context).tip0
|
||||
: (tipId == 1)
|
||||
? AppLocalizations.of(context)!.tip1
|
||||
? AppLocalizations.of(context).tip1
|
||||
: (tipId == 2)
|
||||
? AppLocalizations.of(context)!.tip2
|
||||
? AppLocalizations.of(context).tip2
|
||||
: (tipId == 3)
|
||||
? AppLocalizations.of(context)!.tip3
|
||||
: AppLocalizations.of(context)!.tip4;
|
||||
? AppLocalizations.of(context).tip3
|
||||
: AppLocalizations.of(context).tip4;
|
||||
return (!(prefs?.getBool("tips") ?? true) ||
|
||||
(prefs?.getStringList("chats") ?? []).isNotEmpty ||
|
||||
!allowSettings)
|
||||
|
@ -451,7 +447,7 @@ class _MainAppState extends State<MainApp> {
|
|||
color: Colors.grey)),
|
||||
Expanded(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.tipPrefix + tip,
|
||||
AppLocalizations.of(context).tipPrefix + tip,
|
||||
softWrap: true,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.fade,
|
||||
|
@ -502,11 +498,11 @@ class _MainAppState extends State<MainApp> {
|
|||
if (!allowSettings) return;
|
||||
String oldTitle = jsonDecode(item)["title"];
|
||||
var newTitle = await prompt(context,
|
||||
title: AppLocalizations.of(context)!
|
||||
title: AppLocalizations.of(context)
|
||||
.dialogEnterNewTitle,
|
||||
value: oldTitle,
|
||||
uuid: jsonDecode(item)["uuid"]);
|
||||
var tmp = (prefs!.getStringList("chats") ?? []);
|
||||
var tmp = prefs!.getStringList("chats") ?? [];
|
||||
for (var i = 0; i < tmp.length; i++) {
|
||||
if (jsonDecode((prefs!.getStringList("chats") ??
|
||||
[])[i])["uuid"] ==
|
||||
|
@ -558,13 +554,11 @@ class _MainAppState extends State<MainApp> {
|
|||
child: IconButton(
|
||||
tooltip: allowMultipleChats
|
||||
? allowSettings
|
||||
? AppLocalizations.of(
|
||||
context)!
|
||||
? AppLocalizations.of(context)
|
||||
.tooltipOptions
|
||||
: AppLocalizations.of(
|
||||
context)!
|
||||
: AppLocalizations.of(context)
|
||||
.deleteChat
|
||||
: AppLocalizations.of(context)!
|
||||
: AppLocalizations.of(context)
|
||||
.tooltipReset,
|
||||
onPressed: () {
|
||||
if (!chatAllowed &&
|
||||
|
@ -585,9 +579,9 @@ class _MainAppState extends State<MainApp> {
|
|||
"chats") ??
|
||||
[])[i])["uuid"] ==
|
||||
jsonDecode(item)["uuid"]) {
|
||||
List<String> tmp = prefs!
|
||||
.getStringList("chats")!;
|
||||
tmp.removeAt(i);
|
||||
var tmp = prefs!
|
||||
.getStringList("chats")!
|
||||
..removeAt(i);
|
||||
prefs!.setStringList(
|
||||
"chats", tmp);
|
||||
break;
|
||||
|
@ -646,7 +640,7 @@ class _MainAppState extends State<MainApp> {
|
|||
icon: const Icon(Icons
|
||||
.delete_forever_rounded),
|
||||
label: Text(
|
||||
AppLocalizations.of(context)!.deleteChat))),
|
||||
AppLocalizations.of(context).deleteChat))),
|
||||
const SizedBox(
|
||||
height: 8),
|
||||
SizedBox(
|
||||
|
@ -663,11 +657,11 @@ class _MainAppState extends State<MainApp> {
|
|||
jsonDecode(item)["title"];
|
||||
var newTitle = await prompt(
|
||||
context,
|
||||
title: AppLocalizations.of(context)!.dialogEnterNewTitle,
|
||||
title: AppLocalizations.of(context).dialogEnterNewTitle,
|
||||
value: oldTitle,
|
||||
uuid: jsonDecode(item)["uuid"]);
|
||||
var tmp =
|
||||
(prefs!.getStringList("chats") ?? []);
|
||||
prefs!.getStringList("chats") ?? [];
|
||||
for (var i = 0;
|
||||
i < tmp.length;
|
||||
i++) {
|
||||
|
@ -688,7 +682,7 @@ class _MainAppState extends State<MainApp> {
|
|||
icon: const Icon(Icons
|
||||
.edit_rounded),
|
||||
label: Text(
|
||||
AppLocalizations.of(context)!.renameChat))),
|
||||
AppLocalizations.of(context).renameChat))),
|
||||
const SizedBox(
|
||||
height: 16)
|
||||
]));
|
||||
|
@ -716,15 +710,14 @@ class _MainAppState extends State<MainApp> {
|
|||
? child
|
||||
: Dismissible(
|
||||
key: Key(jsonDecode(item)["uuid"]),
|
||||
direction: (chatAllowed)
|
||||
direction: chatAllowed
|
||||
? DismissDirection.startToEnd
|
||||
: DismissDirection.none,
|
||||
confirmDismiss: (direction) async {
|
||||
if (!chatAllowed && chatUuid == jsonDecode(item)["uuid"]) {
|
||||
return false;
|
||||
}
|
||||
return await deleteChatDialog(context, setState,
|
||||
takeAction: false);
|
||||
return deleteChatDialog(context, setState, takeAction: false);
|
||||
},
|
||||
onDismissed: (direction) {
|
||||
selectionHaptic();
|
||||
|
@ -734,8 +727,7 @@ class _MainAppState extends State<MainApp> {
|
|||
if (jsonDecode(
|
||||
(prefs!.getStringList("chats") ?? [])[i])["uuid"] ==
|
||||
jsonDecode(item)["uuid"]) {
|
||||
List<String> tmp = prefs!.getStringList("chats")!;
|
||||
tmp.removeAt(i);
|
||||
var tmp = prefs!.getStringList("chats")!..removeAt(i);
|
||||
prefs!.setStringList("chats", tmp);
|
||||
break;
|
||||
}
|
||||
|
@ -820,7 +812,7 @@ class _MainAppState extends State<MainApp> {
|
|||
// ignore: use_build_context_synchronously
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
// ignore: use_build_context_synchronously
|
||||
content: Text(AppLocalizations.of(context)!.noHostSelected),
|
||||
content: Text(AppLocalizations.of(context).noHostSelected),
|
||||
showCloseIcon: true));
|
||||
}
|
||||
|
||||
|
@ -840,7 +832,7 @@ class _MainAppState extends State<MainApp> {
|
|||
if (host == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content:
|
||||
Text(AppLocalizations.of(context)!.noHostSelected),
|
||||
Text(AppLocalizations.of(context).noHostSelected),
|
||||
showCloseIcon: true));
|
||||
return;
|
||||
}
|
||||
|
@ -860,7 +852,7 @@ class _MainAppState extends State<MainApp> {
|
|||
Flexible(
|
||||
child: Text(
|
||||
(model ??
|
||||
AppLocalizations.of(context)!.noSelectedModel)
|
||||
AppLocalizations.of(context).noSelectedModel)
|
||||
.split(":")[0],
|
||||
overflow: TextOverflow.fade,
|
||||
style: const TextStyle(
|
||||
|
@ -897,7 +889,7 @@ class _MainAppState extends State<MainApp> {
|
|||
opacity: desktopTitleVisible ? 1.0 : 0.0,
|
||||
duration: desktopTitleVisible
|
||||
? const Duration(milliseconds: 300)
|
||||
: const Duration(milliseconds: 0),
|
||||
: Duration.zero,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: selector,
|
||||
|
@ -938,7 +930,7 @@ class _MainAppState extends State<MainApp> {
|
|||
opacity: desktopTitleVisible ? 1.0 : 0.0,
|
||||
duration: desktopTitleVisible
|
||||
? const Duration(milliseconds: 300)
|
||||
: const Duration(milliseconds: 0),
|
||||
: Duration.zero,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: selector,
|
||||
|
@ -1025,8 +1017,8 @@ class _MainAppState extends State<MainApp> {
|
|||
{required messageWidth, required showName}) {
|
||||
var white =
|
||||
const TextStyle(color: Colors.white);
|
||||
bool greyed = false;
|
||||
String text = p0.text;
|
||||
var greyed = false;
|
||||
var text = p0.text;
|
||||
if (text.trim() == "") {
|
||||
text =
|
||||
"_Empty AI response, try restarting conversation_";
|
||||
|
@ -1066,7 +1058,7 @@ class _MainAppState extends State<MainApp> {
|
|||
content: Text(
|
||||
AppLocalizations.of(
|
||||
// ignore: use_build_context_synchronously
|
||||
context)!
|
||||
context)
|
||||
.settingsHostInvalid(
|
||||
"url")),
|
||||
showCloseIcon: true));
|
||||
|
@ -1089,7 +1081,7 @@ class _MainAppState extends State<MainApp> {
|
|||
.showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
context)
|
||||
.notAValidImage),
|
||||
showCloseIcon: true));
|
||||
},
|
||||
|
@ -1232,13 +1224,13 @@ class _MainAppState extends State<MainApp> {
|
|||
if (p1.author == assistant) return;
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
if (messages[i].id == p1.id) {
|
||||
List messageList =
|
||||
var messageList =
|
||||
(jsonDecode(jsonEncode(messages))
|
||||
as List)
|
||||
.reversed
|
||||
.toList();
|
||||
bool found = false;
|
||||
List index = [];
|
||||
var found = false;
|
||||
var index = [];
|
||||
for (var j = 0;
|
||||
j < messageList.length;
|
||||
j++) {
|
||||
|
@ -1285,7 +1277,7 @@ class _MainAppState extends State<MainApp> {
|
|||
(messages[index] as types.TextMessage).text;
|
||||
var input = await prompt(
|
||||
context,
|
||||
title: AppLocalizations.of(context)!
|
||||
title: AppLocalizations.of(context)
|
||||
.dialogEditMessageTitle,
|
||||
value: text,
|
||||
keyboard: TextInputType.multiline,
|
||||
|
@ -1390,7 +1382,7 @@ class _MainAppState extends State<MainApp> {
|
|||
Icons
|
||||
.headphones_rounded),
|
||||
label: Text(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsTitleVoice)))
|
||||
: const SizedBox
|
||||
.shrink(),
|
||||
|
@ -1413,7 +1405,7 @@ class _MainAppState extends State<MainApp> {
|
|||
Navigator.of(
|
||||
context)
|
||||
.pop();
|
||||
final result =
|
||||
var result =
|
||||
await ImagePicker()
|
||||
.pickImage(
|
||||
source: ImageSource
|
||||
|
@ -1424,14 +1416,14 @@ class _MainAppState extends State<MainApp> {
|
|||
return;
|
||||
}
|
||||
|
||||
final bytes =
|
||||
var bytes =
|
||||
await result
|
||||
.readAsBytes();
|
||||
final image =
|
||||
var image =
|
||||
await decodeImageFromList(
|
||||
bytes);
|
||||
|
||||
final message =
|
||||
var message =
|
||||
types
|
||||
.ImageMessage(
|
||||
author:
|
||||
|
@ -1466,7 +1458,7 @@ class _MainAppState extends State<MainApp> {
|
|||
Icons
|
||||
.photo_camera_rounded),
|
||||
label: Text(AppLocalizations.of(
|
||||
context)!
|
||||
context)
|
||||
.takeImage))),
|
||||
const SizedBox(height: 8),
|
||||
SizedBox(
|
||||
|
@ -1481,7 +1473,7 @@ class _MainAppState extends State<MainApp> {
|
|||
Navigator.of(
|
||||
context)
|
||||
.pop();
|
||||
final result =
|
||||
var result =
|
||||
await ImagePicker()
|
||||
.pickImage(
|
||||
source: ImageSource
|
||||
|
@ -1492,14 +1484,14 @@ class _MainAppState extends State<MainApp> {
|
|||
return;
|
||||
}
|
||||
|
||||
final bytes =
|
||||
var bytes =
|
||||
await result
|
||||
.readAsBytes();
|
||||
final image =
|
||||
var image =
|
||||
await decodeImageFromList(
|
||||
bytes);
|
||||
|
||||
final message =
|
||||
var message =
|
||||
types
|
||||
.ImageMessage(
|
||||
author:
|
||||
|
@ -1534,20 +1526,19 @@ class _MainAppState extends State<MainApp> {
|
|||
Icons
|
||||
.image_rounded),
|
||||
label: Text(AppLocalizations.of(
|
||||
context)!
|
||||
context)
|
||||
.uploadImage)))
|
||||
]));
|
||||
});
|
||||
},
|
||||
l10n: ChatL10nEn(
|
||||
inputPlaceholder: AppLocalizations.of(context)!
|
||||
inputPlaceholder: AppLocalizations.of(context)
|
||||
.messageInputPlaceholder,
|
||||
attachmentButtonAccessibilityLabel:
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.tooltipAttachment,
|
||||
sendButtonAccessibilityLabel:
|
||||
AppLocalizations.of(context)!
|
||||
.tooltipSend),
|
||||
AppLocalizations.of(context).tooltipSend),
|
||||
inputOptions: InputOptions(
|
||||
keyboardType: TextInputType.multiline,
|
||||
onTextChanged: (p0) {
|
||||
|
@ -1557,7 +1548,7 @@ class _MainAppState extends State<MainApp> {
|
|||
},
|
||||
sendButtonVisibilityMode: desktopFeature()
|
||||
? SendButtonVisibilityMode.always
|
||||
: (sendable)
|
||||
: sendable
|
||||
? SendButtonVisibilityMode.always
|
||||
: SendButtonVisibilityMode.hidden),
|
||||
user: user,
|
||||
|
|
|
@ -1,29 +1,26 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'main.dart';
|
||||
import 'worker/haptic.dart';
|
||||
import 'worker/update.dart';
|
||||
import 'worker/desktop.dart';
|
||||
import 'worker/setter.dart';
|
||||
|
||||
import 'package:ollama_app/l10n/gen/app_localizations.dart';
|
||||
|
||||
import 'settings/behavior.dart';
|
||||
import 'settings/interface.dart';
|
||||
import 'settings/voice.dart';
|
||||
import 'settings/export.dart';
|
||||
import 'settings/about.dart';
|
||||
|
||||
import 'package:dartx/dartx.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:dartx/dartx.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:transparent_image/transparent_image.dart';
|
||||
import 'package:version/version.dart';
|
||||
|
||||
import '../l10n/gen/app_localizations.dart';
|
||||
import '../main.dart';
|
||||
import '../services/desktop.dart';
|
||||
import '../services/haptic.dart';
|
||||
import '../services/setter.dart';
|
||||
import '../services/update.dart';
|
||||
import 'settings/about.dart';
|
||||
import 'settings/behavior.dart';
|
||||
import 'settings/export.dart';
|
||||
import 'settings/interface.dart';
|
||||
import 'settings/voice.dart';
|
||||
|
||||
Widget toggle(BuildContext context, String text, bool value,
|
||||
Function(bool value) onChanged,
|
||||
{bool disabled = false,
|
||||
|
@ -191,9 +188,7 @@ Widget button(String text, IconData? icon, void Function()? onPressed,
|
|||
}
|
||||
}
|
||||
: (onPressed == null && (onLongTap != null || onDoubleTap != null))
|
||||
? () {
|
||||
selectionHaptic();
|
||||
}
|
||||
? selectionHaptic
|
||||
: onPressed,
|
||||
onLongPress: (description != null && context != null)
|
||||
? (desktopLayoutNotRequired(context) && !alwaysMobileDescription) ||
|
||||
|
@ -321,13 +316,13 @@ class ScreenSettings extends StatefulWidget {
|
|||
|
||||
class _ScreenSettingsState extends State<ScreenSettings> {
|
||||
final hostInputController = TextEditingController(
|
||||
text: (useHost)
|
||||
text: useHost
|
||||
? fixedHost
|
||||
: (prefs?.getString("host") ?? "http://localhost:11434"));
|
||||
bool hostLoading = false;
|
||||
bool hostInvalidUrl = false;
|
||||
bool hostInvalidHost = false;
|
||||
void checkHost() async {
|
||||
Future<void> checkHost() async {
|
||||
setState(() {
|
||||
hostLoading = true;
|
||||
hostInvalidUrl = false;
|
||||
|
@ -347,7 +342,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
try {
|
||||
// don't use centralized client because of unexplainable inconsistency
|
||||
// between the ways of calling a request
|
||||
final requestBase = http.Request("get", Uri.parse(tmpHost))
|
||||
var requestBase = http.Request("get", Uri.parse(tmpHost))
|
||||
..headers.addAll(
|
||||
(jsonDecode(prefs!.getString("hostHeaders") ?? "{}") as Map)
|
||||
.cast<String, String>(),
|
||||
|
@ -395,9 +390,9 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
void initState() {
|
||||
super.initState();
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
if ((Uri.parse(hostInputController.text.trim().removeSuffix("/").trim())
|
||||
if (Uri.parse(hostInputController.text.trim().removeSuffix("/").trim())
|
||||
.toString() !=
|
||||
fixedHost)) {
|
||||
fixedHost) {
|
||||
checkHost();
|
||||
}
|
||||
}
|
||||
|
@ -425,7 +420,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(children: [
|
||||
Text(AppLocalizations.of(context)!.optionSettings),
|
||||
Text(AppLocalizations.of(context).optionSettings),
|
||||
Expanded(
|
||||
child: SizedBox(height: 200, child: MoveWindow()))
|
||||
]),
|
||||
|
@ -452,23 +447,23 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
checkHost();
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context)!
|
||||
.settingsHost,
|
||||
labelText:
|
||||
AppLocalizations.of(context).settingsHost,
|
||||
hintText: "http://localhost:11434",
|
||||
prefixIcon: IconButton(
|
||||
enableFeedback: false,
|
||||
tooltip: AppLocalizations.of(context)!
|
||||
tooltip: AppLocalizations.of(context)
|
||||
.tooltipAddHostHeaders,
|
||||
onPressed: () async {
|
||||
selectionHaptic();
|
||||
String tmp = await prompt(context,
|
||||
var tmp = await prompt(context,
|
||||
placeholder:
|
||||
"{\"Authorization\": \"Bearer ...\"}",
|
||||
title: AppLocalizations.of(context)!
|
||||
'{"Authorization": "Bearer ..."}',
|
||||
title: AppLocalizations.of(context)
|
||||
.settingsHostHeaderTitle,
|
||||
value: (prefs!
|
||||
value: prefs!
|
||||
.getString("hostHeaders") ??
|
||||
""),
|
||||
"",
|
||||
enableSuggestions: false,
|
||||
valueIfCanceled: "{}",
|
||||
validator: (content) async {
|
||||
|
@ -481,7 +476,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
}
|
||||
},
|
||||
validatorError:
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsHostHeaderInvalid,
|
||||
prefill: !((prefs!.getString(
|
||||
"hostHeaders") ??
|
||||
|
@ -500,7 +495,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
: IconButton(
|
||||
enableFeedback: false,
|
||||
tooltip:
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.tooltipSave,
|
||||
onPressed: () {
|
||||
selectionHaptic();
|
||||
|
@ -517,7 +512,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(SnackBar(
|
||||
content: Text(AppLocalizations
|
||||
.of(context)!
|
||||
.of(context)
|
||||
.settingsHostInvalidDetailed(
|
||||
hostInvalidHost
|
||||
? "host"
|
||||
|
@ -535,7 +530,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
.error),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsHostInvalid(
|
||||
hostInvalidHost
|
||||
? "host"
|
||||
|
@ -548,9 +543,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
))
|
||||
: null,
|
||||
helper: InkWell(
|
||||
onTap: () {
|
||||
selectionHaptic();
|
||||
},
|
||||
onTap: selectionHaptic,
|
||||
splashFactory: NoSplash.splashFactory,
|
||||
highlightColor: Colors.transparent,
|
||||
hoverColor: Colors.transparent,
|
||||
|
@ -561,8 +554,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
color: Colors.grey),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsHostChecking,
|
||||
style: const TextStyle(
|
||||
color: Colors.grey,
|
||||
|
@ -580,8 +572,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
.primary)),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsHostValid,
|
||||
style: TextStyle(
|
||||
color: Colors.green
|
||||
|
@ -598,7 +589,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
var column2 =
|
||||
Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
button(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsTitleBehavior,
|
||||
Icons.psychology_rounded, () {
|
||||
selectionHaptic();
|
||||
|
@ -610,9 +601,9 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
},
|
||||
context: context,
|
||||
description:
|
||||
"\n${AppLocalizations.of(context)!.settingsDescriptionBehavior}"),
|
||||
"\n${AppLocalizations.of(context).settingsDescriptionBehavior}"),
|
||||
button(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsTitleInterface,
|
||||
Icons.web_asset_rounded, () {
|
||||
selectionHaptic();
|
||||
|
@ -624,10 +615,10 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
},
|
||||
context: context,
|
||||
description:
|
||||
"\n${AppLocalizations.of(context)!.settingsDescriptionInterface}"),
|
||||
"\n${AppLocalizations.of(context).settingsDescriptionInterface}"),
|
||||
(!desktopFeature(web: true))
|
||||
? button(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsTitleVoice,
|
||||
Icons.headphones_rounded, () {
|
||||
selectionHaptic();
|
||||
|
@ -639,12 +630,12 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
},
|
||||
context: context,
|
||||
description:
|
||||
"\n${AppLocalizations.of(context)!.settingsDescriptionVoice}",
|
||||
badge: AppLocalizations.of(context)!
|
||||
"\n${AppLocalizations.of(context).settingsDescriptionVoice}",
|
||||
badge: AppLocalizations.of(context)
|
||||
.settingsExperimentalBeta)
|
||||
: const SizedBox.shrink(),
|
||||
button(
|
||||
AppLocalizations.of(context)!.settingsTitleExport,
|
||||
AppLocalizations.of(context).settingsTitleExport,
|
||||
Icons.share_rounded, () {
|
||||
selectionHaptic();
|
||||
Navigator.push(
|
||||
|
@ -655,11 +646,10 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
},
|
||||
context: context,
|
||||
description:
|
||||
"\n${AppLocalizations.of(context)!.settingsDescriptionExport}"),
|
||||
"\n${AppLocalizations.of(context).settingsDescriptionExport}"),
|
||||
Builder(builder: (context) {
|
||||
return button(
|
||||
AppLocalizations.of(context)!
|
||||
.settingsTitleAbout,
|
||||
AppLocalizations.of(context).settingsTitleAbout,
|
||||
Icons.help_rounded, () {
|
||||
selectionHaptic();
|
||||
Navigator.push(
|
||||
|
@ -670,7 +660,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
},
|
||||
context: context,
|
||||
description:
|
||||
"\n${AppLocalizations.of(context)!.settingsDescriptionAbout}",
|
||||
"\n${AppLocalizations.of(context).settingsDescriptionAbout}",
|
||||
iconBadge: (updateStatus == "ok" &&
|
||||
updateDetectedOnStart &&
|
||||
(Version.parse(
|
||||
|
@ -739,7 +729,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
offset: const Offset(0, 8),
|
||||
child: button(
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
context)
|
||||
.settingsSavedAutomatically,
|
||||
Icons.info_rounded,
|
||||
null,
|
||||
|
@ -771,7 +761,7 @@ class _ScreenSettingsState extends State<ScreenSettings> {
|
|||
desktopLayoutNotRequired(context)
|
||||
? const SizedBox.shrink()
|
||||
: button(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsSavedAutomatically,
|
||||
Icons.info_rounded,
|
||||
null,
|
|
@ -1,19 +1,17 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import '../screen_settings.dart';
|
||||
import '../worker/haptic.dart';
|
||||
import '../worker/update.dart';
|
||||
import '../worker/desktop.dart';
|
||||
|
||||
import 'package:ollama_app/l10n/gen/app_localizations.dart';
|
||||
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:simple_icons/simple_icons.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:version/version.dart';
|
||||
|
||||
import '../../l10n/gen/app_localizations.dart';
|
||||
import '../../main.dart';
|
||||
import '../../services/desktop.dart';
|
||||
import '../../services/haptic.dart';
|
||||
import '../../services/update.dart';
|
||||
import '../settings.dart';
|
||||
|
||||
class ScreenSettingsAbout extends StatefulWidget {
|
||||
const ScreenSettingsAbout({super.key});
|
||||
|
||||
|
@ -29,7 +27,7 @@ class _ScreenSettingsAboutState extends State<ScreenSettingsAbout> {
|
|||
updatesSupported(setState, true);
|
||||
setState(() {});
|
||||
|
||||
void setCurrentVersion(Function setState) async {
|
||||
Future<void> setCurrentVersion(Function setState) async {
|
||||
currentVersion = (await PackageInfo.fromPlatform()).version;
|
||||
setState(() {});
|
||||
}
|
||||
|
@ -46,7 +44,7 @@ class _ScreenSettingsAboutState extends State<ScreenSettingsAbout> {
|
|||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(children: [
|
||||
Text(AppLocalizations.of(context)!.settingsTitleAbout),
|
||||
Text(AppLocalizations.of(context).settingsTitleAbout),
|
||||
Expanded(child: SizedBox(height: 200, child: MoveWindow()))
|
||||
]),
|
||||
actions: desktopControlsActions(context)),
|
||||
|
@ -59,7 +57,7 @@ class _ScreenSettingsAboutState extends State<ScreenSettingsAbout> {
|
|||
child: ListView(children: [
|
||||
// const SizedBox(height: 8),
|
||||
button(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsVersion(currentVersion ?? ""),
|
||||
Icons.verified_rounded,
|
||||
null),
|
||||
|
@ -67,26 +65,26 @@ class _ScreenSettingsAboutState extends State<ScreenSettingsAbout> {
|
|||
? const SizedBox.shrink()
|
||||
: button(
|
||||
(!updateChecked
|
||||
? AppLocalizations.of(context)!
|
||||
? AppLocalizations.of(context)
|
||||
.settingsUpdateCheck
|
||||
: updateLoading
|
||||
? AppLocalizations.of(context)!
|
||||
? AppLocalizations.of(context)
|
||||
.settingsUpdateChecking
|
||||
: (updateStatus == "rateLimit")
|
||||
? AppLocalizations.of(context)!
|
||||
? AppLocalizations.of(context)
|
||||
.settingsUpdateRateLimit
|
||||
: (updateStatus != "ok")
|
||||
? AppLocalizations.of(context)!
|
||||
? AppLocalizations.of(context)
|
||||
.settingsUpdateIssue
|
||||
: (Version.parse(latestVersion ??
|
||||
"1.0.0") >
|
||||
Version.parse(
|
||||
currentVersion ??
|
||||
"2.0.0"))
|
||||
? AppLocalizations.of(context)!
|
||||
? AppLocalizations.of(context)
|
||||
.settingsUpdateAvailable(
|
||||
latestVersion!)
|
||||
: AppLocalizations.of(context)!
|
||||
: AppLocalizations.of(context)
|
||||
.settingsUpdateLatest),
|
||||
((updateStatus != "ok")
|
||||
? Icons.warning_rounded
|
||||
|
@ -110,41 +108,42 @@ class _ScreenSettingsAboutState extends State<ScreenSettingsAbout> {
|
|||
iconBadge: (updateStatus == "ok" &&
|
||||
updateDetectedOnStart &&
|
||||
(Version.parse(latestVersion ?? "1.0.0") >
|
||||
Version.parse(currentVersion ?? "2.0.0")))
|
||||
Version.parse(
|
||||
currentVersion ?? "2.0.0")))
|
||||
? ""
|
||||
: null),
|
||||
(updateStatus == "notAvailable")
|
||||
? const SizedBox.shrink()
|
||||
: toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsCheckForUpdates,
|
||||
(prefs!.getBool("checkUpdateOnSettingsOpen") ??
|
||||
true), (value) {
|
||||
prefs!.getBool("checkUpdateOnSettingsOpen") ??
|
||||
true, (value) {
|
||||
selectionHaptic();
|
||||
prefs!
|
||||
.setBool("checkUpdateOnSettingsOpen", value);
|
||||
setState(() {});
|
||||
}),
|
||||
titleDivider(context: context),
|
||||
button(AppLocalizations.of(context)!.settingsGithub,
|
||||
button(AppLocalizations.of(context).settingsGithub,
|
||||
SimpleIcons.github, () {
|
||||
selectionHaptic();
|
||||
launchUrl(
|
||||
mode: LaunchMode.inAppBrowserView,
|
||||
Uri.parse(repoUrl));
|
||||
}),
|
||||
button(AppLocalizations.of(context)!.settingsReportIssue,
|
||||
button(AppLocalizations.of(context).settingsReportIssue,
|
||||
Icons.report_rounded, () {
|
||||
selectionHaptic();
|
||||
launchUrl(
|
||||
mode: LaunchMode.inAppBrowserView,
|
||||
Uri.parse("$repoUrl/issues"));
|
||||
}),
|
||||
button(AppLocalizations.of(context)!.settingsLicenses,
|
||||
button(AppLocalizations.of(context).settingsLicenses,
|
||||
Icons.gavel_rounded, () {
|
||||
selectionHaptic();
|
||||
String legal = "Copyright 2024 JHubi1";
|
||||
var legal = "Copyright 2024 JHubi1";
|
||||
Widget icon = const Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: ImageIcon(AssetImage("assets/logo512.png"),
|
|
@ -1,14 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import '../worker/haptic.dart';
|
||||
import '../worker/desktop.dart';
|
||||
import '../screen_settings.dart';
|
||||
|
||||
import 'package:ollama_app/l10n/gen/app_localizations.dart';
|
||||
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../l10n/gen/app_localizations.dart';
|
||||
import '../../main.dart';
|
||||
import '../../services/desktop.dart';
|
||||
import '../../services/haptic.dart';
|
||||
import '../settings.dart';
|
||||
|
||||
class ScreenSettingsBehavior extends StatefulWidget {
|
||||
const ScreenSettingsBehavior({super.key});
|
||||
|
@ -34,7 +32,7 @@ class _ScreenSettingsBehaviorState extends State<ScreenSettingsBehavior> {
|
|||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(children: [
|
||||
Text(AppLocalizations.of(context)!.settingsTitleBehavior),
|
||||
Text(AppLocalizations.of(context).settingsTitleBehavior),
|
||||
Expanded(child: SizedBox(height: 200, child: MoveWindow()))
|
||||
]),
|
||||
actions: desktopControlsActions(context)),
|
||||
|
@ -51,14 +49,14 @@ class _ScreenSettingsBehaviorState extends State<ScreenSettingsBehavior> {
|
|||
keyboardType: TextInputType.multiline,
|
||||
maxLines: desktopLayoutNotRequired(context) ? 5 : 2,
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context)!
|
||||
labelText: AppLocalizations.of(context)
|
||||
.settingsSystemMessage,
|
||||
alignLabelWithHint: true,
|
||||
hintText: "You are a helpful assistant",
|
||||
suffixIcon: IconButton(
|
||||
enableFeedback: false,
|
||||
tooltip:
|
||||
AppLocalizations.of(context)!.tooltipSave,
|
||||
AppLocalizations.of(context).tooltipSave,
|
||||
onPressed: () {
|
||||
selectionHaptic();
|
||||
prefs?.setString(
|
||||
|
@ -73,8 +71,8 @@ class _ScreenSettingsBehaviorState extends State<ScreenSettingsBehavior> {
|
|||
const SizedBox(height: 16),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!.settingsUseSystem,
|
||||
(prefs!.getBool("useSystem") ?? true),
|
||||
AppLocalizations.of(context).settingsUseSystem,
|
||||
prefs!.getBool("useSystem") ?? true,
|
||||
(value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("useSystem", value);
|
||||
|
@ -86,14 +84,14 @@ class _ScreenSettingsBehaviorState extends State<ScreenSettingsBehavior> {
|
|||
onLongTap: () {
|
||||
selectionHaptic();
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!
|
||||
content: Text(AppLocalizations.of(context)
|
||||
.settingsUseSystemDescription),
|
||||
showCloseIcon: true));
|
||||
}),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!.settingsDisableMarkdown,
|
||||
(prefs!.getBool("noMarkdown") ?? false), (value) {
|
||||
AppLocalizations.of(context).settingsDisableMarkdown,
|
||||
prefs!.getBool("noMarkdown") ?? false, (value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("noMarkdown", value);
|
||||
setState(() {});
|
||||
|
@ -102,7 +100,7 @@ class _ScreenSettingsBehaviorState extends State<ScreenSettingsBehavior> {
|
|||
),
|
||||
const SizedBox(height: 8),
|
||||
button(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsBehaviorNotUpdatedForOlderChats,
|
||||
Icons.info_rounded,
|
||||
null,
|
|
@ -1,22 +1,20 @@
|
|||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import '../worker/haptic.dart';
|
||||
import '../worker/desktop.dart';
|
||||
import '../screen_settings.dart';
|
||||
|
||||
import 'package:ollama_app/l10n/gen/app_localizations.dart';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:file_selector/file_selector.dart' as file_selector;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
|
||||
import '../../l10n/gen/app_localizations.dart';
|
||||
import '../../main.dart';
|
||||
import '../../services/desktop.dart';
|
||||
import '../../services/haptic.dart';
|
||||
import '../settings.dart';
|
||||
|
||||
class ScreenSettingsExport extends StatefulWidget {
|
||||
const ScreenSettingsExport({super.key});
|
||||
|
@ -33,7 +31,7 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(children: [
|
||||
Text(AppLocalizations.of(context)!.settingsTitleExport),
|
||||
Text(AppLocalizations.of(context).settingsTitleExport),
|
||||
Expanded(child: SizedBox(height: 200, child: MoveWindow()))
|
||||
]),
|
||||
actions: desktopControlsActions(context)),
|
||||
|
@ -45,7 +43,7 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
Expanded(
|
||||
child: ListView(children: [
|
||||
// const SizedBox(height: 8),
|
||||
button(AppLocalizations.of(context)!.settingsExportChats,
|
||||
button(AppLocalizations.of(context).settingsExportChats,
|
||||
Icons.upload_rounded, () async {
|
||||
selectionHaptic();
|
||||
var name =
|
||||
|
@ -54,10 +52,10 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
jsonEncode(prefs!.getStringList("chats") ?? []);
|
||||
if (kIsWeb) {
|
||||
// web fallback
|
||||
final bytes = utf8.encode(content);
|
||||
final blob = html.Blob([bytes]);
|
||||
final url = html.Url.createObjectUrlFromBlob(blob);
|
||||
final anchor = html.document.createElement("a")
|
||||
var bytes = utf8.encode(content);
|
||||
var blob = html.Blob([bytes]);
|
||||
var url = html.Url.createObjectUrlFromBlob(blob);
|
||||
var anchor = html.document.createElement("a")
|
||||
as html.AnchorElement
|
||||
..href = url
|
||||
..style.display = "none"
|
||||
|
@ -95,24 +93,23 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
// ignore: use_build_context_synchronously
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
// ignore: use_build_context_synchronously
|
||||
content: Text(AppLocalizations.of(context)!
|
||||
content: Text(AppLocalizations.of(context)
|
||||
.settingsExportChatsSuccess),
|
||||
showCloseIcon: true));
|
||||
}),
|
||||
allowMultipleChats
|
||||
? button(
|
||||
AppLocalizations.of(context)!.settingsImportChats,
|
||||
AppLocalizations.of(context).settingsImportChats,
|
||||
Icons.download_rounded, () async {
|
||||
selectionHaptic();
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!
|
||||
title: Text(AppLocalizations.of(context)
|
||||
.settingsImportChatsTitle),
|
||||
content: Text(AppLocalizations.of(
|
||||
context)!
|
||||
context)
|
||||
.settingsImportChatsDescription),
|
||||
actions: [
|
||||
TextButton(
|
||||
|
@ -121,7 +118,7 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(AppLocalizations.of(
|
||||
context)!
|
||||
context)
|
||||
.settingsImportChatsCancel)),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
|
@ -132,8 +129,8 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
throw Exception(
|
||||
"web must use file picker");
|
||||
}
|
||||
file_selector.XFile? result =
|
||||
await file_selector.openFile(
|
||||
var result = await file_selector
|
||||
.openFile(
|
||||
acceptedTypeGroups: [
|
||||
const file_selector
|
||||
.XTypeGroup(
|
||||
|
@ -151,11 +148,10 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
content = await result
|
||||
.readAsString();
|
||||
} catch (_) {
|
||||
FilePickerResult? result =
|
||||
await FilePicker.platform
|
||||
var result = await FilePicker
|
||||
.platform
|
||||
.pickFiles(
|
||||
type: FileType
|
||||
.custom,
|
||||
type: FileType.custom,
|
||||
allowedExtensions: [
|
||||
"json"
|
||||
]);
|
||||
|
@ -165,7 +161,7 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
File file = File(result
|
||||
var file = File(result
|
||||
.files.single.path!);
|
||||
content = await file
|
||||
.readAsString();
|
||||
|
@ -174,12 +170,12 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
content = utf8.decode(result
|
||||
.files
|
||||
.single
|
||||
.bytes as List<int>);
|
||||
.bytes! as List<int>);
|
||||
}
|
||||
}
|
||||
List<dynamic> tmpHistory =
|
||||
jsonDecode(content);
|
||||
List<String> history = [];
|
||||
var history = <String>[];
|
||||
|
||||
for (var i = 0;
|
||||
i < tmpHistory.length;
|
||||
|
@ -206,12 +202,12 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
.showSnackBar(SnackBar(
|
||||
content: Text(AppLocalizations
|
||||
// ignore: use_build_context_synchronously
|
||||
.of(context)!
|
||||
.of(context)
|
||||
.settingsImportChatsSuccess),
|
||||
showCloseIcon: true));
|
||||
},
|
||||
child: Text(AppLocalizations.of(
|
||||
context)!
|
||||
context)
|
||||
.settingsImportChatsImport))
|
||||
]);
|
||||
});
|
||||
|
@ -220,11 +216,11 @@ class _ScreenSettingsExportState extends State<ScreenSettingsExport> {
|
|||
]),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
button(AppLocalizations.of(context)!.settingsExportInfo,
|
||||
button(AppLocalizations.of(context).settingsExportInfo,
|
||||
Icons.info_rounded, null,
|
||||
color: Colors.grey.harmonizeWith(
|
||||
Theme.of(context).colorScheme.primary)),
|
||||
button(AppLocalizations.of(context)!.settingsExportWarning,
|
||||
button(AppLocalizations.of(context).settingsExportWarning,
|
||||
Icons.warning_rounded, null,
|
||||
color: Colors.orange
|
||||
.harmonizeWith(Theme.of(context).colorScheme.primary))
|
|
@ -1,20 +1,17 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import '../worker/haptic.dart';
|
||||
import '../worker/desktop.dart';
|
||||
import '../worker/theme.dart';
|
||||
import '../screen_settings.dart';
|
||||
|
||||
import 'package:ollama_app/l10n/gen/app_localizations.dart';
|
||||
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:dartx/dartx.dart';
|
||||
import 'package:duration_picker/duration_picker.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../../l10n/gen/app_localizations.dart';
|
||||
import '../../main.dart';
|
||||
import '../../services/desktop.dart';
|
||||
import '../../services/haptic.dart';
|
||||
import '../../services/theme.dart';
|
||||
import '../settings.dart';
|
||||
|
||||
class ScreenSettingsInterface extends StatefulWidget {
|
||||
const ScreenSettingsInterface({super.key});
|
||||
|
||||
|
@ -50,7 +47,7 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(children: [
|
||||
Text(AppLocalizations.of(context)!.settingsTitleInterface),
|
||||
Text(AppLocalizations.of(context).settingsTitleInterface),
|
||||
Expanded(child: SizedBox(height: 200, child: MoveWindow()))
|
||||
]),
|
||||
actions: desktopControlsActions(context)),
|
||||
|
@ -64,25 +61,25 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
// const SizedBox(height: 8),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!.settingsShowModelTags,
|
||||
(prefs!.getBool("modelTags") ?? false), (value) {
|
||||
AppLocalizations.of(context).settingsShowModelTags,
|
||||
prefs!.getBool("modelTags") ?? false, (value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("modelTags", value);
|
||||
setState(() {});
|
||||
}),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!.settingsPreloadModels,
|
||||
(prefs!.getBool("preloadModel") ?? true), (value) {
|
||||
AppLocalizations.of(context).settingsPreloadModels,
|
||||
prefs!.getBool("preloadModel") ?? true, (value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("preloadModel", value);
|
||||
setState(() {});
|
||||
}),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsResetOnModelChange,
|
||||
(prefs!.getBool("resetOnModelSelect") ?? true),
|
||||
prefs!.getBool("resetOnModelSelect") ?? true,
|
||||
(value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("resetOnModelSelect", value);
|
||||
|
@ -95,12 +92,12 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
segments: [
|
||||
ButtonSegment(
|
||||
value: "stream",
|
||||
label: Text(AppLocalizations.of(context)!
|
||||
label: Text(AppLocalizations.of(context)
|
||||
.settingsRequestTypeStream),
|
||||
icon: const Icon(Icons.stream_rounded)),
|
||||
ButtonSegment(
|
||||
value: "request",
|
||||
label: Text(AppLocalizations.of(context)!
|
||||
label: Text(AppLocalizations.of(context)
|
||||
.settingsRequestTypeRequest),
|
||||
icon: const Icon(Icons.send_rounded))
|
||||
],
|
||||
|
@ -116,24 +113,24 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
const SizedBox(height: 16),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!.settingsGenerateTitles,
|
||||
(prefs!.getBool("generateTitles") ?? true), (value) {
|
||||
AppLocalizations.of(context).settingsGenerateTitles,
|
||||
prefs!.getBool("generateTitles") ?? true, (value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("generateTitles", value);
|
||||
setState(() {});
|
||||
}),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!.settingsEnableEditing,
|
||||
(prefs!.getBool("enableEditing") ?? true), (value) {
|
||||
AppLocalizations.of(context).settingsEnableEditing,
|
||||
prefs!.getBool("enableEditing") ?? true, (value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("enableEditing", value);
|
||||
setState(() {});
|
||||
}),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!.settingsAskBeforeDelete,
|
||||
(prefs!.getBool("askBeforeDeletion") ?? false),
|
||||
AppLocalizations.of(context).settingsAskBeforeDelete,
|
||||
prefs!.getBool("askBeforeDeletion") ?? false,
|
||||
(value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("askBeforeDeletion", value);
|
||||
|
@ -141,8 +138,8 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
}),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!.settingsShowTips,
|
||||
(prefs!.getBool("tips") ?? true), (value) {
|
||||
AppLocalizations.of(context).settingsShowTips,
|
||||
prefs!.getBool("tips") ?? true, (value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("tips", value);
|
||||
setState(() {});
|
||||
|
@ -150,7 +147,7 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
titleDivider(context: context),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsKeepModelLoadedAlways,
|
||||
int.parse(prefs!.getString("keepAlive") ?? "300") ==
|
||||
-1, (value) {
|
||||
|
@ -165,7 +162,7 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
}),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsKeepModelLoadedNever,
|
||||
int.parse(prefs!.getString("keepAlive") ?? "300") ==
|
||||
0, (value) {
|
||||
|
@ -181,17 +178,17 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
button(
|
||||
(int.parse(prefs!.getString("keepAlive") ?? "300") >
|
||||
0)
|
||||
? AppLocalizations.of(context)!
|
||||
? AppLocalizations.of(context)
|
||||
.settingsKeepModelLoadedSet((int.parse(
|
||||
prefs!.getString("keepAlive") ??
|
||||
"300") ~/
|
||||
60)
|
||||
.toString())
|
||||
: AppLocalizations.of(context)!
|
||||
: AppLocalizations.of(context)
|
||||
.settingsKeepModelLoadedFor,
|
||||
Icons.snooze_rounded, () async {
|
||||
selectionHaptic();
|
||||
bool loaded = false;
|
||||
var loaded = false;
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
|
@ -210,7 +207,7 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
WidgetsBinding.instance
|
||||
.addPostFrameCallback((timeStamp) {
|
||||
setLocalState(() {});
|
||||
void load() async {
|
||||
Future<void> load() async {
|
||||
try {
|
||||
while (int.parse(prefs!
|
||||
.getString("keepAlive")!) <
|
||||
|
@ -283,7 +280,7 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
}),
|
||||
titleDivider(context: context),
|
||||
button(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsTimeoutMultiplier,
|
||||
Icons.info_rounded,
|
||||
null,
|
||||
|
@ -291,9 +288,9 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
context: context,
|
||||
alwaysMobileDescription: true,
|
||||
description:
|
||||
"\n${AppLocalizations.of(context)!.settingsTimeoutMultiplierDescription}"),
|
||||
"\n${AppLocalizations.of(context).settingsTimeoutMultiplierDescription}"),
|
||||
Slider(
|
||||
value: (prefs!.getDouble("timeoutMultiplier") ?? 1),
|
||||
value: prefs!.getDouble("timeoutMultiplier") ?? 1,
|
||||
min: 0.5,
|
||||
divisions: 19,
|
||||
max: 10,
|
||||
|
@ -306,7 +303,7 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
setState(() {});
|
||||
}),
|
||||
button(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsTimeoutMultiplierExample,
|
||||
Icons.calculate_rounded,
|
||||
null,
|
||||
|
@ -314,7 +311,7 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
// making it complicated because web is weird and doesn't like to round numbers
|
||||
description: "\n${() {
|
||||
var value =
|
||||
(prefs!.getDouble("timeoutMultiplier") ?? 1);
|
||||
prefs!.getDouble("timeoutMultiplier") ?? 1;
|
||||
if (value == 10) {
|
||||
return "${value.round()}.";
|
||||
} else {
|
||||
|
@ -327,9 +324,9 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
titleDivider(context: context),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsEnableHapticFeedback,
|
||||
(prefs!.getBool("enableHaptic") ?? true), (value) {
|
||||
prefs!.getBool("enableHaptic") ?? true, (value) {
|
||||
prefs!.setBool("enableHaptic", value);
|
||||
selectionHaptic();
|
||||
setState(() {});
|
||||
|
@ -337,9 +334,9 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
desktopFeature()
|
||||
? toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsMaximizeOnStart,
|
||||
(prefs!.getBool("maximizeOnStart") ?? false),
|
||||
prefs!.getBool("maximizeOnStart") ?? false,
|
||||
(value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("maximizeOnStart", value);
|
||||
|
@ -351,18 +348,18 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
segments: [
|
||||
ButtonSegment(
|
||||
value: "dark",
|
||||
label: Text(AppLocalizations.of(context)!
|
||||
label: Text(AppLocalizations.of(context)
|
||||
.settingsBrightnessDark),
|
||||
icon: const Icon(Icons.brightness_4_rounded)),
|
||||
ButtonSegment(
|
||||
value: "system",
|
||||
label: Text(AppLocalizations.of(context)!
|
||||
label: Text(AppLocalizations.of(context)
|
||||
.settingsBrightnessSystem),
|
||||
icon:
|
||||
const Icon(Icons.brightness_auto_rounded)),
|
||||
ButtonSegment(
|
||||
value: "light",
|
||||
label: Text(AppLocalizations.of(context)!
|
||||
label: Text(AppLocalizations.of(context)
|
||||
.settingsBrightnessLight),
|
||||
icon: const Icon(Icons.brightness_high_rounded))
|
||||
],
|
||||
|
@ -384,12 +381,12 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
segments: [
|
||||
ButtonSegment(
|
||||
value: "device",
|
||||
label: Text(AppLocalizations.of(context)!
|
||||
label: Text(AppLocalizations.of(context)
|
||||
.settingsThemeDevice),
|
||||
icon: const Icon(Icons.devices_rounded)),
|
||||
ButtonSegment(
|
||||
value: "ollama",
|
||||
label: Text(AppLocalizations.of(context)!
|
||||
label: Text(AppLocalizations.of(context)
|
||||
.settingsThemeOllama),
|
||||
icon: const ImageIcon(
|
||||
AssetImage("assets/logo512.png")))
|
||||
|
@ -409,7 +406,7 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
: const SizedBox.shrink(),
|
||||
titleDivider(),
|
||||
button(
|
||||
AppLocalizations.of(context)!.settingsTemporaryFixes,
|
||||
AppLocalizations.of(context).settingsTemporaryFixes,
|
||||
Icons.fast_forward_rounded, () {
|
||||
selectionHaptic();
|
||||
showModalBottomSheet(
|
||||
|
@ -428,7 +425,7 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
button(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsTemporaryFixesDescription,
|
||||
Icons.info_rounded,
|
||||
null,
|
||||
|
@ -437,7 +434,7 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
.colorScheme
|
||||
.primary)),
|
||||
button(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsTemporaryFixesInstructions,
|
||||
Icons.warning_rounded,
|
||||
null,
|
||||
|
@ -454,9 +451,9 @@ class _ScreenSettingsInterfaceState extends State<ScreenSettingsInterface> {
|
|||
toggle(
|
||||
context,
|
||||
"Fixing code block not scrollable",
|
||||
(prefs!.getBool(
|
||||
prefs!.getBool(
|
||||
"fixCodeblockScroll") ??
|
||||
false), (value) {
|
||||
false, (value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool(
|
||||
"fixCodeblockScroll", value);
|
|
@ -1,17 +1,15 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:ollama_app/worker/haptic.dart';
|
||||
import 'package:ollama_app/worker/theme.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import '../screen_settings.dart';
|
||||
|
||||
import 'package:ollama_app/l10n/gen/app_localizations.dart';
|
||||
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
import '../../l10n/gen/app_localizations.dart';
|
||||
import '../../main.dart';
|
||||
import '../../services/haptic.dart';
|
||||
import '../../services/theme.dart';
|
||||
import '../settings.dart';
|
||||
|
||||
class ScreenSettingsVoice extends StatefulWidget {
|
||||
const ScreenSettingsVoice({super.key});
|
||||
|
@ -44,7 +42,7 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
|
|||
|
||||
voiceLanguageOptions = await voice.getLanguages as List;
|
||||
|
||||
for (int i = 0; i < languageOptionIds.length; i++) {
|
||||
for (var i = 0; i < languageOptionIds.length; i++) {
|
||||
if (voiceLanguageOptions
|
||||
.contains(languageOptionIds.elementAt(i).replaceAll("_", "-"))) {
|
||||
voiceLanguageOptionsAvailable.add(languageOptionIds.elementAt(i));
|
||||
|
@ -68,12 +66,12 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
|
|||
appBar: AppBar(
|
||||
title: Badge(
|
||||
label: Text(
|
||||
AppLocalizations.of(context)!.settingsExperimentalBeta),
|
||||
AppLocalizations.of(context).settingsExperimentalBeta),
|
||||
offset: const Offset(20, -4),
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
textColor: Theme.of(context).colorScheme.onPrimary,
|
||||
child:
|
||||
Text(AppLocalizations.of(context)!.settingsTitleVoice))),
|
||||
Text(AppLocalizations.of(context).settingsTitleVoice))),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.only(left: 16, right: 16),
|
||||
child: Column(children: [
|
||||
|
@ -84,31 +82,30 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
|
|||
permissionRecord &&
|
||||
voiceSupported &&
|
||||
voiceLanguageOptionsAvailable.contains(
|
||||
(prefs!.getString("voiceLanguage") ??
|
||||
"en_US"))))
|
||||
prefs!.getString("voiceLanguage") ??
|
||||
"en_US")))
|
||||
? const SizedBox.shrink()
|
||||
: button(
|
||||
permissionLoading
|
||||
? AppLocalizations.of(context)!
|
||||
? AppLocalizations.of(context)
|
||||
.settingsVoicePermissionLoading
|
||||
: (!voiceLanguageOptionsAvailable.contains(
|
||||
(prefs!.getString(
|
||||
"voiceLanguage") ??
|
||||
"en_US")) &&
|
||||
prefs!.getString("voiceLanguage") ??
|
||||
"en_US") &&
|
||||
(prefs!.getBool("voiceModeEnabled") ??
|
||||
false))
|
||||
? AppLocalizations.of(context)!
|
||||
? AppLocalizations.of(context)
|
||||
.settingsVoiceTtsNotSupported
|
||||
: !(permissionBluetooth && permissionRecord)
|
||||
? AppLocalizations.of(context)!
|
||||
? AppLocalizations.of(context)
|
||||
.settingsVoicePermissionNot
|
||||
: AppLocalizations.of(context)!
|
||||
: AppLocalizations.of(context)
|
||||
.settingsVoiceNotSupported,
|
||||
Icons.info_rounded, () {
|
||||
selectionHaptic();
|
||||
if (permissionLoading) return;
|
||||
if (!(permissionBluetooth && permissionRecord)) {
|
||||
void load() async {
|
||||
Future<void> load() async {
|
||||
try {
|
||||
if (await Permission
|
||||
.bluetooth.isPermanentlyDenied ||
|
||||
|
@ -140,18 +137,17 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
|
|||
|
||||
load();
|
||||
} else if (!voiceLanguageOptions.contains(
|
||||
(prefs!.getString("voiceLanguage") ??
|
||||
"en_US"))) {
|
||||
prefs!.getString("voiceLanguage") ?? "en_US")) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!
|
||||
content: Text(AppLocalizations.of(context)
|
||||
.settingsVoiceTtsNotSupportedDescription),
|
||||
showCloseIcon: true));
|
||||
}
|
||||
}),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!.settingsVoiceEnable,
|
||||
(prefs!.getBool("voiceModeEnabled") ?? false), (value) {
|
||||
AppLocalizations.of(context).settingsVoiceEnable,
|
||||
prefs!.getBool("voiceModeEnabled") ?? false, (value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("voiceModeEnabled", value);
|
||||
setState(() {});
|
||||
|
@ -159,10 +155,10 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
|
|||
button(
|
||||
((prefs!.getString("voiceLanguage") ?? "") == "" ||
|
||||
languageOptions.isEmpty)
|
||||
? AppLocalizations.of(context)!
|
||||
? AppLocalizations.of(context)
|
||||
.settingsVoiceNoLanguage
|
||||
: () {
|
||||
for (int i = 0;
|
||||
for (var i = 0;
|
||||
i < languageOptionIds.length;
|
||||
i++) {
|
||||
if (languageOptionIds.elementAt(i) ==
|
||||
|
@ -173,7 +169,7 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
|
|||
return "";
|
||||
}(),
|
||||
Icons.language_rounded, () {
|
||||
int usedIndex = -1;
|
||||
var usedIndex = -1;
|
||||
Function? setModalState;
|
||||
|
||||
selectionHaptic();
|
||||
|
@ -185,12 +181,12 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
|
|||
builder: (context, setLocalState) {
|
||||
setModalState = setLocalState;
|
||||
|
||||
void loadSelected() async {
|
||||
Future<void> loadSelected() async {
|
||||
await load();
|
||||
if ((prefs!.getString("voiceLanguage") ??
|
||||
"") !=
|
||||
"") {
|
||||
for (int i = 0;
|
||||
for (var i = 0;
|
||||
i < languageOptionIds.length;
|
||||
i++) {
|
||||
if (languageOptionIds.elementAt(i) ==
|
||||
|
@ -318,36 +314,34 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
|
|||
])));
|
||||
}));
|
||||
},
|
||||
disabled: (!voiceSupported ||
|
||||
!(prefs!.getBool("voiceModeEnabled") ?? false))),
|
||||
disabled: !voiceSupported ||
|
||||
!(prefs!.getBool("voiceModeEnabled") ?? false)),
|
||||
titleDivider(),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!
|
||||
.settingsVoiceLimitLanguage,
|
||||
(prefs!.getBool("voiceLimitLanguage") ?? true),
|
||||
(value) {
|
||||
AppLocalizations.of(context).settingsVoiceLimitLanguage,
|
||||
prefs!.getBool("voiceLimitLanguage") ?? true, (value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("voiceLimitLanguage", value);
|
||||
setState(() {});
|
||||
},
|
||||
disabled: (!voiceSupported ||
|
||||
!(prefs!.getBool("voiceModeEnabled") ?? false))),
|
||||
disabled: !voiceSupported ||
|
||||
!(prefs!.getBool("voiceModeEnabled") ?? false)),
|
||||
toggle(
|
||||
context,
|
||||
AppLocalizations.of(context)!.settingsVoicePunctuation,
|
||||
(prefs!.getBool("aiPunctuation") ?? true), (value) {
|
||||
AppLocalizations.of(context).settingsVoicePunctuation,
|
||||
prefs!.getBool("aiPunctuation") ?? true, (value) {
|
||||
selectionHaptic();
|
||||
prefs!.setBool("aiPunctuation", value);
|
||||
setState(() {});
|
||||
},
|
||||
disabled: (!voiceSupported ||
|
||||
!(prefs!.getBool("voiceModeEnabled") ?? false)))
|
||||
disabled: !voiceSupported ||
|
||||
!(prefs!.getBool("voiceModeEnabled") ?? false))
|
||||
]),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
button(
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.settingsExperimentalBetaFeature,
|
||||
Icons.warning_rounded,
|
||||
null,
|
||||
|
@ -356,7 +350,7 @@ class _ScreenSettingsVoiceState extends State<ScreenSettingsVoice> {
|
|||
onLongTap: () {
|
||||
selectionHaptic();
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!
|
||||
content: Text(AppLocalizations.of(context)
|
||||
.settingsExperimentalBetaDescription),
|
||||
showCloseIcon: true));
|
||||
})
|
|
@ -1,17 +1,15 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:ollama_app/worker/clients.dart';
|
||||
|
||||
import 'package:speech_to_text/speech_to_text.dart' as stt;
|
||||
import 'package:ollama_dart/ollama_dart.dart' as llama;
|
||||
import 'package:datetime_loop/datetime_loop.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:ollama_dart/ollama_dart.dart' as llama;
|
||||
import 'package:speech_to_text/speech_to_text.dart' as stt;
|
||||
|
||||
import 'package:ollama_app/l10n/gen/app_localizations.dart';
|
||||
|
||||
import 'main.dart';
|
||||
import 'worker/sender.dart';
|
||||
import 'worker/haptic.dart';
|
||||
import 'worker/setter.dart';
|
||||
import 'worker/theme.dart';
|
||||
import '../l10n/gen/app_localizations.dart';
|
||||
import '../main.dart';
|
||||
import '../services/clients.dart';
|
||||
import '../services/haptic.dart';
|
||||
import '../services/sender.dart';
|
||||
import '../services/setter.dart';
|
||||
import '../services/theme.dart';
|
||||
import 'settings/voice.dart';
|
||||
|
||||
class ScreenVoice extends StatefulWidget {
|
||||
|
@ -34,7 +32,7 @@ class _ScreenVoiceState extends State<ScreenVoice> {
|
|||
|
||||
bool intendedStop = false;
|
||||
|
||||
void process() async {
|
||||
Future<void> process() async {
|
||||
setState(() {
|
||||
speaking = true;
|
||||
sttDone = false;
|
||||
|
@ -44,7 +42,7 @@ class _ScreenVoiceState extends State<ScreenVoice> {
|
|||
text = "";
|
||||
|
||||
speech.listen(
|
||||
localeId: (prefs!.getString("voiceLanguage") ?? "en-US"),
|
||||
localeId: prefs!.getString("voiceLanguage") ?? "en-US",
|
||||
listenOptions:
|
||||
stt.SpeechListenOptions(listenMode: stt.ListenMode.dictation),
|
||||
onResult: (result) {
|
||||
|
@ -57,15 +55,15 @@ class _ScreenVoiceState extends State<ScreenVoice> {
|
|||
},
|
||||
pauseFor: const Duration(seconds: 3));
|
||||
|
||||
DateTime start = DateTime.now();
|
||||
bool timeout = false;
|
||||
var start = DateTime.now();
|
||||
var timeout = false;
|
||||
await Future.doWhile(() =>
|
||||
Future.delayed(const Duration(milliseconds: 1)).then((_) {
|
||||
if (textOld != text) {
|
||||
start = DateTime.now();
|
||||
}
|
||||
timeout =
|
||||
(DateTime.now().difference(start) >= const Duration(seconds: 3));
|
||||
DateTime.now().difference(start) >= const Duration(seconds: 3);
|
||||
textOld = text;
|
||||
return !sttDone && speaking && !timeout;
|
||||
}));
|
||||
|
@ -105,7 +103,7 @@ class _ScreenVoiceState extends State<ScreenVoice> {
|
|||
aiThinking = true;
|
||||
try {
|
||||
if (prefs!.getBool("aiPunctuation") ?? true) {
|
||||
final generated = await ollamaClient
|
||||
var generated = await ollamaClient
|
||||
.generateCompletion(
|
||||
request: llama.GenerateCompletionRequest(
|
||||
model: model!,
|
||||
|
@ -145,19 +143,20 @@ class _ScreenVoiceState extends State<ScreenVoice> {
|
|||
if ((await voice.getLanguages as List).contains(
|
||||
(prefs!.getString("voiceLanguage") ?? "en_US")
|
||||
.replaceAll("_", "-"))) {
|
||||
voice.setLanguage((prefs!.getString("voiceLanguage") ?? "en_US")
|
||||
.replaceAll("_", "-"));
|
||||
voice.setSpeechRate(0.6);
|
||||
voice.setCompletionHandler(() async {
|
||||
voice
|
||||
..setLanguage((prefs!.getString("voiceLanguage") ?? "en_US")
|
||||
.replaceAll("_", "-"))
|
||||
..setSpeechRate(0.6)
|
||||
..setCompletionHandler(() async {
|
||||
speaking = false;
|
||||
try {
|
||||
setState(() {});
|
||||
} catch (_) {}
|
||||
process();
|
||||
});
|
||||
var tmp = aiText;
|
||||
tmp.replaceAll("-", ".");
|
||||
tmp.replaceAll("*", ".");
|
||||
var tmp = aiText
|
||||
..replaceAll("-", ".")
|
||||
..replaceAll("*", ".");
|
||||
|
||||
voice.speak(tmp);
|
||||
}
|
||||
|
@ -181,11 +180,9 @@ class _ScreenVoiceState extends State<ScreenVoice> {
|
|||
void initState() {
|
||||
super.initState();
|
||||
|
||||
scrollController.addListener(() {
|
||||
updateScrollState();
|
||||
});
|
||||
scrollController.addListener(updateScrollState);
|
||||
|
||||
void load() async {
|
||||
Future<void> load() async {
|
||||
var tmp = await speech.locales();
|
||||
languageOptionIds = tmp.map((e) => e.localeId);
|
||||
languageOptions = tmp.map((e) => e.name);
|
||||
|
@ -194,7 +191,7 @@ class _ScreenVoiceState extends State<ScreenVoice> {
|
|||
|
||||
load();
|
||||
|
||||
void loadProcess() async {
|
||||
Future<void> loadProcess() async {
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
process();
|
||||
}
|
||||
|
@ -234,7 +231,7 @@ class _ScreenVoiceState extends State<ScreenVoice> {
|
|||
Expanded(
|
||||
child: Text(
|
||||
(model ??
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.noSelectedModel)
|
||||
.split(":")[0],
|
||||
textAlign: TextAlign.center,
|
||||
|
@ -288,7 +285,7 @@ class _ScreenVoiceState extends State<ScreenVoice> {
|
|||
child: AnimatedScale(
|
||||
scale: speaking
|
||||
? aiThinking
|
||||
? (dateTime.second).isEven
|
||||
? dateTime.second.isEven
|
||||
? 2.4
|
||||
: 2
|
||||
: 2
|
|
@ -1,11 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'main.dart';
|
||||
import 'worker/theme.dart';
|
||||
|
||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||
import 'package:transparent_image/transparent_image.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import '../services/theme.dart';
|
||||
|
||||
class ScreenWelcome extends StatefulWidget {
|
||||
const ScreenWelcome({super.key});
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:ollama_dart/ollama_dart.dart' as llama;
|
|
@ -1,16 +1,15 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
bool desktopFeature({bool web = false}) {
|
||||
try {
|
||||
return (Platform.isWindows ||
|
||||
return Platform.isWindows ||
|
||||
Platform.isLinux ||
|
||||
Platform.isMacOS ||
|
||||
(web ? kIsWeb : false));
|
||||
(web ? kIsWeb : false);
|
||||
} catch (_) {
|
||||
return web ? kIsWeb : false;
|
||||
}
|
||||
|
@ -19,19 +18,19 @@ bool desktopFeature({bool web = false}) {
|
|||
bool desktopLayout(BuildContext context,
|
||||
{bool web = true, double? value, double valueCap = 1000}) {
|
||||
value ??= MediaQuery.of(context).size.width;
|
||||
return (desktopFeature(web: web) || value >= valueCap);
|
||||
return desktopFeature(web: web) || value >= valueCap;
|
||||
}
|
||||
|
||||
bool desktopLayoutRequired(BuildContext context,
|
||||
{bool web = true, double? value, double valueCap = 1000}) {
|
||||
value ??= MediaQuery.of(context).size.width;
|
||||
return (desktopFeature(web: web) && value >= valueCap);
|
||||
return desktopFeature(web: web) && value >= valueCap;
|
||||
}
|
||||
|
||||
bool desktopLayoutNotRequired(BuildContext context,
|
||||
{bool web = true, double? value, double valueCap = 1000}) {
|
||||
value ??= MediaQuery.of(context).size.width;
|
||||
return (value >= valueCap);
|
||||
return value >= valueCap;
|
||||
}
|
||||
|
||||
Widget desktopControls(BuildContext context) {
|
|
@ -1,20 +1,19 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:ollama_app/worker/clients.dart';
|
||||
|
||||
import 'haptic.dart';
|
||||
import 'setter.dart';
|
||||
import '../main.dart';
|
||||
|
||||
import 'package:ollama_app/l10n/gen/app_localizations.dart';
|
||||
|
||||
import 'package:ollama_dart/ollama_dart.dart' as llama;
|
||||
import 'package:dartx/dartx.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
// not creating another dependency for this
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
|
||||
import 'package:ollama_dart/ollama_dart.dart' as llama;
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import '../l10n/gen/app_localizations.dart';
|
||||
import '../main.dart';
|
||||
import 'clients.dart';
|
||||
import 'haptic.dart';
|
||||
import 'setter.dart';
|
||||
// import 'package:scroll_to_index/scroll_to_index.dart';
|
||||
|
||||
List<String> images = [];
|
||||
|
@ -28,10 +27,10 @@ Future<List<llama.Message>> getHistory([String? addToSystem]) async {
|
|||
system += "\n$addToSystem";
|
||||
}
|
||||
|
||||
List<llama.Message> history = (prefs!.getBool("useSystem") ?? true)
|
||||
var history = (prefs!.getBool("useSystem") ?? true)
|
||||
? [llama.Message(role: llama.MessageRole.system, content: system)]
|
||||
: [];
|
||||
List<llama.Message> history2 = [];
|
||||
: <llama.Message>[];
|
||||
var history2 = <llama.Message>[];
|
||||
images = [];
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
if (jsonDecode(jsonEncode(messages[i]))["text"] != null) {
|
||||
|
@ -44,7 +43,7 @@ Future<List<llama.Message>> getHistory([String? addToSystem]) async {
|
|||
images = [];
|
||||
} else {
|
||||
var uri = jsonDecode(jsonEncode(messages[i]))["uri"] as String;
|
||||
String content = (uri.startsWith("data:image/png;base64,"))
|
||||
var content = (uri.startsWith("data:image/png;base64,"))
|
||||
? uri.removePrefix("data:image/png;base64,")
|
||||
: base64.encode(await File(uri).readAsBytes());
|
||||
uri = uri.removePrefix("data:image/png;base64,");
|
||||
|
@ -58,7 +57,7 @@ Future<List<llama.Message>> getHistory([String? addToSystem]) async {
|
|||
|
||||
List getHistoryString([String? uuid]) {
|
||||
uuid ??= chatUuid!;
|
||||
List messages = [];
|
||||
var messages = [];
|
||||
for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) {
|
||||
if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] == uuid) {
|
||||
messages = jsonDecode(
|
||||
|
@ -83,7 +82,7 @@ List getHistoryString([String? uuid]) {
|
|||
}
|
||||
|
||||
Future<String> getTitleAi(List history) async {
|
||||
final generated = await ollamaClient
|
||||
var generated = await ollamaClient
|
||||
.generateChatCompletion(
|
||||
request: llama.GenerateChatCompletionRequest(
|
||||
model: model!,
|
||||
|
@ -105,7 +104,7 @@ Future<String> getTitleAi(List history) async {
|
|||
title = title.replaceAll("\n", " ");
|
||||
|
||||
var terms = [
|
||||
"\"",
|
||||
'"',
|
||||
"'",
|
||||
"*",
|
||||
"_",
|
||||
|
@ -140,7 +139,7 @@ Future<String> getTitleAi(List history) async {
|
|||
Future<void> setTitleAi(List history) async {
|
||||
try {
|
||||
var title = await getTitleAi(history);
|
||||
var tmp = (prefs!.getStringList("chats") ?? []);
|
||||
var tmp = prefs!.getStringList("chats") ?? [];
|
||||
for (var i = 0; i < tmp.length; i++) {
|
||||
if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] ==
|
||||
chatUuid) {
|
||||
|
@ -164,7 +163,7 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
|
||||
if (host == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.noHostSelected),
|
||||
content: Text(AppLocalizations.of(context).noHostSelected),
|
||||
showCloseIcon: true));
|
||||
if (onStream != null) {
|
||||
onStream("", true);
|
||||
|
@ -175,7 +174,7 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
if (!chatAllowed || model == null) {
|
||||
if (model == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.noModelSelected),
|
||||
content: Text(AppLocalizations.of(context).noModelSelected),
|
||||
showCloseIcon: true));
|
||||
}
|
||||
if (onStream != null) {
|
||||
|
@ -184,7 +183,7 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
return "";
|
||||
}
|
||||
|
||||
bool newChat = false;
|
||||
var newChat = false;
|
||||
if (chatUuid == null) {
|
||||
newChat = true;
|
||||
chatUuid = const Uuid().v4();
|
||||
|
@ -192,7 +191,7 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
"chats",
|
||||
(prefs!.getStringList("chats") ?? []).append([
|
||||
jsonEncode({
|
||||
"title": AppLocalizations.of(context)!.newChatTitle,
|
||||
"title": AppLocalizations.of(context).newChatTitle,
|
||||
"uuid": chatUuid,
|
||||
"messages": []
|
||||
})
|
||||
|
@ -215,12 +214,12 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
setState(() {});
|
||||
chatAllowed = false;
|
||||
|
||||
String text = "";
|
||||
String newId = const Uuid().v4();
|
||||
var text = "";
|
||||
var newId = const Uuid().v4();
|
||||
|
||||
try {
|
||||
if ((prefs!.getString("requestType") ?? "stream") == "stream") {
|
||||
final stream = ollamaClient
|
||||
var stream = ollamaClient
|
||||
.generateChatCompletionStream(
|
||||
request: llama.GenerateChatCompletionRequest(
|
||||
model: model!,
|
||||
|
@ -231,8 +230,8 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
seconds: (30.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0))
|
||||
.round()));
|
||||
|
||||
await for (final res in stream) {
|
||||
text += (res.message.content);
|
||||
await for (var res in stream) {
|
||||
text += res.message.content;
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
if (messages[i].id == newId) {
|
||||
messages.removeAt(i);
|
||||
|
@ -284,7 +283,7 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
chatAllowed = true;
|
||||
messages.removeAt(0);
|
||||
if (messages.isEmpty) {
|
||||
var tmp = (prefs!.getStringList("chats") ?? []);
|
||||
var tmp = prefs!.getStringList("chats") ?? [];
|
||||
for (var i = 0; i < tmp.length; i++) {
|
||||
if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] ==
|
||||
chatUuid) {
|
||||
|
@ -300,7 +299,7 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content:
|
||||
// ignore: use_build_context_synchronously
|
||||
Text(AppLocalizations.of(context)!.settingsHostInvalid("timeout")),
|
||||
Text(AppLocalizations.of(context).settingsHostInvalid("timeout")),
|
||||
showCloseIcon: true));
|
||||
return "";
|
||||
}
|
||||
|
@ -316,7 +315,7 @@ Future<String> send(String value, BuildContext context, Function setState,
|
|||
saveChat(chatUuid!, setState);
|
||||
|
||||
if (newChat && (prefs!.getBool("generateTitles") ?? true)) {
|
||||
void setTitle() async {
|
||||
Future<void> setTitle() async {
|
||||
await setTitleAi(getHistoryString());
|
||||
setState(() {});
|
||||
}
|
|
@ -1,37 +1,35 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'desktop.dart';
|
||||
import 'haptic.dart';
|
||||
import '../main.dart';
|
||||
import 'sender.dart';
|
||||
import 'theme.dart';
|
||||
import 'clients.dart';
|
||||
|
||||
import 'package:ollama_app/l10n/gen/app_localizations.dart';
|
||||
|
||||
import 'package:dartx/dartx.dart';
|
||||
import 'package:ollama_dart/ollama_dart.dart' as llama;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:ollama_dart/ollama_dart.dart' as llama;
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import '../l10n/gen/app_localizations.dart';
|
||||
import '../main.dart';
|
||||
import 'clients.dart';
|
||||
import 'desktop.dart';
|
||||
import 'haptic.dart';
|
||||
import 'sender.dart';
|
||||
import 'theme.dart';
|
||||
|
||||
void setModel(BuildContext context, Function setState) {
|
||||
List<String> models = [];
|
||||
List<String> modelsReal = [];
|
||||
List<bool> modal = [];
|
||||
int usedIndex = -1;
|
||||
int oldIndex = -1;
|
||||
int addIndex = -1;
|
||||
bool loaded = false;
|
||||
var models = <String>[];
|
||||
var modelsReal = <String>[];
|
||||
var modal = <bool>[];
|
||||
var usedIndex = -1;
|
||||
var oldIndex = -1;
|
||||
var addIndex = -1;
|
||||
var loaded = false;
|
||||
Function? setModalState;
|
||||
desktopTitleVisible = false;
|
||||
setState(() {});
|
||||
void load() async {
|
||||
Future<void> load() async {
|
||||
try {
|
||||
var list = await ollamaClient.listModels().timeout(Duration(
|
||||
seconds:
|
||||
|
@ -42,14 +40,14 @@ void setModel(BuildContext context, Function setState) {
|
|||
models.add(list.models![i].model!.split(":")[0]);
|
||||
modelsReal.add(list.models![i].model!);
|
||||
modal.add((list.models![i].details!.families ?? []).contains("clip") ||
|
||||
(details.capabilities ?? []).contains("vision"));
|
||||
(details.capabilities ?? []).contains(llama.Capability.vision));
|
||||
}
|
||||
|
||||
addIndex = models.length;
|
||||
// ignore: use_build_context_synchronously
|
||||
models.add(AppLocalizations.of(context)!.modelDialogAddModel);
|
||||
models.add(AppLocalizations.of(context).modelDialogAddModel);
|
||||
// ignore: use_build_context_synchronously
|
||||
modelsReal.add(AppLocalizations.of(context)!.modelDialogAddModel);
|
||||
modelsReal.add(AppLocalizations.of(context).modelDialogAddModel);
|
||||
modal.add(false);
|
||||
|
||||
for (var i = 0; i < modelsReal.length; i++) {
|
||||
|
@ -59,7 +57,7 @@ void setModel(BuildContext context, Function setState) {
|
|||
}
|
||||
}
|
||||
if (prefs!.getBool("modelTags") == null) {
|
||||
List duplicateFinder = [];
|
||||
var duplicateFinder = [];
|
||||
for (var model in models) {
|
||||
if (duplicateFinder.contains(model)) {
|
||||
prefs!.setBool("modelTags", true);
|
||||
|
@ -81,7 +79,7 @@ void setModel(BuildContext context, Function setState) {
|
|||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
// ignore: use_build_context_synchronously
|
||||
AppLocalizations.of(context)!.settingsHostInvalid("timeout")),
|
||||
AppLocalizations.of(context).settingsHostInvalid("timeout")),
|
||||
showCloseIcon: true));
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +96,7 @@ void setModel(BuildContext context, Function setState) {
|
|||
onPopInvokedWithResult: (didPop, result) async {
|
||||
if (!loaded) return;
|
||||
loaded = false;
|
||||
bool preload = false;
|
||||
var preload = false;
|
||||
if (usedIndex >= 0 && modelsReal[usedIndex] != model) {
|
||||
preload = true;
|
||||
if (prefs!.getBool("resetOnModelSelect") ??
|
||||
|
@ -146,7 +144,7 @@ void setModel(BuildContext context, Function setState) {
|
|||
// ignore: use_build_context_synchronously
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
// ignore: use_build_context_synchronously
|
||||
content: Text(AppLocalizations.of(context)!
|
||||
content: Text(AppLocalizations.of(context)
|
||||
.settingsHostInvalid("timeout")),
|
||||
showCloseIcon: true));
|
||||
setState(() {
|
||||
|
@ -286,7 +284,7 @@ void setModel(BuildContext context, Function setState) {
|
|||
return Transform.translate(
|
||||
offset: desktopLayoutRequired(context)
|
||||
? const Offset(289, 0)
|
||||
: const Offset(0, 0),
|
||||
: Offset.zero,
|
||||
child: Dialog(
|
||||
surfaceTintColor:
|
||||
(Theme.of(context).brightness == Brightness.dark)
|
||||
|
@ -304,29 +302,28 @@ void setModel(BuildContext context, Function setState) {
|
|||
}
|
||||
}
|
||||
|
||||
void addModel(BuildContext context, Function setState) async {
|
||||
bool canceled = false;
|
||||
bool networkError = false;
|
||||
bool ratelimitError = false;
|
||||
bool alreadyExists = false;
|
||||
final String invalidText =
|
||||
AppLocalizations.of(context)!.modelDialogAddPromptInvalid;
|
||||
final networkErrorText =
|
||||
AppLocalizations.of(context)!.settingsHostInvalid("other");
|
||||
final timeoutErrorText =
|
||||
AppLocalizations.of(context)!.settingsHostInvalid("timeout");
|
||||
final ratelimitErrorText =
|
||||
AppLocalizations.of(context)!.settingsHostInvalid("ratelimit");
|
||||
final alreadyExistsText =
|
||||
AppLocalizations.of(context)!.modelDialogAddPromptAlreadyExists;
|
||||
final downloadSuccessText =
|
||||
AppLocalizations.of(context)!.modelDialogAddDownloadSuccess;
|
||||
final downloadFailedText =
|
||||
AppLocalizations.of(context)!.modelDialogAddDownloadFailed;
|
||||
Future<void> addModel(BuildContext context, Function setState) async {
|
||||
var canceled = false;
|
||||
var networkError = false;
|
||||
var ratelimitError = false;
|
||||
var alreadyExists = false;
|
||||
var invalidText = AppLocalizations.of(context).modelDialogAddPromptInvalid;
|
||||
var networkErrorText =
|
||||
AppLocalizations.of(context).settingsHostInvalid("other");
|
||||
var timeoutErrorText =
|
||||
AppLocalizations.of(context).settingsHostInvalid("timeout");
|
||||
var ratelimitErrorText =
|
||||
AppLocalizations.of(context).settingsHostInvalid("ratelimit");
|
||||
var alreadyExistsText =
|
||||
AppLocalizations.of(context).modelDialogAddPromptAlreadyExists;
|
||||
var downloadSuccessText =
|
||||
AppLocalizations.of(context).modelDialogAddDownloadSuccess;
|
||||
var downloadFailedText =
|
||||
AppLocalizations.of(context).modelDialogAddDownloadFailed;
|
||||
var requestedModel = await prompt(
|
||||
context,
|
||||
title: AppLocalizations.of(context)!.modelDialogAddPromptTitle,
|
||||
description: AppLocalizations.of(context)!.modelDialogAddPromptDescription,
|
||||
title: AppLocalizations.of(context).modelDialogAddPromptTitle,
|
||||
description: AppLocalizations.of(context).modelDialogAddPromptDescription,
|
||||
placeholder: "llama3:latest",
|
||||
enableSuggestions: false,
|
||||
validator: (content) async {
|
||||
|
@ -355,17 +352,17 @@ void addModel(BuildContext context, Function setState) async {
|
|||
var endpoint = "https://ollama.com/library/";
|
||||
if (kIsWeb) {
|
||||
if (!(prefs!.getBool("allowWebProxy") ?? false)) {
|
||||
bool returnValue = false;
|
||||
var returnValue = false;
|
||||
await showDialog(
|
||||
context: mainContext!,
|
||||
barrierDismissible: false,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(AppLocalizations.of(context)!
|
||||
title: Text(AppLocalizations.of(context)
|
||||
.modelDialogAddAllowanceTitle),
|
||||
content: SizedBox(
|
||||
width: 640,
|
||||
child: Text(AppLocalizations.of(context)!
|
||||
child: Text(AppLocalizations.of(context)
|
||||
.modelDialogAddAllowanceDescription),
|
||||
),
|
||||
actions: [
|
||||
|
@ -374,14 +371,14 @@ void addModel(BuildContext context, Function setState) async {
|
|||
canceled = true;
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!
|
||||
child: Text(AppLocalizations.of(context)
|
||||
.modelDialogAddAllowanceDeny)),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
returnValue = true;
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!
|
||||
child: Text(AppLocalizations.of(context)
|
||||
.modelDialogAddAllowanceAllow))
|
||||
]);
|
||||
});
|
||||
|
@ -402,17 +399,17 @@ void addModel(BuildContext context, Function setState) async {
|
|||
return false;
|
||||
}
|
||||
if (response.statusCode == 200) {
|
||||
bool returnValue = false;
|
||||
var returnValue = false;
|
||||
await showDialog(
|
||||
context: mainContext!,
|
||||
barrierDismissible: false,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(AppLocalizations.of(context)!
|
||||
title: Text(AppLocalizations.of(context)
|
||||
.modelDialogAddAssuranceTitle(model)),
|
||||
content: SizedBox(
|
||||
width: 640,
|
||||
child: Text(AppLocalizations.of(context)!
|
||||
child: Text(AppLocalizations.of(context)
|
||||
.modelDialogAddAssuranceDescription(model)),
|
||||
),
|
||||
actions: [
|
||||
|
@ -421,14 +418,14 @@ void addModel(BuildContext context, Function setState) async {
|
|||
canceled = true;
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!
|
||||
child: Text(AppLocalizations.of(context)
|
||||
.modelDialogAddAssuranceCancel)),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
returnValue = true;
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!
|
||||
child: Text(AppLocalizations.of(context)
|
||||
.modelDialogAddAssuranceAdd))
|
||||
]);
|
||||
});
|
||||
|
@ -470,9 +467,9 @@ void addModel(BuildContext context, Function setState) async {
|
|||
children: [
|
||||
Text(
|
||||
percent == null
|
||||
? AppLocalizations.of(context)!
|
||||
? AppLocalizations.of(context)
|
||||
.modelDialogAddDownloadPercentLoading
|
||||
: AppLocalizations.of(context)!
|
||||
: AppLocalizations.of(context)
|
||||
.modelDialogAddDownloadPercent(
|
||||
(percent * 100).round().toString()),
|
||||
),
|
||||
|
@ -483,15 +480,15 @@ void addModel(BuildContext context, Function setState) async {
|
|||
});
|
||||
});
|
||||
try {
|
||||
final stream = ollamaClient
|
||||
var stream = ollamaClient
|
||||
.pullModelStream(request: llama.PullModelRequest(model: requestedModel))
|
||||
.timeout(Duration(
|
||||
seconds: (10.0 * (prefs!.getDouble("timeoutMultiplier") ?? 1.0))
|
||||
.round()));
|
||||
bool alreadyProgressed = false;
|
||||
await for (final res in stream) {
|
||||
double tmpPercent =
|
||||
((res.completed ?? 0).toInt() / (res.total ?? 100).toInt());
|
||||
var alreadyProgressed = false;
|
||||
await for (var res in stream) {
|
||||
var tmpPercent =
|
||||
(res.completed ?? 0).toInt() / (res.total ?? 100).toInt();
|
||||
if ((tmpPercent * 100).round() == 0) {
|
||||
if (!alreadyProgressed) {
|
||||
percent = null;
|
||||
|
@ -511,7 +508,7 @@ void addModel(BuildContext context, Function setState) async {
|
|||
if (model!.split(":").length == 1) {
|
||||
model = "$model:latest";
|
||||
}
|
||||
bool exists = false;
|
||||
var exists = false;
|
||||
try {
|
||||
var request = await ollamaClient.listModels().timeout(Duration(
|
||||
seconds:
|
||||
|
@ -558,15 +555,15 @@ void addModel(BuildContext context, Function setState) async {
|
|||
}
|
||||
}
|
||||
|
||||
void saveChat(String uuid, Function setState) async {
|
||||
int index = -1;
|
||||
Future<void> saveChat(String uuid, Function setState) async {
|
||||
var index = -1;
|
||||
for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) {
|
||||
if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] == uuid) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
if (index == -1) return;
|
||||
List<Map<String, String>> history = [];
|
||||
var history = <Map<String, String>>[];
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
if ((jsonDecode(jsonEncode(messages[i])) as Map).containsKey("text")) {
|
||||
history.add({
|
||||
|
@ -575,7 +572,7 @@ void saveChat(String uuid, Function setState) async {
|
|||
});
|
||||
} else {
|
||||
var uri = jsonDecode(jsonEncode(messages[i]))["uri"] as String;
|
||||
String content = (uri.startsWith("data:image/png;base64,"))
|
||||
var content = (uri.startsWith("data:image/png;base64,"))
|
||||
? uri.removePrefix("data:image/png;base64,")
|
||||
: base64.encode(await File(uri).readAsBytes());
|
||||
history.add({
|
||||
|
@ -591,8 +588,7 @@ void saveChat(String uuid, Function setState) async {
|
|||
for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) {
|
||||
if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] ==
|
||||
chatUuid) {
|
||||
List<String> tmp = prefs!.getStringList("chats")!;
|
||||
tmp.removeAt(i);
|
||||
var tmp = prefs!.getStringList("chats")!..removeAt(i);
|
||||
prefs!.setStringList("chats", tmp);
|
||||
chatUuid = null;
|
||||
return;
|
||||
|
@ -621,9 +617,9 @@ void saveChat(String uuid, Function setState) async {
|
|||
history.add({"role": "system", "content": system});
|
||||
}
|
||||
history = history.reversed.toList();
|
||||
List<String> tmp = prefs!.getStringList("chats") ?? [];
|
||||
tmp.removeAt(index);
|
||||
tmp.insert(
|
||||
var tmp = prefs!.getStringList("chats") ?? []
|
||||
..removeAt(index)
|
||||
..insert(
|
||||
0,
|
||||
jsonEncode({
|
||||
"title":
|
||||
|
@ -637,7 +633,7 @@ void saveChat(String uuid, Function setState) async {
|
|||
}
|
||||
|
||||
void loadChat(String uuid, Function setState) {
|
||||
int index = -1;
|
||||
var index = -1;
|
||||
for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) {
|
||||
if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] == uuid) {
|
||||
index = i;
|
||||
|
@ -683,15 +679,14 @@ Future<bool> deleteChatDialog(BuildContext context, Function setState,
|
|||
additionalCondition ??= true;
|
||||
uuid ??= chatUuid;
|
||||
|
||||
bool returnValue = false;
|
||||
var returnValue = false;
|
||||
void delete(BuildContext context) {
|
||||
returnValue = true;
|
||||
if (takeAction) {
|
||||
for (var i = 0; i < (prefs!.getStringList("chats") ?? []).length; i++) {
|
||||
if (jsonDecode((prefs!.getStringList("chats") ?? [])[i])["uuid"] ==
|
||||
uuid) {
|
||||
List<String> tmp = prefs!.getStringList("chats")!;
|
||||
tmp.removeAt(i);
|
||||
var tmp = prefs!.getStringList("chats")!..removeAt(i);
|
||||
prefs!.setStringList("chats", tmp);
|
||||
break;
|
||||
}
|
||||
|
@ -714,9 +709,9 @@ Future<bool> deleteChatDialog(BuildContext context, Function setState,
|
|||
builder: (context) {
|
||||
return StatefulBuilder(builder: (context, setLocalState) {
|
||||
return AlertDialog(
|
||||
title: Text(AppLocalizations.of(context)!.deleteDialogTitle),
|
||||
title: Text(AppLocalizations.of(context).deleteDialogTitle),
|
||||
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
Text(AppLocalizations.of(context)!.deleteDialogDescription),
|
||||
Text(AppLocalizations.of(context).deleteDialogDescription),
|
||||
]),
|
||||
actions: [
|
||||
TextButton(
|
||||
|
@ -725,15 +720,15 @@ Future<bool> deleteChatDialog(BuildContext context, Function setState,
|
|||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.deleteDialogCancel)),
|
||||
AppLocalizations.of(context).deleteDialogCancel)),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
selectionHaptic();
|
||||
Navigator.of(context).pop();
|
||||
delete(context);
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.deleteDialogDelete))
|
||||
child:
|
||||
Text(AppLocalizations.of(context).deleteDialogDelete))
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -762,23 +757,22 @@ Future<String> prompt(BuildContext context,
|
|||
String? placeholder,
|
||||
bool prefill = true}) async {
|
||||
var returnText = (valueIfCanceled != null) ? valueIfCanceled : value;
|
||||
final TextEditingController controller =
|
||||
TextEditingController(text: prefill ? value : "");
|
||||
bool loading = false;
|
||||
var controller = TextEditingController(text: prefill ? value : "");
|
||||
var loading = false;
|
||||
String? error;
|
||||
await showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return StatefulBuilder(builder: (context, setLocalState) {
|
||||
void submit() async {
|
||||
Future<void> submit() async {
|
||||
selectionHaptic();
|
||||
if (validator != null) {
|
||||
setLocalState(() {
|
||||
error = null;
|
||||
loading = true;
|
||||
});
|
||||
bool valid = await validator(controller.text);
|
||||
var valid = await validator(controller.text);
|
||||
setLocalState(() {
|
||||
loading = false;
|
||||
});
|
||||
|
@ -841,17 +835,17 @@ Future<String> prompt(BuildContext context,
|
|||
errorText: error,
|
||||
suffixIcon: IconButton(
|
||||
enableFeedback: false,
|
||||
tooltip: AppLocalizations.of(context)!
|
||||
tooltip: AppLocalizations.of(context)
|
||||
.tooltipSave,
|
||||
onPressed: submit,
|
||||
icon: const Icon(Icons.save_rounded)),
|
||||
prefixIcon: (title ==
|
||||
AppLocalizations.of(context)!
|
||||
AppLocalizations.of(context)
|
||||
.dialogEnterNewTitle &&
|
||||
uuid != null)
|
||||
? IconButton(
|
||||
enableFeedback: false,
|
||||
tooltip: AppLocalizations.of(context)!
|
||||
tooltip: AppLocalizations.of(context)
|
||||
.tooltipLetAIThink,
|
||||
onPressed: () async {
|
||||
selectionHaptic();
|
||||
|
@ -877,7 +871,7 @@ Future<String> prompt(BuildContext context,
|
|||
content: Text(
|
||||
AppLocalizations.of(
|
||||
// ignore: use_build_context_synchronously
|
||||
context)!
|
||||
context)
|
||||
.settingsHostInvalid(
|
||||
"timeout")),
|
||||
showCloseIcon: true));
|
||||
|
@ -889,7 +883,7 @@ Future<String> prompt(BuildContext context,
|
|||
: prefixIcon)),
|
||||
SizedBox(
|
||||
height: 3,
|
||||
child: (loading)
|
||||
child: loading
|
||||
? const LinearProgressIndicator()
|
||||
: const SizedBox.shrink()),
|
||||
(MediaQuery.of(context).viewInsets.bottom != 0)
|
|
@ -2,21 +2,18 @@ import 'dart:async';
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:ollama_app/worker/clients.dart';
|
||||
import 'package:ollama_app/worker/desktop.dart';
|
||||
|
||||
import 'haptic.dart';
|
||||
|
||||
import 'package:ollama_app/l10n/gen/app_localizations.dart';
|
||||
|
||||
import '../main.dart';
|
||||
|
||||
import 'package:flutter_install_referrer/flutter_install_referrer.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:version/version.dart';
|
||||
|
||||
import '../l10n/gen/app_localizations.dart';
|
||||
import '../main.dart';
|
||||
import 'clients.dart';
|
||||
import 'desktop.dart';
|
||||
import 'haptic.dart';
|
||||
|
||||
const repoUrl = "https://github.com/JHubi1/ollama-app";
|
||||
|
||||
bool updateChecked = false;
|
||||
|
@ -28,7 +25,7 @@ String? currentVersion;
|
|||
String? updateChangeLog;
|
||||
Future<bool> updatesSupported(Function setState,
|
||||
[bool takeAction = false]) async {
|
||||
bool returnValue = true;
|
||||
var returnValue = true;
|
||||
var installerApps = [
|
||||
"org.fdroid.fdroid",
|
||||
"org.gdroid.gdroid",
|
||||
|
@ -122,22 +119,21 @@ Future<bool> checkUpdate(Function setState) async {
|
|||
updateLoading = false;
|
||||
});
|
||||
}
|
||||
return (updateStatus == "ok" &&
|
||||
return updateStatus == "ok" &&
|
||||
(Version.parse(latestVersion ?? "1.0.0") >
|
||||
Version.parse(currentVersion ?? "2.0.0")));
|
||||
Version.parse(currentVersion ?? "2.0.0"));
|
||||
}
|
||||
|
||||
void updateDialog(BuildContext context, Function title) async {
|
||||
Future<void> updateDialog(BuildContext context, Function title) async {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title:
|
||||
Text(AppLocalizations.of(context)!.settingsUpdateDialogTitle),
|
||||
title: Text(AppLocalizations.of(context).settingsUpdateDialogTitle),
|
||||
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
Text(AppLocalizations.of(context)!
|
||||
.settingsUpdateDialogDescription),
|
||||
title(AppLocalizations.of(context)!.settingsUpdateChangeLog),
|
||||
Text(
|
||||
AppLocalizations.of(context).settingsUpdateDialogDescription),
|
||||
title(AppLocalizations.of(context).settingsUpdateChangeLog),
|
||||
Flexible(
|
||||
child: SingleChildScrollView(
|
||||
child: Container(
|
||||
|
@ -153,8 +149,8 @@ void updateDialog(BuildContext context, Function title) async {
|
|||
selectionHaptic();
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!
|
||||
.settingsUpdateDialogCancel)),
|
||||
child: Text(
|
||||
AppLocalizations.of(context).settingsUpdateDialogCancel)),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
selectionHaptic();
|
||||
|
@ -164,7 +160,7 @@ void updateDialog(BuildContext context, Function title) async {
|
|||
Uri.parse(updateUrl!));
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.settingsUpdateDialogUpdate))
|
||||
AppLocalizations.of(context).settingsUpdateDialogUpdate))
|
||||
]);
|
||||
});
|
||||
}
|
20
pubspec.lock
20
pubspec.lock
|
@ -1,14 +1,6 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
animated_text_kit:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: animated_text_kit
|
||||
sha256: adba517adb7e6adeb1eb5e1c8a147dd7bc664dfdf2f5e92226b572a91393a93d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.3"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -287,7 +279,7 @@ packages:
|
|||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_chat_types:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_chat_types
|
||||
sha256: e285b588f6d19d907feb1f6d912deaf22e223656769c34093b64e1c59b094fb9
|
||||
|
@ -551,7 +543,7 @@ packages:
|
|||
source: hosted
|
||||
version: "4.0.0"
|
||||
markdown:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: markdown
|
||||
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
|
||||
|
@ -1035,14 +1027,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.3.1"
|
||||
volume_controller:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: volume_controller
|
||||
sha256: "30863a51338db47fe16f92902b1a6c4ee5e15c9287b46573d7c2eb6be1f197d2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.1"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -18,7 +18,6 @@ dependencies:
|
|||
flutter_chat_ui: ^1.6.13
|
||||
scroll_to_index: ^3.0.1
|
||||
uuid: ^4.4.0
|
||||
animated_text_kit: ^4.2.2
|
||||
image_picker: ^1.1.1
|
||||
visibility_detector: ^0.4.0+2
|
||||
http: ^1.2.1
|
||||
|
@ -44,10 +43,11 @@ dependencies:
|
|||
permission_handler: ^11.3.1
|
||||
datetime_loop: ^1.2.0
|
||||
dynamic_color: ^1.7.0
|
||||
volume_controller: ^3.3.1
|
||||
universal_html: ^2.2.4
|
||||
pwa_install: ^0.0.5
|
||||
|
||||
flutter_chat_types: any
|
||||
markdown: any
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'dart:io';
|
|||
|
||||
void main() async {
|
||||
Directory.current = Directory(Platform.script.toFilePath()).parent.parent;
|
||||
String flutterExecutable = Platform.isWindows ? 'flutter.bat' : 'flutter';
|
||||
var flutterExecutable = Platform.isWindows ? 'flutter.bat' : 'flutter';
|
||||
|
||||
print("Build script for Ollama App by JHubi1");
|
||||
print("Report issues at: https://github.com/JHubi1/ollama-app/issues");
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:ollama_app/screens/settings.dart';
|
||||
|
||||
import 'functions.dart';
|
||||
import 'package:ollama_app/screen_settings.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets("Widget: button", (WidgetTester tester) async {
|
||||
String text = random(10);
|
||||
bool clicked = false;
|
||||
var text = random(10);
|
||||
var clicked = false;
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
body: button(text, Icons.add_rounded, () {
|
||||
|
@ -23,8 +23,8 @@ void main() {
|
|||
expect(clicked, true);
|
||||
});
|
||||
testWidgets("Widget: toggle", (WidgetTester tester) async {
|
||||
String text = random(10);
|
||||
bool toggled = false;
|
||||
var text = random(10);
|
||||
var toggled = false;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(home: Scaffold(body: Builder(builder: (context) {
|
||||
return toggle(context, text, toggled, (value) {
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <flutter_tts/flutter_tts_plugin.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
#include <volume_controller/volume_controller_plugin_c_api.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
BitsdojoWindowPluginRegisterWithRegistrar(
|
||||
|
@ -27,6 +26,4 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|||
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||
VolumeControllerPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("VolumeControllerPluginCApi"));
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||
flutter_tts
|
||||
permission_handler_windows
|
||||
url_launcher_windows
|
||||
volume_controller
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
|
|
Loading…
Reference in New Issue