From 8eb3dfb35ebf73ea3bde53df00e40eed82960192 Mon Sep 17 00:00:00 2001 From: JHubi1 Date: Fri, 31 May 2024 23:57:46 +0200 Subject: [PATCH] Added export function --- lib/l10n/app_de.arb | 40 +++++++++++++++ lib/l10n/app_en.arb | 40 +++++++++++++++ lib/screen_settings.dart | 102 +++++++++++++++++++++++++++++++++++++++ lib/worker_setter.dart | 22 +++++---- pubspec.lock | 16 ++++++ pubspec.yaml | 2 + 6 files changed, 213 insertions(+), 9 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 402f868..47e7b0e 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -145,6 +145,11 @@ "description": "Title of the interface settings section", "context": "Visible in the settings view" }, + "settingsTitleExport": "Exportieren", + "@settingsTitleExport": { + "description": "Title of the export settings section", + "context": "Visible in the settings view" + }, "settingsTitleContact": "Kontakt", "@settingsTitleContact": { "description": "Title of the contact settings section", @@ -262,6 +267,41 @@ "description": "Text displayed for cancel button, should be capitalized", "context": "Visible in the settings view" }, + "settingsExportChats": "Chats exportieren", + "@settingsExportChats": { + "description": "Text displayed as description for export chats button", + "context": "Visible in the settings view" + }, + "settingsImportChats": "Chats importieren", + "@settingsImportChats": { + "description": "Text displayed as description for import chats button", + "context": "Visible in the settings view" + }, + "settingsImportChatsTitle": "Importieren", + "@settingsImportChatsTitle": { + "description": "Title of the import dialog", + "context": "Visible in the settings view" + }, + "settingsImportChatsDescription": "Der folgende Schritt importiert die Chats aus der ausgewählten Datei. Dadurch werden die aktuellen Chats überschrieben.\nMöchtest du fortfahren?", + "@settingsImportChatsDescription": { + "description": "Description of the import dialog", + "context": "Visible in the settings view" + }, + "settingsImportChatsImport": "Importieren und Löschen", + "@settingsImportChatsImport": { + "description": "Text displayed for import button, should be capitalized", + "context": "Visible in the settings view" + }, + "settingsImportChatsCancel": "Abbrechen", + "@settingsImportChatsCancel": { + "description": "Text displayed for cancel button, should be capitalized", + "context": "Visible in the settings view" + }, + "settingsImportChatsSuccess": "Chats erfolgreich importiert", + "@settingsImportChatsSuccess": { + "description": "Text displayed when chats are imported successfully", + "context": "Visible in the settings view" + }, "settingsGithub": "GitHub", "@settingsGithub": { "description": "Text displayed as description for GitHub button", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 1bbdda9..fb79641 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -145,6 +145,11 @@ "description": "Title of the interface settings section", "context": "Visible in the settings view" }, + "settingsTitleExport": "Export", + "@settingsTitleExport": { + "description": "Title of the export settings section", + "context": "Visible in the settings view" + }, "settingsTitleContact": "Contact", "@settingsTitleContact": { "description": "Title of the contact settings section", @@ -262,6 +267,41 @@ "description": "Text displayed for cancel button, should be capitalized", "context": "Visible in the settings view" }, + "settingsExportChats": "Export chats", + "@settingsExportChats": { + "description": "Text displayed as description for export chats button", + "context": "Visible in the settings view" + }, + "settingsImportChats": "Import chats", + "@settingsImportChats": { + "description": "Text displayed as description for import chats button", + "context": "Visible in the settings view" + }, + "settingsImportChatsTitle": "Import", + "@settingsImportChatsTitle": { + "description": "Title of the import dialog", + "context": "Visible in the settings view" + }, + "settingsImportChatsDescription": "The following step will import the chats from the selected file. This will overwrite the current chats.\nDo you want to continue?", + "@settingsImportChatsDescription": { + "description": "Description of the import dialog", + "context": "Visible in the settings view" + }, + "settingsImportChatsImport": "Import and Erase", + "@settingsImportChatsImport": { + "description": "Text displayed for import button, should be capitalized", + "context": "Visible in the settings view" + }, + "settingsImportChatsCancel": "Cancel", + "@settingsImportChatsCancel": { + "description": "Text displayed for cancel button, should be capitalized", + "context": "Visible in the settings view" + }, + "settingsImportChatsSuccess": "Chats imported successfully", + "@settingsImportChatsSuccess": { + "description": "Text displayed when chats are imported successfully", + "context": "Visible in the settings view" + }, "settingsGithub": "GitHub", "@settingsGithub": { "description": "Text displayed as description for GitHub button", diff --git a/lib/screen_settings.dart b/lib/screen_settings.dart index 7ad2e80..5cd31f4 100644 --- a/lib/screen_settings.dart +++ b/lib/screen_settings.dart @@ -1,8 +1,12 @@ +import 'dart:convert'; +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'main.dart'; +import 'package:intl/intl.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:dartx/dartx.dart'; @@ -10,6 +14,8 @@ import 'package:http/http.dart' as http; import 'package:simple_icons/simple_icons.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:restart_app/restart_app.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:pick_or_save/pick_or_save.dart'; class ScreenSettings extends StatefulWidget { const ScreenSettings({super.key}); @@ -398,6 +404,102 @@ class _ScreenSettingsState extends State { }); }); }), + title(AppLocalizations.of(context)!.settingsTitleExport), + InkWell( + onTap: () async { + await PickOrSave().fileSaver( + params: FileSaverParams( + mimeTypesFilter: ["application/json"], + saveFiles: [ + SaveFileInfo( + fileData: utf8.encode(jsonEncode( + prefs!.getStringList("chats") ?? [])), + fileName: + "ollama-export-${DateFormat('yyyy-MM-dd-H-m-s').format(DateTime.now())}.json") + ], + )); + }, + child: Row(children: [ + const Icon(Icons.upload_rounded), + const SizedBox(width: 16, height: 42), + Expanded( + child: Text(AppLocalizations.of(context)! + .settingsExportChats)) + ])), + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text(AppLocalizations.of(context)! + .settingsImportChatsTitle), + content: Text(AppLocalizations.of(context)! + .settingsImportChatsDescription), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text(AppLocalizations.of(context)! + .settingsImportChatsCancel)), + TextButton( + onPressed: () async { + FilePickerResult? result = + await FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: ["json"]); + if (result == null) { + // ignore: use_build_context_synchronously + Navigator.of(context).pop(); + return; + } + + File file = + File(result.files.single.path!); + var content = await file.readAsString(); + List tmpHistory = + jsonDecode(content); + List history = []; + + for (var i = 0; + i < tmpHistory.length; + i++) { + history.add(tmpHistory[i]); + } + + prefs!.setStringList("chats", history); + + messages = []; + chatUuid = null; + + setState(() {}); + + // ignore: use_build_context_synchronously + Navigator.of(context).pop(); + // ignore: use_build_context_synchronously + Navigator.of(context).pop(); + // ignore: use_build_context_synchronously + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar( + content: Text(AppLocalizations + // ignore: use_build_context_synchronously + .of(context)! + .settingsImportChatsSuccess), + showCloseIcon: true)); + }, + child: Text(AppLocalizations.of(context)! + .settingsImportChatsImport)) + ]); + }); + }, + child: Row(children: [ + const Icon(Icons.download_rounded), + const SizedBox(width: 16, height: 42), + Expanded( + child: Text(AppLocalizations.of(context)! + .settingsImportChats)) + ])), title(AppLocalizations.of(context)!.settingsTitleContact), InkWell( onTap: () { diff --git a/lib/worker_setter.dart b/lib/worker_setter.dart index f157a5e..8fe3cfd 100644 --- a/lib/worker_setter.dart +++ b/lib/worker_setter.dart @@ -90,16 +90,20 @@ void setModel(BuildContext context, Function setState) { return ChoiceChip( label: Text(models[index]), selected: usedIndex == index, - avatar: (addIndex == index) - ? const Icon(Icons.add_rounded) - : ((recommendedModels - .contains(models[index])) + avatar: (usedIndex == index) + ? null + : (addIndex == index) ? const Icon( - Icons.star_rounded) - : ((modal[index]) - ? const Icon(Icons - .collections_rounded) - : null)), + Icons.add_rounded) + : ((recommendedModels + .contains( + models[index])) + ? const Icon( + Icons.star_rounded) + : ((modal[index]) + ? const Icon(Icons + .collections_rounded) + : null)), checkmarkColor: (usedIndex == index) ? ((MediaQuery.of(context) .platformBrightness == diff --git a/pubspec.lock b/pubspec.lock index 1e8ce42..e04e43d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -145,6 +145,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + file_picker: + dependency: "direct main" + description: + name: file_picker + sha256: "29c90806ac5f5fb896547720b73b17ee9aed9bba540dc5d91fe29f8c5745b10a" + url: "https://pub.dev" + source: hosted + version: "8.0.3" file_selector_linux: dependency: transitive description: @@ -510,6 +518,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.15.0" + pick_or_save: + dependency: "direct main" + description: + name: pick_or_save + sha256: "5e562e714e8486000b1144e580dfbd6db888a0b4dd02bf4c28501b244dd22fd3" + url: "https://pub.dev" + source: hosted + version: "2.2.4" platform: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 9fc7c0c..434f665 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,6 +31,8 @@ dependencies: url_launcher: ^6.2.6 restart_app: ^1.2.1 flutter_markdown: ^0.7.1 + file_picker: ^8.0.3 + pick_or_save: ^2.2.4 dev_dependencies: flutter_test: