diff --git a/lib/core/configuration.dart b/lib/core/configuration.dart index a39052e6552a49784a2e64e253807be27cde5f3b..0717e4b46ad5e6246497b0ee0ead01a25e849518 100644 --- a/lib/core/configuration.dart +++ b/lib/core/configuration.dart @@ -45,7 +45,7 @@ class Configuration { final List onlineSecureKeys = [ keyKey, secretKeyKey, - authSecretKeyKey + authSecretKeyKey, ]; final kTempFolderDeletionTimeBuffer = const Duration(days: 1).inMicroseconds; diff --git a/lib/core/logging/tunneled_transport.dart b/lib/core/logging/tunneled_transport.dart index 9706f72fd8165c748953d21270a78469b2fd699d..daf8a7941f5dd55c71bef48688bd881d232e8645 100644 --- a/lib/core/logging/tunneled_transport.dart +++ b/lib/core/logging/tunneled_transport.dart @@ -122,7 +122,7 @@ class _CredentialBuilder { return headers ..addAll( { - 'X-Sentry-Auth': '$_authHeader, sentry_timestamp=$timestamp' + 'X-Sentry-Auth': '$_authHeader, sentry_timestamp=$timestamp', }, ); } diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index e5cc9b7ab146ba91d94d2744421026e3423e63fb..b572856ed7b0de9b4f6fba0955aef4e60bfdacf2 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -332,5 +332,6 @@ "showLargeIcons": "Show large icons", "shouldHideCode": "Hide codes", "focusOnSearchBar": "Focus search on app start", - "confirmUpdatingkey": "Are you sure you want to update the secret key?" + "confirmUpdatingkey": "Are you sure you want to update the secret key?", + "minimizeAppOnCopy": "Minimize app on copy" } diff --git a/lib/locale.dart b/lib/locale.dart index c45f38d75a39b4c42dc49ef25c093d0b9a29e5f3..ebca9528af3234514ed69aad74f4a2d6b82df83f 100644 --- a/lib/locale.dart +++ b/lib/locale.dart @@ -24,7 +24,7 @@ Locale localResolutionCallBack(locales, supportedLocales) { Locale? languageCodeMatch; final Map languageCodeToLocale = { for (Locale supportedLocale in appSupportedLocales) - supportedLocale.languageCode: supportedLocale + supportedLocale.languageCode: supportedLocale, }; for (Locale locale in locales) { diff --git a/lib/onboarding/view/view_qr_page.dart b/lib/onboarding/view/view_qr_page.dart index 9b29b457e4ecf0762e40804b71c74c0bf0fa00de..71f4756a7ca4bf2c7b43f50484d5c6016f958597 100644 --- a/lib/onboarding/view/view_qr_page.dart +++ b/lib/onboarding/view/view_qr_page.dart @@ -89,7 +89,7 @@ class ViewQrPage extends StatelessWidget { child: Text(l10n.back), ), ), - ) + ), ], ), ), diff --git a/lib/services/preference_service.dart b/lib/services/preference_service.dart index cad38143d48dc3eda8cd57fa7ed57fe8597c75f3..66d96c7fdda0fc28d41e76abe527f907520707c2 100644 --- a/lib/services/preference_service.dart +++ b/lib/services/preference_service.dart @@ -13,6 +13,7 @@ class PreferenceService { static const kShouldShowLargeIconsKey = "should_show_large_icons"; static const kShouldHideCodesKey = "should_hide_codes"; static const kShouldAutoFocusOnSearchBar = "should_auto_focus_on_search_bar"; + static const kShouldMinimizeOnCopy = "should_minimize_on_copy"; Future init() async { _prefs = await SharedPreferences.getInstance(); @@ -64,4 +65,16 @@ class PreferenceService { await _prefs.setBool(kShouldAutoFocusOnSearchBar, value); Bus.instance.fire(IconsChangedEvent()); } + + bool shouldMinimizeOnCopy() { + if (_prefs.containsKey(kShouldMinimizeOnCopy)) { + return _prefs.getBool(kShouldMinimizeOnCopy)!; + } else { + return false; + } + } + + Future setShouldMinimizeOnCopy(bool value) async { + await _prefs.setBool(kShouldMinimizeOnCopy, value); + } } diff --git a/lib/ui/account/email_entry_page.dart b/lib/ui/account/email_entry_page.dart index f84b68cfeb315a3c9f1c58f019c441d5df55aea0..e1147f41640392e4ce4ee8f6bbbc88f043d3d5a4 100644 --- a/lib/ui/account/email_entry_page.dart +++ b/lib/ui/account/email_entry_page.dart @@ -403,7 +403,7 @@ class _EmailEntryPageState extends State { style: const TextStyle( decoration: TextDecoration.underline, ), - ) + ), }, ), ), diff --git a/lib/ui/account/login_page.dart b/lib/ui/account/login_page.dart index a2f9414a293c3b1f651bb69f32a3cb6a3ea3728d..b2cfce7458534817a039ba1c41abec15c1f56612 100644 --- a/lib/ui/account/login_page.dart +++ b/lib/ui/account/login_page.dart @@ -204,14 +204,14 @@ class _LoginPageState extends State { style: const TextStyle( decoration: TextDecoration.underline, ), - ) + ), }, ), ), Expanded( flex: 2, child: Container(), - ) + ), ], ), ), diff --git a/lib/ui/account/login_pwd_verification_page.dart b/lib/ui/account/login_pwd_verification_page.dart index 0755be1b19517c87e8951dbf85cba06dcea60a80..a443cf249853ce358862dddbc3ec498e73a2e073 100644 --- a/lib/ui/account/login_pwd_verification_page.dart +++ b/lib/ui/account/login_pwd_verification_page.dart @@ -221,7 +221,7 @@ State { ), ], ), - ) + ), ], ), ), diff --git a/lib/ui/account/ott_verification_page.dart b/lib/ui/account/ott_verification_page.dart index ce7b8ea3545a03f4f9d867b04d4415e2e0d625ec..8bcaf3e3499e1d6d1d98b03f852ebf4773c2cc66 100644 --- a/lib/ui/account/ott_verification_page.dart +++ b/lib/ui/account/ott_verification_page.dart @@ -152,7 +152,7 @@ class _OTTVerificationPageState extends State { SizedBox( width: MediaQuery.of(context).size.width * 0.2, height: 1, - ) + ), ], ), ), @@ -203,7 +203,7 @@ class _OTTVerificationPageState extends State { decoration: TextDecoration.underline, ), ), - ) + ), ], ), ), diff --git a/lib/ui/account/password_reentry_page.dart b/lib/ui/account/password_reentry_page.dart index c8fc23a6711e68e805af59564250065db3a8473c..aab2553ebc39dee0a5bdfba7798719cc12b7137c 100644 --- a/lib/ui/account/password_reentry_page.dart +++ b/lib/ui/account/password_reentry_page.dart @@ -310,7 +310,7 @@ class _PasswordReentryPageState extends State { ), ], ), - ) + ), ], ), ), diff --git a/lib/ui/account/recovery_key_page.dart b/lib/ui/account/recovery_key_page.dart index bbe08b7e51b38ab9e3c9293628aadacedce9749a..c5ca66fdc99038a28a09fc0db7ace7e9b36da9d7 100644 --- a/lib/ui/account/recovery_key_page.dart +++ b/lib/ui/account/recovery_key_page.dart @@ -191,7 +191,7 @@ class _RecoveryKeyPageState extends State { children: _saveOptions(context, recoveryKey), ), ), - ) + ), ], ), // columnEnds ), diff --git a/lib/ui/account/verify_recovery_page.dart b/lib/ui/account/verify_recovery_page.dart index 3c9796d106343a122ce0b8cd57a73ff80d4b68bf..dad67590b47705012a7d51c0dfc86098cd460d7e 100644 --- a/lib/ui/account/verify_recovery_page.dart +++ b/lib/ui/account/verify_recovery_page.dart @@ -196,7 +196,7 @@ class _VerifyRecoveryPageState extends State { ), ), ), - const SizedBox(height: 20) + const SizedBox(height: 20), ], ), ), diff --git a/lib/ui/code_widget.dart b/lib/ui/code_widget.dart index b3f24022415a1f678636818bdaa3518ab0d20381..a26cc20b2b8721e1bf2fbe8bba377f65a7816ea7 100644 --- a/lib/ui/code_widget.dart +++ b/lib/ui/code_widget.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'package:clipboard/clipboard.dart'; import 'package:ente_auth/core/configuration.dart'; @@ -17,6 +18,7 @@ import 'package:ente_auth/utils/totp_util.dart'; import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:logging/logging.dart'; +import 'package:move_to_background/move_to_background.dart'; class CodeWidget extends StatefulWidget { final Code code; @@ -141,7 +143,7 @@ class _CodeWidgetState extends State { borderRadius: BorderRadius.circular(10), ), onTap: () { - _copyToClipboard(); + _copyCurrentOTPToClipboard(); }, onDoubleTap: isMaskingEnabled ? () { @@ -153,7 +155,7 @@ class _CodeWidgetState extends State { } : null, onLongPress: () { - _copyToClipboard(); + _copyCurrentOTPToClipboard(); }, child: _getCardContents(l10n), ), @@ -328,17 +330,34 @@ class _CodeWidgetState extends State { ); } - void _copyToClipboard() { - FlutterClipboard.copy(_getCurrentOTP()) - .then((value) => showToast(context, context.l10n.copiedToClipboard)); + void _copyCurrentOTPToClipboard() async { + _copyToClipboard( + _getCurrentOTP(), + confirmationMessage: context.l10n.copiedToClipboard, + ); } void _copyNextToClipboard() { - FlutterClipboard.copy(_getNextTotp()).then( - (value) => showToast(context, context.l10n.copiedNextToClipboard), + _copyToClipboard( + _getNextTotp(), + confirmationMessage: context.l10n.copiedNextToClipboard, ); } + void _copyToClipboard( + String content, { + required String confirmationMessage, + }) async { + final shouldMinimizeOnCopy = + PreferenceService.instance.shouldMinimizeOnCopy(); + + await FlutterClipboard.copy(content); + showToast(context, confirmationMessage); + if (Platform.isAndroid && shouldMinimizeOnCopy) { + MoveToBackground.moveTaskToBack(); + } + } + void _onNextHotpTapped() { if (widget.code.type == Type.hotp) { CodeStore.instance diff --git a/lib/ui/common/dynamic_fab.dart b/lib/ui/common/dynamic_fab.dart index 0fedcff94ff456962042a7bc083a51041c7a7b89..db612882a10cf6c150b49e52816772dadc641cc5 100644 --- a/lib/ui/common/dynamic_fab.dart +++ b/lib/ui/common/dynamic_fab.dart @@ -30,7 +30,7 @@ class DynamicFAB extends StatelessWidget { spreadRadius: 200, blurRadius: 100, offset: const Offset(0, 230), - ) + ), ], ), width: double.infinity, diff --git a/lib/ui/common/progress_dialog.dart b/lib/ui/common/progress_dialog.dart index a05f031e6219ba506d9ab729e4a61845609c1ad0..8c9a4e1f168c5c4c09e2d3cd70a64f87979ad5a2 100644 --- a/lib/ui/common/progress_dialog.dart +++ b/lib/ui/common/progress_dialog.dart @@ -277,7 +277,7 @@ class _BodyState extends State<_Body> { _direction == TextDirection.ltr ? loader : text, const SizedBox(width: 8.0), _direction == TextDirection.rtl ? loader : text, - const SizedBox(width: 8.0) + const SizedBox(width: 8.0), ], ), ], diff --git a/lib/ui/components/buttons/button_widget.dart b/lib/ui/components/buttons/button_widget.dart index 36f79a364cf3bf48d0b489bb6cf61e335e1ad614..28d62f4a66a54c88f532266af526555ff052ed44 100644 --- a/lib/ui/components/buttons/button_widget.dart +++ b/lib/ui/components/buttons/button_widget.dart @@ -308,7 +308,7 @@ class _ButtonChildWidgetState extends State { overflow: TextOverflow.ellipsis, ), ), - ) + ), ], ); }, diff --git a/lib/ui/components/captioned_text_widget.dart b/lib/ui/components/captioned_text_widget.dart index 77a161bde232b36dcd94e9c6b3b5c6988e044bdf..f03c8551fd54ab7e952ab0453a7476d60e4efae5 100644 --- a/lib/ui/components/captioned_text_widget.dart +++ b/lib/ui/components/captioned_text_widget.dart @@ -48,7 +48,7 @@ class CaptionedTextWidget extends StatelessWidget { ], ), ), - ) + ), ], ), ), diff --git a/lib/ui/components/dialog_widget.dart b/lib/ui/components/dialog_widget.dart index 02311fc53f354c4804cde92c355adda615dee195..ab96a0dbe80416ae1f0edd99530f0ed125dd07ba 100644 --- a/lib/ui/components/dialog_widget.dart +++ b/lib/ui/components/dialog_widget.dart @@ -280,7 +280,7 @@ class _TextInputDialogState extends State { ), ), ], - ) + ), ], ), ), diff --git a/lib/ui/components/title_bar_widget.dart b/lib/ui/components/title_bar_widget.dart index 6ee76e1a087e063717af4ddc253168af71f9e7cd..8e22d4f65f39b6febe67f961ef6974d4193e3744 100644 --- a/lib/ui/components/title_bar_widget.dart +++ b/lib/ui/components/title_bar_widget.dart @@ -61,7 +61,7 @@ class TitleBarWidget extends StatelessWidget { : Text( caption!, style: textTheme.mini.copyWith(color: colorTheme.textMuted), - ) + ), ], ), ), @@ -112,7 +112,7 @@ class TitleBarWidget extends StatelessWidget { ), overflow: TextOverflow.ellipsis, maxLines: 1, - ) + ), ], ), ), diff --git a/lib/ui/home/coach_mark_widget.dart b/lib/ui/home/coach_mark_widget.dart index 9b4b8b48cd7cd9b3ce966c0217144fe3ba5bd06a..b0e15d7d2b4360ac88121ccce0d26ca50c331504 100644 --- a/lib/ui/home/coach_mark_widget.dart +++ b/lib/ui/home/coach_mark_widget.dart @@ -56,7 +56,7 @@ class CoachMarkWidget extends StatelessWidget { }, child: Text(l10n.ok), ), - ) + ), ], ), ], diff --git a/lib/ui/scanner_gauth_page.dart b/lib/ui/scanner_gauth_page.dart index 41909ed3256d52748c678b9fb86b6bd1899ce614..785f1d3d3af9ad453c7616e2fbe80c2e1f73c498 100644 --- a/lib/ui/scanner_gauth_page.dart +++ b/lib/ui/scanner_gauth_page.dart @@ -46,7 +46,8 @@ class ScannerGoogleAuthPageState extends State { child: QRView( key: qrKey, overlay: QrScannerOverlayShape( - borderColor: getEnteColorScheme(context).primary700,), + borderColor: getEnteColorScheme(context).primary700, + ), onQRViewCreated: _onQRViewCreated, formatsAllowed: const [BarcodeFormat.qrcode], ), @@ -56,7 +57,7 @@ class ScannerGoogleAuthPageState extends State { child: Center( child: (totp != null) ? Text(totp!) : Text(l10n.scanACode), ), - ) + ), ], ), ); diff --git a/lib/ui/scanner_page.dart b/lib/ui/scanner_page.dart index 97ff1278a1321fccd245ac435604922bececcc5d..0159f0cfabda813dd3c7447ed2e0e2ac3735df88 100644 --- a/lib/ui/scanner_page.dart +++ b/lib/ui/scanner_page.dart @@ -51,7 +51,7 @@ class ScannerPageState extends State { child: Center( child: (totp != null) ? Text(totp!) : Text(l10n.scanACode), ), - ) + ), ], ), ); diff --git a/lib/ui/settings/faq.dart b/lib/ui/settings/faq.dart index 3d5c78ab82b5ba033e251aad0b836ddcdd0ecfc8..d9aa88f1b0852937825739a410d798ac6f3ad038 100644 --- a/lib/ui/settings/faq.dart +++ b/lib/ui/settings/faq.dart @@ -95,7 +95,7 @@ class FaqWidget extends StatelessWidget { ), ), ), - ) + ), ], ), ); diff --git a/lib/ui/settings/general_section_widget.dart b/lib/ui/settings/general_section_widget.dart index 428e7635737bdc6641febd16337436a6f1befe87..986ef3a8e71608269fb85ae88cedbd2d44bed7f2 100644 --- a/lib/ui/settings/general_section_widget.dart +++ b/lib/ui/settings/general_section_widget.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:ente_auth/app/view/app.dart'; import 'package:ente_auth/core/logging/super_logging.dart'; import 'package:ente_auth/l10n/l10n.dart'; @@ -120,6 +122,23 @@ class _AdvancedSectionWidgetState extends State { ), ), sectionOptionSpacing, + if (Platform.isAndroid) ...[ + MenuItemWidget( + captionedTextWidget: CaptionedTextWidget( + title: l10n.minimizeAppOnCopy, + ), + trailingWidget: ToggleSwitchWidget( + value: () => PreferenceService.instance.shouldMinimizeOnCopy(), + onChanged: () async { + await PreferenceService.instance.setShouldMinimizeOnCopy( + !PreferenceService.instance.shouldMinimizeOnCopy(), + ); + setState(() {}); + }, + ), + ), + sectionOptionSpacing, + ], ], ); } diff --git a/lib/utils/device_info.dart b/lib/utils/device_info.dart index 10ca82c2a0824df705c807ec8429bee2e804e4fa..5832ec6de74a3f41c5f58c8230180023946bf3b0 100644 --- a/lib/utils/device_info.dart +++ b/lib/utils/device_info.dart @@ -27,7 +27,7 @@ late Set iOSLowEndMachineCodes = { "iPhone10,2", // iPhone 8 Plus "iPhone10,3", // iPhone X Global "iPhone10,4", // iPhone 8 - "iPhone10,5" // iPhone 8 + "iPhone10,5", // iPhone 8 }; Future isLowSpecDevice() async { diff --git a/lib/utils/email_util.dart b/lib/utils/email_util.dart index cdbbfda12362781c93aa5b9e7e7bcb8f7d827198..d1ae183958d5bc4af7aa25a6e1608e9a70813bac 100644 --- a/lib/utils/email_util.dart +++ b/lib/utils/email_util.dart @@ -277,7 +277,7 @@ void _showNoMailAppsDialog(BuildContext context, String toEmail) { onPressed: () { Navigator.pop(context); }, - ) + ), ], ); },