diff --git a/README.md b/README.md index d8502e9..97840e2 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ That's it, you can now just chat. Enter a message into the box at the bottom and ## Side Menu -The button on the top left opens the menu. In it, you have two options for now: `New Chat` and `Settings`. The first option clears the chat (-> creates a new one), and the second one reopens the host dialog from the initial start of the app to adapt to changing hosts. +The button on the top left opens the menu. In it, you have three options: `New Chat`, `Ask before Deletion` and `Set Host`. The first option clears the chat (-> creates a new one), the second one opens a new dialog that has a toggle you can toggle if you don't want to be asked or want to be asked again before deleting a chat, and the third option reopens the host dialog from the initial start of the app to adapt to changing hosts. ![side menu](assets/screenshots/other/s02.png) diff --git a/assets/screenshots/other/s02.png b/assets/screenshots/other/s02.png index 005a5a3..98e0ee2 100644 Binary files a/assets/screenshots/other/s02.png and b/assets/screenshots/other/s02.png differ diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index fd028c6..20fe960 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -5,16 +5,21 @@ "description": "Title of the application", "context": "Visible in the side bar" }, - "optionSettings": "Einstellungen", - "@optionSettings": { - "description": "Text displayed for settings option", - "context": "Visible in the side bar" - }, "optionNewChat": "Neuer Chat", "@optionNewChat": { "description": "Text displayed for new chat option", "context": "Visible in the side bar" }, + "optionSetHost": "Host Setzen", + "@optionSetHost": { + "description": "Text displayed for set host option", + "context": "Visible in the side bar" + }, + "optionSetAskDeletion": "Vor dem Löschen fragen", + "@optionSetAskDeletion": { + "description": "Text displayed for ask before deletion option", + "context": "Visible in the side bar" + }, "takeImage": "Bild Aufnehmen", "@takeImage": { "description": "Text displayed for take image button", @@ -35,7 +40,7 @@ "description": "Text displayed when no model is selected", "context": "Visible in the chat view" }, - "hostDialogTitle": "Host Festlegen", + "hostDialogTitle": "Host Setzen", "@hostDialogTitle": { "description": "Title of the host dialog", "context": "Visible in the host dialog" @@ -60,6 +65,11 @@ "description": "Text displayed for save host button, should be capitalized", "context": "Visible in the host dialog" }, + "hostDialogCancel": "Abbrechen", + "@hostDialogCancel": { + "description": "Text displayed for cancel button, should be capitalized", + "context": "Visible in the host dialog" + }, "noSelectedModel": "", "@noSelectedModel": { "description": "Text displayed when no model is selected", @@ -74,5 +84,30 @@ "@modelDialogAddSteps": { "description": "Steps to add a new model", "context": "Visible in the model dialog" + }, + "deleteDialogTitle": "Löschen Bestätigen", + "@deleteDialogTitle": { + "description": "Title of the delete dialog", + "context": "Visible in the delete dialog" + }, + "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.", + "@deleteDialogDescription": { + "description": "Description of the delete dialog", + "context": "Visible in the delete dialog" + }, + "deleteDialogDelete": "Löschen", + "@deleteDialogDelete": { + "description": "Text displayed for delete button, should be capitalized", + "context": "Visible in the delete dialog" + }, + "deleteDialogCancel": "Abbrechen", + "@deleteDialogCancel": { + "description": "Text displayed for cancel button, should be capitalized", + "context": "Visible in the delete dialog" + }, + "deleteDialogAskAlways": "Jedesmal nachfragen", + "@deleteDialogAskAlways": { + "description": "Text displayed for ask me always again checkbox", + "context": "Visible in the delete dialog" } } \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 6fc224b..488040d 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -5,16 +5,21 @@ "description": "Title of the application", "context": "Visible in the side bar" }, - "optionSettings": "Settings", - "@optionSettings": { - "description": "Text displayed for settings option", - "context": "Visible in the side bar" - }, "optionNewChat": "New Chat", "@optionNewChat": { "description": "Text displayed for new chat option", "context": "Visible in the side bar" }, + "optionSetHost": "Set Host", + "@optionSetHost": { + "description": "Text displayed for set host option", + "context": "Visible in the side bar" + }, + "optionSetAskDeletion": "Ask before Deletion", + "@optionSetAskDeletion": { + "description": "Text displayed for ask before deletion option", + "context": "Visible in the side bar" + }, "takeImage": "Take Image", "@takeImage": { "description": "Text displayed for take image button", @@ -79,5 +84,30 @@ "@modelDialogAddSteps": { "description": "Steps to add a new model", "context": "Visible in the model dialog" + }, + "deleteDialogTitle": "Confirm Deletion", + "@deleteDialogTitle": { + "description": "Title of the delete dialog", + "context": "Visible in the delete dialog" + }, + "deleteDialogDescription": "Are you sure you want to continue? This will wipe all memory of this chat and cannot be undone.", + "@deleteDialogDescription": { + "description": "Description of the delete dialog", + "context": "Visible in the delete dialog" + }, + "deleteDialogDelete": "Delete", + "@deleteDialogDelete": { + "description": "Text displayed for delete button, should be capitalized", + "context": "Visible in the delete dialog" + }, + "deleteDialogCancel": "Cancel", + "@deleteDialogCancel": { + "description": "Text displayed for cancel button, should be capitalized", + "context": "Visible in the delete dialog" + }, + "deleteDialogAskAlways": "Ask me every time", + "@deleteDialogAskAlways": { + "description": "Text displayed for ask me always again checkbox", + "context": "Visible in the delete dialog" } } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 0bd11f6..44ea751 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -209,7 +209,7 @@ class _MainAppState extends State { onPressed: () { HapticFeedback.selectionClick(); if (!chatAllowed) return; - messages = []; + deleteChat(context, setState); setState(() {}); }, icon: const Icon(Icons.restart_alt_rounded)) @@ -497,9 +497,12 @@ class _MainAppState extends State { HapticFeedback.selectionClick(); Navigator.of(context).pop(); if (!chatAllowed) return; - messages = []; - setState(() {}); + deleteChat(context, setState); } else if (value == 2) { + HapticFeedback.selectionClick(); + Navigator.of(context).pop(); + setAskBeforeDeletion(context, setState); + } else if (value == 3) { HapticFeedback.selectionClick(); Navigator.of(context).pop(); if (!chatAllowed) return; @@ -517,11 +520,15 @@ class _MainAppState extends State { NavigationDrawerDestination( icon: const Icon(Icons.add_rounded), label: Text(AppLocalizations.of(context)!.optionNewChat)), + NavigationDrawerDestination( + icon: const Icon(Icons.live_help_rounded), + label: + Text(AppLocalizations.of(context)!.optionSetAskDeletion)), (useHost) ? const SizedBox.shrink() : NavigationDrawerDestination( - icon: const Icon(Icons.settings_rounded), - label: Text(AppLocalizations.of(context)!.optionSettings)) + icon: const Icon(Icons.dns_rounded), + label: Text(AppLocalizations.of(context)!.optionSetHost)), ])); } } diff --git a/lib/worker_setter.dart b/lib/worker_setter.dart index df104b4..d5900c1 100644 --- a/lib/worker_setter.dart +++ b/lib/worker_setter.dart @@ -52,6 +52,14 @@ void setHost(BuildContext context, [bool force = true]) { hintText: "http://example.com:8080")) ]), actions: [ + !force + ? TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text( + AppLocalizations.of(context)!.hostDialogCancel)) + : const SizedBox.shrink(), TextButton( onPressed: () async { setState(() { @@ -108,15 +116,7 @@ void setHost(BuildContext context, [bool force = true]) { } }, child: - Text(AppLocalizations.of(context)!.hostDialogSave)), - !force - ? TextButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: Text( - AppLocalizations.of(context)!.hostDialogCancel)) - : const SizedBox.shrink() + Text(AppLocalizations.of(context)!.hostDialogSave)) ])))); } @@ -269,3 +269,82 @@ void setModel(BuildContext context, Function setState) { }); }); } + +void deleteChat(BuildContext context, Function setState) { + if (prefs!.getBool("askBeforeDeletion") ?? true && messages.isNotEmpty) { + showDialog( + context: context, + builder: (context) { + return StatefulBuilder(builder: (context, setLocalState) { + return AlertDialog( + title: Text(AppLocalizations.of(context)!.deleteDialogTitle), + content: Column(mainAxisSize: MainAxisSize.min, children: [ + Text(AppLocalizations.of(context)!.deleteDialogDescription), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text(AppLocalizations.of(context)! + .deleteDialogAskAlways), + const Expanded(child: SizedBox()), + Switch( + value: prefs!.getBool("askBeforeDeletion") ?? true, + onChanged: (value) { + prefs!.setBool("askBeforeDeletion", value); + setLocalState(() {}); + }, + ) + ]) + ]), + actions: [ + TextButton( + onPressed: () { + HapticFeedback.selectionClick(); + Navigator.of(context).pop(); + }, + child: Text( + AppLocalizations.of(context)!.deleteDialogCancel)), + TextButton( + onPressed: () { + HapticFeedback.selectionClick(); + Navigator.of(context).pop(); + messages = []; + setState(() {}); + }, + child: Text( + AppLocalizations.of(context)!.deleteDialogDelete)) + ]); + }); + }); + } else { + messages = []; + setState(() {}); + } +} + +void setAskBeforeDeletion(BuildContext context, Function setState) { + showDialog( + context: context, + builder: (context) { + return StatefulBuilder(builder: (context, setLocalState) { + return Dialog( + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text(AppLocalizations.of(context)! + .deleteDialogAskAlways), + const Expanded(child: SizedBox()), + Switch( + value: prefs!.getBool("askBeforeDeletion") ?? true, + onChanged: (value) { + prefs!.setBool("askBeforeDeletion", value); + setLocalState(() {}); + }, + ) + ]))); + }); + }); +}