[Part-2] l10n: Extract strings (#958)

This commit is contained in:
Neeraj Gupta 2023-04-06 14:44:30 +05:30 committed by GitHub
commit 1e77dbd44d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
62 changed files with 4445 additions and 558 deletions

View file

@ -16,17 +16,45 @@ import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
import 'package:intl/src/intl_helpers.dart';
import 'messages_cs.dart' as messages_cs;
import 'messages_de.dart' as messages_de;
import 'messages_en.dart' as messages_en;
import 'messages_es.dart' as messages_es;
import 'messages_fr.dart' as messages_fr;
import 'messages_it.dart' as messages_it;
import 'messages_nl.dart' as messages_nl;
import 'messages_pl.dart' as messages_pl;
typedef Future<dynamic> LibraryLoader();
Map<String, LibraryLoader> _deferredLibraries = {
'cs': () => new SynchronousFuture(null),
'de': () => new SynchronousFuture(null),
'en': () => new SynchronousFuture(null),
'es': () => new SynchronousFuture(null),
'fr': () => new SynchronousFuture(null),
'it': () => new SynchronousFuture(null),
'nl': () => new SynchronousFuture(null),
'pl': () => new SynchronousFuture(null),
};
MessageLookupByLibrary? _findExact(String localeName) {
switch (localeName) {
case 'cs':
return messages_cs.messages;
case 'de':
return messages_de.messages;
case 'en':
return messages_en.messages;
case 'es':
return messages_es.messages;
case 'fr':
return messages_fr.messages;
case 'it':
return messages_it.messages;
case 'nl':
return messages_nl.messages;
case 'pl':
return messages_pl.messages;
default:
return null;
}

View file

@ -0,0 +1,25 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a cs locale. All the
// messages from the main program should be duplicated here with the same
// function name.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
final messages = new MessageLookup();
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'cs';
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{};
}

View file

@ -0,0 +1,25 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a de locale. All the
// messages from the main program should be duplicated here with the same
// function name.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
final messages = new MessageLookup();
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'de';
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{};
}

View file

@ -20,38 +20,121 @@ typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'en';
static String m0(user) =>
static String m0(paymentProvider) =>
"Please cancel your existing subscription from ${paymentProvider} first";
static String m1(user) =>
"${user} will not be able to add more photos to this album\n\nThey will still be able to remove existing photos added by them";
static String m1(supportEmail) =>
static String m2(isFamilyMember, storageAmountInGb) =>
"${Intl.select(isFamilyMember, {
'true': 'Your family has claimed ${storageAmountInGb} Gb so far',
'false': 'You have claimed ${storageAmountInGb} Gb so far',
'other': 'You have claimed ${storageAmountInGb} Gb so far!',
})}";
static String m3(provider) =>
"Please contact us at support@ente.io to manage your ${provider} subscription.";
static String m4(albumName) =>
"This will remove the public link for accessing \"${albumName}\".";
static String m5(supportEmail) =>
"Please drop an email to ${supportEmail} from your registered email address";
static String m2(email) =>
static String m6(count, storageSaved) =>
"Your have cleaned up ${Intl.plural(count, one: '${count} duplicate file', other: '${count} duplicate files')}, saving (${storageSaved}!)";
static String m7(email) =>
"${email} does not have an ente account.\n\nSend them an invite to share photos.";
static String m3(expiryTime) => "Link will expire on ${expiryTime}";
static String m8(storageAmountInGB) =>
"${storageAmountInGB} GB each time someone signs up for a paid plan and applies your code";
static String m4(maxValue) =>
static String m9(endDate) => "Free trial valid till ${endDate}";
static String m10(count) =>
"${Intl.plural(count, one: '${count} item', other: '${count} items')}";
static String m11(expiryTime) => "Link will expire on ${expiryTime}";
static String m12(maxValue) =>
"When set to the maximum (${maxValue}), the device limit will be relaxed to allow for temporary spikes of large number of viewers.";
static String m5(passwordStrengthValue) =>
static String m13(count) =>
"${Intl.plural(count, zero: 'no memories', one: '${count} memory', other: '${count} memories')}";
static String m14(passwordStrengthValue) =>
"Password strength: ${passwordStrengthValue}";
static String m6(verificationID) =>
static String m15(providerName) =>
"Please talk to ${providerName} support if you were charged";
static String m16(reason) =>
"Unfortunately your payment failed due to ${reason}";
static String m17(storeName) => "Rate us on ${storeName}";
static String m18(storageInGB) =>
"3. Both of you get ${storageInGB} GB* free";
static String m19(userEmail) =>
"${userEmail} will be removed from this shared album\n\nAny photos added by them will also be removed from the album";
static String m20(endDate) => "Renews on ${endDate}";
static String m21(count) => "${count} selected";
static String m22(count, yourCount) =>
"${count} selected (${yourCount} yours)";
static String m23(verificationID) =>
"Here\'s my verification ID: ${verificationID} for ente.io.";
static String m7(verificationID) =>
static String m24(verificationID) =>
"Hey, can you confirm that this is your ente.io verification ID: ${verificationID}";
static String m8(numberOfPeople) =>
static String m25(referralCode, referralStorageInGB) =>
"ente referral code: ${referralCode} \n\nApply it in Settings → General → Referrals to get ${referralStorageInGB} GB free after you signup for a paid plan\n\nhttps://ente.io";
static String m26(numberOfPeople) =>
"${Intl.plural(numberOfPeople, zero: 'Share with specific people', one: 'Shared with 1 person', other: 'Shared with ${numberOfPeople} people')}";
static String m9(email) => "This is ${email}\'s Verification ID";
static String m27(fileType) =>
"This ${fileType} will be deleted from your device.";
static String m10(email) => "Verify ${email}";
static String m28(fileType) =>
"This ${fileType} is in both ente and your device.";
static String m29(fileType) => "This ${fileType} will be deleted from ente.";
static String m30(storageAmountInGB) => "${storageAmountInGB} GB";
static String m31(id) =>
"Your ${id} is already linked to another ente account.\nIf you would like to use your ${id} with this account, please contact our support\'\'";
static String m32(endDate) =>
"Your subscription will be cancelled on ${endDate}";
static String m33(storageAmountInGB) =>
"They also get ${storageAmountInGB} GB";
static String m34(email) => "This is ${email}\'s Verification ID";
static String m35(email) => "Verify ${email}";
static String m36(count) =>
"${Intl.plural(count, one: '${count} year ago', other: '${count} years ago')}";
static String m37(storageSaved) =>
"You have successfully freed up ${storageSaved}!";
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
"aNewVersionOfEnteIsAvailable": MessageLookupByLibrary.simpleMessage(
"A new version of ente is available."),
"about": MessageLookupByLibrary.simpleMessage("About"),
"account": MessageLookupByLibrary.simpleMessage("Account"),
"accountWelcomeBack":
MessageLookupByLibrary.simpleMessage("Welcome back!"),
"ackPasswordLostWarningPart1": MessageLookupByLibrary.simpleMessage(
@ -66,6 +149,10 @@ class MessageLookup extends MessageLookupByLibrary {
"addMore": MessageLookupByLibrary.simpleMessage("Add more"),
"addViewer": MessageLookupByLibrary.simpleMessage("Add viewer"),
"addedAs": MessageLookupByLibrary.simpleMessage("Added as"),
"addingToFavorites":
MessageLookupByLibrary.simpleMessage("Adding to favorites..."),
"advanced": MessageLookupByLibrary.simpleMessage("Advanced"),
"advancedSettings": MessageLookupByLibrary.simpleMessage("Advanced"),
"after1Day": MessageLookupByLibrary.simpleMessage("After 1 day"),
"after1Hour": MessageLookupByLibrary.simpleMessage("After 1 hour"),
"after1Month": MessageLookupByLibrary.simpleMessage("After 1 month"),
@ -73,28 +160,105 @@ class MessageLookup extends MessageLookupByLibrary {
"after1Year": MessageLookupByLibrary.simpleMessage("After 1 year"),
"albumOwner": MessageLookupByLibrary.simpleMessage("Owner"),
"albumUpdated": MessageLookupByLibrary.simpleMessage("Album updated"),
"albums": MessageLookupByLibrary.simpleMessage("Albums"),
"allClear": MessageLookupByLibrary.simpleMessage("✨ All clear"),
"allowAddPhotosDescription": MessageLookupByLibrary.simpleMessage(
"Allow people with the link to also add photos to the shared album."),
"allowAddingPhotos":
MessageLookupByLibrary.simpleMessage("Allow adding photos"),
"allowDownloads":
MessageLookupByLibrary.simpleMessage("Allow downloads"),
"allowPeopleToAddPhotos":
MessageLookupByLibrary.simpleMessage("Allow people to add photos"),
"and": MessageLookupByLibrary.simpleMessage("and"),
"androidIosWebDesktop":
MessageLookupByLibrary.simpleMessage("Android, iOS, Web, Desktop"),
"appleId": MessageLookupByLibrary.simpleMessage("Apple ID"),
"apply": MessageLookupByLibrary.simpleMessage("Apply"),
"applyCodeTitle": MessageLookupByLibrary.simpleMessage("Apply code"),
"appstoreSubscription":
MessageLookupByLibrary.simpleMessage("AppStore subscription"),
"archive": MessageLookupByLibrary.simpleMessage("Archive"),
"areYouSureThatYouWantToLeaveTheFamily":
MessageLookupByLibrary.simpleMessage(
"Are you sure that you want to leave the family plan?"),
"areYouSureYouWantToCancel": MessageLookupByLibrary.simpleMessage(
"Are you sure you want to cancel?"),
"areYouSureYouWantToChangeYourPlan":
MessageLookupByLibrary.simpleMessage(
"Are you sure you want to change your plan?"),
"areYouSureYouWantToExit": MessageLookupByLibrary.simpleMessage(
"Are you sure you want to exit?"),
"areYouSureYouWantToLogout": MessageLookupByLibrary.simpleMessage(
"Are you sure you want to logout?"),
"areYouSureYouWantToRenew": MessageLookupByLibrary.simpleMessage(
"Are you sure you want to renew?"),
"askCancelReason": MessageLookupByLibrary.simpleMessage(
"Your subscription was cancelled. Would you like to share the reason?"),
"askDeleteReason": MessageLookupByLibrary.simpleMessage(
"What is the main reason you are deleting your account?"),
"atAFalloutShelter":
MessageLookupByLibrary.simpleMessage("at a fallout shelter"),
"authToChangeLockscreenSetting": MessageLookupByLibrary.simpleMessage(
"Please authenticate to change lockscreen setting"),
"authToChangeYourEmail": MessageLookupByLibrary.simpleMessage(
"Please authenticate to change your email"),
"authToChangeYourPassword": MessageLookupByLibrary.simpleMessage(
"Please authenticate to change your password"),
"authToConfigureTwofactorAuthentication":
MessageLookupByLibrary.simpleMessage(
"Please authenticate to configure two-factor authentication"),
"authToInitiateAccountDeletion": MessageLookupByLibrary.simpleMessage(
"Please authenticate to initiate account deletion"),
"authToViewYourActiveSessions": MessageLookupByLibrary.simpleMessage(
"Please authenticate to view your active sessions"),
"authToViewYourHiddenFiles": MessageLookupByLibrary.simpleMessage(
"Please authenticate to view your hidden files"),
"authToViewYourRecoveryKey": MessageLookupByLibrary.simpleMessage(
"Please authenticate to view your recovery key"),
"available": MessageLookupByLibrary.simpleMessage("Available"),
"backedUpFolders":
MessageLookupByLibrary.simpleMessage("Backed up folders"),
"backup": MessageLookupByLibrary.simpleMessage("Backup"),
"backupFailed": MessageLookupByLibrary.simpleMessage("Backup failed"),
"backupOverMobileData":
MessageLookupByLibrary.simpleMessage("Backup over mobile data"),
"backupSettings":
MessageLookupByLibrary.simpleMessage("Backup settings"),
"backupVideos": MessageLookupByLibrary.simpleMessage("Backup videos"),
"blog": MessageLookupByLibrary.simpleMessage("Blog"),
"byClickingLogInIAgreeToThe": MessageLookupByLibrary.simpleMessage(
"By clicking log in, I agree to the"),
"canOnlyRemoveFilesOwnedByYou": MessageLookupByLibrary.simpleMessage(
"Can only remove files owned by you"),
"cancel": MessageLookupByLibrary.simpleMessage("Cancel"),
"cannotAddMorePhotosAfterBecomingViewer": m0,
"cancelOtherSubscription": m0,
"cancelSubscription":
MessageLookupByLibrary.simpleMessage("Cancel subscription"),
"cannotAddMorePhotosAfterBecomingViewer": m1,
"changeEmail": MessageLookupByLibrary.simpleMessage("Change email"),
"changePassword":
MessageLookupByLibrary.simpleMessage("Change password"),
"changePasswordTitle":
MessageLookupByLibrary.simpleMessage("Change password"),
"changePermissions":
MessageLookupByLibrary.simpleMessage("Change permissions?"),
"checkForUpdates":
MessageLookupByLibrary.simpleMessage("Check for updates"),
"checkInboxAndSpamFolder": MessageLookupByLibrary.simpleMessage(
"Please check your inbox (and spam) to complete verification"),
"checking": MessageLookupByLibrary.simpleMessage("Checking..."),
"claimFreeStorage":
MessageLookupByLibrary.simpleMessage("Claim free storage"),
"claimMore": MessageLookupByLibrary.simpleMessage("Claim more!"),
"claimed": MessageLookupByLibrary.simpleMessage("Claimed"),
"claimedStorageSoFar": m2,
"codeAppliedPageTitle":
MessageLookupByLibrary.simpleMessage("Code applied"),
"codeCopiedToClipboard":
MessageLookupByLibrary.simpleMessage("Code copied to clipboard"),
"codeUsedByYou":
MessageLookupByLibrary.simpleMessage("Code used by you"),
"collabLinkSectionDescription": MessageLookupByLibrary.simpleMessage(
"Create a link to allow people to add and view photos in your shared album without needing an ente app or account. Great for collecting event photos."),
"collaborativeLink":
@ -103,39 +267,79 @@ class MessageLookup extends MessageLookupByLibrary {
"collaboratorsCanAddPhotosAndVideosToTheSharedAlbum":
MessageLookupByLibrary.simpleMessage(
"Collaborators can add photos and videos to the shared album."),
"collectEventPhotos":
MessageLookupByLibrary.simpleMessage("Collect event photos"),
"collectPhotos": MessageLookupByLibrary.simpleMessage("Collect photos"),
"confirm": MessageLookupByLibrary.simpleMessage("Confirm"),
"confirm2FADisable": MessageLookupByLibrary.simpleMessage(
"Are you sure you want to disable two-factor authentication?"),
"confirmAccountDeletion":
MessageLookupByLibrary.simpleMessage("Confirm Account Deletion"),
"confirmDeletePrompt": MessageLookupByLibrary.simpleMessage(
"Yes, I want to permanently delete this account and all its data."),
"confirmPassword":
MessageLookupByLibrary.simpleMessage("Confirm password"),
"confirmPlanChange":
MessageLookupByLibrary.simpleMessage("Confirm plan change"),
"confirmRecoveryKey":
MessageLookupByLibrary.simpleMessage("Confirm recovery key"),
"confirmYourRecoveryKey":
MessageLookupByLibrary.simpleMessage("Confirm your recovery key"),
"contactFamilyAdminPart1":
MessageLookupByLibrary.simpleMessage("Please contact"),
"contactFamilyAdminPart2":
MessageLookupByLibrary.simpleMessage("to manage your subscription"),
"contactSupport":
MessageLookupByLibrary.simpleMessage("Contact support"),
"contactToManageSubscription": m3,
"continueLabel": MessageLookupByLibrary.simpleMessage("Continue"),
"continueOnFreeTrial":
MessageLookupByLibrary.simpleMessage("Continue on free trial"),
"copyLink": MessageLookupByLibrary.simpleMessage("Copy link"),
"copypasteThisCodentoYourAuthenticatorApp":
MessageLookupByLibrary.simpleMessage(
"Copy-paste this code\nto your authenticator app"),
"couldNotBackUpTryLater": MessageLookupByLibrary.simpleMessage(
"We could not backup your data.\nWe will retry later."),
"couldNotUpdateSubscription": MessageLookupByLibrary.simpleMessage(
"Could not update subscription"),
"createAccount": MessageLookupByLibrary.simpleMessage("Create account"),
"createAlbumActionHint": MessageLookupByLibrary.simpleMessage(
"Long press to select photos and click + to create an album"),
"createNewAccount":
MessageLookupByLibrary.simpleMessage("Create new account"),
"createPublicLink":
MessageLookupByLibrary.simpleMessage("Create public link"),
"creatingLink":
MessageLookupByLibrary.simpleMessage("Creating link..."),
"criticalUpdateAvailable":
MessageLookupByLibrary.simpleMessage("Critical update available"),
"currentUsageIs":
MessageLookupByLibrary.simpleMessage("Current usage is "),
"custom": MessageLookupByLibrary.simpleMessage("Custom"),
"darkTheme": MessageLookupByLibrary.simpleMessage("Dark"),
"decrypting": MessageLookupByLibrary.simpleMessage("Decrypting..."),
"deleteAccount": MessageLookupByLibrary.simpleMessage("Delete account"),
"deleteAccountFeedbackPrompt": MessageLookupByLibrary.simpleMessage(
"We are sorry to see you go. Please share your feedback to help us improve."),
"deleteAccountPermanentlyButton":
MessageLookupByLibrary.simpleMessage("Delete Account Permanently"),
"deleteAlbum": MessageLookupByLibrary.simpleMessage("Delete album"),
"deleteAlbumDialogPart1": MessageLookupByLibrary.simpleMessage(
"Also delete the photos (and videos) present in this album from "),
"deleteAlbumDialogPart2Bold":
MessageLookupByLibrary.simpleMessage("all"),
"deleteAlbumDialogPart3": MessageLookupByLibrary.simpleMessage(
" other albums they are part of?"),
"deleteConfirmDialogBody": MessageLookupByLibrary.simpleMessage(
"You are about to permanently delete your account and all its data.\nThis action is irreversible."),
"deleteFromBoth":
MessageLookupByLibrary.simpleMessage("Delete from both"),
"deleteFromDevice":
MessageLookupByLibrary.simpleMessage("Delete from device"),
"deleteFromEnte":
MessageLookupByLibrary.simpleMessage("Delete from ente"),
"deletePhotos": MessageLookupByLibrary.simpleMessage("Delete photos"),
"deleteReason1": MessageLookupByLibrary.simpleMessage(
"Its missing a key feature that I need"),
"deleteReason2": MessageLookupByLibrary.simpleMessage(
@ -146,27 +350,60 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("My reason isnt listed"),
"deleteRequestSLAText": MessageLookupByLibrary.simpleMessage(
"Your request will be processed within 72 hours."),
"deleteSharedAlbum":
MessageLookupByLibrary.simpleMessage("Delete shared album?"),
"deleteSharedAlbumDialogBody": MessageLookupByLibrary.simpleMessage(
"The album will be deleted for everyone\n\nYou will lose access to shared photos in this album that are owned by others"),
"designedToOutlive":
MessageLookupByLibrary.simpleMessage("Designed to outlive"),
"details": MessageLookupByLibrary.simpleMessage("Details"),
"devAccountChanged": MessageLookupByLibrary.simpleMessage(
"The developer account we use to publish ente on App Store has changed. Because of this, you will need to login again.\n\nOur apologies for the inconvenience, but this was unavoidable."),
"deviceLockExplanation": MessageLookupByLibrary.simpleMessage(
"Disable the device screen lock when ente is in the foreground and there is a backup in progress. This is normally not needed, but may help big uploads and initial imports of large libraries complete faster."),
"disableAutoLock":
MessageLookupByLibrary.simpleMessage("Disable auto lock"),
"disableDownloadWarningBody": MessageLookupByLibrary.simpleMessage(
"Viewers can still take screenshots or save a copy of your photos using external tools"),
"disableDownloadWarningTitle":
MessageLookupByLibrary.simpleMessage("Please note"),
"disableLinkMessage": m4,
"disableTwofactor":
MessageLookupByLibrary.simpleMessage("Disable two-factor"),
"discord": MessageLookupByLibrary.simpleMessage("Discord"),
"doThisLater": MessageLookupByLibrary.simpleMessage("Do this later"),
"done": MessageLookupByLibrary.simpleMessage("Done"),
"dropSupportEmail": m1,
"downloading": MessageLookupByLibrary.simpleMessage("Downloading..."),
"dropSupportEmail": m5,
"duplicateFileCountWithStorageSaved": m6,
"eligible": MessageLookupByLibrary.simpleMessage("eligible"),
"email": MessageLookupByLibrary.simpleMessage("Email"),
"emailNoEnteAccount": m2,
"emailNoEnteAccount": m7,
"encryption": MessageLookupByLibrary.simpleMessage("Encryption"),
"encryptionKeys":
MessageLookupByLibrary.simpleMessage("Encryption keys"),
"endToEndEncrypted":
MessageLookupByLibrary.simpleMessage("end-to-end encrypted"),
"endtoendEncryptedByDefault": MessageLookupByLibrary.simpleMessage(
"End-to-end encrypted by default"),
"enteCanEncryptAndPreserveFilesOnlyIfYouGrant":
MessageLookupByLibrary.simpleMessage(
"ente can encrypt and preserve files only if you grant access to them"),
"enteSubscriptionPitch": MessageLookupByLibrary.simpleMessage(
"ente preserves your memories, so they\'re always available to you, even if you lose your device."),
"enteSubscriptionShareWithFamily": MessageLookupByLibrary.simpleMessage(
"Your family can be added to your plan as well."),
"enterCode": MessageLookupByLibrary.simpleMessage("Enter code"),
"enterCodeDescription": MessageLookupByLibrary.simpleMessage(
"Enter the code provided by your friend to claim free storage for both of you"),
"enterEmail": MessageLookupByLibrary.simpleMessage("Enter email"),
"enterNewPasswordToEncrypt": MessageLookupByLibrary.simpleMessage(
"Enter a new password we can use to encrypt your data"),
"enterPassword": MessageLookupByLibrary.simpleMessage("Enter password"),
"enterPasswordToEncrypt": MessageLookupByLibrary.simpleMessage(
"Enter a password we can use to encrypt your data"),
"enterReferralCode":
MessageLookupByLibrary.simpleMessage("Enter referral code"),
"enterThe6digitCodeFromnyourAuthenticatorApp":
MessageLookupByLibrary.simpleMessage(
"Enter the 6-digit code from\nyour authenticator app"),
@ -178,18 +415,52 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Enter your password"),
"enterYourRecoveryKey":
MessageLookupByLibrary.simpleMessage("Enter your recovery key"),
"everywhere": MessageLookupByLibrary.simpleMessage("everywhere"),
"existingUser": MessageLookupByLibrary.simpleMessage("Existing user"),
"expiredLinkInfo": MessageLookupByLibrary.simpleMessage(
"This link has expired. Please select a new expiry time or disable link expiry."),
"exportYourData":
MessageLookupByLibrary.simpleMessage("Export your data"),
"failedToApplyCode":
MessageLookupByLibrary.simpleMessage("Failed to apply code"),
"failedToCancel":
MessageLookupByLibrary.simpleMessage("Failed to cancel"),
"failedToFetchReferralDetails": MessageLookupByLibrary.simpleMessage(
"Unable to fetch referral details. Please try again later."),
"failedToLoadAlbums":
MessageLookupByLibrary.simpleMessage("Failed to load albums"),
"failedToRenew":
MessageLookupByLibrary.simpleMessage("Failed to renew"),
"failedToVerifyPaymentStatus": MessageLookupByLibrary.simpleMessage(
"Failed to verify payment status"),
"familyPlans": MessageLookupByLibrary.simpleMessage("Family plans"),
"faq": MessageLookupByLibrary.simpleMessage("FAQ"),
"faqs": MessageLookupByLibrary.simpleMessage("FAQs"),
"feedback": MessageLookupByLibrary.simpleMessage("Feedback"),
"forYourMemories":
MessageLookupByLibrary.simpleMessage("for your memories"),
"forgotPassword":
MessageLookupByLibrary.simpleMessage("Forgot password"),
"freeStorageClaimed":
MessageLookupByLibrary.simpleMessage("Free storage claimed"),
"freeStorageOnReferralSuccess": m8,
"freeStorageUsable":
MessageLookupByLibrary.simpleMessage("Free storage usable"),
"freeTrial": MessageLookupByLibrary.simpleMessage("Free trial"),
"freeTrialValidTill": m9,
"freeUpDeviceSpace":
MessageLookupByLibrary.simpleMessage("Free up device space"),
"fromYourRegisteredEmailAddress": MessageLookupByLibrary.simpleMessage(
"from your registered email address."),
"general": MessageLookupByLibrary.simpleMessage("General"),
"generatingEncryptionKeys": MessageLookupByLibrary.simpleMessage(
"Generating encryption keys..."),
"googlePlayId": MessageLookupByLibrary.simpleMessage("Google Play ID"),
"hidden": MessageLookupByLibrary.simpleMessage("Hidden"),
"howItWorks": MessageLookupByLibrary.simpleMessage("How it works"),
"howToViewShareeVerificationID": MessageLookupByLibrary.simpleMessage(
"Please ask them to long-press their email address on the settings screen, and verify that the IDs on both devices match."),
"importing": MessageLookupByLibrary.simpleMessage("Importing...."),
"incorrectPasswordTitle":
MessageLookupByLibrary.simpleMessage("Incorrect password"),
"incorrectRecoveryKeyBody": MessageLookupByLibrary.simpleMessage(
@ -198,57 +469,135 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Incorrect recovery key"),
"insecureDevice":
MessageLookupByLibrary.simpleMessage("Insecure device"),
"installManually":
MessageLookupByLibrary.simpleMessage("Install manually"),
"invalidEmailAddress":
MessageLookupByLibrary.simpleMessage("Invalid email address"),
"invalidKey": MessageLookupByLibrary.simpleMessage("Invalid key"),
"invalidRecoveryKey": MessageLookupByLibrary.simpleMessage(
"The recovery key you entered is not valid. Please make sure it "),
"inviteToEnte": MessageLookupByLibrary.simpleMessage("Invite to ente"),
"inviteYourFriends":
MessageLookupByLibrary.simpleMessage("Invite your friends"),
"itemCount": m10,
"itemsWillBeRemovedFromAlbum": MessageLookupByLibrary.simpleMessage(
"Selected items will be removed from this album"),
"keepPhotos": MessageLookupByLibrary.simpleMessage("Keep Photos"),
"kindlyHelpUsWithThisInformation": MessageLookupByLibrary.simpleMessage(
"Kindly help us with this information"),
"lastUpdated": MessageLookupByLibrary.simpleMessage("Last updated"),
"leave": MessageLookupByLibrary.simpleMessage("Leave"),
"leaveFamily": MessageLookupByLibrary.simpleMessage("Leave family"),
"lightTheme": MessageLookupByLibrary.simpleMessage("Light"),
"linkDeviceLimit": MessageLookupByLibrary.simpleMessage("Device limit"),
"linkEnabled": MessageLookupByLibrary.simpleMessage("Enabled"),
"linkExpired": MessageLookupByLibrary.simpleMessage("Expired"),
"linkExpiresOn": m3,
"linkExpiresOn": m11,
"linkExpiry": MessageLookupByLibrary.simpleMessage("Link expiry"),
"linkHasExpired":
MessageLookupByLibrary.simpleMessage("Link has expired"),
"linkNeverExpires": MessageLookupByLibrary.simpleMessage("Never"),
"lockButtonLabel": MessageLookupByLibrary.simpleMessage("Lock"),
"lockScreenEnablePreSteps": MessageLookupByLibrary.simpleMessage(
"To enable lockscreen, please setup device passcode or screen lock in your system settings."),
"lockscreen": MessageLookupByLibrary.simpleMessage("Lockscreen"),
"logInLabel": MessageLookupByLibrary.simpleMessage("Log in"),
"loggingOut": MessageLookupByLibrary.simpleMessage("Logging out..."),
"logout": MessageLookupByLibrary.simpleMessage("Logout"),
"lostDevice": MessageLookupByLibrary.simpleMessage("Lost device?"),
"manage": MessageLookupByLibrary.simpleMessage("Manage"),
"manageDeviceStorage":
MessageLookupByLibrary.simpleMessage("Manage device storage"),
"manageFamily": MessageLookupByLibrary.simpleMessage("Manage Family"),
"manageLink": MessageLookupByLibrary.simpleMessage("Manage link"),
"manageParticipants": MessageLookupByLibrary.simpleMessage("Manage"),
"maxDeviceLimitSpikeHandling": m4,
"manageSubscription":
MessageLookupByLibrary.simpleMessage("Manage subscription"),
"mastodon": MessageLookupByLibrary.simpleMessage("Mastodon"),
"matrix": MessageLookupByLibrary.simpleMessage("Matrix"),
"maxDeviceLimitSpikeHandling": m12,
"memoryCount": m13,
"merchandise": MessageLookupByLibrary.simpleMessage("Merchandise"),
"mobileWebDesktop":
MessageLookupByLibrary.simpleMessage("Mobile, Web, Desktop"),
"moderateStrength": MessageLookupByLibrary.simpleMessage("Moderate"),
"monthly": MessageLookupByLibrary.simpleMessage("Monthly"),
"movedToTrash": MessageLookupByLibrary.simpleMessage("Moved to trash"),
"name": MessageLookupByLibrary.simpleMessage("Name"),
"never": MessageLookupByLibrary.simpleMessage("Never"),
"newAlbum": MessageLookupByLibrary.simpleMessage("New album"),
"newToEnte": MessageLookupByLibrary.simpleMessage("New to ente"),
"newest": MessageLookupByLibrary.simpleMessage("Newest"),
"no": MessageLookupByLibrary.simpleMessage("No"),
"noDeviceThatCanBeDeleted": MessageLookupByLibrary.simpleMessage(
"You\'ve no files on this device that can be deleted"),
"noDuplicates": MessageLookupByLibrary.simpleMessage("✨ No duplicates"),
"noPasswordWarningPart1": MessageLookupByLibrary.simpleMessage(
"We don\'t store this password, so if you forget,"),
"noPasswordWarningPart2":
MessageLookupByLibrary.simpleMessage("we cannot decrypt your data"),
"noPhotosAreBeingBackedUpRightNow":
MessageLookupByLibrary.simpleMessage(
"No photos are being backed up right now"),
"noRecoveryKey":
MessageLookupByLibrary.simpleMessage("No recovery key?"),
"noRecoveryKeyNoDecryption": MessageLookupByLibrary.simpleMessage(
"Due to the nature of our end-to-end encryption protocol, your data cannot be decrypted without your password or recovery key"),
"ok": MessageLookupByLibrary.simpleMessage("Ok"),
"oops": MessageLookupByLibrary.simpleMessage("Oops"),
"oopsSomethingWentWrong":
MessageLookupByLibrary.simpleMessage("Oops, something went wrong"),
"optionalAsShortAsYouLike": MessageLookupByLibrary.simpleMessage(
"Optional, as short as you like..."),
"orPickAnExistingOne":
MessageLookupByLibrary.simpleMessage("Or pick an existing one"),
"password": MessageLookupByLibrary.simpleMessage("Password"),
"passwordChangedSuccessfully": MessageLookupByLibrary.simpleMessage(
"Password changed successfully"),
"passwordLock": MessageLookupByLibrary.simpleMessage("Password lock"),
"passwordStrength": m5,
"passwordStrength": m14,
"paymentDetails":
MessageLookupByLibrary.simpleMessage("Payment details"),
"paymentFailed": MessageLookupByLibrary.simpleMessage("Payment failed"),
"paymentFailedTalkToProvider": m15,
"paymentFailedWithReason": m16,
"peopleUsingYourCode":
MessageLookupByLibrary.simpleMessage("People using your code"),
"photoGridSize":
MessageLookupByLibrary.simpleMessage("Photo grid size"),
"photoSmallCase": MessageLookupByLibrary.simpleMessage("photo"),
"playstoreSubscription":
MessageLookupByLibrary.simpleMessage("PlayStore subscription"),
"pleaseContactSupportAndWeWillBeHappyToHelp":
MessageLookupByLibrary.simpleMessage(
"Please contact support@ente.io and we will be happy to help!"),
"pleaseGrantPermissions":
MessageLookupByLibrary.simpleMessage("Please grant permissions"),
"pleaseLoginAgain":
MessageLookupByLibrary.simpleMessage("Please login again"),
"pleaseSendAnEmailTo":
MessageLookupByLibrary.simpleMessage("Please send an email to"),
"pleaseTryAgain":
MessageLookupByLibrary.simpleMessage("Please try again"),
"pleaseWait": MessageLookupByLibrary.simpleMessage("Please wait..."),
"pleaseWaitForSometimeBeforeRetrying":
MessageLookupByLibrary.simpleMessage(
"Please wait for sometime before retrying"),
"preserveMore": MessageLookupByLibrary.simpleMessage("Preserve more"),
"privacy": MessageLookupByLibrary.simpleMessage("Privacy"),
"privacyPolicy": MessageLookupByLibrary.simpleMessage("privacy policy"),
"privacyPolicyTitle":
MessageLookupByLibrary.simpleMessage("Privacy Policy"),
"privateBackups":
MessageLookupByLibrary.simpleMessage("Private backups"),
"privateSharing":
MessageLookupByLibrary.simpleMessage("Private sharing"),
"publicLinkEnabled":
MessageLookupByLibrary.simpleMessage("Public link enabled"),
"raiseTicket": MessageLookupByLibrary.simpleMessage("Raise ticket"),
"rateTheApp": MessageLookupByLibrary.simpleMessage("Rate the app"),
"rateUs": MessageLookupByLibrary.simpleMessage("Rate us"),
"rateUsOnStore": m17,
"recover": MessageLookupByLibrary.simpleMessage("Recover"),
"recoverAccount":
MessageLookupByLibrary.simpleMessage("Recover account"),
@ -272,13 +621,46 @@ class MessageLookup extends MessageLookupByLibrary {
"The current device is not powerful enough to verify your "),
"recreatePasswordTitle":
MessageLookupByLibrary.simpleMessage("Recreate password"),
"reddit": MessageLookupByLibrary.simpleMessage("Reddit"),
"referralStep1": MessageLookupByLibrary.simpleMessage(
"1. Give this code to your friends"),
"referralStep2": MessageLookupByLibrary.simpleMessage(
"2. They sign up for a paid plan"),
"referralStep3": m18,
"referrals": MessageLookupByLibrary.simpleMessage("Referrals"),
"referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage(
"Referrals are currently paused"),
"remindToEmptyDeviceTrash": MessageLookupByLibrary.simpleMessage(
"Also empty \"Recently Deleted\" from \"Settings\" -> \"Storage\" to claim the freed space"),
"remindToEmptyEnteTrash": MessageLookupByLibrary.simpleMessage(
"Also empty your \"Trash\" to claim the freed up space"),
"remove": MessageLookupByLibrary.simpleMessage("Remove"),
"removeDuplicates":
MessageLookupByLibrary.simpleMessage("Remove duplicates"),
"removeFromAlbum":
MessageLookupByLibrary.simpleMessage("Remove from album?"),
"removeLink": MessageLookupByLibrary.simpleMessage("Remove link"),
"removeParticipant":
MessageLookupByLibrary.simpleMessage("Remove participant"),
"removeParticipantBody": m19,
"removePublicLink":
MessageLookupByLibrary.simpleMessage("Remove public link"),
"removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(
"Some of the items you are removing were added by other people, and you will lose access to them"),
"removeWithQuestionMark":
MessageLookupByLibrary.simpleMessage("Remove?"),
"removingFromFavorites":
MessageLookupByLibrary.simpleMessage("Removing from favorites..."),
"renewSubscription":
MessageLookupByLibrary.simpleMessage("Renew subscription"),
"renewsOn": m20,
"reportABug": MessageLookupByLibrary.simpleMessage("Report a bug"),
"reportBug": MessageLookupByLibrary.simpleMessage("Report bug"),
"resendEmail": MessageLookupByLibrary.simpleMessage("Resend email"),
"resetPasswordTitle":
MessageLookupByLibrary.simpleMessage("Reset password"),
"retry": MessageLookupByLibrary.simpleMessage("Retry"),
"safelyStored": MessageLookupByLibrary.simpleMessage("Safely stored"),
"saveKey": MessageLookupByLibrary.simpleMessage("Save key"),
"saveYourRecoveryKeyIfYouHaventAlready":
MessageLookupByLibrary.simpleMessage(
@ -287,24 +669,51 @@ class MessageLookup extends MessageLookupByLibrary {
"scanThisBarcodeWithnyourAuthenticatorApp":
MessageLookupByLibrary.simpleMessage(
"Scan this barcode with\nyour authenticator app"),
"security": MessageLookupByLibrary.simpleMessage("Security"),
"selectAll": MessageLookupByLibrary.simpleMessage("Select all"),
"selectFoldersForBackup":
MessageLookupByLibrary.simpleMessage("Select folders for backup"),
"selectReason": MessageLookupByLibrary.simpleMessage("Select reason"),
"selectYourPlan":
MessageLookupByLibrary.simpleMessage("Select your plan"),
"selectedFoldersWillBeEncryptedAndBackedUp":
MessageLookupByLibrary.simpleMessage(
"Selected folders will be encrypted and backed up"),
"selectedPhotos": m21,
"selectedPhotosWithYours": m22,
"send": MessageLookupByLibrary.simpleMessage("Send"),
"sendEmail": MessageLookupByLibrary.simpleMessage("Send email"),
"sendInvite": MessageLookupByLibrary.simpleMessage("Send invite"),
"sendLink": MessageLookupByLibrary.simpleMessage("Send link"),
"sessionExpired":
MessageLookupByLibrary.simpleMessage("Session expired"),
"setAPassword": MessageLookupByLibrary.simpleMessage("Set a password"),
"setPasswordTitle":
MessageLookupByLibrary.simpleMessage("Set password"),
"setupComplete": MessageLookupByLibrary.simpleMessage("Setup complete"),
"shareALink": MessageLookupByLibrary.simpleMessage("Share a link"),
"shareMyVerificationID": m6,
"shareTextConfirmOthersVerificationID": m7,
"shareAnAlbumNow":
MessageLookupByLibrary.simpleMessage("Share an album now"),
"shareMyVerificationID": m23,
"shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage(
"Share only with the people you want"),
"shareTextConfirmOthersVerificationID": m24,
"shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage(
"Download ente so we can easily share original "),
"Download ente so we can easily share original quality photos and videos\n\nhttps://ente.io/#download"),
"shareTextReferralCode": m25,
"shareWithNonenteUsers":
MessageLookupByLibrary.simpleMessage("Share with non-ente users"),
"shareWithPeopleSectionTitle": m8,
"shareWithPeopleSectionTitle": m26,
"sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage(
"Create shared and collaborative albums with other ente users, including users on free plans."),
"sharing": MessageLookupByLibrary.simpleMessage("Sharing..."),
"singleFileDeleteFromDevice": m27,
"singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage(
"It will be deleted from all albums."),
"singleFileInBothLocalAndRemote": m28,
"singleFileInRemoteOnly": m29,
"skip": MessageLookupByLibrary.simpleMessage("Skip"),
"social": MessageLookupByLibrary.simpleMessage("Social"),
"someoneSharingAlbumsWithYouShouldSeeTheSameId":
MessageLookupByLibrary.simpleMessage(
"Someone sharing albums with you should see the same ID on their device."),
@ -314,26 +723,55 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage(
"Something went wrong, please try again"),
"sorry": MessageLookupByLibrary.simpleMessage("Sorry"),
"sorryCouldNotAddToFavorites": MessageLookupByLibrary.simpleMessage(
"Sorry, could not add to favorites!"),
"sorryCouldNotRemoveFromFavorites":
MessageLookupByLibrary.simpleMessage(
"Sorry, could not remove from favorites!"),
"sorryWeCouldNotGenerateSecureKeysOnThisDevicennplease":
MessageLookupByLibrary.simpleMessage(
"Sorry, we could not generate secure keys on this device.\n\nplease sign up from a different device."),
"sparkleSuccess": MessageLookupByLibrary.simpleMessage("✨ Success"),
"startBackup": MessageLookupByLibrary.simpleMessage("Start backup"),
"storageInGB": m30,
"storageLimitExceeded":
MessageLookupByLibrary.simpleMessage("Storage limit exceeded"),
"strongStrength": MessageLookupByLibrary.simpleMessage("Strong"),
"subAlreadyLinkedErrMessage": m31,
"subWillBeCancelledOn": m32,
"subscribe": MessageLookupByLibrary.simpleMessage("Subscribe"),
"subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage(
"Looks like your subscription has expired. Please subscribe to enable sharing."),
"subscription": MessageLookupByLibrary.simpleMessage("Subscription"),
"success": MessageLookupByLibrary.simpleMessage("Success"),
"suggestFeatures":
MessageLookupByLibrary.simpleMessage("Suggest features"),
"support": MessageLookupByLibrary.simpleMessage("Support"),
"systemTheme": MessageLookupByLibrary.simpleMessage("System"),
"tapToCopy": MessageLookupByLibrary.simpleMessage("tap to copy"),
"tapToEnterCode":
MessageLookupByLibrary.simpleMessage("Tap to enter code"),
"terminate": MessageLookupByLibrary.simpleMessage("Terminate"),
"terminateSession":
MessageLookupByLibrary.simpleMessage("Terminate session?"),
"terms": MessageLookupByLibrary.simpleMessage("Terms"),
"termsAgreePart1":
MessageLookupByLibrary.simpleMessage("I agree to the "),
"termsOfService":
MessageLookupByLibrary.simpleMessage("terms of service"),
"termsOfServicesTitle": MessageLookupByLibrary.simpleMessage("Terms"),
"thankYou": MessageLookupByLibrary.simpleMessage("Thank you"),
"thankYouForSubscribing":
MessageLookupByLibrary.simpleMessage("Thank you for subscribing!"),
"theDownloadCouldNotBeCompleted": MessageLookupByLibrary.simpleMessage(
"The download could not be completed"),
"theme": MessageLookupByLibrary.simpleMessage("Theme"),
"theyAlsoGetXGb": m33,
"thisCanBeUsedToRecoverYourAccountIfYou":
MessageLookupByLibrary.simpleMessage(
"This can be used to recover your account if you lose your second factor"),
"thisDevice": MessageLookupByLibrary.simpleMessage("This device"),
"thisIsPersonVerificationId": m9,
"thisIsPersonVerificationId": m34,
"thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage(
"This is your Verification ID"),
"thisWillLogYouOutOfTheFollowingDevice":
@ -341,33 +779,96 @@ class MessageLookup extends MessageLookupByLibrary {
"This will log you out of the following device:"),
"thisWillLogYouOutOfThisDevice": MessageLookupByLibrary.simpleMessage(
"This will log you out of this device!"),
"total": MessageLookupByLibrary.simpleMessage("total"),
"trash": MessageLookupByLibrary.simpleMessage("Trash"),
"tryAgain": MessageLookupByLibrary.simpleMessage("Try again"),
"twitter": MessageLookupByLibrary.simpleMessage("Twitter"),
"twoMonthsFreeOnYearlyPlans": MessageLookupByLibrary.simpleMessage(
"2 months free on yearly plans"),
"twofactor": MessageLookupByLibrary.simpleMessage("Two-factor"),
"twofactorAuthenticationPageTitle":
MessageLookupByLibrary.simpleMessage("Two-factor authentication"),
"twofactorSetup":
MessageLookupByLibrary.simpleMessage("Two-factor setup"),
"uncategorized": MessageLookupByLibrary.simpleMessage("Uncategorized"),
"unselectAll": MessageLookupByLibrary.simpleMessage("Unselect all"),
"update": MessageLookupByLibrary.simpleMessage("Update"),
"updateAvailable":
MessageLookupByLibrary.simpleMessage("Update available"),
"updatingFolderSelection": MessageLookupByLibrary.simpleMessage(
"Updating folder selection..."),
"upgrade": MessageLookupByLibrary.simpleMessage("Upgrade"),
"usableReferralStorageInfo": MessageLookupByLibrary.simpleMessage(
"Usable storage is limited by your current plan. Excess claimed storage will automatically become usable when you upgrade your plan."),
"usePublicLinksForPeopleNotOnEnte":
MessageLookupByLibrary.simpleMessage(
"Use public links for people not on ente"),
"useRecoveryKey":
MessageLookupByLibrary.simpleMessage("Use recovery key"),
"verificationId":
MessageLookupByLibrary.simpleMessage("Verification ID"),
"verify": MessageLookupByLibrary.simpleMessage("Verify"),
"verifyEmail": MessageLookupByLibrary.simpleMessage("Verify email"),
"verifyEmailID": m10,
"verifyEmailID": m35,
"verifyPassword":
MessageLookupByLibrary.simpleMessage("Verify password"),
"verifyingRecoveryKey":
MessageLookupByLibrary.simpleMessage("Verifying recovery key..."),
"videoSmallCase": MessageLookupByLibrary.simpleMessage("video"),
"viewActiveSessions":
MessageLookupByLibrary.simpleMessage("View active sessions"),
"viewRecoveryKey":
MessageLookupByLibrary.simpleMessage("View recovery key"),
"viewer": MessageLookupByLibrary.simpleMessage("Viewer"),
"visitWebToManage": MessageLookupByLibrary.simpleMessage(
"Please visit web.ente.io to manage your subscription"),
"weAreOpenSource":
MessageLookupByLibrary.simpleMessage("We are open source!"),
"weakStrength": MessageLookupByLibrary.simpleMessage("Weak"),
"welcomeBack": MessageLookupByLibrary.simpleMessage("Welcome back!"),
"weveSentAMailTo":
MessageLookupByLibrary.simpleMessage("We\'ve sent a mail to"),
"yearly": MessageLookupByLibrary.simpleMessage("Yearly"),
"yearsAgo": m36,
"yes": MessageLookupByLibrary.simpleMessage("Yes"),
"yesCancel": MessageLookupByLibrary.simpleMessage("Yes, cancel"),
"yesConvertToViewer":
MessageLookupByLibrary.simpleMessage("Yes, convert to viewer"),
"yesDelete": MessageLookupByLibrary.simpleMessage("Yes, delete"),
"yesLogout": MessageLookupByLibrary.simpleMessage("Yes, logout"),
"yesRemove": MessageLookupByLibrary.simpleMessage("Yes, remove"),
"yesRenew": MessageLookupByLibrary.simpleMessage("Yes, Renew"),
"you": MessageLookupByLibrary.simpleMessage("You"),
"youAreOnAFamilyPlan":
MessageLookupByLibrary.simpleMessage("You are on a family plan!"),
"youAreOnTheLatestVersion": MessageLookupByLibrary.simpleMessage(
"You are on the latest version"),
"youCanAtMaxDoubleYourStorage": MessageLookupByLibrary.simpleMessage(
"* You can at max double your storage"),
"youCannotDowngradeToThisPlan": MessageLookupByLibrary.simpleMessage(
"You cannot downgrade to this plan"),
"youCannotShareWithYourself": MessageLookupByLibrary.simpleMessage(
"You cannot share with yourself"),
"youHaveSuccessfullyFreedUp": m37,
"yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage(
"Your account has been deleted")
"Your account has been deleted"),
"yourPlanWasSuccessfullyDowngraded":
MessageLookupByLibrary.simpleMessage(
"Your plan was successfully downgraded"),
"yourPlanWasSuccessfullyUpgraded": MessageLookupByLibrary.simpleMessage(
"Your plan was successfully upgraded"),
"yourPurchaseWasSuccessful": MessageLookupByLibrary.simpleMessage(
"Your purchase was successful"),
"yourStorageDetailsCouldNotBeFetched":
MessageLookupByLibrary.simpleMessage(
"Your storage details could not be fetched"),
"yourSubscriptionHasExpired": MessageLookupByLibrary.simpleMessage(
"Your subscription has expired"),
"yourSubscriptionWasUpdatedSuccessfully":
MessageLookupByLibrary.simpleMessage(
"Your subscription was updated successfully"),
"youveNoDuplicateFilesThatCanBeCleared":
MessageLookupByLibrary.simpleMessage(
"You\'ve no duplicate files that can be cleared")
};
}

View file

@ -0,0 +1,25 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a es locale. All the
// messages from the main program should be duplicated here with the same
// function name.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
final messages = new MessageLookup();
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'es';
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{};
}

View file

@ -0,0 +1,25 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a fr locale. All the
// messages from the main program should be duplicated here with the same
// function name.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
final messages = new MessageLookup();
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'fr';
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{};
}

View file

@ -0,0 +1,25 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a it locale. All the
// messages from the main program should be duplicated here with the same
// function name.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
final messages = new MessageLookup();
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'it';
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{};
}

View file

@ -0,0 +1,25 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a nl locale. All the
// messages from the main program should be duplicated here with the same
// function name.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
final messages = new MessageLookup();
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'nl';
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{};
}

View file

@ -0,0 +1,25 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a pl locale. All the
// messages from the main program should be duplicated here with the same
// function name.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
final messages = new MessageLookup();
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'pl';
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{};
}

File diff suppressed because it is too large Load diff

View file

@ -279,6 +279,402 @@
"shareTextConfirmOthersVerificationID": "Hey, can you confirm that this is your ente.io verification ID: {verificationID}",
"somethingWentWrong": "Something went wrong",
"sendInvite": "Send invite",
"shareTextRecommendUsingEnte": "Download ente so we can easily share original ",
"done": "Done"
"shareTextRecommendUsingEnte": "Download ente so we can easily share original quality photos and videos\n\nhttps://ente.io/#download",
"done": "Done",
"applyCodeTitle": "Apply code",
"enterCodeDescription": "Enter the code provided by your friend to claim free storage for both of you",
"apply": "Apply",
"failedToApplyCode": "Failed to apply code",
"enterReferralCode": "Enter referral code",
"codeAppliedPageTitle": "Code applied",
"storageInGB": "{storageAmountInGB} GB",
"claimed": "Claimed",
"@claimed": {
"description": "Used to indicate storage claimed, like 10GB Claimed"
},
"details": "Details",
"claimMore": "Claim more!",
"theyAlsoGetXGb": "They also get {storageAmountInGB} GB",
"freeStorageOnReferralSuccess": "{storageAmountInGB} GB each time someone signs up for a paid plan and applies your code",
"shareTextReferralCode": "ente referral code: {referralCode} \n\nApply it in Settings → General → Referrals to get {referralStorageInGB} GB free after you signup for a paid plan\n\nhttps://ente.io",
"claimFreeStorage": "Claim free storage",
"inviteYourFriends": "Invite your friends",
"failedToFetchReferralDetails": "Unable to fetch referral details. Please try again later.",
"referralStep1": "1. Give this code to your friends",
"referralStep2": "2. They sign up for a paid plan",
"referralStep3": "3. Both of you get {storageInGB} GB* free",
"referralsAreCurrentlyPaused": "Referrals are currently paused",
"youCanAtMaxDoubleYourStorage": "* You can at max double your storage",
"claimedStorageSoFar": "{isFamilyMember, select, true {Your family has claimed {storageAmountInGb} Gb so far} false {You have claimed {storageAmountInGb} Gb so far} other {You have claimed {storageAmountInGb} Gb so far!}}",
"@claimedStorageSoFar": {
"placeholders": {
"isFamilyMember": {
"type": "String",
"example": "true"
},
"storageAmountInGb": {
"type": "int",
"example": "10"
}
}
},
"faq": "FAQ",
"oopsSomethingWentWrong": "Oops, something went wrong",
"peopleUsingYourCode": "People using your code",
"eligible": "eligible",
"total": "total",
"codeUsedByYou": "Code used by you",
"freeStorageClaimed": "Free storage claimed",
"freeStorageUsable": "Free storage usable",
"usableReferralStorageInfo": "Usable storage is limited by your current plan. Excess claimed storage will automatically become usable when you upgrade your plan.",
"removeFromAlbum": "Remove from album?",
"itemsWillBeRemovedFromAlbum": "Selected items will be removed from this album",
"removeShareItemsWarning": "Some of the items you are removing were added by other people, and you will lose access to them",
"addingToFavorites": "Adding to favorites...",
"removingFromFavorites": "Removing from favorites...",
"sorryCouldNotAddToFavorites": "Sorry, could not add to favorites!",
"sorryCouldNotRemoveFromFavorites": "Sorry, could not remove from favorites!",
"subscribeToEnableSharing": "Looks like your subscription has expired. Please subscribe to enable sharing.",
"subscribe": "Subscribe",
"canOnlyRemoveFilesOwnedByYou": "Can only remove files owned by you",
"deleteSharedAlbum": "Delete shared album?",
"deleteAlbum": "Delete album",
"deleteAlbumDialogPart1": "Also delete the photos (and videos) present in this album from ",
"@deleteAlbumDialogPart1": {
"description": "Part of this string 'Also delete the photos (and videos) present in this album from all other albums they are part of?'"
},
"deleteAlbumDialogPart2Bold": "all",
"@deleteAlbumDialogPart2Bold": {
"description": "Part of this string 'Also delete the photos (and videos) present in this album from all other albums they are part of?'"
},
"deleteAlbumDialogPart3": " other albums they are part of?",
"@deleteAlbumDialogPart3": {
"description": "Part of this string 'Also delete the photos (and videos) present in this album from all other albums they are part of?'"
},
"deleteSharedAlbumDialogBody": "The album will be deleted for everyone\n\nYou will lose access to shared photos in this album that are owned by others",
"yesRemove": "Yes, remove",
"creatingLink": "Creating link...",
"removeWithQuestionMark": "Remove?",
"removeParticipantBody": "{userEmail} will be removed from this shared album\n\nAny photos added by them will also be removed from the album",
"keepPhotos": "Keep Photos",
"deletePhotos": "Delete photos",
"inviteToEnte": "Invite to ente",
"removePublicLink": "Remove public link",
"disableLinkMessage": "This will remove the public link for accessing \"{albumName}\".",
"sharing": "Sharing...",
"youCannotShareWithYourself": "You cannot share with yourself",
"archive": "Archive",
"createAlbumActionHint": "Long press to select photos and click + to create an album",
"importing": "Importing....",
"failedToLoadAlbums": "Failed to load albums",
"hidden": "Hidden",
"authToViewYourHiddenFiles": "Please authenticate to view your hidden files",
"trash": "Trash",
"uncategorized": "Uncategorized",
"videoSmallCase": "video",
"photoSmallCase": "photo",
"singleFileDeleteHighlight": "It will be deleted from all albums.",
"singleFileInBothLocalAndRemote": "This {fileType} is in both ente and your device.",
"singleFileInRemoteOnly": "This {fileType} will be deleted from ente.",
"singleFileDeleteFromDevice": "This {fileType} will be deleted from your device.",
"deleteFromEnte": "Delete from ente",
"yesDelete": "Yes, delete",
"movedToTrash": "Moved to trash",
"deleteFromDevice": "Delete from device",
"deleteFromBoth": "Delete from both",
"newAlbum": "New album",
"albums": "Albums",
"memoryCount": "{count, plural, zero{no memories} one{{count} memory} other{{count} memories}}",
"@memoryCount": {
"description": "The text to display the number of memories",
"type": "text",
"placeholders": {
"count": {
"example": "1",
"type": "int"
}
}
},
"selectedPhotos": "{count} selected",
"@selectedPhotos": {
"description": "Display the number of selected photos",
"type": "text",
"placeholders": {
"count": {
"example": "5",
"type": "int"
}
}
},
"selectedPhotosWithYours": "{count} selected ({yourCount} yours)",
"@selectedPhotosWithYours": {
"description": "Display the number of selected photos, including the number of selected photos owned by the user",
"type": "text",
"placeholders": {
"count": {
"example": "12",
"type": "int"
},
"yourCount": {
"example": "2",
"type": "int"
}
}
},
"advancedSettings": "Advanced",
"@advancedSettings": {
"description": "The text to display in the advanced settings section"
},
"photoGridSize": "Photo grid size",
"manageDeviceStorage": "Manage device storage",
"selectFoldersForBackup": "Select folders for backup",
"selectedFoldersWillBeEncryptedAndBackedUp": "Selected folders will be encrypted and backed up",
"unselectAll": "Unselect all",
"selectAll": "Select all",
"skip": "Skip",
"updatingFolderSelection": "Updating folder selection...",
"itemCount": "{count, plural, one{{count} item} other{{count} items}}",
"yearsAgo": "{count, plural, one{{count} year ago} other{{count} years ago}}",
"backupSettings": "Backup settings",
"backupOverMobileData": "Backup over mobile data",
"backupVideos": "Backup videos",
"disableAutoLock": "Disable auto lock",
"deviceLockExplanation": "Disable the device screen lock when ente is in the foreground and there is a backup in progress. This is normally not needed, but may help big uploads and initial imports of large libraries complete faster.",
"about": "About",
"weAreOpenSource": "We are open source!",
"privacy": "Privacy",
"terms": "Terms",
"checkForUpdates": "Check for updates",
"checking": "Checking...",
"youAreOnTheLatestVersion": "You are on the latest version",
"account": "Account",
"manageSubscription": "Manage subscription",
"authToChangeYourEmail": "Please authenticate to change your email",
"changePassword": "Change password",
"authToChangeYourPassword": "Please authenticate to change your password",
"exportYourData": "Export your data",
"logout": "Logout",
"authToInitiateAccountDeletion": "Please authenticate to initiate account deletion",
"areYouSureYouWantToLogout": "Are you sure you want to logout?",
"yesLogout": "Yes, logout",
"aNewVersionOfEnteIsAvailable": "A new version of ente is available.",
"update": "Update",
"installManually": "Install manually",
"criticalUpdateAvailable": "Critical update available",
"updateAvailable": "Update available",
"downloading": "Downloading...",
"theDownloadCouldNotBeCompleted": "The download could not be completed",
"retry": "Retry",
"backedUpFolders": "Backed up folders",
"backup": "Backup",
"freeUpDeviceSpace": "Free up device space",
"allClear": "✨ All clear",
"noDeviceThatCanBeDeleted": "You've no files on this device that can be deleted",
"removeDuplicates": "Remove duplicates",
"noDuplicates": "✨ No duplicates",
"youveNoDuplicateFilesThatCanBeCleared": "You've no duplicate files that can be cleared",
"success": "Success",
"rateUs": "Rate us",
"remindToEmptyDeviceTrash": "Also empty \"Recently Deleted\" from \"Settings\" -> \"Storage\" to claim the freed space",
"youHaveSuccessfullyFreedUp": "You have successfully freed up {storageSaved}!",
"@youHaveSuccessfullyFreedUp": {
"description": "The text to display when the user has successfully freed up storage",
"type": "text",
"placeholders": {
"storageSaved": {
"example": "1.2 GB",
"type": "String"
}
}
},
"remindToEmptyEnteTrash": "Also empty your \"Trash\" to claim the freed up space",
"sparkleSuccess": "✨ Success",
"duplicateFileCountWithStorageSaved": "Your have cleaned up {count, plural, one{{count} duplicate file} other{{count} duplicate files}}, saving ({storageSaved}!)",
"@duplicateFileCountWithStorageSaved": {
"description": "The text to display when the user has successfully cleaned up duplicate files",
"type": "text",
"placeholders": {
"count": {
"example": "1",
"type": "int"
},
"storageSaved": {
"example": "1.2 GB",
"type": "String"
}
}
},
"familyPlans": "Family plans",
"referrals": "Referrals",
"advanced": "Advanced",
"general": "General",
"security": "Security",
"authToViewYourRecoveryKey": "Please authenticate to view your recovery key",
"twofactor": "Two-factor",
"authToConfigureTwofactorAuthentication": "Please authenticate to configure two-factor authentication",
"lockscreen": "Lockscreen",
"authToChangeLockscreenSetting": "Please authenticate to change lockscreen setting",
"lockScreenEnablePreSteps": "To enable lockscreen, please setup device passcode or screen lock in your system settings.",
"viewActiveSessions": "View active sessions",
"authToViewYourActiveSessions": "Please authenticate to view your active sessions",
"disableTwofactor": "Disable two-factor",
"confirm2FADisable": "Are you sure you want to disable two-factor authentication?",
"no": "No",
"yes": "Yes",
"social": "Social",
"rateUsOnStore": "Rate us on {storeName}",
"blog": "Blog",
"merchandise": "Merchandise",
"twitter": "Twitter",
"mastodon": "Mastodon",
"matrix": "Matrix",
"discord": "Discord",
"reddit": "Reddit",
"yourStorageDetailsCouldNotBeFetched": "Your storage details could not be fetched",
"reportABug": "Report a bug",
"reportBug": "Report bug",
"suggestFeatures": "Suggest features",
"support": "Support",
"theme": "Theme",
"lightTheme": "Light",
"darkTheme" : "Dark",
"systemTheme": "System",
"freeTrial": "Free trial",
"selectYourPlan": "Select your plan",
"enteSubscriptionPitch": "ente preserves your memories, so they're always available to you, even if you lose your device.",
"enteSubscriptionShareWithFamily": "Your family can be added to your plan as well.",
"currentUsageIs": "Current usage is ",
"@currentUsageIs": {
"description": "This text is followed by storage usaged",
"examples": [
"Current usage is 1.2 GB"
],
"type": "text"
},
"faqs": "FAQs",
"renewsOn": "Renews on {endDate}",
"freeTrialValidTill": "Free trial valid till {endDate}",
"subWillBeCancelledOn": "Your subscription will be cancelled on {endDate}",
"subscription": "Subscription",
"paymentDetails": "Payment details",
"manageFamily": "Manage Family",
"contactToManageSubscription": "Please contact us at support@ente.io to manage your {provider} subscription.",
"renewSubscription": "Renew subscription",
"cancelSubscription": "Cancel subscription",
"areYouSureYouWantToRenew": "Are you sure you want to renew?",
"yesRenew": "Yes, Renew",
"areYouSureYouWantToCancel": "Are you sure you want to cancel?",
"yesCancel": "Yes, cancel",
"failedToRenew": "Failed to renew",
"failedToCancel": "Failed to cancel",
"twoMonthsFreeOnYearlyPlans": "2 months free on yearly plans",
"monthly": "Monthly",
"@monthly": {
"description": "The text to display for monthly plans",
"type": "text"
},
"yearly": "Yearly",
"@yearly": {
"description": "The text to display for yearly plans",
"type": "text"
},
"confirmPlanChange": "Confirm plan change",
"areYouSureYouWantToChangeYourPlan": "Are you sure you want to change your plan?",
"youCannotDowngradeToThisPlan": "You cannot downgrade to this plan",
"cancelOtherSubscription": "Please cancel your existing subscription from {paymentProvider} first",
"@cancelOtherSubscription": {
"description": "The text to display when the user has an existing subscription from a different payment provider",
"type": "text",
"placeholders": {
"paymentProvider": {
"example": "Apple",
"type": "String"
}
}
},
"optionalAsShortAsYouLike": "Optional, as short as you like...",
"send": "Send",
"askCancelReason": "Your subscription was cancelled. Would you like to share the reason?",
"thankYouForSubscribing": "Thank you for subscribing!",
"yourPurchaseWasSuccessful": "Your purchase was successful",
"yourPlanWasSuccessfullyUpgraded": "Your plan was successfully upgraded",
"yourPlanWasSuccessfullyDowngraded": "Your plan was successfully downgraded",
"yourSubscriptionWasUpdatedSuccessfully": "Your subscription was updated successfully",
"googlePlayId": "Google Play ID",
"appleId": "Apple ID",
"playstoreSubscription": "PlayStore subscription",
"appstoreSubscription": "AppStore subscription",
"subAlreadyLinkedErrMessage": "Your {id} is already linked to another ente account.\nIf you would like to use your {id} with this account, please contact our support''",
"visitWebToManage": "Please visit web.ente.io to manage your subscription",
"couldNotUpdateSubscription": "Could not update subscription",
"pleaseContactSupportAndWeWillBeHappyToHelp": "Please contact support@ente.io and we will be happy to help!",
"paymentFailed": "Payment failed",
"paymentFailedTalkToProvider" : "Please talk to {providerName} support if you were charged",
"@paymentFailedTalkToProvider": {
"description": "The text to display when the payment failed",
"type": "text",
"placeholders": {
"providerName": {
"example": "AppStore|PlayStore",
"type": "String"
}
}
},
"continueOnFreeTrial": "Continue on free trial",
"areYouSureYouWantToExit": "Are you sure you want to exit?",
"thankYou": "Thank you",
"failedToVerifyPaymentStatus": "Failed to verify payment status",
"pleaseWaitForSometimeBeforeRetrying": "Please wait for sometime before retrying",
"paymentFailedWithReason": "Unfortunately your payment failed due to {reason}",
"youAreOnAFamilyPlan": "You are on a family plan!",
"contactFamilyAdminPart1": "Please contact",
"@contactFamilyAdminPart1": {
"description": "Part1 of the sentence 'Please contact {familyAdminName} to manage your subscription'",
"type": "text"
},
"contactFamilyAdminPart2": "to manage your subscription",
"@contactFamilyAdminPart2": {
"description": "Part2 of the sentence 'Please contact {familyAdminName} to manage your subscription'",
"type": "text"
},
"leaveFamily": "Leave family",
"areYouSureThatYouWantToLeaveTheFamily": "Are you sure that you want to leave the family plan?",
"leave": "Leave",
"rateTheApp": "Rate the app",
"startBackup": "Start backup",
"noPhotosAreBeingBackedUpRightNow": "No photos are being backed up right now",
"preserveMore": "Preserve more",
"existingUser": "Existing user",
"privateBackups": "Private backups",
"forYourMemories": "for your memories",
"endtoendEncryptedByDefault": "End-to-end encrypted by default",
"safelyStored": "Safely stored",
"atAFalloutShelter": "at a fallout shelter",
"designedToOutlive": "Designed to outlive",
"available": "Available",
"everywhere": "everywhere",
"androidIosWebDesktop": "Android, iOS, Web, Desktop",
"mobileWebDesktop": "Mobile, Web, Desktop",
"newToEnte": "New to ente",
"pleaseLoginAgain": "Please login again",
"devAccountChanged": "The developer account we use to publish ente on App Store has changed. Because of this, you will need to login again.\n\nOur apologies for the inconvenience, but this was unavoidable.",
"yourSubscriptionHasExpired": "Your subscription has expired",
"storageLimitExceeded": "Storage limit exceeded",
"upgrade": "Upgrade",
"raiseTicket": "Raise ticket",
"backupFailed": "Backup failed",
"couldNotBackUpTryLater": "We could not backup your data.\nWe will retry later.",
"enteCanEncryptAndPreserveFilesOnlyIfYouGrant": "ente can encrypt and preserve files only if you grant access to them",
"pleaseGrantPermissions": "Please grant permissions",
"privateSharing": "Private sharing",
"shareOnlyWithThePeopleYouWant": "Share only with the people you want",
"usePublicLinksForPeopleNotOnEnte": "Use public links for people not on ente",
"allowPeopleToAddPhotos": "Allow people to add photos",
"shareAnAlbumNow": "Share an album now",
"collectEventPhotos": "Collect event photos",
"sessionExpired": "Session expired",
"loggingOut": "Logging out...",
"name": "Name",
"newest": "Newest",
"lastUpdated": "Last updated"
}

View file

@ -1,4 +1,5 @@
import 'package:flutter/cupertino.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/collection.dart';
import 'package:photos/models/file.dart';
import 'package:photos/models/selected_files.dart';
@ -22,7 +23,7 @@ extension CollectionFileActions on CollectionActions {
context: bContext,
buttons: [
ButtonWidget(
labelText: "Remove",
labelText: S.of(bContext).remove,
buttonType:
removingOthersFile ? ButtonType.critical : ButtonType.neutral,
buttonSize: ButtonSize.large,
@ -41,8 +42,8 @@ extension CollectionFileActions on CollectionActions {
}
},
),
const ButtonWidget(
labelText: "Cancel",
ButtonWidget(
labelText: S.of(bContext).cancel,
buttonType: ButtonType.secondary,
buttonSize: ButtonSize.large,
buttonAction: ButtonAction.second,
@ -50,11 +51,10 @@ extension CollectionFileActions on CollectionActions {
isInAlert: true,
),
],
title: removingOthersFile ? "Remove from album?" : null,
title: removingOthersFile ? S.of(bContext).removeFromAlbum : null,
body: removingOthersFile
? "Some of the items you are removing were "
"added by other people, and you will lose access to them"
: "Selected items will be removed from this album",
? S.of(bContext).removeShareItemsWarning
: S.of(bContext).itemsWillBeRemovedFromAlbum,
actionSheetType: ActionSheetType.defaultActionSheet,
);
if (actionResult?.action != null &&
@ -72,7 +72,9 @@ extension CollectionFileActions on CollectionActions {
) async {
final ProgressDialog dialog = createProgressDialog(
context,
markAsFavorite ? "Adding to favorites..." : "Removing from favorites...",
markAsFavorite
? S.of(context).addingToFavorites
: S.of(context).removingFromFavorites,
);
await dialog.show();
@ -84,8 +86,9 @@ extension CollectionFileActions on CollectionActions {
logger.severe(e, s);
showShortToast(
context,
"Sorry, could not" +
(markAsFavorite ? "add to favorites!" : "remove from favorites!"),
markAsFavorite
? S.of(context).sorryCouldNotAddToFavorites
: S.of(context).sorryCouldNotRemoveFromFavorites,
);
} finally {
await dialog.hide();

View file

@ -3,6 +3,7 @@ import 'package:logging/logging.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/db/files_db.dart';
import 'package:photos/ente_theme_data.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/api/collection/create_request.dart';
import 'package:photos/models/collection.dart';
import 'package:photos/models/file.dart';
@ -63,22 +64,23 @@ class CollectionActions {
shouldStickToDarkTheme: true,
buttonAction: ButtonAction.first,
shouldSurfaceExecutionStates: true,
labelText: "Yes, remove",
labelText: S.of(context).yesRemove,
onTap: () async {
await CollectionsService.instance.disableShareUrl(collection);
},
),
const ButtonWidget(
ButtonWidget(
buttonType: ButtonType.secondary,
buttonAction: ButtonAction.cancel,
isInAlert: true,
shouldStickToDarkTheme: true,
labelText: "Cancel",
labelText: S.of(context).cancel,
)
],
title: "Remove public link",
title: S.of(context).removePublicLink,
body:
'This will remove the public link for accessing "${collection.name}".',
//'This will remove the public link for accessing "${collection.name}".',
S.of(context).disableLinkMessage(collection.collectionName),
);
if (actionResult?.action != null) {
if (actionResult!.action == ButtonAction.error) {
@ -94,8 +96,8 @@ class CollectionActions {
BuildContext context,
List<File> files,
) async {
final dialog =
createProgressDialog(context, "Creating link...", isDismissible: true);
final dialog = createProgressDialog(context, S.of(context).creatingLink,
isDismissible: true);
dialog.show();
try {
// create album with emptyName, use collectionCreationTime on UI to
@ -141,33 +143,31 @@ class CollectionActions {
User user,
) async {
final actionResult = await showActionSheet(
context: context,
buttons: [
ButtonWidget(
buttonType: ButtonType.critical,
isInAlert: true,
shouldStickToDarkTheme: true,
buttonAction: ButtonAction.first,
shouldSurfaceExecutionStates: true,
labelText: "Yes, remove",
onTap: () async {
final newSharees = await CollectionsService.instance
.unshare(collection.id, user.email);
collection.updateSharees(newSharees);
},
),
const ButtonWidget(
buttonType: ButtonType.secondary,
buttonAction: ButtonAction.cancel,
isInAlert: true,
shouldStickToDarkTheme: true,
labelText: "Cancel",
)
],
title: "Remove?",
body: '${user.email} will be removed from this shared album\n\nAny '
'photos added by them will also be removed from the album',
);
context: context,
buttons: [
ButtonWidget(
buttonType: ButtonType.critical,
isInAlert: true,
shouldStickToDarkTheme: true,
buttonAction: ButtonAction.first,
shouldSurfaceExecutionStates: true,
labelText: S.of(context).yesRemove,
onTap: () async {
final newSharees = await CollectionsService.instance
.unshare(collection.id, user.email);
collection.updateSharees(newSharees);
},
),
ButtonWidget(
buttonType: ButtonType.secondary,
buttonAction: ButtonAction.cancel,
isInAlert: true,
shouldStickToDarkTheme: true,
labelText: S.of(context).cancel,
)
],
title: S.of(context).removeWithQuestionMark,
body: S.of(context).removeParticipantBody(user.email));
if (actionResult?.action != null) {
if (actionResult!.action == ButtonAction.error) {
showGenericErrorDialog(context: context);
@ -188,19 +188,21 @@ class CollectionActions {
if (!isValidEmail(email)) {
await showErrorDialog(
context,
"Invalid email address",
"Please enter a valid email address.",
S.of(context).invalidEmailAddress,
S.of(context).enterValidEmail,
);
return false;
} else if (email.trim() == Configuration.instance.getEmail()) {
await showErrorDialog(context, "Oops", "You cannot share with yourself");
await showErrorDialog(context, S.of(context).oops,
S.of(context).youCannotShareWithYourself);
return false;
}
ProgressDialog? dialog;
String? publicKey;
if (showProgress) {
dialog = createProgressDialog(context, "Sharing...", isDismissible: true);
dialog = createProgressDialog(context, S.of(context).sharing,
isDismissible: true);
await dialog.show();
}
@ -219,21 +221,19 @@ class CollectionActions {
// is used for error. Do this change along with handling of network errors
await showDialogWidget(
context: context,
title: "Invite to ente",
title: S.of(context).inviteToEnte,
icon: Icons.info_outline,
body: "$email does not have an ente account\n\nSend them an invite to"
" add them after they sign up",
body: S.of(context).emailNoEnteAccount(email),
isDismissible: true,
buttons: [
ButtonWidget(
buttonType: ButtonType.neutral,
icon: Icons.adaptive.share,
labelText: "Send invite",
labelText: S.of(context).sendInvite,
isInAlert: true,
onTap: () async {
shareText(
"Download ente so we can easily share original quality photos"
" and videos\n\nhttps://ente.io/#download",
S.of(context).shareTextRecommendUsingEnte,
);
},
),
@ -281,7 +281,7 @@ class CollectionActions {
context: bContext,
buttons: [
ButtonWidget(
labelText: "Keep Photos",
labelText: S.of(bContext).keepPhotos,
buttonType: ButtonType.neutral,
buttonSize: ButtonSize.large,
buttonAction: ButtonAction.first,
@ -301,7 +301,7 @@ class CollectionActions {
},
),
ButtonWidget(
labelText: "Delete photos",
labelText: S.of(bContext).deletePhotos,
buttonType: ButtonType.critical,
buttonSize: ButtonSize.large,
buttonAction: ButtonAction.second,
@ -316,8 +316,8 @@ class CollectionActions {
}
},
),
const ButtonWidget(
labelText: "Cancel",
ButtonWidget(
labelText: S.of(bContext).cancel,
buttonType: ButtonType.secondary,
buttonSize: ButtonSize.large,
buttonAction: ButtonAction.third,
@ -329,16 +329,15 @@ class CollectionActions {
text: TextSpan(
style: textTheme.body.copyWith(color: textMutedDark),
children: <TextSpan>[
const TextSpan(
text: 'Also delete the photos (and videos) present in this '
'album from ',
TextSpan(
text: S.of(bContext).deleteAlbumDialogPart1,
),
TextSpan(
text: 'all',
text: S.of(bContext).deleteAlbumDialogPart2Bold,
style: textTheme.body.copyWith(color: textBaseDark),
),
const TextSpan(
text: ' other albums they are part of?',
TextSpan(
text: S.of(bContext).deleteAlbumDialogPart3,
),
],
),
@ -367,10 +366,9 @@ class CollectionActions {
final actionResult = await showChoiceActionSheet(
context,
isCritical: true,
title: "Delete shared album?",
firstButtonLabel: "Delete album",
body: "The album will be deleted for everyone\n\nYou will lose access to "
"shared photos in this album that are owned by others",
title: S.of(context).deleteSharedAlbum,
firstButtonLabel: S.of(context).deleteAlbum,
body: S.of(context).deleteSharedAlbumDialogBody,
);
return actionResult?.action != null &&
actionResult!.action == ButtonAction.first;
@ -420,7 +418,7 @@ class CollectionActions {
}
if (!isCollectionOwner && split.ownedByOtherUsers.isNotEmpty) {
showShortToast(context, "Can only remove files owned by you");
showShortToast(context, S.of(context).canOnlyRemoveFilesOwnedByYou);
return;
}
@ -523,15 +521,14 @@ class CollectionActions {
void _showUnSupportedAlert(BuildContext context) {
final AlertDialog alert = AlertDialog(
title: const Text("Sorry"),
content: const Text(
"Looks like your subscription has expired. Please subscribe to enable"
" sharing.",
title: Text(S.of(context).sorry),
content: Text(
S.of(context).subscribeToEnableSharing,
),
actions: [
TextButton(
child: Text(
"Subscribe",
S.of(context).subscribe,
style: TextStyle(
color: Theme.of(context).colorScheme.greenAlternative,
),
@ -549,7 +546,7 @@ class CollectionActions {
),
TextButton(
child: Text(
"Ok",
S.of(context).ok,
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
),

View file

@ -1,5 +1,6 @@
import "package:flutter/cupertino.dart";
import "package:modal_bottom_sheet/modal_bottom_sheet.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/models/file.dart";
import "package:photos/models/file_type.dart";
import "package:photos/theme/colors.dart";
@ -18,19 +19,21 @@ Future<void> showSingleFileDeleteSheet(
Function(File)? onFileRemoved,
}) async {
final List<ButtonWidget> buttons = [];
final String fileType = file.fileType == FileType.video ? "video" : "photo";
final String fileType = file.fileType == FileType.video
? S.of(context).videoSmallCase
: S.of(context).photoSmallCase;
final bool isBothLocalAndRemote =
file.uploadedFileID != null && file.localID != null;
final bool isLocalOnly = file.uploadedFileID == null && file.localID != null;
final bool isRemoteOnly = file.uploadedFileID != null && file.localID == null;
const String bodyHighlight = "It will be deleted from all albums.";
String bodyHighlight = S.of(context).singleFileDeleteHighlight;
String body = "";
if (isBothLocalAndRemote) {
body = "This $fileType is in both ente and your device.";
body = S.of(context).singleFileInBothLocalAndRemote(fileType);
} else if (isRemoteOnly) {
body = "This $fileType will be deleted from ente.";
body = S.of(context).singleFileInRemoteOnly(fileType);
} else if (isLocalOnly) {
body = "This $fileType will be deleted from your device.";
body = S.of(context).singleFileDeleteFromDevice(fileType);
} else {
throw AssertionError("Unexpected state");
}
@ -38,7 +41,9 @@ Future<void> showSingleFileDeleteSheet(
if (isBothLocalAndRemote || isRemoteOnly) {
buttons.add(
ButtonWidget(
labelText: isBothLocalAndRemote ? "Delete from ente" : "Yes, delete",
labelText: isBothLocalAndRemote
? S.of(context).deleteFromEnte
: S.of(context).yesDelete,
buttonType: ButtonType.neutral,
buttonSize: ButtonSize.large,
shouldStickToDarkTheme: true,
@ -47,7 +52,7 @@ Future<void> showSingleFileDeleteSheet(
isInAlert: true,
onTap: () async {
await deleteFilesFromRemoteOnly(context, [file]);
showShortToast(context, "Moved to trash");
showShortToast(context, S.of(context).movedToTrash);
if (isRemoteOnly) {
Navigator.of(context, rootNavigator: true).pop();
if (onFileRemoved != null) {
@ -62,7 +67,9 @@ Future<void> showSingleFileDeleteSheet(
if (isBothLocalAndRemote || isLocalOnly) {
buttons.add(
ButtonWidget(
labelText: isBothLocalAndRemote ? "Delete from device" : "Yes, delete",
labelText: isBothLocalAndRemote
? S.of(context).deleteFromDevice
: S.of(context).yesDelete,
buttonType: ButtonType.neutral,
buttonSize: ButtonSize.large,
shouldStickToDarkTheme: true,
@ -84,7 +91,7 @@ Future<void> showSingleFileDeleteSheet(
if (isBothLocalAndRemote) {
buttons.add(
ButtonWidget(
labelText: "Delete from both",
labelText: S.of(context).deleteFromBoth,
buttonType: ButtonType.neutral,
buttonSize: ButtonSize.large,
shouldStickToDarkTheme: true,
@ -102,8 +109,8 @@ Future<void> showSingleFileDeleteSheet(
);
}
buttons.add(
const ButtonWidget(
labelText: "Cancel",
ButtonWidget(
labelText: S.of(context).cancel,
buttonType: ButtonType.secondary,
buttonSize: ButtonSize.large,
shouldStickToDarkTheme: true,

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/components/buttons/icon_button_widget.dart';
import 'package:photos/ui/components/captioned_text_widget.dart';
@ -34,8 +35,8 @@ class _AdvancedSettingsScreenState extends State<AdvancedSettingsScreen> {
primary: false,
slivers: <Widget>[
TitleBarWidget(
flexibleSpaceTitle: const TitleBarTitleWidget(
title: "Advanced",
flexibleSpaceTitle: TitleBarTitleWidget(
title: S.of(context).advancedSettings,
),
actionIcons: [
IconButtonWidget(
@ -74,7 +75,7 @@ class _AdvancedSettingsScreenState extends State<AdvancedSettingsScreen> {
},
child: MenuItemWidget(
captionedTextWidget: CaptionedTextWidget(
title: "Photo grid size",
title: S.of(context).photoGridSize,
subTitle: _photoGridSize.toString(),
),
menuItemColor: colorScheme.fillFaint,
@ -91,8 +92,8 @@ class _AdvancedSettingsScreenState extends State<AdvancedSettingsScreen> {
height: 24,
),
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Manage device storage",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).manageDeviceStorage,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: Icon(

View file

@ -1,8 +1,8 @@
import 'dart:io';
import 'dart:ui';
import "package:animated_list_plus/animated_list_plus.dart";
import "package:animated_list_plus/transitions.dart";
import 'package:animated_list_plus/animated_list_plus.dart';
import 'package:animated_list_plus/transitions.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
@ -10,6 +10,7 @@ import 'package:photos/core/configuration.dart';
import 'package:photos/db/device_files_db.dart';
import 'package:photos/db/files_db.dart';
import 'package:photos/ente_theme_data.dart';
import 'package:photos/generated/l10n.dart';
import 'package:photos/models/device_collection.dart';
import 'package:photos/models/file.dart';
import 'package:photos/services/remote_sync_service.dart';
@ -86,7 +87,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
child: Container(
padding: const EdgeInsets.fromLTRB(24, 32, 24, 8),
child: Text(
'Select folders for backup',
S.of(context).selectFoldersForBackup,
textAlign: TextAlign.left,
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
@ -100,7 +101,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
Padding(
padding: const EdgeInsets.only(left: 24, right: 48),
child: Text(
"Selected folders will be encrypted and backed up",
S.of(context).selectedFoldersWillBeEncryptedAndBackedUp,
style: Theme.of(context).textTheme.caption!.copyWith(height: 1.3),
),
),
@ -118,8 +119,8 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
child: Text(
_selectedDevicePathIDs.length ==
_allDevicePathIDs.length
? "Unselect all"
: "Select all",
? S.of(context).unselectAll
: S.of(context).selectAll,
textAlign: TextAlign.right,
style: const TextStyle(
decoration: TextDecoration.underline,
@ -188,7 +189,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
Navigator.of(context).pop();
},
child: Text(
"Skip",
S.of(context).skip,
style: Theme.of(context).textTheme.caption!.copyWith(
decoration: TextDecoration.underline,
),
@ -206,7 +207,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
Future<void> updateFolderSettings() async {
final dialog = createProgressDialog(
context,
"Updating folder selection...",
S.of(context).updatingFolderSelection,
);
await dialog.show();
try {
@ -358,9 +359,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
const Padding(padding: EdgeInsets.only(top: 2)),
Text(
(kDebugMode ? 'inApp: $importedCount : device ' : '') +
(deviceCollection.count).toString() +
" item" +
((deviceCollection.count) == 1 ? "" : "s"),
S.of(context).itemCount(deviceCollection.count),
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 12,

View file

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:photos/core/configuration.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/components/buttons/icon_button_widget.dart';
import 'package:photos/ui/components/captioned_text_widget.dart';
@ -23,8 +24,8 @@ class BackupSettingsScreen extends StatelessWidget {
primary: false,
slivers: <Widget>[
TitleBarWidget(
flexibleSpaceTitle: const TitleBarTitleWidget(
title: "Backup settings",
flexibleSpaceTitle: TitleBarTitleWidget(
title: S.of(context).backupSettings,
),
actionIcons: [
IconButtonWidget(
@ -50,8 +51,8 @@ class BackupSettingsScreen extends StatelessWidget {
Column(
children: [
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Backup over mobile data",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).backupOverMobileData,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: ToggleSwitchWidget(
@ -75,8 +76,8 @@ class BackupSettingsScreen extends StatelessWidget {
bgColor: colorScheme.fillFaint,
),
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Backup videos",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).backupVideos,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: ToggleSwitchWidget(
@ -99,9 +100,8 @@ class BackupSettingsScreen extends StatelessWidget {
? Column(
children: [
MenuItemWidget(
captionedTextWidget:
const CaptionedTextWidget(
title: "Disable auto lock",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).disableAutoLock,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: ToggleSwitchWidget(
@ -119,9 +119,9 @@ class BackupSettingsScreen extends StatelessWidget {
alignCaptionedTextToLeft: true,
isGestureDetectorDisabled: true,
),
const MenuSectionDescriptionWidget(
MenuSectionDescriptionWidget(
content:
"Disable the device screen lock when ente is in the foreground and there is a backup in progress. This is normally not needed, but may help big uploads and initial imports of large libraries complete faster.",
S.of(context).deviceLockExplanation,
)
],
)

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/db/files_db.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/magic_metadata.dart';
import "package:photos/services/collections_service.dart";
import 'package:photos/ui/viewer/gallery/archive_page.dart';
@ -58,7 +59,7 @@ class ArchivedCollectionsButtonWidget extends StatelessWidget {
style: textStyle,
children: [
TextSpan(
text: "Archive",
text: S.of(context).archive,
style: Theme.of(context).textTheme.subtitle1,
),
const TextSpan(text: " \u2022 "),
@ -75,7 +76,7 @@ class ArchivedCollectionsButtonWidget extends StatelessWidget {
style: textStyle,
children: [
TextSpan(
text: "Archive",
text: S.of(context).archive,
style: Theme.of(context).textTheme.subtitle1,
),
//need to query in db and bring this value

View file

@ -61,7 +61,7 @@ class CollectionItem extends StatelessWidget {
children: [
const SizedBox(height: 2),
Text(
(c.collection.name ?? "Unnamed").trim(),
(c.collection.collectionName).trim(),
style: enteTextTheme.small,
overflow: TextOverflow.ellipsis,
),

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:photos/core/event_bus.dart';
import 'package:photos/events/tab_changed_event.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/utils/toast_util.dart';
class CreateNewAlbumWidget extends StatelessWidget {
@ -32,7 +33,7 @@ class CreateNewAlbumWidget extends StatelessWidget {
onTap: () async {
await showToast(
context,
"Long press to select photos and click + to create an album",
S.of(context).createAlbumActionHint,
toastLength: Toast.LENGTH_LONG,
);
Bus.instance

View file

@ -7,6 +7,7 @@ import 'package:photos/db/device_files_db.dart';
import 'package:photos/db/files_db.dart';
import 'package:photos/events/backup_folders_updated_event.dart';
import 'package:photos/events/local_photos_updated_event.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/device_collection.dart';
import 'package:photos/services/local_sync_service.dart';
import 'package:photos/ui/collections/device_folder_icon_widget.dart';
@ -68,8 +69,8 @@ class _DeviceFoldersGridViewWidgetState
padding: const EdgeInsets.all(22),
child: (isMigrationDone
? const EmptyState()
: const EmptyState(
text: "Importing....",
: EmptyState(
text: S.of(context).importing,
)),
)
: ListView.builder(
@ -86,7 +87,7 @@ class _DeviceFoldersGridViewWidgetState
);
} else if (snapshot.hasError) {
logger.severe("failed to load device gallery", snapshot.error);
return const Text("Failed to load albums");
return Text(S.of(context).failedToLoadAlbums);
} else {
return const EnteLoadingWidget();
}

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/local_authentication_service.dart';
import 'package:photos/ui/viewer/gallery/hidden_page.dart';
import 'package:photos/utils/navigation_util.dart';
@ -45,7 +46,7 @@ class HiddenCollectionsButtonWidget extends StatelessWidget {
style: textStyle,
children: [
TextSpan(
text: "Hidden",
text: S.of(context).hidden,
style: Theme.of(context).textTheme.subtitle1,
),
const TextSpan(text: " \u2022 "),
@ -74,7 +75,7 @@ class HiddenCollectionsButtonWidget extends StatelessWidget {
final hasAuthenticated = await LocalAuthenticationService.instance
.requestLocalAuthentication(
context,
"Please authenticate to view your hidden files",
S.of(context).authToViewYourHiddenFiles,
);
if (hasAuthenticated) {
routeToPage(

View file

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:photos/core/event_bus.dart';
import 'package:photos/db/trash_db.dart';
import 'package:photos/events/trash_updated_event.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/ui/viewer/gallery/trash_page.dart';
import 'package:photos/utils/navigation_util.dart';
@ -77,7 +78,7 @@ class _TrashButtonWidgetState extends State<TrashButtonWidget> {
style: widget.textStyle,
children: [
TextSpan(
text: "Trash",
text: S.of(context).trash,
style: Theme.of(context).textTheme.subtitle1,
),
const TextSpan(text: " \u2022 "),
@ -94,7 +95,7 @@ class _TrashButtonWidgetState extends State<TrashButtonWidget> {
style: widget.textStyle,
children: [
TextSpan(
text: "Trash",
text: S.of(context).trash,
style: Theme.of(context).textTheme.subtitle1,
),
//need to query in db and bring this value

View file

@ -1,6 +1,7 @@
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:photos/db/files_db.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/collection.dart';
import 'package:photos/services/collections_service.dart';
import 'package:photos/services/hidden_service.dart';
@ -62,7 +63,7 @@ class UnCatCollectionsButtonWidget extends StatelessWidget {
style: textStyle,
children: [
TextSpan(
text: "Uncategorized",
text: S.of(context).uncategorized,
style: Theme.of(context).textTheme.subtitle1,
),
const TextSpan(text: " \u2022 "),
@ -79,7 +80,7 @@ class UnCatCollectionsButtonWidget extends StatelessWidget {
style: textStyle,
children: [
TextSpan(
text: "Uncategorized",
text: S.of(context).uncategorized,
style: Theme.of(context).textTheme.subtitle1,
),
//need to query in db and bring this value

View file

@ -10,6 +10,7 @@ import 'package:photos/events/collection_updated_event.dart';
import 'package:photos/events/local_photos_updated_event.dart';
import 'package:photos/events/user_logged_out_event.dart';
import 'package:photos/extensions/list.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/collection.dart';
import 'package:photos/models/collection_items.dart';
import 'package:photos/services/collections_service.dart';
@ -193,13 +194,13 @@ class _CollectionsGalleryWidgetState extends State<CollectionsGalleryWidget>
String text = key.toString();
switch (key) {
case AlbumSortKey.albumName:
text = "Name";
text = S.of(context).name;
break;
case AlbumSortKey.newestPhoto:
text = "Newest";
text = S.of(context).newest;
break;
case AlbumSortKey.lastUpdated:
text = "Last updated";
text = S.of(context).lastUpdated;
}
return Text(
text,

View file

@ -4,6 +4,7 @@ import "package:flutter/cupertino.dart";
import "package:logging/logging.dart";
import "package:photos/core/event_bus.dart";
import "package:photos/events/collection_updated_event.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/models/collection_items.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/collections/collection_item_widget.dart";
@ -52,7 +53,7 @@ class _AlbumHorizontalListWidgetState extends State<AlbumHorizontalListWidget> {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Text(
"Albums",
S.of(context).albums,
style: getEnteTextTheme(context).large,
),
),

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:photos/db/files_db.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/collection_items.dart';
import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/viewer/file/no_thumbnail_widget.dart';
@ -9,6 +10,7 @@ import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
///https://www.figma.com/file/SYtMyLBs5SAOkTbfMMzhqt/ente-Visual-Design?node-id=7480%3A33462&t=H5AvR79OYDnB9ekw-4
class AlbumListItemWidget extends StatelessWidget {
final CollectionWithThumbnail item;
const AlbumListItemWidget(
this.item, {
super.key,
@ -56,10 +58,8 @@ class AlbumListItemWidget extends StatelessWidget {
),
builder: (context, snapshot) {
if (snapshot.hasData) {
final text =
snapshot.data == 1 ? " memory" : " memories";
return Text(
snapshot.data.toString() + text,
S.of(context).memoryCount(snapshot.data!),
style: textTheme.small.copyWith(
color: colorScheme.textMuted,
),

View file

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:photos/core/configuration.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/gallery_type.dart';
import 'package:photos/models/selected_files.dart';
import 'package:photos/theme/ente_theme.dart';
@ -78,12 +79,15 @@ class _ActionBarWidgetState extends State<ActionBarWidget> {
valueListenable: _selectedFilesNotifier,
builder: (context, value, child) {
return Text(
"${_selectedFilesNotifier.value} selected" +
(_selectedOwnedFilesNotifier.value !=
_selectedFilesNotifier.value
? " (${_selectedOwnedFilesNotifier.value} "
"yours) "
: ""),
_selectedOwnedFilesNotifier.value !=
_selectedFilesNotifier.value
? S.of(context).selectedPhotosWithYours(
_selectedFilesNotifier.value,
_selectedOwnedFilesNotifier.value,
)
: S.of(context).selectedPhotos(
_selectedFilesNotifier.value,
),
style: textTheme.body.copyWith(
color: colorScheme.blurTextBase,
),

View file

@ -3,6 +3,7 @@ import 'dart:ui';
import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart';
import 'package:photos/core/constants.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/gallery_type.dart';
import 'package:photos/models/selected_files.dart';
import 'package:photos/theme/effects.dart';
@ -88,7 +89,7 @@ class BottomActionBarWidget extends StatelessWidget {
},
child: Center(
child: Text(
"Cancel",
S.of(context).cancel,
style: textTheme.bodyBold
.copyWith(color: colorScheme.blurTextBase),
),

View file

@ -2,6 +2,7 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:photos/core/constants.dart';
import "package:photos/generated/l10n.dart";
import "package:photos/models/search/button_result.dart";
import 'package:photos/models/typedefs.dart';
import 'package:photos/theme/colors.dart';
@ -256,11 +257,11 @@ class _TextInputDialogState extends State<TextInputDialog> {
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Expanded(
Expanded(
child: ButtonWidget(
buttonType: ButtonType.secondary,
buttonSize: ButtonSize.small,
labelText: "Cancel",
labelText: S.of(context).cancel,
isInAlert: true,
),
),

View file

@ -1,16 +1,17 @@
import 'package:flutter/cupertino.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/theme/ente_theme.dart';
class KeyboardTopButton extends StatelessWidget {
final VoidCallback? onDoneTap;
final VoidCallback? onCancelTap;
final String doneText;
final String cancelText;
final String? doneText;
final String? cancelText;
const KeyboardTopButton({
super.key,
this.doneText = "Done",
this.cancelText = "Cancel",
this.doneText,
this.cancelText,
this.onDoneTap,
this.onCancelTap,
});
@ -36,12 +37,18 @@ class KeyboardTopButton extends StatelessWidget {
CupertinoButton(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 14),
onPressed: onCancelTap,
child: Text(cancelText, style: enteTheme.bodyBold),
child: Text(
cancelText ?? S.of(context).cancel,
style: enteTheme.bodyBold,
),
),
CupertinoButton(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 14),
onPressed: onDoneTap,
child: Text(doneText, style: enteTheme.bodyBold),
child: Text(
doneText ?? S.of(context).done,
style: enteTheme.bodyBold,
),
),
],
),

View file

@ -1,5 +1,6 @@
import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/theme/ente_theme.dart';
///https://www.figma.com/file/SYtMyLBs5SAOkTbfMMzhqt/ente-Visual-Design?node-id=10854%3A57947&t=H5AvR79OYDnB9ekw-4
@ -36,7 +37,7 @@ class NewAlbumListItemWidget extends StatelessWidget {
Padding(
padding: const EdgeInsets.only(left: 12),
child: Text(
"New album",
S.of(context).newAlbum,
style:
textTheme.body.copyWith(color: colorScheme.textMuted),
),

View file

@ -1,6 +1,7 @@
import "package:flutter/material.dart";
import "package:logging/logging.dart";
import "package:photos/extensions/input_formatter.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/models/api/storage_bonus/storage_bonus.dart";
import "package:photos/models/user_details.dart";
import "package:photos/services/storage_bonus_service.dart";
@ -57,8 +58,8 @@ class _ApplyCodeScreenState extends State<ApplyCodeScreen> {
primary: false,
slivers: <Widget>[
TitleBarWidget(
flexibleSpaceTitle: const TitleBarTitleWidget(
title: "Apply code",
flexibleSpaceTitle: TitleBarTitleWidget(
title: S.of(context).applyCodeTitle,
),
actionIcons: [
IconButtonWidget(
@ -87,8 +88,7 @@ class _ApplyCodeScreenState extends State<ApplyCodeScreen> {
Column(
children: [
Text(
"Enter the code provided by your friend to "
"claim free storage for both of you",
S.of(context).enterCodeDescription,
style: textStyle.small
.copyWith(color: colorScheme.textMuted),
),
@ -115,7 +115,7 @@ class _ApplyCodeScreenState extends State<ApplyCodeScreen> {
ButtonWidget(
buttonType: ButtonType.neutral,
buttonSize: ButtonSize.large,
labelText: "Apply",
labelText: S.of(context).apply,
isDisabled: code.trim().length < 4,
onTap: () async {
try {
@ -137,7 +137,7 @@ class _ApplyCodeScreenState extends State<ApplyCodeScreen> {
showErrorDialogForException(
context: context,
exception: e as Exception,
apiErrorPrefix: "Failed to apply code",
apiErrorPrefix: S.of(context).failedToApplyCode,
);
}
},
@ -167,7 +167,7 @@ class _ApplyCodeScreenState extends State<ApplyCodeScreen> {
),
fillColor: getEnteColorScheme(context).fillFaint,
filled: true,
hintText: 'Enter referral code',
hintText: S.of(context).enterReferralCode,
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 14,

View file

@ -1,5 +1,6 @@
import "package:flutter/material.dart";
import "package:flutter_animate/flutter_animate.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/models/api/storage_bonus/storage_bonus.dart";
import "package:photos/models/user_details.dart";
import "package:photos/theme/ente_theme.dart";
@ -28,8 +29,8 @@ class CodeSuccessScreen extends StatelessWidget {
primary: false,
slivers: <Widget>[
TitleBarWidget(
flexibleSpaceTitle: const TitleBarTitleWidget(
title: "Code applied",
flexibleSpaceTitle: TitleBarTitleWidget(
title: S.of(context).codeAppliedPageTitle,
),
actionIcons: [
IconButtonWidget(
@ -72,18 +73,16 @@ class CodeSuccessScreen extends StatelessWidget {
curve: Curves.easeInOutCubic,
),
Text(
"${referralView.planInfo.storageInGB} GB",
S.of(context).storageInGB(
referralView.planInfo.storageInGB,
),
style: textStyle.h2Bold,
),
Text(
"Claimed",
style: textStyle.body
.copyWith(color: colorScheme.textMuted),
),
Text(S.of(context).claimed, style: textStyle.bodyMuted),
const SizedBox(height: 32),
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Details",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).details,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: Icon(
@ -103,7 +102,10 @@ class CodeSuccessScreen extends StatelessWidget {
InkWell(
onTap: () {
shareText(
"ente referral code: ${referralView.code} \n\nApply it in Settings → General → Referrals to get ${referralView.planInfo.storageInGB} GB free after you signup for a paid plan\n\nhttps://ente.io",
S.of(context).shareTextReferralCode(
referralView.code,
referralView.planInfo.storageInGB,
),
);
},
child: Container(
@ -124,23 +126,25 @@ class CodeSuccessScreen extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"Claim more!",
S.of(context).claimMore,
style: textStyle.body,
),
const SizedBox(height: 8),
Text(
"${referralView.planInfo.storageInGB} GB each time someone signs up for a paid plan and applies your code",
style: textStyle.small
.copyWith(color: colorScheme.textMuted),
S.of(context).freeStorageOnReferralSuccess(
referralView.planInfo.storageInGB,
),
style: textStyle.smallMuted,
textAlign: TextAlign.center,
),
const SizedBox(height: 16),
ReferralCodeWidget(referralView.code),
const SizedBox(height: 16),
Text(
"They also get ${referralView.planInfo.storageInGB} GB",
style: textStyle.small
.copyWith(color: colorScheme.textMuted),
S.of(context).theyAlsoGetXGb(
referralView.planInfo.storageInGB,
),
style: textStyle.smallMuted,
textAlign: TextAlign.center,
),
],

View file

@ -1,4 +1,5 @@
import "package:flutter/material.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/models/api/storage_bonus/storage_bonus.dart";
import "package:photos/models/user_details.dart";
import "package:photos/services/storage_bonus_service.dart";
@ -53,10 +54,10 @@ class _ReferralScreenState extends State<ReferralScreen> {
primary: false,
slivers: <Widget>[
TitleBarWidget(
flexibleSpaceTitle: const TitleBarTitleWidget(
title: "Claim free storage",
flexibleSpaceTitle: TitleBarTitleWidget(
title: S.of(context).claimFreeStorage,
),
flexibleSpaceCaption: "Invite your friends",
flexibleSpaceCaption: S.of(context).inviteYourFriends,
actionIcons: [
IconButtonWidget(
icon: Icons.close_outlined,
@ -84,11 +85,11 @@ class _ReferralScreenState extends State<ReferralScreen> {
notifyParent: _safeUIUpdate,
);
} else if (snapshot.hasError) {
return const Center(
return Center(
child: Padding(
padding: EdgeInsets.all(24.0),
padding: const EdgeInsets.all(24.0),
child: Text(
"Unable to fetch referral details. Please try again later.",
S.of(context).failedToFetchReferralDetails,
),
),
);
@ -134,7 +135,10 @@ class ReferralWidget extends StatelessWidget {
? InkWell(
onTap: () {
shareText(
"ente referral code: ${referralView.code} \n\nApply it in Settings → General → Referrals to get 10 GB free after you signup for a paid plan\n\nhttps://ente.io",
S.of(context).shareTextReferralCode(
referralView.code,
referralView.planInfo.storageInGB,
),
);
},
child: Container(
@ -154,20 +158,20 @@ class ReferralWidget extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"1. Give this code to your "
"friends",
Text(
S.of(context).referralStep1,
),
const SizedBox(height: 12),
ReferralCodeWidget(referralView.code),
const SizedBox(height: 12),
const Text(
"2. They sign up for a paid plan",
Text(
S.of(context).referralStep2,
),
const SizedBox(height: 12),
Text(
"3. Both of you get ${referralView.planInfo.storageInGB} "
"GB* free",
S
.of(context)
.referralStep3(referralView.planInfo.storageInGB),
),
],
),
@ -186,7 +190,7 @@ class ReferralWidget extends StatelessWidget {
),
const SizedBox(height: 12),
Text(
"Referrals are currently paused",
S.of(context).referralsAreCurrentlyPaused,
style: textStyle.small
.copyWith(color: colorScheme.textFaint),
),
@ -197,7 +201,7 @@ class ReferralWidget extends StatelessWidget {
const SizedBox(height: 4),
isReferralEnabled
? Text(
"* You can at max double your storage",
S.of(context).youCanAtMaxDoubleYourStorage,
style: textStyle.mini.copyWith(
color: colorScheme.textMuted,
),
@ -207,8 +211,8 @@ class ReferralWidget extends StatelessWidget {
const SizedBox(height: 24),
referralView.enableApplyCode
? MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Apply code",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).applyCodeTitle,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: Icon(
@ -234,8 +238,8 @@ class ReferralWidget extends StatelessWidget {
)
: const SizedBox.shrink(),
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "FAQ",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).faq,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: Icon(
@ -248,8 +252,8 @@ class ReferralWidget extends StatelessWidget {
onTap: () async {
routeToPage(
context,
const WebPage(
"FAQ",
WebPage(
S.of(context).faq,
"https://ente.io/faq/general/referral-program",
),
);
@ -262,16 +266,18 @@ class ReferralWidget extends StatelessWidget {
vertical: 6.0,
),
child: Text(
"${referralView.isFamilyMember ? 'Your family has' : 'You have'} claimed "
"${convertBytesToAbsoluteGBs(referralView.claimedStorage)} GB so far",
S.of(context).claimedStorageSoFar(
referralView.isFamilyMember.toString().toLowerCase(),
convertBytesToAbsoluteGBs(referralView.claimedStorage),
),
style: textStyle.small.copyWith(
color: colorScheme.textMuted,
),
),
),
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Details",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).details,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: Icon(

View file

@ -1,6 +1,7 @@
import "dart:math";
import "package:flutter/material.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/models/api/storage_bonus/storage_bonus.dart";
import "package:photos/models/user_details.dart";
import "package:photos/services/storage_bonus_service.dart";
@ -14,6 +15,7 @@ import "package:photos/utils/data_util.dart";
class StorageDetailsScreen extends StatefulWidget {
final ReferralView referralView;
final UserDetails userDetails;
const StorageDetailsScreen(this.referralView, this.userDetails, {super.key});
@override
@ -37,10 +39,10 @@ class _StorageDetailsScreenState extends State<StorageDetailsScreen> {
primary: false,
slivers: <Widget>[
TitleBarWidget(
flexibleSpaceTitle: const TitleBarTitleWidget(
title: "Claim free storage",
flexibleSpaceTitle: TitleBarTitleWidget(
title: S.of(context).claimFreeStorage,
),
flexibleSpaceCaption: "Details",
flexibleSpaceCaption: S.of(context).details,
actionIcons: [
IconButtonWidget(
icon: Icons.close_outlined,
@ -79,7 +81,7 @@ class _StorageDetailsScreenState extends State<StorageDetailsScreen> {
}
if (snapshot.hasError) {
debugPrint(snapshot.error.toString());
return const Text("Oops, something went wrong");
return Text(S.of(context).oopsSomethingWentWrong);
} else {
final BonusDetails data = snapshot.data!;
return Padding(
@ -89,24 +91,26 @@ class _StorageDetailsScreenState extends State<StorageDetailsScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BonusInfoSection(
sectionName: "People using your code",
sectionName:
S.of(context).peopleUsingYourCode,
leftValue: data.refUpgradeCount,
leftUnitName: "eligible",
leftUnitName: S.of(context).eligible,
rightValue: data.refUpgradeCount >= 0
? data.refCount
: null,
rightUnitName: "total",
rightUnitName: S.of(context).total,
showUnit: data.refCount > 0,
),
data.hasAppliedCode
? const BonusInfoSection(
sectionName: "Code used by you",
? BonusInfoSection(
sectionName:
S.of(context).codeUsedByYou,
leftValue: 1,
showUnit: false,
)
: const SizedBox.shrink(),
BonusInfoSection(
sectionName: "Free storage claimed",
sectionName: S.of(context).freeStorageClaimed,
leftValue: convertBytesToAbsoluteGBs(
widget.referralView.claimedStorage,
),
@ -114,7 +118,7 @@ class _StorageDetailsScreenState extends State<StorageDetailsScreen> {
rightValue: null,
),
BonusInfoSection(
sectionName: "Free storage usable",
sectionName: S.of(context).freeStorageUsable,
leftValue: convertBytesToAbsoluteGBs(
min(
widget.referralView.claimedStorage,
@ -131,10 +135,7 @@ class _StorageDetailsScreenState extends State<StorageDetailsScreen> {
height: 24,
),
Text(
"Usable storage is limited by your current"
" plan. Excess"
" claimed storage will automatically become"
" usable when you upgrade your plan.",
S.of(context).usableReferralStorageInfo,
style: textStyle.small
.copyWith(color: colorScheme.textMuted),
)

View file

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:photo_manager/photo_manager.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/sync_service.dart';
class GrantPermissionsWidget extends StatelessWidget {
@ -99,14 +100,14 @@ class GrantPermissionsWidget extends StatelessWidget {
await SyncService.instance.onPermissionGranted(state);
} else if (state == PermissionState.denied) {
final AlertDialog alert = AlertDialog(
title: const Text("Please grant permissions"),
content: const Text(
"ente can encrypt and preserve files only if you grant access to them",
title: Text(S.of(context).pleaseGrantPermissions),
content: Text(
S.of(context).enteCanEncryptAndPreserveFilesOnlyIfYouGrant,
),
actions: [
TextButton(
child: Text(
"OK",
S.of(context).ok,
style: Theme.of(context).textTheme.subtitle1!.copyWith(
fontSize: 14,
fontWeight: FontWeight.w700,

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:photos/core/errors.dart';
import 'package:photos/ente_theme_data.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/ui/payment/subscription.dart';
import 'package:photos/utils/email_util.dart';
@ -21,13 +22,13 @@ class HeaderErrorWidget extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Icon(
children: [
const Icon(
Icons.error_outline,
color: Colors.orange,
),
Padding(padding: EdgeInsets.all(4)),
Text("Your subscription has expired"),
const Padding(padding: EdgeInsets.all(4)),
Text(S.of(context).yourSubscriptionHasExpired),
],
),
const Padding(padding: EdgeInsets.all(8)),
@ -36,7 +37,7 @@ class HeaderErrorWidget extends StatelessWidget {
height: 52,
padding: const EdgeInsets.fromLTRB(80, 0, 80, 0),
child: OutlinedButton(
child: const Text("Subscribe"),
child: Text(S.of(context).subscribe),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
@ -60,13 +61,13 @@ class HeaderErrorWidget extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Icon(
children: [
const Icon(
Icons.error_outline,
color: Colors.orange,
),
Padding(padding: EdgeInsets.all(4)),
Text("Storage limit exceeded"),
const Padding(padding: EdgeInsets.all(4)),
Text(S.of(context).storageLimitExceeded),
],
),
const Padding(padding: EdgeInsets.all(8)),
@ -75,9 +76,9 @@ class HeaderErrorWidget extends StatelessWidget {
height: 52,
padding: const EdgeInsets.fromLTRB(80, 0, 80, 0),
child: OutlinedButton(
child: const Text(
"Upgrade",
style: TextStyle(height: 1.1),
child: Text(
S.of(context).upgrade,
style: const TextStyle(height: 1.1),
),
onPressed: () {
Navigator.of(context).push(
@ -104,8 +105,8 @@ class HeaderErrorWidget extends StatelessWidget {
color: Colors.red[400],
),
const Padding(padding: EdgeInsets.all(4)),
const Text(
"We could not backup your data.\nWe will retry later.",
Text(
S.of(context).couldNotBackUpTryLater,
style: TextStyle(height: 1.4),
textAlign: TextAlign.center,
),
@ -125,7 +126,7 @@ class HeaderErrorWidget extends StatelessWidget {
),
),
child: Text(
"Raise ticket",
S.of(context).raiseTicket,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
@ -136,9 +137,9 @@ class HeaderErrorWidget extends StatelessWidget {
onPressed: () {
sendLogs(
context,
"Raise ticket",
S.of(context).raiseTicket,
"support@ente.io",
subject: "Backup failed",
subject: S.of(context).backupFailed,
);
},
),

View file

@ -4,6 +4,7 @@ import 'package:dots_indicator/dots_indicator.dart';
import 'package:flutter/material.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/ente_theme_data.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/update_service.dart';
import 'package:photos/ui/account/email_entry_page.dart';
import 'package:photos/ui/account/login_page.dart';
@ -88,9 +89,9 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
style:
Theme.of(context).colorScheme.optionalActionButtonStyle,
onPressed: _navigateToSignInPage,
child: const Text(
"Existing user",
style: TextStyle(
child: Text(
S.of(context).existingUser,
style: const TextStyle(
color: Colors.black, // same for both themes
),
),
@ -112,7 +113,7 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
padding: const EdgeInsets.symmetric(horizontal: 20),
child: GradientButton(
onTap: _navigateToSignUpPage,
text: "New to ente",
text: S.of(context).newToEnte,
),
);
}
@ -122,25 +123,25 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
constraints: const BoxConstraints(maxHeight: 320),
child: PageView(
children: [
const FeatureItemWidget(
FeatureItemWidget(
"assets/onboarding_lock.png",
"Private backups",
"for your memories",
"End-to-end encrypted by default",
S.of(context).privateBackups,
S.of(context).forYourMemories,
S.of(context).endtoendEncryptedByDefault,
),
const FeatureItemWidget(
FeatureItemWidget(
"assets/onboarding_safe.png",
"Safely stored",
"at a fallout shelter",
"Designed to outlive",
S.of(context).safelyStored,
S.of(context).atAFalloutShelter,
S.of(context).designedToOutlive,
),
FeatureItemWidget(
"assets/onboarding_sync.png",
"Available",
"everywhere",
S.of(context).available,
S.of(context).everywhere,
Platform.isAndroid
? "Android, iOS, Web, Desktop"
: "Mobile, Web, Desktop",
? S.of(context).androidIosWebDesktop
: S.of(context).mobileWebDesktop,
),
],
onPageChanged: (index) {
@ -211,10 +212,8 @@ class _LandingPageWidgetState extends State<LandingPageWidget> {
if (autoLogout) {
final result = await showDialogWidget(
context: context,
title: "Please login again",
body: "The developer account we use to publish ente on App Store has "
"changed. Because of this, you will need to login again.\n\nOur "
"apologies for the inconvenience, but this was unavoidable.",
title: S.of(context).pleaseLoginAgain,
body: S.of(context).devAccountChanged,
buttons: const [
ButtonWidget(
buttonType: ButtonType.neutral,

View file

@ -2,6 +2,7 @@ import "dart:io";
import "package:flutter/cupertino.dart";
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/memory.dart';
import 'package:photos/services/memories_service.dart';
import "package:photos/theme/ente_theme.dart";
@ -187,11 +188,7 @@ class _MemoryWidgetState extends State<MemoryWidget> {
final present = DateTime.now();
final then = DateTime.fromMicrosecondsSinceEpoch(memory.file.creationTime!);
final diffInYears = present.year - then.year;
if (diffInYears == 1) {
return "1 year ago";
} else {
return diffInYears.toString() + " years ago";
}
return S.of(context).yearsAgo(diffInYears);
}
}

View file

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:photo_manager/photo_manager.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/local_sync_service.dart';
import 'package:photos/ui/backup_folder_selection_page.dart';
import 'package:photos/ui/common/gradient_button.dart';
@ -29,7 +30,7 @@ class PreserveFooterWidget extends StatelessWidget {
);
}
},
text: "Preserve more",
text: S.of(context).preserveMore,
iconData: Icons.cloud_upload_outlined,
),
);

View file

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:photos/generated/l10n.dart';
import 'package:photos/services/local_sync_service.dart';
import 'package:photos/ui/backup_folder_selection_page.dart';
import 'package:photos/ui/common/gradient_button.dart';
@ -24,7 +25,7 @@ class StartBackupHookWidget extends StatelessWidget {
),
),
Text(
'No photos are being backed up right now',
S.of(context).noPhotosAreBeingBackedUpRightNow,
style: Theme.of(context)
.textTheme
.caption!
@ -45,13 +46,13 @@ class StartBackupHookWidget extends StatelessWidget {
} else {
routeToPage(
context,
const BackupFolderSelectionPage(
buttonText: "Start backup",
BackupFolderSelectionPage(
buttonText: S.of(context).startBackup,
),
);
}
},
text: "Start backup",
text: S.of(context).startBackup,
),
),
),

View file

@ -19,6 +19,7 @@ import 'package:photos/events/sync_status_update_event.dart';
import 'package:photos/events/tab_changed_event.dart';
import 'package:photos/events/trigger_logout_event.dart';
import 'package:photos/events/user_logged_out_event.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/selected_files.dart';
import 'package:photos/services/app_lifecycle_service.dart';
import 'package:photos/services/collections_service.dart';
@ -192,12 +193,12 @@ class _HomeWidgetState extends State<HomeWidget> {
Future<void> _autoLogoutAlert() async {
final AlertDialog alert = AlertDialog(
title: const Text("Session expired"),
content: const Text("Please login again"),
title: Text(S.of(context).sessionExpired),
content: Text(S.of(context).pleaseLoginAgain),
actions: [
TextButton(
child: Text(
"Ok",
S.of(context).ok,
style: TextStyle(
color: Theme.of(context).colorScheme.greenAlternative,
),
@ -205,7 +206,8 @@ class _HomeWidgetState extends State<HomeWidget> {
onPressed: () async {
Navigator.of(context, rootNavigator: true).pop('dialog');
Navigator.of(context).popUntil((route) => route.isFirst);
final dialog = createProgressDialog(context, "Logging out...");
final dialog =
createProgressDialog(context, S.of(context).loggingOut);
await dialog.show();
await Configuration.instance.logout();
await dialog.hide();

View file

@ -1,5 +1,6 @@
import "package:flutter/material.dart";
import "package:photos/core/constants.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/collection_action_sheet.dart";
import 'package:photos/ui/components/buttons/button_widget.dart';
@ -44,24 +45,24 @@ class EmptyStateWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Private sharing",
S.of(context).privateSharing,
style: textTheme.h3Bold,
textAlign: TextAlign.start,
),
const SizedBox(height: 24),
Column(
mainAxisSize: MainAxisSize.min,
children: const [
children: [
EmptyStateItemWidget(
"Share only with the people you want",
S.of(context).shareOnlyWithThePeopleYouWant,
),
SizedBox(height: 12),
const SizedBox(height: 12),
EmptyStateItemWidget(
"Use public links for people not on ente",
S.of(context).usePublicLinksForPeopleNotOnEnte,
),
SizedBox(height: 12),
const SizedBox(height: 12),
EmptyStateItemWidget(
"Allow people to add photos",
S.of(context).allowPeopleToAddPhotos,
),
],
),
@ -76,7 +77,7 @@ class EmptyStateWidget extends StatelessWidget {
children: [
ButtonWidget(
buttonType: ButtonType.trailingIconPrimary,
labelText: "Share an album now",
labelText: S.of(context).shareAnAlbumNow,
icon: Icons.arrow_forward_outlined,
onTap: () async {
showCollectionActionSheet(
@ -88,7 +89,7 @@ class EmptyStateWidget extends StatelessWidget {
const SizedBox(height: 6),
ButtonWidget(
buttonType: ButtonType.trailingIconSecondary,
labelText: "Collect event photos",
labelText: S.of(context).collectEventPhotos,
icon: Icons.add_photo_alternate_outlined,
onTap: () async {
showCollectionActionSheet(
@ -100,10 +101,10 @@ class EmptyStateWidget extends StatelessWidget {
const SizedBox(height: 6),
ButtonWidget(
buttonType: ButtonType.trailingIconSecondary,
labelText: "Invite your friends",
labelText: S.of(context).inviteYourFriends,
icon: Icons.ios_share_outlined,
onTap: () async {
shareText("Check out https://ente.io");
shareText(S.of(context).shareTextRecommendUsingEnte);
},
),
],

View file

@ -1,6 +1,7 @@
import "dart:io";
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/update_service.dart';
import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/components/buttons/button_widget.dart';
@ -67,7 +68,7 @@ class _ChangeLogPageState extends State<ChangeLogPage> {
ButtonWidget(
buttonType: ButtonType.trailingIconPrimary,
buttonSize: ButtonSize.large,
labelText: "Continue",
labelText: S.of(context).continueLabel,
icon: Icons.arrow_forward_outlined,
onTap: () async {
await UpdateService.instance.hideChangeLog();
@ -82,7 +83,7 @@ class _ChangeLogPageState extends State<ChangeLogPage> {
ButtonWidget(
buttonType: ButtonType.trailingIconSecondary,
buttonSize: ButtonSize.large,
labelText: "Rate the app",
labelText: S.of(context).rateTheApp,
icon: Icons.favorite_rounded,
iconColor: enteColorScheme.primary500,
onTap: () async {

View file

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/user_details.dart';
import 'package:photos/services/user_service.dart';
import 'package:photos/ui/components/buttons/button_widget.dart';
@ -25,7 +26,7 @@ class ChildSubscriptionWidget extends StatelessWidget {
children: [
Center(
child: Text(
"You are on a family plan!",
S.of(context).youAreOnAFamilyPlan,
style: Theme.of(context).textTheme.bodyText1,
),
),
@ -38,16 +39,16 @@ class ChildSubscriptionWidget extends StatelessWidget {
textAlign: TextAlign.center,
text: TextSpan(
children: [
const TextSpan(
text: "Please contact ",
TextSpan(
text: S.of(context).contactFamilyAdminPart1 + " ",
),
TextSpan(
text: familyAdmin,
style:
const TextStyle(color: Color.fromRGBO(29, 185, 84, 1)),
),
const TextSpan(
text: " to manage your subscription",
TextSpan(
text: " " + S.of(context).contactFamilyAdminPart2,
),
],
style: Theme.of(context).textTheme.bodyText1,
@ -74,9 +75,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(
S.of(context).leaveFamily,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.white, // same for both themes
@ -94,17 +95,9 @@ class ChildSubscriptionWidget extends StatelessWidget {
text: TextSpan(
children: [
TextSpan(
text: "Please contact ",
style: Theme.of(context).textTheme.bodyText2,
),
TextSpan(
text: "support@ente.io",
style: Theme.of(context).textTheme.bodyText2?.copyWith(
color: const Color.fromRGBO(29, 185, 84, 1),
),
),
TextSpan(
text: " for help",
text: S
.of(context)
.pleaseContactSupportAndWeWillBeHappyToHelp,
style: Theme.of(context).textTheme.bodyText2,
),
],
@ -120,9 +113,9 @@ class ChildSubscriptionWidget extends StatelessWidget {
Future<void> _leaveFamilyPlan(BuildContext context) async {
final choice = await showChoiceDialog(
context,
title: "Leave family",
body: "Are you sure that you want to leave the family plan?",
firstButtonLabel: "Leave",
title: S.of(context).leaveFamily,
body: S.of(context).areYouSureThatYouWantToLeaveTheFamily,
firstButtonLabel: S.of(context).leave,
firstButtonOnTap: () async {
try {
await UserService.instance.leaveFamilyPlan();

View file

@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:logging/logging.dart';
import 'package:photos/ente_theme_data.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/subscription.dart';
import 'package:photos/services/billing_service.dart';
import 'package:photos/services/user_service.dart';
@ -48,7 +49,7 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
@override
Widget build(BuildContext context) {
_dialog = createProgressDialog(context, "Please wait...");
_dialog = createProgressDialog(context, S.of(context).pleaseWait);
if (initPaymentUrl == null) {
return const EnteLoadingWidget();
}
@ -56,7 +57,7 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
onWillPop: (() async => _buildPageExitWidget(context)),
child: Scaffold(
appBar: AppBar(
title: const Text('Subscription'),
title: Text(S.of(context).subscription),
),
body: Column(
children: <Widget>[
@ -144,12 +145,12 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
final result = await showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('Are you sure you want to exit?'),
title: Text(S.of(context).areYouSureYouWantToExit),
actions: <Widget>[
TextButton(
child: const Text(
'Yes',
style: TextStyle(
child: Text(
S.of(context).yes,
style: const TextStyle(
color: Colors.redAccent,
),
),
@ -157,7 +158,7 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
),
TextButton(
child: Text(
'No',
S.of(context).no,
style: TextStyle(
color: Theme.of(context).colorScheme.greenAlternative,
),
@ -198,11 +199,11 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
title: const Text('Payment failed'),
content: Text("Unfortunately your payment failed due to $reason"),
title: Text(S.of(context).paymentFailed),
content: Text(S.of(context).paymentFailedWithReason(reason)),
actions: <Widget>[
TextButton(
child: const Text('Ok'),
child: Text(S.of(context).ok),
onPressed: () {
Navigator.of(context).pop('dialog');
},
@ -225,15 +226,16 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
);
await _dialog.hide();
final content = widget.actionType == 'buy'
? 'Your purchase was successful'
: 'Your subscription was updated successfully';
await _showExitPageDialog(title: 'Thank you', content: content);
? S.of(context).yourPurchaseWasSuccessful
: S.of(context).yourSubscriptionWasUpdatedSuccessfully;
await _showExitPageDialog(
title: S.of(context).thankYou, content: content);
} catch (error) {
_logger.severe(error);
await _dialog.hide();
await _showExitPageDialog(
title: 'Failed to verify payment status',
content: 'Please wait for sometime before retrying',
title: S.of(context).failedToVerifyPaymentStatus,
content: S.of(context).pleaseWaitForSometimeBeforeRetrying,
);
}
}
@ -249,7 +251,7 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
actions: <Widget>[
TextButton(
child: Text(
'Ok',
S.of(context).ok,
style: TextStyle(
color: Theme.of(context).colorScheme.greenAlternative,
),

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:photos/core/event_bus.dart';
import 'package:photos/events/subscription_purchased_event.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/billing_plan.dart';
import 'package:photos/models/subscription.dart';
import 'package:photos/services/billing_service.dart';
@ -42,7 +43,7 @@ class SkipSubscriptionWidget extends StatelessWidget {
BillingService.instance
.verifySubscription(freeProductID, "", paymentProvider: "ente");
},
child: const Text("Continue on free trial"),
child: Text(S.of(context).continueOnFreeTrial),
),
);
}

View file

@ -8,6 +8,7 @@ import 'package:logging/logging.dart';
import 'package:photos/core/errors.dart';
import 'package:photos/core/event_bus.dart';
import 'package:photos/events/subscription_purchased_event.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/billing_plan.dart';
import 'package:photos/models/subscription.dart';
import 'package:photos/models/user_details.dart';
@ -83,16 +84,16 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
purchase.verificationData.serverVerificationData,
);
await InAppPurchase.instance.completePurchase(purchase);
String text = "Thank you for subscribing!";
String text = S.of(context).thankYouForSubscribing;
if (!widget.isOnboarding) {
final isUpgrade = _hasActiveSubscription &&
newSubscription.storage > _currentSubscription!.storage;
final isDowngrade = _hasActiveSubscription &&
newSubscription.storage < _currentSubscription!.storage;
if (isUpgrade) {
text = "Your plan was successfully upgraded";
text = S.of(context).yourPlanWasSuccessfullyUpgraded;
} else if (isDowngrade) {
text = "Your plan was successfully downgraded";
text = S.of(context).yourPlanWasSuccessfullyDowngraded;
}
}
showShortToast(context, text);
@ -107,13 +108,13 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
} on SubscriptionAlreadyClaimedError catch (e) {
_logger.warning("subscription is already claimed ", e);
await _dialog.hide();
final String title = "${Platform.isAndroid ? "Play" : "App"}"
"Store subscription";
final String id =
Platform.isAndroid ? "Google Play ID" : "Apple ID";
final String message = '''Your $id is already linked to another
ente account.\nIf you would like to use your $id with this
account, please contact our support''';
final String title = Platform.isAndroid
? S.of(context).playstoreSubscription
: S.of(context).appstoreSubscription;
final String id = Platform.isAndroid
? S.of(context).googlePlayId
: S.of(context).appleId;
final String message = S.of(context).subAlreadyLinkedErrMessage(id);
showErrorDialog(context, title, message);
return;
} catch (e) {
@ -121,10 +122,10 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
await _dialog.hide();
showErrorDialog(
context,
"Payment failed",
"Please talk to " +
(Platform.isAndroid ? "PlayStore" : "AppStore") +
" support if you were charged",
S.of(context).paymentFailed,
S.of(context).paymentFailedTalkToProvider(
Platform.isAndroid ? "PlayStore" : "AppStore",
),
);
return;
}
@ -152,11 +153,11 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
_isLoading = true;
_fetchSubData();
}
_dialog = createProgressDialog(context, "Please wait...");
_dialog = createProgressDialog(context, S.of(context).pleaseWait);
final appBar = AppBar(
title: widget.isOnboarding
? null
: const Text("Subscription${kDebugMode ? ' Store' : ''}"),
: Text("${S.of(context).subscription}${kDebugMode ? ' Store' : ''}"),
);
return Scaffold(
appBar: appBar,
@ -255,7 +256,7 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
Padding(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
child: Text(
"Visit web.ente.io to manage your subscription",
S.of(context).visitWebToManage,
style: getEnteTextTheme(context).small.copyWith(
color: colorScheme.textMuted,
),
@ -267,8 +268,8 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
Padding(
padding: const EdgeInsets.fromLTRB(16, 40, 16, 4),
child: MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Payment details",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).paymentDetails,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: Icon(
@ -291,7 +292,9 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
padding: const EdgeInsets.fromLTRB(16, 0, 16, 80),
child: MenuItemWidget(
captionedTextWidget: CaptionedTextWidget(
title: _isFreePlanUser() ? "Family Plans" : "Manage Family",
title: _isFreePlanUser()
? S.of(context).familyPlans
: S.of(context).manageFamily,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: Icon(
@ -328,8 +331,8 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
} else if (paymentProvider == stripe) {
showErrorDialog(
context,
"Sorry",
"Visit web.ente.io to manage your subscription",
S.of(context).sorry,
S.of(context).visitWebToManage,
);
} else {
final String capitalizedWord = paymentProvider.isNotEmpty
@ -337,9 +340,8 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
: '';
showErrorDialog(
context,
"Sorry",
"Please contact us at support@ente.io to manage your "
"$capitalizedWord subscription.",
S.of(context).sorry,
S.of(context).contactToManageSubscription(capitalizedWord),
);
}
}
@ -388,7 +390,7 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
planText("Monthly", showYearlyPlan),
planText(S.of(context).monthly, showYearlyPlan),
Switch(
value: showYearlyPlan,
activeColor: Colors.white,
@ -399,13 +401,13 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
await _filterStorePlansForUi();
},
),
planText("Yearly", !showYearlyPlan),
planText(S.of(context).yearly, !showYearlyPlan),
],
),
),
_isFreePlanUser()
? Text(
"2 months free on yearly plans",
S.of(context).twoMonthsFreeOnYearlyPlans,
style: getEnteTextTheme(context).miniMuted,
)
: const SizedBox.shrink(),
@ -438,8 +440,8 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
}
showErrorDialog(
context,
"Sorry",
"Please visit web.ente.io to manage your subscription",
S.of(context).sorry,
S.of(context).visitWebToManage,
);
},
child: SubscriptionPlanWidget(
@ -467,7 +469,7 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
planWidgets.add(
SubscriptionPlanWidget(
storage: _freePlan.storage,
price: "Free trial",
price: S.of(context).freeTrial,
period: "",
isActive: true,
),
@ -490,8 +492,8 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
if (_userDetails.getFamilyOrPersonalUsage() > plan.storage) {
showErrorDialog(
context,
"Sorry",
"You cannot downgrade to this plan",
S.of(context).sorry,
S.of(context).youCannotDowngradeToThisPlan,
);
return;
}
@ -514,8 +516,8 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
await _dialog.hide();
showErrorDialog(
context,
"Could not update subscription",
"Please contact support@ente.io and we will be happy to help!",
S.of(context).couldNotUpdateSubscription,
S.of(context).pleaseContactSupportAndWeWillBeHappyToHelp,
);
return;
} else {

View file

@ -4,6 +4,7 @@ import "package:flutter/foundation.dart";
import 'package:flutter/material.dart';
import "package:logging/logging.dart";
import 'package:photos/ente_theme_data.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/billing_plan.dart';
import 'package:photos/models/subscription.dart';
import 'package:photos/models/user_details.dart';
@ -151,7 +152,8 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
)
: AppBar(
elevation: 0,
title: const Text("Subscription${kDebugMode ? ' Stripe' : ''}"),
title: Text("${S.of(context).subscription}${kDebugMode ? ' '
'Stripe' : ''}"),
),
),
);
@ -172,7 +174,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
Widget _getBody() {
if (!_isLoading) {
_isLoading = true;
_dialog = createProgressDialog(context, "Please wait...");
_dialog = createProgressDialog(context, S.of(context).pleaseWait);
_fetchSub();
}
if (_hasLoadedData) {
@ -228,8 +230,8 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
Padding(
padding: const EdgeInsets.fromLTRB(16, 40, 16, 4),
child: MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Payment details",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).paymentDetails,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: Icon(
@ -251,8 +253,8 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 80),
child: MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Manage Family",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).manageFamily,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: Icon(
@ -301,9 +303,8 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
: '';
showErrorDialog(
context,
"Sorry",
"Please contact us at support@ente.io to manage your "
"$capitalizedWord subscription.",
S.of(context).sorry,
S.of(context).contactToManageSubscription(capitalizedWord),
);
}
}
@ -315,7 +316,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return WebPage("Payment details", url);
return WebPage(S.of(context).paymentDetails, url);
},
),
).then((value) => onWebPaymentGoBack);
@ -329,8 +330,9 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
Widget _stripeRenewOrCancelButton() {
final bool isRenewCancelled =
_currentSubscription!.attributes?.isCancelled ?? false;
final String title =
isRenewCancelled ? "Renew subscription" : "Cancel subscription";
final String title = isRenewCancelled
? S.of(context).renewSubscription
: S.of(context).cancelSubscription;
return TextButton(
child: Text(
title,
@ -346,17 +348,17 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
final choice = await showChoiceDialog(
context,
title: title,
body: "Are you sure you want to renew?",
firstButtonLabel: "Yes, Renew",
body: S.of(context).areYouSureYouWantToRenew,
firstButtonLabel: S.of(context).yesRenew,
);
confirmAction = choice!.action == ButtonAction.first;
} else {
final choice = await showChoiceDialog(
context,
title: title,
body: "Are you sure you want to cancel?",
firstButtonLabel: "Yes, cancel",
secondButtonLabel: "No",
body: S.of(context).areYouSureYouWantToCancel,
firstButtonLabel: S.of(context).yesCancel,
secondButtonLabel: S.of(context).no,
isCritical: true,
);
confirmAction = choice!.action == ButtonAction.first;
@ -380,17 +382,18 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
} catch (e) {
showShortToast(
context,
isAutoRenewDisabled ? 'Failed to renew' : 'Failed to cancel',
isAutoRenewDisabled
? S.of(context).failedToRenew
: S.of(context).failedToCancel,
);
}
await _dialog.hide();
if (!isAutoRenewDisabled && mounted) {
await showTextInputDialog(
context,
title: "Your subscription was cancelled. Would you like to share the "
"reason?",
submitButtonLabel: "Send",
hintText: "Optional, as short as you like...",
title: S.of(context).askCancelReason,
submitButtonLabel: S.of(context).send,
hintText: S.of(context).optionalAsShortAsYouLike,
alwaysShowSuccessState: true,
textCapitalization: TextCapitalization.words,
onSubmit: (String text) async {
@ -435,17 +438,18 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
_currentSubscription!.productID != freeProductID) {
showErrorDialog(
context,
"Sorry",
"Please cancel your existing subscription from "
"${_currentSubscription!.paymentProvider} first",
S.of(context).sorry,
S.of(context).cancelOtherSubscription(
_currentSubscription!.paymentProvider,
),
);
return;
}
if (_userDetails.getFamilyOrPersonalUsage() > plan.storage) {
showErrorDialog(
context,
"Sorry",
"You cannot downgrade to this plan",
S.of(context).sorry,
S.of(context).youCannotDowngradeToThisPlan,
);
return;
}
@ -454,9 +458,9 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
// confirm if user wants to change plan or not
final result = await showChoiceDialog(
context,
title: "Confirm plan change",
body: "Are you sure you want to change your plan?",
firstButtonLabel: "Yes",
title: S.of(context).confirmPlanChange,
body: S.of(context).areYouSureYouWantToChangeYourPlan,
firstButtonLabel: S.of(context).yes,
);
if (result!.action == ButtonAction.first) {
stripPurChaseAction = 'update';
@ -522,7 +526,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
planText("Monthly", _showYearlyPlan),
planText(S.of(context).monthly, _showYearlyPlan),
Switch(
value: _showYearlyPlan,
activeColor: Colors.white,
@ -533,13 +537,13 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
await _filterStripeForUI();
},
),
planText("Yearly", !_showYearlyPlan),
planText(S.of(context).yearly, !_showYearlyPlan),
],
),
),
_isFreePlanUser()
? Text(
"2 months free on yearly plans",
S.of(context).twoMonthsFreeOnYearlyPlans,
style: getEnteTextTheme(context).miniMuted,
)
: const SizedBox.shrink(),

View file

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:photos/ente_theme_data.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/subscription.dart';
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/components/captioned_text_widget.dart";
@ -36,19 +37,19 @@ class _SubscriptionHeaderWidgetState extends State<SubscriptionHeaderWidget> {
Row(
children: [
Text(
"Select your plan",
S.of(context).selectYourPlan,
style: Theme.of(context).textTheme.headline4,
),
],
),
const SizedBox(height: 10),
Text(
"ente preserves your memories, so they're always available to you, even if you lose your device.",
S.of(context).enteSubscriptionPitch,
style: Theme.of(context).textTheme.caption,
),
const SizedBox(height: 4),
Text(
"Your family can be added to your plan as well. ",
S.of(context).enteSubscriptionShareWithFamily,
style: Theme.of(context).textTheme.caption,
),
],
@ -64,7 +65,7 @@ class _SubscriptionHeaderWidgetState extends State<SubscriptionHeaderWidget> {
text: TextSpan(
children: [
TextSpan(
text: "Current usage is ",
text: S.of(context).currentUsageIs,
style: Theme.of(context).textTheme.subtitle1,
),
TextSpan(
@ -96,11 +97,11 @@ class ValidityWidget extends StatelessWidget {
final endDate = getDateAndMonthAndYear(
DateTime.fromMicrosecondsSinceEpoch(currentSubscription!.expiryTime),
);
var message = "Renews on $endDate";
var message = S.of(context).renewsOn(endDate);
if (currentSubscription!.productID == freeProductID) {
message = "Free trial valid till $endDate";
message = S.of(context).freeTrialValidTill(endDate);
} else if (currentSubscription!.attributes?.isCancelled ?? false) {
message = "Your subscription will be cancelled on $endDate";
message = S.of(context).subWillBeCancelledOn(endDate);
}
return Padding(
padding: const EdgeInsets.only(top: 8),
@ -123,8 +124,8 @@ class SubFaqWidget extends StatelessWidget {
return Padding(
padding: EdgeInsets.fromLTRB(16, 40, 16, isOnboarding ? 40 : 4),
child: MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "FAQs",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).faqs,
),
menuItemColor: colorScheme.fillFaint,
trailingWidget: Icon(

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/utils/data_util.dart';
class SubscriptionPlanWidget extends StatelessWidget {
@ -15,9 +16,10 @@ class SubscriptionPlanWidget extends StatelessWidget {
final String period;
final bool isActive;
String _displayPrice() {
String _displayPrice(BuildContext context) {
// todo: l10n pricing part
final result = price + (period.isNotEmpty ? " / " + period : "");
return price.isNotEmpty ? result : "Free trial";
return price.isNotEmpty ? result : S.of(context).freeTrial;
}
@override
@ -59,7 +61,7 @@ class SubscriptionPlanWidget extends StatelessWidget {
.copyWith(color: textColor),
),
Text(
_displayPrice(),
_displayPrice(context),
style: Theme.of(context).textTheme.headline6!.copyWith(
color: textColor,
fontWeight: FontWeight.normal,

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/update_service.dart';
import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/common/web_page.dart';
@ -17,7 +18,7 @@ class AboutSectionWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ExpandableMenuItemWidget(
title: "About",
title: S.of(context).about,
selectionOptionsWidget: _getSectionOptions(context),
leadingIcon: Icons.info_outline,
);
@ -28,8 +29,8 @@ class AboutSectionWidget extends StatelessWidget {
children: [
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "We are open source!",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).weAreOpenSource,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -39,13 +40,13 @@ class AboutSectionWidget extends StatelessWidget {
},
),
sectionOptionSpacing,
const AboutMenuItemWidget(
title: "Privacy",
AboutMenuItemWidget(
title: S.of(context).privacy,
url: "https://ente.io/privacy",
),
sectionOptionSpacing,
const AboutMenuItemWidget(
title: "Terms",
AboutMenuItemWidget(
title: S.of(context).termsOfServicesTitle,
url: "https://ente.io/terms",
),
sectionOptionSpacing,
@ -53,15 +54,15 @@ class AboutSectionWidget extends StatelessWidget {
? Column(
children: [
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Check for updates",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).checkForUpdates,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
trailingIconIsMuted: true,
onTap: () async {
final dialog =
createProgressDialog(context, "Checking...");
createProgressDialog(context, S.of(context).checking);
await dialog.show();
final shouldUpdate =
await UpdateService.instance.shouldUpdate();
@ -79,7 +80,7 @@ class AboutSectionWidget extends StatelessWidget {
} else {
showShortToast(
context,
"You are on the latest version",
S.of(context).youAreOnTheLatestVersion,
);
}
},

View file

@ -1,6 +1,7 @@
import 'dart:async';
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/local_authentication_service.dart';
import 'package:photos/services/user_service.dart';
import 'package:photos/theme/ente_theme.dart';
@ -21,7 +22,7 @@ class AccountSectionWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ExpandableMenuItemWidget(
title: "Account",
title: S.of(context).account,
selectionOptionsWidget: _getSectionOptions(context),
leadingIcon: Icons.account_circle_outlined,
);
@ -32,8 +33,8 @@ class AccountSectionWidget extends StatelessWidget {
children: [
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Manage subscription",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).manageSubscription,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -44,8 +45,8 @@ class AccountSectionWidget extends StatelessWidget {
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Change email",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).changeEmail,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -55,7 +56,7 @@ class AccountSectionWidget extends StatelessWidget {
final hasAuthenticated = await LocalAuthenticationService.instance
.requestLocalAuthentication(
context,
"Please authenticate to change your email",
S.of(context).authToChangeYourEmail,
);
if (hasAuthenticated) {
showDialog(
@ -71,8 +72,8 @@ class AccountSectionWidget extends StatelessWidget {
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Change password",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).changePassword,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -82,7 +83,7 @@ class AccountSectionWidget extends StatelessWidget {
final hasAuthenticated = await LocalAuthenticationService.instance
.requestLocalAuthentication(
context,
"Please authenticate to change your password",
S.of(context).authToChangeYourPassword,
);
if (hasAuthenticated) {
Navigator.of(context).push(
@ -99,8 +100,8 @@ class AccountSectionWidget extends StatelessWidget {
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Export your data ",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).exportYourData,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -111,8 +112,8 @@ class AccountSectionWidget extends StatelessWidget {
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Logout",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).logout,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -123,8 +124,8 @@ class AccountSectionWidget extends StatelessWidget {
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Delete account",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).deleteAccount,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -133,7 +134,7 @@ class AccountSectionWidget extends StatelessWidget {
final hasAuthenticated = await LocalAuthenticationService.instance
.requestLocalAuthentication(
context,
"Please authenticate to initiate account deletion",
S.of(context).authToInitiateAccountDeletion,
);
if (hasAuthenticated) {
unawaited(
@ -156,8 +157,8 @@ class AccountSectionWidget extends StatelessWidget {
void _onLogoutTapped(BuildContext context) {
showChoiceActionSheet(
context,
title: "Are you sure you want to logout?",
firstButtonLabel: "Yes, logout",
title: S.of(context).areYouSureYouWantToLogout,
firstButtonLabel: S.of(context).yesLogout,
isCritical: true,
firstButtonOnTap: () async {
await UserService.instance.logout(context);

View file

@ -4,6 +4,7 @@ import 'package:logging/logging.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/core/network/network.dart';
import 'package:photos/ente_theme_data.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/update_service.dart';
import 'package:photos/theme/ente_theme.dart';
import 'package:url_launcher/url_launcher_string.dart';
@ -53,7 +54,7 @@ class _AppUpdateDialogState extends State<AppUpdateDialog> {
mainAxisSize: MainAxisSize.min,
children: [
Text(
"A new version of ente is available.",
S.of(context).aNewVersionOfEnteIsAvailable,
style: enteTextTheme.body.copyWith(color: enteColor.textMuted),
),
const Padding(padding: EdgeInsets.all(8)),
@ -83,8 +84,8 @@ class _AppUpdateDialogState extends State<AppUpdateDialog> {
barrierDismissible: false,
);
},
child: const Text(
"Update",
child: Text(
S.of(context).update,
),
),
),
@ -92,7 +93,7 @@ class _AppUpdateDialogState extends State<AppUpdateDialog> {
Center(
child: InkWell(
child: Text(
"Install manually",
S.of(context).installManually,
style: Theme.of(context)
.textTheme
.caption!
@ -124,8 +125,8 @@ class _AppUpdateDialogState extends State<AppUpdateDialog> {
),
Text(
shouldForceUpdate
? "Critical update available"
: "Update available",
? S.of(context).criticalUpdateAvailable
: S.of(context).updateAvailable,
style: enteTextTheme.h3Bold,
),
],
@ -164,9 +165,9 @@ class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
return WillPopScope(
onWillPop: () async => false,
child: AlertDialog(
title: const Text(
"Downloading...",
style: TextStyle(
title: Text(
S.of(context).downloading,
style: const TextStyle(
fontSize: 16,
),
textAlign: TextAlign.center,
@ -197,8 +198,8 @@ class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
} catch (e) {
Logger("ApkDownloader").severe(e);
final AlertDialog alert = AlertDialog(
title: const Text("Sorry"),
content: const Text("The download could not be completed"),
title: Text(S.of(context).sorry),
content: Text(S.of(context).theDownloadCouldNotBeCompleted),
actions: [
TextButton(
child: const Text(
@ -214,7 +215,7 @@ class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
),
TextButton(
child: Text(
"Retry",
S.of(context).retry,
style: TextStyle(
color: Theme.of(context).colorScheme.greenAlternative,
),

View file

@ -1,6 +1,7 @@
import 'dart:io';
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/backup_status.dart';
import 'package:photos/models/duplicate_files.dart';
import 'package:photos/services/deduplication_service.dart';
@ -33,7 +34,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
@override
Widget build(BuildContext context) {
return ExpandableMenuItemWidget(
title: "Backup",
title: S.of(context).backup,
selectionOptionsWidget: _getSectionOptions(context),
leadingIcon: Icons.backup_outlined,
);
@ -43,8 +44,8 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
final List<Widget> sectionOptions = [
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Backed up folders",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).backedUpFolders,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -52,16 +53,16 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
onTap: () async {
routeToPage(
context,
const BackupFolderSelectionPage(
buttonText: "Backup",
BackupFolderSelectionPage(
buttonText: S.of(context).backup,
),
);
},
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Backup settings",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).backupSettings,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -79,8 +80,8 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
sectionOptions.addAll(
[
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Free up device space",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).freeUpDeviceSpace,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -98,8 +99,8 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
if (status.localIDs.isEmpty) {
showErrorDialog(
context,
"✨ All clear",
"You've no files on this device that can be deleted",
S.of(context).allClear,
S.of(context).noDeviceThatCanBeDeleted,
);
} else {
final bool? result =
@ -112,8 +113,8 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Remove duplicates",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).removeDuplicates,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -132,8 +133,8 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
if (duplicates.isEmpty) {
showErrorDialog(
context,
"✨ No duplicates",
"You've no duplicate files that can be cleared",
S.of(context).noDuplicates,
S.of(context).youveNoDuplicateFilesThatCanBeCleared,
);
} else {
final DeduplicationResult? result =
@ -154,19 +155,19 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
void _showSpaceFreedDialog(BackupStatus status) {
final DialogWidget dialog = choiceDialog(
title: "Success",
body: "You have successfully freed up " + formatBytes(status.size) + "!",
firstButtonLabel: "Rate us",
title: S.of(context).success,
body: S.of(context).youHaveSuccessfullyFreedUp(formatBytes(status.size)),
firstButtonLabel: S.of(context).rateUs,
firstButtonOnTap: () async {
UpdateService.instance.launchReviewUrl();
},
firstButtonType: ButtonType.primary,
secondButtonLabel: "OK",
secondButtonLabel: S.of(context).ok,
secondButtonOnTap: () async {
if (Platform.isIOS) {
showToast(
context,
"Also empty \"Recently Deleted\" from \"Settings\" -> \"Storage\" to claim the freed space",
S.of(context).remindToEmptyDeviceTrash,
);
}
},
@ -184,27 +185,22 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
}
void _showDuplicateFilesDeletedDialog(DeduplicationResult result) {
final String countText = result.count.toString() +
" duplicate file" +
(result.count == 1 ? "" : "s");
final DialogWidget dialog = choiceDialog(
title: "✨ Success",
body: "You have cleaned up " +
countText +
", saving " +
formatBytes(result.size) +
"!",
firstButtonLabel: "Rate us",
title: S.of(context).sparkleSuccess,
body: S.of(context).duplicateFileCountWithStorageSaved(
result.count,
formatBytes(result.size),
),
firstButtonLabel: S.of(context).rateUs,
firstButtonOnTap: () async {
UpdateService.instance.launchReviewUrl();
},
firstButtonType: ButtonType.primary,
secondButtonLabel: "OK",
secondButtonLabel: S.of(context).ok,
secondButtonOnTap: () async {
showShortToast(
context,
"Also empty your \"Trash\" to claim the freed up space",
S.of(context).remindToEmptyEnteTrash,
);
},
);

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/billing_service.dart';
import 'package:photos/services/user_service.dart';
import 'package:photos/theme/ente_theme.dart';
@ -16,7 +17,7 @@ class GeneralSectionWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ExpandableMenuItemWidget(
title: "General",
title: S.of(context).general,
selectionOptionsWidget: _getSectionOptions(context),
leadingIcon: Icons.graphic_eq,
);
@ -27,8 +28,8 @@ class GeneralSectionWidget extends StatelessWidget {
children: [
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Family plans",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).familyPlans,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -40,8 +41,8 @@ class GeneralSectionWidget extends StatelessWidget {
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Referrals",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).referrals,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -56,8 +57,8 @@ class GeneralSectionWidget extends StatelessWidget {
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Advanced",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).advanced,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,

View file

@ -5,6 +5,7 @@ import 'package:photos/core/configuration.dart';
import 'package:photos/core/event_bus.dart';
import 'package:photos/ente_theme_data.dart';
import 'package:photos/events/two_factor_status_change_event.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/local_authentication_service.dart';
import 'package:photos/services/user_service.dart';
import 'package:photos/theme/ente_theme.dart';
@ -52,7 +53,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
@override
Widget build(BuildContext context) {
return ExpandableMenuItemWidget(
title: "Security",
title: S.of(context).security,
selectionOptionsWidget: _getSectionOptions(context),
leadingIcon: Icons.local_police_outlined,
);
@ -66,8 +67,8 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
[
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Recovery key",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).recoveryKey,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -77,7 +78,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
final hasAuthenticated = await LocalAuthenticationService.instance
.requestLocalAuthentication(
context,
"Please authenticate to view your recovery key",
S.of(context).authToViewYourRecoveryKey,
);
if (hasAuthenticated) {
String recoveryKey;
@ -92,7 +93,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
context,
RecoveryKeyPage(
recoveryKey,
"OK",
S.of(context).ok,
showAppBar: true,
onDone: () {},
),
@ -103,8 +104,8 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Two-factor",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).twofactor,
),
trailingWidget: ToggleSwitchWidget(
value: () => UserService.instance.hasEnabledTwoFactor(),
@ -113,7 +114,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
.instance
.requestLocalAuthentication(
context,
"Please authenticate to configure two-factor authentication",
S.of(context).authToConfigureTwofactorAuthentication,
);
final isTwoFactorEnabled =
UserService.instance.hasEnabledTwoFactor();
@ -136,8 +137,8 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
}
children.addAll([
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Lockscreen",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).lockscreen,
),
trailingWidget: ToggleSwitchWidget(
value: () => _config.shouldShowLockScreen(),
@ -146,16 +147,16 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
.requestLocalAuthForLockScreen(
context,
!_config.shouldShowLockScreen(),
"Please authenticate to change lockscreen setting",
"To enable lockscreen, please setup device passcode or screen lock in your system settings.",
S.of(context).authToChangeLockscreenSetting,
S.of(context).lockScreenEnablePreSteps,
);
},
),
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "View active sessions",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).viewActiveSessions,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -165,7 +166,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
final hasAuthenticated = await LocalAuthenticationService.instance
.requestLocalAuthentication(
context,
"Please authenticate to view your active sessions",
S.of(context).authToViewYourActiveSessions,
);
if (hasAuthenticated) {
unawaited(
@ -189,14 +190,14 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
Future<void> _disableTwoFactor() async {
final AlertDialog alert = AlertDialog(
title: const Text("Disable two-factor"),
content: const Text(
"Are you sure you want to disable two-factor authentication?",
title: Text(S.of(context).disableTwofactor),
content: Text(
S.of(context).confirm2FADisable,
),
actions: [
TextButton(
child: Text(
"No",
S.of(context).no,
style: TextStyle(
color: Theme.of(context).colorScheme.greenAlternative,
),
@ -206,9 +207,9 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
},
),
TextButton(
child: const Text(
"Yes",
style: TextStyle(
child: Text(
S.of(context).yes,
style: const TextStyle(
color: Colors.red,
),
),

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/update_service.dart';
import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/components/captioned_text_widget.dart';
@ -13,7 +14,7 @@ class SocialSectionWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ExpandableMenuItemWidget(
title: "Social",
title: S.of(context).social,
selectionOptionsWidget: _getSectionOptions(context),
leadingIcon: Icons.interests_outlined,
);
@ -27,28 +28,40 @@ class SocialSectionWidget extends StatelessWidget {
options.addAll(
[
sectionOptionSpacing,
SocialsMenuItemWidget("Rate us on $ratePlace", rateUrl),
SocialsMenuItemWidget(S.of(context).rateUsOnStore(ratePlace), rateUrl),
sectionOptionSpacing,
],
);
options.addAll(
[
const SocialsMenuItemWidget("Blog", "https://ente.io/blog"),
SocialsMenuItemWidget(S.of(context).blog, "https://ente.io/blog"),
sectionOptionSpacing,
const SocialsMenuItemWidget("Merchandise", "https://shop.ente.io"),
SocialsMenuItemWidget(
S.of(context).merchandise,
"https://shop.ente.io",
),
sectionOptionSpacing,
const SocialsMenuItemWidget("Twitter", "https://twitter.com/enteio"),
SocialsMenuItemWidget(
S.of(context).twitter,
"https://twitter.com/enteio",
),
sectionOptionSpacing,
const SocialsMenuItemWidget("Mastodon", "https://mstdn.social/@ente"),
SocialsMenuItemWidget(
S.of(context).mastodon,
"https://mstdn.social/@ente",
),
sectionOptionSpacing,
const SocialsMenuItemWidget(
"Matrix",
SocialsMenuItemWidget(
S.of(context).matrix,
"https://ente.io/matrix/",
),
sectionOptionSpacing,
const SocialsMenuItemWidget("Discord", "https://ente.io/discord"),
SocialsMenuItemWidget(S.of(context).discord, "https://ente.io/discord"),
sectionOptionSpacing,
const SocialsMenuItemWidget("Reddit", "https://reddit.com/r/enteio"),
SocialsMenuItemWidget(
S.of(context).reddit,
"https://reddit.com/r/enteio",
),
sectionOptionSpacing,
],
);
@ -60,6 +73,7 @@ class SocialSectionWidget extends StatelessWidget {
class SocialsMenuItemWidget extends StatelessWidget {
final String text;
final String urlSring;
const SocialsMenuItemWidget(this.text, this.urlSring, {Key? key})
: super(key: key);

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/theme/colors.dart';
import 'package:photos/theme/ente_theme.dart';
@ -19,7 +20,7 @@ class StorageErrorWidget extends StatelessWidget {
),
const SizedBox(height: 8),
Text(
"Your storage details could not be fetched",
S.of(context).yourStorageDetailsCouldNotBeFetched,
style: getEnteTextTheme(context).small.copyWith(
color: textMutedDark,
),

View file

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/core/constants.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/common/web_page.dart';
import 'package:photos/ui/components/captioned_text_widget.dart';
@ -18,7 +19,7 @@ class SupportSectionWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ExpandableMenuItemWidget(
title: "Support",
title: S.of(context).support,
selectionOptionsWidget: _getSectionOptions(context),
leadingIcon: Icons.help_outline_outlined,
);
@ -31,8 +32,8 @@ class SupportSectionWidget extends StatelessWidget {
children: [
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Contact support",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).contactSupport,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -42,14 +43,14 @@ class SupportSectionWidget extends StatelessWidget {
},
),
sectionOptionSpacing,
const AboutMenuItemWidget(
title: "FAQ",
AboutMenuItemWidget(
title: S.of(context).faq,
url: "https://ente.io/faq",
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Suggest features",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).suggestFeatures,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
@ -65,7 +66,7 @@ class SupportSectionWidget extends StatelessWidget {
"?token=" +
Configuration.instance.getToken()!
: roadmapURL;
return WebPage("Suggest features", url);
return WebPage(S.of(context).suggestFeatures, url);
},
),
);
@ -73,14 +74,14 @@ class SupportSectionWidget extends StatelessWidget {
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Report a bug",
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).reportABug,
),
pressedColor: getEnteColorScheme(context).fillFaint,
trailingIcon: Icons.chevron_right_outlined,
trailingIconIsMuted: true,
onTap: () async {
await sendLogs(context, "Report bug", bugsEmail);
await sendLogs(context, S.of(context).reportBug, bugsEmail);
},
onDoubleTap: () async {
final zipFilePath = await getZippedLogsFile(context);

View file

@ -1,7 +1,7 @@
import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:photos/ente_theme_data.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/components/captioned_text_widget.dart';
import 'package:photos/ui/components/expandable_menu_item_widget.dart';
@ -40,7 +40,7 @@ class _ThemeSwitchWidgetState extends State<ThemeSwitchWidget> {
@override
Widget build(BuildContext context) {
return ExpandableMenuItemWidget(
title: "Theme",
title: S.of(context).theme,
selectionOptionsWidget: _getSectionOptions(context),
leadingIcon: Theme.of(context).brightness == Brightness.light
? Icons.light_mode_outlined
@ -63,9 +63,21 @@ class _ThemeSwitchWidgetState extends State<ThemeSwitchWidget> {
}
Widget _menuItem(BuildContext context, AdaptiveThemeMode themeMode) {
late String themeName;
switch (themeMode) {
case AdaptiveThemeMode.light:
themeName = S.of(context).lightTheme;
break;
case AdaptiveThemeMode.dark:
themeName = S.of(context).darkTheme;
break;
case AdaptiveThemeMode.system:
themeName = S.of(context).systemTheme;
break;
}
return MenuItemWidget(
captionedTextWidget: CaptionedTextWidget(
title: toBeginningOfSentenceCase(themeMode.name)!,
title: themeName,
textStyle: Theme.of(context).colorScheme.enteTheme.textTheme.body,
),
pressedColor: getEnteColorScheme(context).fillFaint,