diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index e7ac72ad3..80dbf60e6 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -9,6 +9,7 @@ "onBoardingGetStarted": "Get Started", "setupFirstAccount": "Setup your first account", "importScanQrCode": "Scan a QR Code", + "qrCode": "QR Code", "importEnterSetupKey": "Enter a setup key", "importAccountPageTitle": "Enter account details", "secretCanNotBeEmpty": "Secret can not be empty", @@ -184,6 +185,7 @@ "recoveryKeySaveDescription": "We don't store this key, please save this 24 word key in a safe place.", "doThisLater": "Do this later", "saveKey": "Save key", + "back": "Back", "createAccount": "Create account", "passwordStrength": "Password strength: {passwordStrengthValue}", "@passwordStrength": { diff --git a/lib/onboarding/view/view_qr_page.dart b/lib/onboarding/view/view_qr_page.dart new file mode 100644 index 000000000..30b3c2c71 --- /dev/null +++ b/lib/onboarding/view/view_qr_page.dart @@ -0,0 +1,99 @@ + +import 'dart:math'; + +import "package:ente_auth/l10n/l10n.dart"; +import 'package:ente_auth/models/code.dart'; +import 'package:ente_auth/theme/ente_theme.dart'; +import "package:flutter/material.dart"; +import 'package:qr_flutter/qr_flutter.dart'; + +class ViewQrPage extends StatelessWidget { + final Code? code; + + ViewQrPage({this.code, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final screenWidth = MediaQuery.of(context).size.width; + final double qrSize = min(screenWidth - 80, 300.0); + final enteTextTheme = getEnteTextTheme(context); + final l10n = context.l10n; + return Scaffold( + appBar: AppBar( + title: Text(l10n.qrCode), + ), + body: SafeArea( + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 40.0, horizontal: 40), + child: Column( + children: [ + QrImage( + data: code!.rawData, + version: QrVersions.auto, + size: qrSize, + ), + const SizedBox( + height: 20, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + l10n.account, + style: enteTextTheme.largeMuted, + ), + const SizedBox( + width: 10, + ), + Text( + code?.account ?? '', + style: enteTextTheme.largeBold, + ), + ], + ), + const SizedBox( + height: 4, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + l10n.codeIssuerHint, + style: enteTextTheme.largeMuted, + ), + const SizedBox( + width: 10, + ), + Text( + code?.issuer ?? '', + style: enteTextTheme.largeBold, + ), + ], + ), + const SizedBox( + height: 80, + ), + SizedBox( + width: 400, + child: OutlinedButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 4, + ), + child: Text(l10n.back), + ), + ), + ) + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/ui/code_widget.dart b/lib/ui/code_widget.dart index 4ca26a65c..09b81f559 100644 --- a/lib/ui/code_widget.dart +++ b/lib/ui/code_widget.dart @@ -5,6 +5,7 @@ import 'package:ente_auth/ente_theme_data.dart'; import 'package:ente_auth/l10n/l10n.dart'; import 'package:ente_auth/models/code.dart'; import 'package:ente_auth/onboarding/view/setup_enter_secret_key_page.dart'; +import 'package:ente_auth/onboarding/view/view_qr_page.dart'; import 'package:ente_auth/store/code_store.dart'; import 'package:ente_auth/ui/code_timer_progress.dart'; import 'package:ente_auth/utils/dialog_util.dart'; @@ -69,8 +70,27 @@ class _CodeWidgetState extends State { child: Slidable( key: ValueKey(widget.code.hashCode), endActionPane: ActionPane( + extentRatio: 0.60, motion: const ScrollMotion(), children: [ + const SizedBox( + width: 4, + ), + SlidableAction( + onPressed: _onShowQrPressed, + backgroundColor: Colors.grey.withOpacity(0.1), + borderRadius: const BorderRadius.all(Radius.circular(12.0)), + foregroundColor: + Theme.of(context).colorScheme.inverseBackgroundColor, + icon: Icons.qr_code_2_outlined, + label: "QR", + padding: const EdgeInsets.only(left: 4, right: 0), + spacing: 8, + ), + const SizedBox( + width: 4, + ), + SlidableAction( onPressed: _onEditPressed, backgroundColor: Colors.grey.withOpacity(0.1), @@ -262,6 +282,16 @@ class _CodeWidgetState extends State { } } + Future _onShowQrPressed(_) async { + final Code? code = await Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) { + return ViewQrPage(code: widget.code); + }, + ), + ); + } + void _onDeletePressed(_) async { final l10n = context.l10n; await showChoiceActionSheet( diff --git a/lib/ui/settings/support_dev_widget.dart b/lib/ui/settings/support_dev_widget.dart index 471ba36e7..a5be4da45 100644 --- a/lib/ui/settings/support_dev_widget.dart +++ b/lib/ui/settings/support_dev_widget.dart @@ -23,7 +23,7 @@ class SupportDevWidget extends StatelessWidget { builder: (context, snapshot) { if (snapshot.hasData) { final subscription = snapshot.data; - if (subscription != null && subscription.productID != "free") { + if (subscription != null && subscription.productID == "free") { return GestureDetector( onTap: () { launchUrl(Uri.parse("https://ente.io")); diff --git a/pubspec.lock b/pubspec.lock index e09d0238a..381bb81b6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1095,6 +1095,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.3" + qr: + dependency: transitive + description: + name: qr + sha256: "5c4208b4dc0d55c3184d10d83ee0ded6212dc2b5e2ba17c5a0c0aab279128d21" + url: "https://pub.dev" + source: hosted + version: "2.1.0" qr_code_scanner: dependency: "direct main" description: @@ -1103,6 +1111,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + sha256: c5c121c54cb6dd837b9b9d57eb7bc7ec6df4aee741032060c8833a678c80b87e + url: "https://pub.dev" + source: hosted + version: "4.0.0" sentry: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index dc41789ac..8efbcbde6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,6 +62,7 @@ dependencies: pointycastle: ^3.7.3 protobuf: ^3.0.0 qr_code_scanner: ^1.0.1 + qr_flutter: 4.0.0 sentry: ^6.12.1 sentry_flutter: ^6.12.1 share_plus: ^4.4.0