From a339c6c9df27d535ce74dbe0a095aca2b4fc80da Mon Sep 17 00:00:00 2001 From: otsmr Date: Tue, 3 Jun 2025 15:30:14 +0200 Subject: [PATCH] fix #190 --- lib/src/localization/app_de.arb | 6 +++- lib/src/localization/app_en.arb | 6 +++- .../generated/app_localizations.dart | 24 +++++++++++++ .../generated/app_localizations_de.dart | 12 +++++++ .../generated/app_localizations_en.dart | 12 +++++++ .../memories/memories_photo_slider.view.dart | 34 ++++++++++++++++++- 6 files changed, 91 insertions(+), 3 deletions(-) diff --git a/lib/src/localization/app_de.arb b/lib/src/localization/app_de.arb index 8407526..3af5392 100644 --- a/lib/src/localization/app_de.arb +++ b/lib/src/localization/app_de.arb @@ -243,6 +243,8 @@ "planNotAllowed": "In deinem aktuellen Plan kannst du keine Mediendateien versenden. Aktualisiere deinen Plan jetzt, um die Mediendatei zu senden.", "planLimitReached": "Du hast dein Planlimit für heute erreicht. Aktualisiere deinen Plan jetzt, um die Mediendatei zu senden.", "galleryDelete": "Datei löschen", + "galleryExport": "In Galerie exportieren", + "galleryExportSuccess": "Erfolgreich in der Gallery gespeichert.", "galleryDetails": "Details anzeigen", "settingsResetTutorials": "Tutorials erneut anzeigen", "settingsResetTutorialsDesc": "Klicke hier, um bereits angezeigte Tutorials erneut anzuzeigen.", @@ -255,5 +257,7 @@ "tutorialChatMessagesVerifyShieldDesc": "twonly nutzt das Signal-Protokoll für eine sichere Ende-zu-Ende Verschlüsselung. Bei der ersten Kontaktaufnahme wird dafür der öffentliche Identitätsschlüssel von deinem Kontakt heruntergeladen. Um sicherzustellen, dass dieser Schlüssel nicht von Dritten ausgetauscht wurde, solltest du ihn mit deinem Freund vergleichen, wenn ihr euch persönlich trefft. Sobald du den Benutzer verifiziert hast, kannst du auch beim verschicken von Bildern und Videos den twonly-Modus aktivieren.", "tutorialChatMessagesReopenMessageTitle": "Bilder und Videos erneut öffnen", "tutorialChatMessagesReopenMessageDesc": "Wenn dein Freund dir ein Bild oder Video mit unendlicher Anzeigezeit gesendet hat, kannst du es bis zum Neustart der App jederzeit erneut öffnen. Um dies zu tun, musst du einfach doppelt auf die Nachricht klicken. Dein Freund erhält dann eine Benachrichtigung, dass du das Bild erneut angesehen hast.", - "memoriesEmpty": "Sobald du Bilder oder Videos speicherst, landen sie hier in deinen Erinnerungen." + "memoriesEmpty": "Sobald du Bilder oder Videos speicherst, landen sie hier in deinen Erinnerungen.", + "deleteImageTitle": "Bist du dir sicher?", + "deleteImageBody": "Das Bild wird unwiderruflich gelöscht." } \ No newline at end of file diff --git a/lib/src/localization/app_en.arb b/lib/src/localization/app_en.arb index befc3cf..0c0b161 100644 --- a/lib/src/localization/app_en.arb +++ b/lib/src/localization/app_en.arb @@ -403,6 +403,8 @@ "planNotAllowed": "You cannot send media files with your current tariff. Upgrade your plan now to send the media file.", "galleryDelete": "Delete file", "galleryDetails": "Show details", + "galleryExport": "Export to gallery", + "galleryExportSuccess": "Successfully saved in the Gallery.", "settingsResetTutorials": "Show tutorials again", "settingsResetTutorialsDesc": "Click here to show already displayed tutorials again.", "settingsResetTutorialsSuccess": "Tutorials will be displayed again.", @@ -414,5 +416,7 @@ "tutorialChatMessagesVerifyShieldDesc": "twonly uses the Signal protocol for secure end-to-end encryption. When you first contact someone, their public identity key is downloaded. To ensure that this key has not been tampered with by third parties, you should compare it with your friend when you meet in person. Once you have verified the user, you can also enable the twonly mode when sending images and videos.", "tutorialChatMessagesReopenMessageTitle": "Reopen Images and Videos", "tutorialChatMessagesReopenMessageDesc": "If your friend has sent you a picture or video with infinite display time, you can open it again at any time until you restart the app. To do this, simply double-click on the message. Your friend will then receive a notification that you have viewed the picture again.", - "memoriesEmpty": "As soon as you save pictures or videos, they end up here in your memories." + "memoriesEmpty": "As soon as you save pictures or videos, they end up here in your memories.", + "deleteImageTitle": "Are you sure?", + "deleteImageBody": "The image will be irrevocably deleted." } \ No newline at end of file diff --git a/lib/src/localization/generated/app_localizations.dart b/lib/src/localization/generated/app_localizations.dart index ed9327d..809fe79 100644 --- a/lib/src/localization/generated/app_localizations.dart +++ b/lib/src/localization/generated/app_localizations.dart @@ -1478,6 +1478,18 @@ abstract class AppLocalizations { /// **'Show details'** String get galleryDetails; + /// No description provided for @galleryExport. + /// + /// In en, this message translates to: + /// **'Export to gallery'** + String get galleryExport; + + /// No description provided for @galleryExportSuccess. + /// + /// In en, this message translates to: + /// **'Successfully saved in the Gallery.'** + String get galleryExportSuccess; + /// No description provided for @settingsResetTutorials. /// /// In en, this message translates to: @@ -1549,6 +1561,18 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'As soon as you save pictures or videos, they end up here in your memories.'** String get memoriesEmpty; + + /// No description provided for @deleteImageTitle. + /// + /// In en, this message translates to: + /// **'Are you sure?'** + String get deleteImageTitle; + + /// No description provided for @deleteImageBody. + /// + /// In en, this message translates to: + /// **'The image will be irrevocably deleted.'** + String get deleteImageBody; } class _AppLocalizationsDelegate diff --git a/lib/src/localization/generated/app_localizations_de.dart b/lib/src/localization/generated/app_localizations_de.dart index d980bcc..8e7f3a5 100644 --- a/lib/src/localization/generated/app_localizations_de.dart +++ b/lib/src/localization/generated/app_localizations_de.dart @@ -775,6 +775,12 @@ class AppLocalizationsDe extends AppLocalizations { @override String get galleryDetails => 'Details anzeigen'; + @override + String get galleryExport => 'In Galerie exportieren'; + + @override + String get galleryExportSuccess => 'Erfolgreich in der Gallery gespeichert.'; + @override String get settingsResetTutorials => 'Tutorials erneut anzeigen'; @@ -821,4 +827,10 @@ class AppLocalizationsDe extends AppLocalizations { @override String get memoriesEmpty => 'Sobald du Bilder oder Videos speicherst, landen sie hier in deinen Erinnerungen.'; + + @override + String get deleteImageTitle => 'Bist du dir sicher?'; + + @override + String get deleteImageBody => 'Das Bild wird unwiderruflich gelöscht.'; } diff --git a/lib/src/localization/generated/app_localizations_en.dart b/lib/src/localization/generated/app_localizations_en.dart index 14d8841..a02ddff 100644 --- a/lib/src/localization/generated/app_localizations_en.dart +++ b/lib/src/localization/generated/app_localizations_en.dart @@ -770,6 +770,12 @@ class AppLocalizationsEn extends AppLocalizations { @override String get galleryDetails => 'Show details'; + @override + String get galleryExport => 'Export to gallery'; + + @override + String get galleryExportSuccess => 'Successfully saved in the Gallery.'; + @override String get settingsResetTutorials => 'Show tutorials again'; @@ -815,4 +821,10 @@ class AppLocalizationsEn extends AppLocalizations { @override String get memoriesEmpty => 'As soon as you save pictures or videos, they end up here in your memories.'; + + @override + String get deleteImageTitle => 'Are you sure?'; + + @override + String get deleteImageBody => 'The image will be irrevocably deleted.'; } diff --git a/lib/src/views/memories/memories_photo_slider.view.dart b/lib/src/views/memories/memories_photo_slider.view.dart index 395afd4..6b54fda 100644 --- a/lib/src/views/memories/memories_photo_slider.view.dart +++ b/lib/src/views/memories/memories_photo_slider.view.dart @@ -53,7 +53,10 @@ class _MemoriesPhotoSliderViewState extends State { Future deleteFile() async { List messages = widget.galleryItems[currentIndex].messages; bool confirmed = await showAlertDialog( - context, "Are you sure?", "The image will be irrevocably deleted."); + context, + context.lang.deleteImageTitle, + context.lang.deleteImageBody, + ); if (!confirmed) return; @@ -75,6 +78,28 @@ class _MemoriesPhotoSliderViewState extends State { } } + Future exportFile() async { + final item = widget.galleryItems[currentIndex]; + + try { + if (item.videoPath != null) { + await saveVideoToGallery(item.videoPath!.path); + } else if (item.imagePath != null) { + final imageBytes = await item.imagePath!.readAsBytes(); + await saveImageToGallery(imageBytes); + } + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(context.lang.galleryExportSuccess)), + ); + } catch (e) { + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('$e')), + ); + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -142,6 +167,9 @@ class _MemoriesPhotoSliderViewState extends State { if (result == "delete") { deleteFile(); } + if (result == "export") { + exportFile(); + } }, itemBuilder: (BuildContext context) => >[ @@ -149,6 +177,10 @@ class _MemoriesPhotoSliderViewState extends State { value: 'delete', child: Text(context.lang.galleryDelete), ), + PopupMenuItem( + value: 'export', + child: Text(context.lang.galleryExport), + ), // PopupMenuItem( // value: 'details', // child: Text(context.lang.galleryDetails),