diff --git a/lib/l10n/intl_cy.arb b/lib/l10n/intl_cy.arb index 9291bcd3..b3c6a4d0 100644 --- a/lib/l10n/intl_cy.arb +++ b/lib/l10n/intl_cy.arb @@ -1,6 +1,8 @@ { "@@locale": "cy", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.", diff --git a/lib/l10n/intl_da.arb b/lib/l10n/intl_da.arb index aa14e07a..857783a3 100644 --- a/lib/l10n/intl_da.arb +++ b/lib/l10n/intl_da.arb @@ -1,6 +1,8 @@ { "@@locale": "da", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.", diff --git a/lib/l10n/intl_de.arb b/lib/l10n/intl_de.arb index 6e355995..83ccfa09 100644 --- a/lib/l10n/intl_de.arb +++ b/lib/l10n/intl_de.arb @@ -1,6 +1,8 @@ { "@@locale": "de", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "localeIt": "Italienisch \/ Italiano", diff --git a/lib/l10n/intl_el.arb b/lib/l10n/intl_el.arb index fb518eb5..abc79461 100644 --- a/lib/l10n/intl_el.arb +++ b/lib/l10n/intl_el.arb @@ -1,6 +1,8 @@ { "@@locale": "el", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.", diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 87395b1d..e724e679 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -1,6 +1,8 @@ { "@@locale": "en", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.", diff --git a/lib/l10n/intl_es.arb b/lib/l10n/intl_es.arb index a2c38335..831f9365 100644 --- a/lib/l10n/intl_es.arb +++ b/lib/l10n/intl_es.arb @@ -1,6 +1,8 @@ { "@@locale": "es", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "tooltipPinConversation": "Fija la conversación en la parte superior de \"Conversaciones\"", "errorDownloadDirectoryDoesNotExist": "No se puede habilitar el uso compartido de archivos porque la carpeta de descarga no se ha configurado o se configuró en una carpeta que no existe.", "acquiringTicketsFromServer": "Realizando Desafío Antispam", diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb index 079dff13..6f48f075 100644 --- a/lib/l10n/intl_fr.arb +++ b/lib/l10n/intl_fr.arb @@ -1,6 +1,8 @@ { "@@locale": "fr", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Le partage de fichiers ne peut pas être activé car le dossier de téléchargement n'a pas été défini ou est défini sur un dossier qui n'existe pas.", diff --git a/lib/l10n/intl_it.arb b/lib/l10n/intl_it.arb index e403987d..fdcacec0 100644 --- a/lib/l10n/intl_it.arb +++ b/lib/l10n/intl_it.arb @@ -1,6 +1,8 @@ { "@@locale": "it", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.", diff --git a/lib/l10n/intl_lb.arb b/lib/l10n/intl_lb.arb index 260d347d..79c444af 100644 --- a/lib/l10n/intl_lb.arb +++ b/lib/l10n/intl_lb.arb @@ -1,6 +1,8 @@ { "@@locale": "lb", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.", diff --git a/lib/l10n/intl_no.arb b/lib/l10n/intl_no.arb index 00b265b9..1eebd14e 100644 --- a/lib/l10n/intl_no.arb +++ b/lib/l10n/intl_no.arb @@ -1,6 +1,8 @@ { "@@locale": "no", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.", diff --git a/lib/l10n/intl_pl.arb b/lib/l10n/intl_pl.arb index e864744b..a5ee1ed2 100644 --- a/lib/l10n/intl_pl.arb +++ b/lib/l10n/intl_pl.arb @@ -1,6 +1,8 @@ { "@@locale": "pl", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.", diff --git a/lib/l10n/intl_pt.arb b/lib/l10n/intl_pt.arb index fed22cbe..b14d0033 100644 --- a/lib/l10n/intl_pt.arb +++ b/lib/l10n/intl_pt.arb @@ -1,6 +1,8 @@ { "@@locale": "pt", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.", diff --git a/lib/l10n/intl_ro.arb b/lib/l10n/intl_ro.arb index 0e912a7d..4fe2e500 100644 --- a/lib/l10n/intl_ro.arb +++ b/lib/l10n/intl_ro.arb @@ -1,6 +1,8 @@ { "@@locale": "ro", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.", diff --git a/lib/l10n/intl_ru.arb b/lib/l10n/intl_ru.arb index 396c57ef..5a6877ee 100644 --- a/lib/l10n/intl_ru.arb +++ b/lib/l10n/intl_ru.arb @@ -1,6 +1,8 @@ { "@@locale": "ru", - "@@last_modified": "2022-09-09T21:46:36+02:00", + "@@last_modified": "2022-09-09T22:56:43+02:00", + "shareMenuQRCode": "Show QR Code", + "shareProfileMenuTooltop": "Share profile via...", "acquiredTicketsFromServer": "Antispam Challenge Complete", "acquiringTicketsFromServer": "Performing Antispam Challenge", "errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.", diff --git a/lib/views/contactsview.dart b/lib/views/contactsview.dart index 5324564c..06283f36 100644 --- a/lib/views/contactsview.dart +++ b/lib/views/contactsview.dart @@ -19,9 +19,12 @@ import '../main.dart'; import '../settings.dart'; import 'addcontactview.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:qr_flutter/qr_flutter.dart'; import 'messageview.dart'; +enum ShareMenu { copyCode, qrcode } + class ContactsView extends StatefulWidget { const ContactsView({Key? key}) : super(key: key); @@ -163,16 +166,38 @@ class _ContactsViewState extends State { actions.add(Tooltip(message: AppLocalizations.of(context)!.blockUnknownConnectionsEnabledDescription, child: Icon(CwtchIcons.block_unknown))); } - // Copy profile onion - actions.add(IconButton( + actions.add(PopupMenuButton( icon: Icon(CwtchIcons.address_copy_2), - tooltip: AppLocalizations.of(context)!.copyAddress, + tooltip: AppLocalizations.of(context)!.shareProfileMenuTooltop, splashRadius: Material.defaultSplashRadius / 2, - onPressed: () { - Clipboard.setData(new ClipboardData(text: Provider.of(context, listen: false).onion)); - final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.copiedToClipboardNotification)); - ScaffoldMessenger.of(context).showSnackBar(snackBar); - })); + onSelected: (ShareMenu item) { + switch(item) { + case ShareMenu.copyCode: + { + Clipboard.setData(new ClipboardData(text: Provider + .of(context, listen: false) + .onion)); + final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.copiedToClipboardNotification)); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + } + break; + case ShareMenu.qrcode: { + _showQRCode("cwtch:" + Provider.of(context, listen: false).onion); + } + break; + } + }, + itemBuilder: (BuildContext context) => >[ + PopupMenuItem( + value: ShareMenu.copyCode, + child: Text(AppLocalizations.of(context)!.copyAddress), + ), + PopupMenuItem( + value: ShareMenu.qrcode, + child: Text(AppLocalizations.of(context)!.shareMenuQRCode), + ), + ], + )); // Manage known Servers if (Provider.of(context, listen: false).isExperimentEnabled(TapirGroupsExperiment) || Provider.of(context, listen: false).isExperimentEnabled(ServerManagementExperiment)) { @@ -381,4 +406,25 @@ class _ContactsViewState extends State { ))); }); } + + void _showQRCode(String profile_code) { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Wrap( children: [ + Center( child: + QrImage( + data: profile_code, + version: QrVersions.auto, + size: 400.0, + backgroundColor: Provider.of(context).theme.backgroundPaneColor, + foregroundColor: Provider.of(context).theme.mainTextColor, + gapless: false, + ), + )]); + + }, + ); + } + } diff --git a/pubspec.lock b/pubspec.lock index 644a5885..b1f454c3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -617,6 +617,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + qr: + dependency: transitive + description: + name: qr + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" screen_retriever: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d12d5ae6..871f6773 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.8.0+34 +version: 1.9.0+35 environment: sdk: ">=2.15.0 <3.0.0" @@ -46,6 +46,7 @@ dependencies: win_toast: ^0.0.2 flutter_local_notifications: ^9.6.1 desktop_notifications: ^0.6.3 + qr_flutter: ^4.0.0 dev_dependencies: msix: ^3.6.2