Extract more strings into ARB files for localization
This commit is contained in:
parent
0894a7eb36
commit
359dc09d6a
23 changed files with 300 additions and 151 deletions
|
@ -6,7 +6,6 @@
|
|||
},
|
||||
"onBoardingBody": "Secure your 2FA codes",
|
||||
"onBoardingGetStarted": "Get Started",
|
||||
|
||||
"setupFirstAccount": "Setup your first account",
|
||||
"importScanQrCode": "Scan a QR Code",
|
||||
"importEnterSetupKey": "Enter a setup key",
|
||||
|
@ -18,7 +17,100 @@
|
|||
"timeBasedKeyType": "Time based (TOTP)",
|
||||
"counterBasedKeyType": "Counter based (HOTP)",
|
||||
"saveAction": "Save",
|
||||
|
||||
"nextTotpTitle": "next",
|
||||
"deleteCodeTitle": "Delete code?",
|
||||
"deleteCodeMessage": "Are you sure you want to delete this code? This action is irreversible.",
|
||||
"viewLogsAction": "View logs",
|
||||
"sendLogsDescription": "This will send across logs to help us debug your issue. While we take precautions to ensure that sensitive information is not logged, we encourage you to view these logs before sharing them.",
|
||||
"preparingLogsTitle": "Preparing logs...",
|
||||
"emailLogsTitle": "Email logs",
|
||||
"emailLogsMessage": "Please send the logs to {email}",
|
||||
"@emailLogsMessage": {
|
||||
"placeholders": {
|
||||
"email": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"copyEmailAction": "Copy email",
|
||||
"exportLogsAction": "Export logs",
|
||||
"reportABug": "Report a bug",
|
||||
"crashAndErrorReporting": "Crash & error reporting",
|
||||
"reportBug": "Report bug",
|
||||
"emailUsMessage": "Please email us at {email}",
|
||||
"@emailUsMessage": {
|
||||
"placeholders": {
|
||||
"email": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"contactSupport": "Contact support",
|
||||
"verifyPassword": "Verify password",
|
||||
"pleaseWaitTitle": "Please wait...",
|
||||
"generatingEncryptionKeysTitle": "Generating encryption keys...",
|
||||
"recreatePassword": "Recreate password",
|
||||
"recreatePasswordMessage": "The current device is not powerful enough to verify your password, so we need to regenerate it once in a way that works with all devices. \n\nPlease login using your recovery key and regenerate your password (you can use the same one again if you wish).",
|
||||
"useRecoveryKeyAction": "Use recovery key",
|
||||
"incorrectPassword": "Incorrect password",
|
||||
"welcomeBackTitle": "Welcome back!",
|
||||
"madeWithLoveAtPrefix": "made with ❤️ at ",
|
||||
"changeEmail": "change email",
|
||||
"ok": "OK",
|
||||
"cancel": "Cancel",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"email": "Email",
|
||||
"support": "Support",
|
||||
"settings": "Settings",
|
||||
"copied": "Copied",
|
||||
"tryAgainMessage": "Please try again",
|
||||
"existingUser": "Existing User",
|
||||
"newUser" : "New to ente"
|
||||
}
|
||||
"newUser" : "New to ente",
|
||||
"delete": "Delete",
|
||||
"enterYourPasswordHint": "Enter your password",
|
||||
"forgotPassword": "Forgot password",
|
||||
"oops": "Oops",
|
||||
"somethingWentWrongMessage": "Something went wrong, please try again",
|
||||
"leaveFamily": "Leave family",
|
||||
"leaveFamilyMessage": "Are you sure that you want to leave the family plan?",
|
||||
"inFamilyPlanMessage": "You are on a family plan!",
|
||||
"swipeHint": "Swipe left to edit or remove codes",
|
||||
"scan": "Scan",
|
||||
"scanACode": "Scan a code",
|
||||
"verify": "Verify",
|
||||
"enterCodeHint": "Enter the 6-digit code from\nyour authenticator app",
|
||||
"lostDeviceTitle": "Lost device?",
|
||||
"twoFactorAuthTitle": "Two-factor authentication",
|
||||
"recoverAccount": "Recover account",
|
||||
"enterRecoveryKeyHint": "Enter your recovery key",
|
||||
"recover": "Recover",
|
||||
"contactSupportViaEmailMessage":"Please drop an email to {email} from your registered email address",
|
||||
"@contactSupportViaEmailMessage": {
|
||||
"placeholders": {
|
||||
"email": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"noRecoveryKeyTitle": "No recovery key?",
|
||||
"enterEmailHint": "Enter your email address",
|
||||
"invalidEmailTitle": "Invalid email address",
|
||||
"invalidEmailMessage": "Please enter a valid email address.",
|
||||
"deleteAccount": "Delete account",
|
||||
"deleteAccountQuery": "We'll be sorry to see you go. Are you facing some issue?",
|
||||
"yesSendFeedbackAction": "Yes, send feedback",
|
||||
"noDeleteAccountAction": "No, delete account",
|
||||
"initiateAccountDeleteTitle": "Please authenticate to initiate account deletion",
|
||||
"confirmAccountDeleteTitle": "Are you sure you want to delete your ente account?",
|
||||
"confirmAccountDeleteMessage": "Your uploaded data, across all apps (Photos and Authenticator both), will be scheduled for deletion, and your account will be permanently deleted.",
|
||||
"sendEmail": "Send email",
|
||||
"createNewAccount": "Create new account",
|
||||
"passwordStrengthWeak": "Weak",
|
||||
"passwordStrengthStrong": "Strong",
|
||||
"passwordStrengthModerate": "Moderate",
|
||||
"confirmPassword": "Confirm password",
|
||||
"close": "Close",
|
||||
"oopsSomethingWentWrong": "Oops, Something went wrong."
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:ente_auth/core/constants.dart';
|
|||
import 'package:ente_auth/core/event_bus.dart';
|
||||
import 'package:ente_auth/core/network.dart';
|
||||
import 'package:ente_auth/events/user_details_changed_event.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/delete_account.dart';
|
||||
import 'package:ente_auth/models/key_attributes.dart';
|
||||
import 'package:ente_auth/models/key_gen_result.dart';
|
||||
|
@ -47,7 +48,8 @@ class UserService {
|
|||
bool isChangeEmail = false,
|
||||
bool isCreateAccountScreen = false,
|
||||
}) async {
|
||||
final dialog = createProgressDialog(context, "Please wait...");
|
||||
final l10n = context.l10n;
|
||||
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
final response = await _dio.post(
|
||||
|
@ -191,7 +193,8 @@ class UserService {
|
|||
Future<DeleteChallengeResponse> getDeleteChallenge(
|
||||
BuildContext context,
|
||||
) async {
|
||||
final dialog = createProgressDialog(context, "Please wait...");
|
||||
final l10n = context.l10n;
|
||||
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
final response = await _dio.get(
|
||||
|
@ -259,7 +262,8 @@ class UserService {
|
|||
}
|
||||
|
||||
Future<void> verifyEmail(BuildContext context, String ott) async {
|
||||
final dialog = createProgressDialog(context, "Please wait...");
|
||||
final l10n = context.l10n;
|
||||
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
final response = await _dio.post(
|
||||
|
@ -329,7 +333,8 @@ class UserService {
|
|||
String email,
|
||||
String ott,
|
||||
) async {
|
||||
final dialog = createProgressDialog(context, "Please wait...");
|
||||
final l10n = context.l10n;
|
||||
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
final response = await _dio.post(
|
||||
|
@ -498,7 +503,8 @@ class UserService {
|
|||
}
|
||||
|
||||
Future<void> recoverTwoFactor(BuildContext context, String sessionID) async {
|
||||
final dialog = createProgressDialog(context, "Please wait...");
|
||||
final l10n = context.l10n;
|
||||
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
final response = await _dio.get(
|
||||
|
@ -618,7 +624,8 @@ class UserService {
|
|||
String encryptedSecret,
|
||||
String secretDecryptionNonce,
|
||||
) async {
|
||||
final dialog = createProgressDialog(context, "Please wait...");
|
||||
final l10n = context.l10n;
|
||||
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
await dialog.show();
|
||||
String secret;
|
||||
try {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:ente_auth/utils/dialog_util.dart';
|
||||
import 'package:ente_auth/utils/email_util.dart';
|
||||
|
@ -17,20 +18,21 @@ class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return AlertDialog(
|
||||
title: const Text("Enter your email address"),
|
||||
title: Text(l10n.enterEmailHint),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'Email',
|
||||
hintStyle: TextStyle(
|
||||
decoration: InputDecoration(
|
||||
hintText: l10n.email,
|
||||
hintStyle: const TextStyle(
|
||||
color: Colors.white30,
|
||||
),
|
||||
contentPadding: EdgeInsets.all(12),
|
||||
contentPadding: const EdgeInsets.all(12),
|
||||
),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
|
@ -47,9 +49,9 @@ class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
|
|||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text(
|
||||
"Cancel",
|
||||
style: TextStyle(
|
||||
child: Text(
|
||||
l10n.cancel,
|
||||
style: const TextStyle(
|
||||
color: Colors.redAccent,
|
||||
),
|
||||
),
|
||||
|
@ -58,9 +60,9 @@ class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
|
|||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text(
|
||||
"Verify",
|
||||
style: TextStyle(
|
||||
child: Text(
|
||||
l10n.verify,
|
||||
style: const TextStyle(
|
||||
color: Colors.purple,
|
||||
),
|
||||
),
|
||||
|
@ -68,8 +70,8 @@ class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
|
|||
if (!isValidEmail(_email)) {
|
||||
showErrorDialog(
|
||||
context,
|
||||
"Invalid email address",
|
||||
"Please enter a valid email address.",
|
||||
l10n.invalidEmailTitle,
|
||||
l10n.invalidEmailMessage,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/delete_account.dart';
|
||||
import 'package:ente_auth/services/local_authentication_service.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
|
@ -20,10 +21,11 @@ class DeleteAccountPage extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
title: const Text("Delete account"),
|
||||
title: Text(l10n.deleteAccount),
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
|
@ -47,7 +49,7 @@ class DeleteAccountPage extends StatelessWidget {
|
|||
),
|
||||
Center(
|
||||
child: Text(
|
||||
"We'll be sorry to see you go. Are you facing some issue?",
|
||||
l10n.deleteAccountQuery,
|
||||
style: Theme.of(context).textTheme.subtitle1,
|
||||
),
|
||||
),
|
||||
|
@ -74,7 +76,7 @@ class DeleteAccountPage extends StatelessWidget {
|
|||
height: 24,
|
||||
),
|
||||
GradientButton(
|
||||
text: "Yes, send feedback",
|
||||
text: l10n.yesSendFeedbackAction,
|
||||
iconData: Icons.check,
|
||||
onTap: () async {
|
||||
await sendEmail(
|
||||
|
@ -104,9 +106,9 @@ class DeleteAccountPage extends StatelessWidget {
|
|||
),
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
label: const Text(
|
||||
"No, delete account",
|
||||
style: TextStyle(
|
||||
label: Text(
|
||||
l10n.noDeleteAccountAction,
|
||||
style: const TextStyle(
|
||||
color: Colors.redAccent, // same for both themes
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
|
@ -143,21 +145,20 @@ class DeleteAccountPage extends StatelessWidget {
|
|||
BuildContext context,
|
||||
DeleteChallengeResponse response,
|
||||
) async {
|
||||
final l10n = context.l10n;
|
||||
final hasAuthenticated =
|
||||
await LocalAuthenticationService.instance.requestLocalAuthentication(
|
||||
context,
|
||||
"Please authenticate to initiate account deletion",
|
||||
l10n.initiateAccountDeleteTitle,
|
||||
);
|
||||
|
||||
if (hasAuthenticated) {
|
||||
final choice = await showChoiceDialog(
|
||||
context,
|
||||
'Are you sure you want to delete your ente account?',
|
||||
'Your uploaded data, across all apps '
|
||||
'(Photos and Authenticator both), will be scheduled for deletion,'
|
||||
'and your account will be permanently deleted.',
|
||||
firstAction: 'Cancel',
|
||||
secondAction: 'Delete',
|
||||
l10n.confirmAccountDeleteTitle,
|
||||
l10n.confirmAccountDeleteMessage,
|
||||
firstAction: l10n.cancel,
|
||||
secondAction: l10n.delete,
|
||||
firstActionColor: Theme.of(context).colorScheme.onSurface,
|
||||
secondActionColor: Colors.red,
|
||||
);
|
||||
|
@ -175,10 +176,11 @@ class DeleteAccountPage extends StatelessWidget {
|
|||
}
|
||||
|
||||
Future<void> _requestEmailForDeletion(BuildContext context) async {
|
||||
final l10n = context.l10n;
|
||||
final AlertDialog alert = AlertDialog(
|
||||
title: const Text(
|
||||
"Delete account",
|
||||
style: TextStyle(
|
||||
title: Text(
|
||||
l10n.deleteAccount,
|
||||
style: const TextStyle(
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
|
@ -208,9 +210,9 @@ class DeleteAccountPage extends StatelessWidget {
|
|||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text(
|
||||
"Send email",
|
||||
style: TextStyle(
|
||||
child: Text(
|
||||
l10n.sendEmail,
|
||||
style: const TextStyle(
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
|
@ -225,7 +227,7 @@ class DeleteAccountPage extends StatelessWidget {
|
|||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
"Ok",
|
||||
l10n.ok,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'dart:io';
|
|||
import 'package:email_validator/email_validator.dart';
|
||||
import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/ente_theme_data.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/billing_plan.dart';
|
||||
import 'package:ente_auth/services/billing_service.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
|
@ -122,13 +123,14 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
|
|||
}
|
||||
|
||||
Widget _getBody() {
|
||||
var passwordStrengthText = 'Weak';
|
||||
final l10n = context.l10n;
|
||||
var passwordStrengthText = l10n.passwordStrengthWeak;
|
||||
var passwordStrengthColor = Colors.redAccent;
|
||||
if (_passwordStrength > kStrongPasswordStrengthThreshold) {
|
||||
passwordStrengthText = 'Strong';
|
||||
passwordStrengthText = l10n.passwordStrengthStrong;
|
||||
passwordStrengthColor = Colors.greenAccent;
|
||||
} else if (_passwordStrength > kMildPasswordStrengthThreshold) {
|
||||
passwordStrengthText = 'Moderate';
|
||||
passwordStrengthText = l10n.passwordStrengthModerate;
|
||||
passwordStrengthColor = Colors.orangeAccent;
|
||||
}
|
||||
return Column(
|
||||
|
@ -141,7 +143,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
|
|||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 30, horizontal: 20),
|
||||
child: Text(
|
||||
'Create new account',
|
||||
l10n.createNewAccount,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
),
|
||||
),
|
||||
|
@ -153,7 +155,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
|
|||
decoration: InputDecoration(
|
||||
fillColor: _emailIsValid ? _validFieldValueColor : null,
|
||||
filled: true,
|
||||
hintText: 'Email',
|
||||
hintText: l10n.email,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 14,
|
||||
|
@ -268,7 +270,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
|
|||
decoration: InputDecoration(
|
||||
fillColor: _passwordsMatch ? _validFieldValueColor : null,
|
||||
filled: true,
|
||||
hintText: "Confirm password",
|
||||
hintText: l10n.confirmPassword,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 14,
|
||||
|
@ -510,13 +512,14 @@ class PricingWidget extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return FutureBuilder<BillingPlans>(
|
||||
future: BillingService.instance.getBillingPlans(),
|
||||
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return _buildPlans(context, snapshot.data);
|
||||
} else if (snapshot.hasError) {
|
||||
return const Text("Oops, Something went wrong.");
|
||||
return Text(l10n.oopsSomethingWentWrong);
|
||||
}
|
||||
return const EnteLoadingWidget();
|
||||
},
|
||||
|
@ -524,6 +527,7 @@ class PricingWidget extends StatelessWidget {
|
|||
}
|
||||
|
||||
Container _buildPlans(BuildContext context, BillingPlans plans) {
|
||||
final l10n = context.l10n;
|
||||
final planWidgets = <BillingPlanWidget>[];
|
||||
for (final plan in plans.plans) {
|
||||
final productID = Platform.isAndroid ? plan.androidID : plan.iosID;
|
||||
|
@ -564,16 +568,16 @@ class PricingWidget extends StatelessWidget {
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: const [
|
||||
Icon(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.close,
|
||||
size: 12,
|
||||
color: Colors.white38,
|
||||
),
|
||||
Padding(padding: EdgeInsets.all(1)),
|
||||
const Padding(padding: EdgeInsets.all(1)),
|
||||
Text(
|
||||
"Close",
|
||||
style: TextStyle(
|
||||
l10n.close,
|
||||
style: const TextStyle(
|
||||
color: Colors.white38,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:ente_auth/ui/account/recovery_key_page.dart';
|
||||
import 'package:ente_auth/ui/common/dynamic_fab.dart';
|
||||
|
@ -400,15 +401,16 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
|
|||
}
|
||||
|
||||
Future<void> _showRecoveryCodeDialog(String password) async {
|
||||
final l10n = context.l10n;
|
||||
final dialog =
|
||||
createProgressDialog(context, "Generating encryption keys...");
|
||||
createProgressDialog(context, l10n.generatingEncryptionKeysTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
final result = await Configuration.instance.generateKey(password);
|
||||
Configuration.instance.setVolatilePassword(null);
|
||||
await dialog.hide();
|
||||
onDone() async {
|
||||
final dialog = createProgressDialog(context, "Please wait...");
|
||||
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
await UserService.instance.setAttributes(result);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/core/errors.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/key_attributes.dart';
|
||||
import 'package:ente_auth/ui/account/recovery_page.dart';
|
||||
import 'package:ente_auth/ui/common/dialogs.dart';
|
||||
|
@ -40,6 +41,7 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
final isKeypadOpen = MediaQuery.of(context).viewInsets.bottom > 100;
|
||||
|
||||
FloatingActionButtonLocation fabLocation() {
|
||||
|
@ -66,10 +68,10 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
|
|||
floatingActionButton: DynamicFAB(
|
||||
isKeypadOpen: isKeypadOpen,
|
||||
isFormValid: _passwordController.text.isNotEmpty,
|
||||
buttonText: 'Verify password',
|
||||
buttonText: l10n.verifyPassword,
|
||||
onPressedFunction: () async {
|
||||
FocusScope.of(context).unfocus();
|
||||
final dialog = createProgressDialog(context, "Please wait...");
|
||||
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
await Configuration.instance.decryptAndSaveSecrets(
|
||||
|
@ -81,14 +83,11 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
|
|||
await dialog.hide();
|
||||
final dialogUserChoice = await showChoiceDialog(
|
||||
context,
|
||||
"Recreate password",
|
||||
"The current device is not powerful enough to verify your "
|
||||
"password, so we need to regenerate it once in a way that "
|
||||
"works with all devices. \n\nPlease login using your "
|
||||
"recovery key and regenerate your password (you can use the same one again if you wish).",
|
||||
firstAction: "Cancel",
|
||||
l10n.recreatePassword,
|
||||
l10n.recreatePasswordMessage,
|
||||
firstAction: l10n.cancel,
|
||||
firstActionColor: Theme.of(context).colorScheme.primary,
|
||||
secondAction: "Use recovery key",
|
||||
secondAction: l10n.useRecoveryKeyAction,
|
||||
secondActionColor: Theme.of(context).colorScheme.primary,
|
||||
);
|
||||
if (dialogUserChoice == DialogUserChoice.secondChoice) {
|
||||
|
@ -107,17 +106,17 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
|
|||
|
||||
final dialogUserChoice = await showChoiceDialog(
|
||||
context,
|
||||
"Incorrect password",
|
||||
"Please try again",
|
||||
firstAction: "Contact Support",
|
||||
l10n.incorrectPassword,
|
||||
l10n.tryAgainMessage,
|
||||
firstAction: l10n.contactSupport,
|
||||
firstActionColor: Theme.of(context).colorScheme.primary,
|
||||
secondAction: "Ok",
|
||||
secondAction: l10n.ok,
|
||||
secondActionColor: Theme.of(context).colorScheme.primary,
|
||||
);
|
||||
if (dialogUserChoice == DialogUserChoice.firstChoice) {
|
||||
await sendLogs(
|
||||
context,
|
||||
"Contact support",
|
||||
l10n.contactSupport,
|
||||
"support@ente.io",
|
||||
postShare: () {},
|
||||
);
|
||||
|
@ -141,6 +140,7 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
|
|||
}
|
||||
|
||||
Widget _getBody() {
|
||||
final l10n = context.l10n;
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
|
@ -151,7 +151,7 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
|
|||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 30, horizontal: 20),
|
||||
child: Text(
|
||||
'Welcome back!',
|
||||
l10n.welcomeBackTitle,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
),
|
||||
),
|
||||
|
@ -174,7 +174,7 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
|
|||
child: TextFormField(
|
||||
autofillHints: const [AutofillHints.password],
|
||||
decoration: InputDecoration(
|
||||
hintText: "Enter your password",
|
||||
hintText: l10n.enterYourPasswordHint,
|
||||
filled: true,
|
||||
contentPadding: const EdgeInsets.all(20),
|
||||
border: UnderlineInputBorder(
|
||||
|
@ -236,7 +236,7 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
|
|||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
"Forgot password",
|
||||
l10n.forgotPassword,
|
||||
style:
|
||||
Theme.of(context).textTheme.subtitle1.copyWith(
|
||||
fontSize: 14,
|
||||
|
@ -248,8 +248,10 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
|
|||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () async {
|
||||
final dialog =
|
||||
createProgressDialog(context, "Please wait...");
|
||||
final dialog = createProgressDialog(
|
||||
context,
|
||||
l10n.pleaseWaitTitle,
|
||||
);
|
||||
await dialog.show();
|
||||
await Configuration.instance.logout();
|
||||
await dialog.hide();
|
||||
|
@ -258,7 +260,7 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
|
|||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
"Change email",
|
||||
l10n.changeEmail,
|
||||
style:
|
||||
Theme.of(context).textTheme.subtitle1.copyWith(
|
||||
fontSize: 14,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/ente_theme_data.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/sessions.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:ente_auth/ui/common/loading_widget.dart';
|
||||
|
@ -111,7 +112,8 @@ class _SessionsPageState extends State<SessionsPage> {
|
|||
}
|
||||
|
||||
Future<void> _terminateSession(Session session) async {
|
||||
final dialog = createProgressDialog(context, "Please wait...");
|
||||
final l10n = context.l10n;
|
||||
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
await UserService.instance.terminateSession(session.token);
|
||||
|
@ -122,8 +124,8 @@ class _SessionsPageState extends State<SessionsPage> {
|
|||
_logger.severe('failed to terminate', e, s);
|
||||
showErrorDialog(
|
||||
context,
|
||||
'Oops',
|
||||
"Something went wrong, please try again",
|
||||
l10n.oops,
|
||||
l10n.somethingWentWrongMessage,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||
|
||||
import 'package:clipboard/clipboard.dart';
|
||||
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/store/code_store.dart';
|
||||
|
@ -49,6 +50,7 @@ class _CodeWidgetState extends State<CodeWidget> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(left: 16, right: 16, bottom: 8, top: 8),
|
||||
child: Slidable(
|
||||
|
@ -174,7 +176,7 @@ class _CodeWidgetState extends State<CodeWidget> {
|
|||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
"next",
|
||||
l10n.nextTotpTitle,
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
),
|
||||
Text(
|
||||
|
@ -224,20 +226,21 @@ class _CodeWidgetState extends State<CodeWidget> {
|
|||
}
|
||||
|
||||
void _onDeletePressed(_) {
|
||||
final l10n = context.l10n;
|
||||
final AlertDialog alert = AlertDialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||
title: Text(
|
||||
"Delete code?",
|
||||
l10n.deleteCodeTitle,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
content: const Text(
|
||||
"Are you sure you want to delete this code? This action is irreversible.",
|
||||
content: Text(
|
||||
l10n.deleteCodeMessage,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text(
|
||||
"Delete",
|
||||
style: TextStyle(
|
||||
child: Text(
|
||||
l10n.delete,
|
||||
style: const TextStyle(
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -240,6 +240,7 @@ class _HomePageState extends State<HomePage> {
|
|||
}
|
||||
|
||||
Widget _getCoachMarkWidget() {
|
||||
final l10n = context.l10n;
|
||||
return GestureDetector(
|
||||
onTap: () async {
|
||||
await PreferenceService.instance.setHasShownCoachMark(true);
|
||||
|
@ -268,7 +269,7 @@ class _HomePageState extends State<HomePage> {
|
|||
height: 24,
|
||||
),
|
||||
Text(
|
||||
"Swipe left to edit or remove codes",
|
||||
l10n.swipeHint,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
const SizedBox(
|
||||
|
@ -282,7 +283,7 @@ class _HomePageState extends State<HomePage> {
|
|||
.setHasShownCoachMark(true);
|
||||
setState(() {});
|
||||
},
|
||||
child: const Text("OK"),
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:ente_auth/ente_theme_data.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/user_details.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:ente_auth/ui/common/dialogs.dart';
|
||||
|
@ -17,6 +18,7 @@ class ChildSubscriptionWidget extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
final String familyAdmin = userDetails.familyData.members
|
||||
.firstWhere((element) => element.isAdmin)
|
||||
.email;
|
||||
|
@ -27,7 +29,7 @@ class ChildSubscriptionWidget extends StatelessWidget {
|
|||
children: [
|
||||
Center(
|
||||
child: Text(
|
||||
"You are on a family plan!",
|
||||
l10n.inFamilyPlanMessage,
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
),
|
||||
),
|
||||
|
@ -76,9 +78,9 @@ class ChildSubscriptionWidget extends StatelessWidget {
|
|||
const EdgeInsets.symmetric(vertical: 18, horizontal: 100),
|
||||
backgroundColor: Colors.red[500],
|
||||
),
|
||||
child: const Text(
|
||||
"Leave Family",
|
||||
style: TextStyle(
|
||||
child: Text(
|
||||
l10n.leaveFamily,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18,
|
||||
color: Colors.white, // same for both themes
|
||||
|
@ -120,19 +122,20 @@ class ChildSubscriptionWidget extends StatelessWidget {
|
|||
}
|
||||
|
||||
Future<void> _leaveFamilyPlan(BuildContext context) async {
|
||||
final l10n = context.l10n;
|
||||
final choice = await showChoiceDialog(
|
||||
context,
|
||||
'Leave family',
|
||||
'Are you sure that you want to leave the family plan?',
|
||||
firstAction: 'No',
|
||||
secondAction: 'Yes',
|
||||
l10n.leaveFamily,
|
||||
l10n.leaveFamilyMessage,
|
||||
firstAction: l10n.no,
|
||||
secondAction: l10n.yes,
|
||||
firstActionColor: Theme.of(context).colorScheme.alternativeColor,
|
||||
secondActionColor: Theme.of(context).colorScheme.onSurface,
|
||||
);
|
||||
if (choice != DialogUserChoice.secondChoice) {
|
||||
return;
|
||||
}
|
||||
final dialog = createProgressDialog(context, "Please wait...");
|
||||
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
await UserService.instance.leaveFamilyPlan();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:ente_auth/ente_theme_data.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/subscription.dart';
|
||||
import 'package:ente_auth/services/billing_service.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
|
@ -49,7 +50,8 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_dialog = createProgressDialog(context, "Please wait...");
|
||||
final l10n = context.l10n;
|
||||
_dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
if (initPaymentUrl == null) {
|
||||
return const EnteLoadingWidget();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/code.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:qr_code_scanner/qr_code_scanner.dart';
|
||||
|
@ -30,9 +31,10 @@ class ScannerPageState extends State<ScannerPage> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Scan"),
|
||||
title: Text(l10n.scan),
|
||||
),
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
|
@ -47,7 +49,7 @@ class ScannerPageState extends State<ScannerPage> {
|
|||
Expanded(
|
||||
flex: 1,
|
||||
child: Center(
|
||||
child: (totp != null) ? Text(totp!) : const Text('Scan a code'),
|
||||
child: (totp != null) ? Text(totp!) : Text(l10n.scanACode),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'dart:ui';
|
|||
|
||||
import 'package:ente_auth/core/configuration.dart';
|
||||
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/services/authenticator_service.dart';
|
||||
import 'package:ente_auth/services/local_authentication_service.dart';
|
||||
|
@ -215,11 +216,12 @@ class DataSectionWidget extends StatelessWidget {
|
|||
}
|
||||
|
||||
Future<void> _pickImportFile(BuildContext context) async {
|
||||
final l10n = context.l10n;
|
||||
FilePickerResult result = await FilePicker.platform.pickFiles();
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
final dialog = createProgressDialog(context, "Please wait...");
|
||||
final dialog = createProgressDialog(context, l10n.pleaseWaitTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
File file = File(result.files.single.path);
|
||||
|
@ -257,7 +259,7 @@ class DataSectionWidget extends StatelessWidget {
|
|||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
"Okay",
|
||||
l10n.ok,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/ui/settings/common_settings.dart';
|
||||
import 'package:ente_auth/ui/settings/settings_section_title.dart';
|
||||
import 'package:ente_auth/ui/settings/settings_text_item.dart';
|
||||
|
@ -12,6 +13,8 @@ class DebugSectionWidget extends StatelessWidget {
|
|||
const DebugSectionWidget({Key key}) : super(key: key);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// This is a debug only section not shown to end users, so these strings are
|
||||
// not translated.
|
||||
return ExpandablePanel(
|
||||
header: const SettingsSectionTitle("Debug"),
|
||||
collapsed: Container(),
|
||||
|
@ -38,6 +41,7 @@ class DebugSectionWidget extends StatelessWidget {
|
|||
}
|
||||
|
||||
void _showKeyAttributesDialog(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
final keyAttributes = Configuration.instance.getKeyAttributes();
|
||||
final AlertDialog alert = AlertDialog(
|
||||
title: const Text("key attributes"),
|
||||
|
@ -73,7 +77,7 @@ class DebugSectionWidget extends StatelessWidget {
|
|||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text("OK"),
|
||||
child: Text(l10n.ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context, rootNavigator: true).pop('dialog');
|
||||
},
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
|
@ -8,13 +9,14 @@ class MadeWithLoveWidget extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
launchUrl(Uri.parse("https://ente.io"));
|
||||
},
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: "made with ❤️ at ",
|
||||
text: l10n.madeWithLoveAtPrefix,
|
||||
style: DefaultTextStyle.of(context).style,
|
||||
children: const <TextSpan>[
|
||||
TextSpan(
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'dart:io';
|
|||
|
||||
import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/ente_theme_data.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/services/local_authentication_service.dart';
|
||||
import 'package:ente_auth/theme/ente_theme.dart';
|
||||
import 'package:ente_auth/ui/account/sessions_page.dart';
|
||||
|
@ -45,6 +46,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
|
|||
}
|
||||
|
||||
Widget _getSectionOptions(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
final List<Widget> children = [];
|
||||
children.addAll([
|
||||
MenuItemWidget(
|
||||
|
@ -106,7 +108,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
|
|||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
"No",
|
||||
l10n.no,
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).colorScheme.defaultTextColor,
|
||||
|
@ -119,7 +121,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
|
|||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
"Yes",
|
||||
l10n.yes,
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).colorScheme.defaultTextColor,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import 'package:ente_auth/core/constants.dart';
|
||||
import 'package:ente_auth/core/logging/super_logging.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/theme/ente_theme.dart';
|
||||
import 'package:ente_auth/ui/components/captioned_text_widget.dart';
|
||||
import 'package:ente_auth/ui/components/expandable_menu_item_widget.dart';
|
||||
|
@ -21,20 +22,22 @@ class SupportSectionWidget extends StatefulWidget {
|
|||
class _SupportSectionWidgetState extends State<SupportSectionWidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return ExpandableMenuItemWidget(
|
||||
title: "Support",
|
||||
title: l10n.support,
|
||||
selectionOptionsWidget: _getSectionOptions(context),
|
||||
leadingIcon: Icons.help_outline_outlined,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _getSectionOptions(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return Column(
|
||||
children: [
|
||||
sectionOptionSpacing,
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: const CaptionedTextWidget(
|
||||
title: "Email",
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: l10n.email,
|
||||
),
|
||||
pressedColor: getEnteColorScheme(context).fillFaint,
|
||||
trailingIcon: Icons.chevron_right_outlined,
|
||||
|
@ -45,14 +48,14 @@ class _SupportSectionWidgetState extends State<SupportSectionWidget> {
|
|||
),
|
||||
sectionOptionSpacing,
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: const CaptionedTextWidget(
|
||||
title: "Report a bug",
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: l10n.reportABug,
|
||||
),
|
||||
pressedColor: getEnteColorScheme(context).fillFaint,
|
||||
trailingIcon: Icons.chevron_right_outlined,
|
||||
trailingIconIsMuted: true,
|
||||
onTap: () async {
|
||||
await sendLogs(context, "Report bug", "auth@ente.io");
|
||||
await sendLogs(context, l10n.reportBug, "auth@ente.io");
|
||||
},
|
||||
onDoubleTap: () async {
|
||||
final zipFilePath = await getZippedLogsFile(context);
|
||||
|
@ -61,8 +64,8 @@ class _SupportSectionWidgetState extends State<SupportSectionWidget> {
|
|||
),
|
||||
sectionOptionSpacing,
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: const CaptionedTextWidget(
|
||||
title: "Crash & error reporting",
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: l10n.crashAndErrorReporting,
|
||||
),
|
||||
trailingSwitch: ToggleSwitchWidget(
|
||||
value: SuperLogging.shouldReportErrors(),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SettingsTitleBarWidget extends StatelessWidget {
|
||||
|
@ -5,6 +6,7 @@ class SettingsTitleBarWidget extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Padding(
|
||||
|
@ -19,7 +21,7 @@ class SettingsTitleBarWidget extends StatelessWidget {
|
|||
},
|
||||
icon: const Icon(Icons.keyboard_double_arrow_left_outlined),
|
||||
),
|
||||
const Text("Settings"),
|
||||
Text(l10n.settings),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @dart=2.9
|
||||
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:ente_auth/ui/lifecycle_event_handler.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -47,10 +48,11 @@ class _TwoFactorAuthenticationPageState
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text(
|
||||
"Two-factor authentication",
|
||||
title: Text(
|
||||
l10n.twoFactorAuthTitle,
|
||||
),
|
||||
),
|
||||
body: _getBody(),
|
||||
|
@ -58,6 +60,7 @@ class _TwoFactorAuthenticationPageState
|
|||
}
|
||||
|
||||
Widget _getBody() {
|
||||
final l10n = context.l10n;
|
||||
final pinPutDecoration = BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Theme.of(context)
|
||||
|
@ -73,9 +76,9 @@ class _TwoFactorAuthenticationPageState
|
|||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
const Text(
|
||||
"Enter the 6-digit code from\nyour authenticator app",
|
||||
style: TextStyle(
|
||||
Text(
|
||||
l10n.enterCodeHint,
|
||||
style: const TextStyle(
|
||||
height: 1.4,
|
||||
fontSize: 16,
|
||||
),
|
||||
|
@ -121,7 +124,7 @@ class _TwoFactorAuthenticationPageState
|
|||
_verifyTwoFactorCode(_code);
|
||||
}
|
||||
: null,
|
||||
child: const Text("Verify"),
|
||||
child: Text(l10n.verify),
|
||||
),
|
||||
),
|
||||
const Padding(padding: EdgeInsets.all(30)),
|
||||
|
@ -132,10 +135,10 @@ class _TwoFactorAuthenticationPageState
|
|||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: const Center(
|
||||
child: Center(
|
||||
child: Text(
|
||||
"Lost device?",
|
||||
style: TextStyle(
|
||||
l10n.lostDeviceTitle,
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
fontSize: 12,
|
||||
),
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:ente_auth/utils/dialog_util.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -27,11 +28,12 @@ class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text(
|
||||
"Recover account",
|
||||
style: TextStyle(
|
||||
title: Text(
|
||||
l10n.recoverAccount,
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
|
@ -44,9 +46,9 @@ class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
|
|||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(60, 0, 60, 0),
|
||||
child: TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
hintText: "Enter your recovery key",
|
||||
contentPadding: EdgeInsets.all(20),
|
||||
decoration: InputDecoration(
|
||||
hintText: l10n.enterRecoveryKeyHint,
|
||||
contentPadding: const EdgeInsets.all(20),
|
||||
),
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
|
@ -79,7 +81,7 @@ class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
|
|||
);
|
||||
}
|
||||
: null,
|
||||
child: const Text("Recover"),
|
||||
child: Text(l10n.recover),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
|
@ -87,15 +89,15 @@ class _TwoFactorRecoveryPageState extends State<TwoFactorRecoveryPage> {
|
|||
onTap: () {
|
||||
showErrorDialog(
|
||||
context,
|
||||
"Contact support",
|
||||
"Please drop an email to support@ente.io from your registered email address",
|
||||
l10n.contactSupport,
|
||||
l10n.contactSupportViaEmailMessage("support@ente.io"),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(40),
|
||||
child: Center(
|
||||
child: Text(
|
||||
"No recovery key?",
|
||||
l10n.noRecoveryKeyTitle,
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
fontSize: 12,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:confetti/confetti.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/ui/common/loading_widget.dart';
|
||||
import 'package:ente_auth/ui/common/progress_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -32,6 +33,7 @@ Future<dynamic> showErrorDialog(
|
|||
String title,
|
||||
String content,
|
||||
) {
|
||||
final l10n = context.l10n;
|
||||
final AlertDialog alert = AlertDialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||
title: title.isEmpty
|
||||
|
@ -44,7 +46,7 @@ Future<dynamic> showErrorDialog(
|
|||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
"Ok",
|
||||
l10n.ok,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:email_validator/email_validator.dart';
|
|||
import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/core/logging/super_logging.dart';
|
||||
import 'package:ente_auth/ente_theme_data.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/ui/common/dialogs.dart';
|
||||
import 'package:ente_auth/ui/tools/debug/log_file_viewer.dart';
|
||||
// import 'package:ente_auth/ui/tools/debug/log_file_viewer.dart';
|
||||
|
@ -37,6 +38,7 @@ Future<void> sendLogs(
|
|||
String subject,
|
||||
String body,
|
||||
}) async {
|
||||
final l10n = context.l10n;
|
||||
final List<Widget> actions = [
|
||||
TextButton(
|
||||
child: Row(
|
||||
|
@ -48,7 +50,7 @@ Future<void> sendLogs(
|
|||
),
|
||||
const Padding(padding: EdgeInsets.all(4)),
|
||||
Text(
|
||||
"View logs",
|
||||
l10n.viewLogsAction,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
|
@ -88,11 +90,9 @@ Future<void> sendLogs(
|
|||
final List<Widget> content = [];
|
||||
content.addAll(
|
||||
[
|
||||
const Text(
|
||||
"This will send across logs to help us debug your issue. "
|
||||
"While we take precautions to ensure that sensitive information is not "
|
||||
"logged, we encourage you to view these logs before sharing them.",
|
||||
style: TextStyle(
|
||||
Text(
|
||||
l10n.sendLogsDescription,
|
||||
style: const TextStyle(
|
||||
height: 1.5,
|
||||
fontSize: 16,
|
||||
),
|
||||
|
@ -148,7 +148,8 @@ Future<void> _sendLogs(
|
|||
}
|
||||
|
||||
Future<String> getZippedLogsFile(BuildContext context) async {
|
||||
final dialog = createProgressDialog(context, "Preparing logs...");
|
||||
final l10n = context.l10n;
|
||||
final dialog = createProgressDialog(context, l10n.preparingLogsTitle);
|
||||
await dialog.show();
|
||||
final logsPath = (await getApplicationSupportDirectory()).path;
|
||||
final logsDirectory = Directory(logsPath + "/logs");
|
||||
|
@ -168,12 +169,13 @@ Future<void> shareLogs(
|
|||
String toEmail,
|
||||
String zipFilePath,
|
||||
) async {
|
||||
final l10n = context.l10n;
|
||||
final result = await showChoiceDialog(
|
||||
context,
|
||||
"Email logs",
|
||||
"Please send the logs to $toEmail",
|
||||
firstAction: "Copy email",
|
||||
secondAction: "Export logs",
|
||||
l10n.emailLogsTitle,
|
||||
l10n.emailLogsMessage(toEmail),
|
||||
firstAction: l10n.copyEmailAction,
|
||||
secondAction: l10n.exportLogsAction,
|
||||
);
|
||||
if (result != null && result == DialogUserChoice.firstChoice) {
|
||||
await Clipboard.setData(ClipboardData(text: toEmail));
|
||||
|
@ -237,21 +239,22 @@ Future<String> _clientInfo() async {
|
|||
}
|
||||
|
||||
void _showNoMailAppsDialog(BuildContext context, String toEmail) {
|
||||
final l10n = context.l10n;
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text('Please email us at $toEmail'),
|
||||
title: Text(l10n.emailUsMessage(toEmail)),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text("Copy email"),
|
||||
child: Text(l10n.copyEmailAction),
|
||||
onPressed: () async {
|
||||
await Clipboard.setData(ClipboardData(text: toEmail));
|
||||
showShortToast(context, 'Copied');
|
||||
showShortToast(context, l10n.copied);
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text("OK"),
|
||||
child: Text(l10n.ok),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
|
|
Loading…
Add table
Reference in a new issue