瀏覽代碼

Merge branch 'main' into load_model_perf_improvement

ashilkn 1 年之前
父節點
當前提交
7966c6bbc8
共有 31 個文件被更改,包括 947 次插入731 次删除
  1. 38 0
      .github/workflows/server-publish.yml
  2. 4 4
      .github/workflows/server-release.yml
  3. 二進制
      docs/docs/photos/migration/export/continuous-sync.webp
  4. 9 2
      docs/docs/photos/migration/export/index.md
  5. 6 1
      docs/docs/self-hosting/index.md
  6. 1 1
      mobile/fastlane/metadata/android/zh/full_description.txt
  7. 62 66
      mobile/lib/generated/intl/messages_de.dart
  8. 64 66
      mobile/lib/generated/intl/messages_en.dart
  9. 54 58
      mobile/lib/generated/intl/messages_es.dart
  10. 62 66
      mobile/lib/generated/intl/messages_fr.dart
  11. 60 64
      mobile/lib/generated/intl/messages_it.dart
  12. 62 66
      mobile/lib/generated/intl/messages_nl.dart
  13. 62 66
      mobile/lib/generated/intl/messages_pt.dart
  14. 62 65
      mobile/lib/generated/intl/messages_zh.dart
  15. 5 5
      mobile/lib/generated/l10n.dart
  16. 1 1
      mobile/lib/l10n/intl_en.arb
  17. 7 7
      mobile/lib/l10n/intl_pt.arb
  18. 3 3
      mobile/lib/l10n/intl_zh.arb
  19. 13 0
      mobile/lib/models/subscription.dart
  20. 14 25
      mobile/lib/ui/payment/payment_web_page.dart
  21. 8 3
      mobile/lib/ui/payment/stripe_subscription_page.dart
  22. 12 5
      server/README.md
  23. 8 7
      server/RUNNING.md
  24. 83 0
      server/docs/docker.md
  25. 41 0
      server/docs/publish.md
  26. 1 1
      server/ente/billing.go
  27. 3 3
      server/mail-templates/on_hold.html
  28. 171 142
      server/pkg/controller/stripe.go
  29. 5 1
      web/apps/photos/src/components/Sidebar/SubscriptionStatus/index.tsx
  30. 16 3
      web/apps/photos/src/components/Sidebar/userDetailsSection.tsx
  31. 10 0
      web/apps/photos/src/utils/billing/index.ts

+ 38 - 0
.github/workflows/server-publish.yml

@@ -0,0 +1,38 @@
+name: "Publish (server)"
+
+on:
+    # Run manually, providing it the commit.
+    #
+    # To obtain the commit from the currently deployed museum, do:
+    # curl -s https://api.ente.io/ping | jq -r '.id'
+    #
+    # See server/docs/publish.md for more details.
+    workflow_dispatch:
+        inputs:
+            commit:
+                description: "Commit to publish the image from"
+                type: string
+                required: true
+
+jobs:
+    publish:
+        runs-on: ubuntu-latest
+        steps:
+            - name: Checkout code
+              uses: actions/checkout@v4
+              with:
+                  ref: ${{ inputs.commit }}
+
+            - name: Build and push
+              uses: mr-smithers-excellent/docker-build-push@v6
+              with:
+                  dockerfile: server/Dockerfile
+                  directory: server
+                  # Resultant package name will be ghcr.io/ente-io/server
+                  image: server
+                  registry: ghcr.io
+                  enableBuildKit: true
+                  buildArgs: GIT_COMMIT=${{ inputs.commit }}
+                  tags: ${{ inputs.commit }}, latest
+                  username: ${{ github.actor }}
+                  password: ${{ secrets.GITHUB_TOKEN }}

+ 4 - 4
.github/workflows/server-release.yml

@@ -7,11 +7,11 @@ jobs:
     build:
         runs-on: ubuntu-latest
         steps:
-            - uses: actions/checkout@v4
-              name: Check out code
+            - name: Checkout code
+              uses: actions/checkout@v4
 
-            - uses: mr-smithers-excellent/docker-build-push@v6
-              name: Build & Push
+            - name: Build and push
+              uses: mr-smithers-excellent/docker-build-push@v6
               with:
                   dockerfile: server/Dockerfile
                   directory: server

二進制
docs/docs/photos/migration/export/continuous-sync.webp


+ 9 - 2
docs/docs/photos/migration/export/index.md

@@ -29,8 +29,15 @@ videos you have uploaded to Ente.
 
     ![Ente - Rexport](export-4.png)
 
-In case your download gets interrupted, Ente will resume from where it left off.
-Simply select **export data** again and click on **resync**.
+6. In case your download gets interrupted, Ente will resume from where it left
+   off. Simply select **export data** again and click on **resync**.
+
+7. **Sync continuously** : You can utilize Continuous Sync to eliminate manual
+   exports each time new photos are added to Ente. This feature automatically
+   detects new files and runs exports accordingly, It also ensures that exported
+   data reflects the latest album states with new files, moves, and deletions.
+
+    ![Ente - Continuous sync](continuous-sync.webp)
 
 If you run into any issues during your data export, please reach out to
 [support@ente.io](mailto:support@ente.io) and we will be happy to help you!

+ 6 - 1
docs/docs/self-hosting/index.md

@@ -24,6 +24,11 @@ cd ente/server
 docker compose up --build
 ```
 
+> [!TIP]
+>
+> You can also use a pre-built Docker image from `ghcr.io/ente-io/server` ([More
+> info](https://github.com/ente-io/ente/blob/main/server/docs/docker.md))
+
 Then in a separate terminal, you can run (e.g) the web client
 
 ```sh
@@ -42,7 +47,7 @@ For the mobile apps, you don't even need to build, and can install normal Ente
 apps and configure them to use your
 [custom self-hosted server](guides/custom-server/).
 
-> If you want to build from source, see the instructions
+> If you want to build the mobile apps from source, see the instructions
 > [here](guides/mobile-build).
 
 ## Next steps

+ 1 - 1
mobile/fastlane/metadata/android/zh/full_description.txt

@@ -4,7 +4,7 @@ ente 是一个简单的应用程序来备份和分享您的照片和视频。
 
 我们在Android、iOS、web 和桌面上有开源应用, 和您的照片将以端到端加密方式 (e2ee) 无缝同步。
 
-ente也使分享相册给自己的爱人、亲人变得轻而易举,即使他们可能并不使用ente。 您可以分享可公开查看的链接,使他们可以查看您的相册,并通过添加照片来协作而不需要注册账户或下载app。 ente也使分享相册给自己的爱人、亲人变得轻而易举,即使他们可能并不使用ente。 您可以分享可公开查看的链接,使他们可以查看您的相册,并通过添加照片来协作而不需要注册账户或下载app。 权限
+ente也使分享相册给自己的爱人、亲人变得轻而易举,即使他们可能并不使用ente。 您可以分享可公开查看的链接,使他们可以查看您的相册,并通过添加照片来协作而不需要注册账户或下载app。 您可以共享公开可见的链接,他们可以在其中查看您的相册并通过向其中添加照片进行协作,即使没有账户或应用程序也是如此。
 
 您的加密数据已复制到三个不同的地点,包括巴黎的一个安全屋。 我们认真对待子孙后代,并确保您的回忆比您长寿。 我们认真对待子孙后代,并确保您的回忆比您长寿。
 

+ 62 - 66
mobile/lib/generated/intl/messages_de.dart

@@ -131,90 +131,87 @@ class MessageLookup extends MessageLookupByLibrary {
   static String m37(providerName) =>
       "Bitte kontaktiere den Support von ${providerName}, falls etwas abgebucht wurde";
 
-  static String m38(reason) =>
-      "Leider ist deine Zahlung aus folgendem Grund fehlgeschlagen: ${reason}";
-
-  static String m39(endDate) =>
+  static String m38(endDate) =>
       "Kostenlose Testversion gültig bis ${endDate}.\nSie können anschließend ein bezahltes Paket auswählen.";
 
-  static String m40(toEmail) => "Bitte sende uns eine E-Mail an ${toEmail}";
+  static String m39(toEmail) => "Bitte sende uns eine E-Mail an ${toEmail}";
 
-  static String m41(toEmail) => "Bitte sende die Protokolle an ${toEmail}";
+  static String m40(toEmail) => "Bitte sende die Protokolle an ${toEmail}";
 
-  static String m42(storeName) => "Bewerte uns auf ${storeName}";
+  static String m41(storeName) => "Bewerte uns auf ${storeName}";
 
-  static String m43(storageInGB) =>
+  static String m42(storageInGB) =>
       "3. Ihr beide erhaltet ${storageInGB} GB* kostenlos";
 
-  static String m44(userEmail) =>
+  static String m43(userEmail) =>
       "${userEmail} wird aus diesem geteilten Album entfernt\n\nAlle von ihnen hinzugefügte Fotos werden ebenfalls aus dem Album entfernt";
 
-  static String m45(endDate) => "Erneuert am ${endDate}";
+  static String m44(endDate) => "Erneuert am ${endDate}";
 
-  static String m46(count) =>
+  static String m45(count) =>
       "${Intl.plural(count, one: '${count} Ergebnis gefunden', other: '${count} Ergebnisse gefunden')}";
 
-  static String m47(count) => "${count} ausgewählt";
+  static String m46(count) => "${count} ausgewählt";
 
-  static String m48(count, yourCount) =>
+  static String m47(count, yourCount) =>
       "${count} ausgewählt (${yourCount} von Ihnen)";
 
-  static String m49(verificationID) =>
+  static String m48(verificationID) =>
       "Hier ist meine Verifizierungs-ID: ${verificationID} für ente.io.";
 
-  static String m50(verificationID) =>
+  static String m49(verificationID) =>
       "Hey, kannst du bestätigen, dass dies deine ente.io Verifizierungs-ID ist: ${verificationID}";
 
-  static String m51(referralCode, referralStorageInGB) =>
+  static String m50(referralCode, referralStorageInGB) =>
       "ente Weiterempfehlungs-Code: ${referralCode} \n\nEinlösen unter Einstellungen → Allgemein → Weiterempfehlungen, um ${referralStorageInGB} GB kostenlos zu erhalten, sobald Sie einen kostenpflichtigen Tarif abgeschlossen haben\n\nhttps://ente.io";
 
-  static String m52(numberOfPeople) =>
+  static String m51(numberOfPeople) =>
       "${Intl.plural(numberOfPeople, zero: 'Teile mit bestimmten Personen', one: 'Teilen mit 1 Person', other: 'Teilen mit ${numberOfPeople} Personen')}";
 
-  static String m53(emailIDs) => "Geteilt mit ${emailIDs}";
+  static String m52(emailIDs) => "Geteilt mit ${emailIDs}";
 
-  static String m54(fileType) =>
+  static String m53(fileType) =>
       "Dieses ${fileType} wird von deinem Gerät gelöscht.";
 
-  static String m55(fileType) =>
+  static String m54(fileType) =>
       "Dieses ${fileType} existiert auf ente.io und deinem Gerät.";
 
-  static String m56(fileType) =>
+  static String m55(fileType) =>
       "Dieses ${fileType} wird auf ente.io gelöscht.";
 
-  static String m57(storageAmountInGB) => "${storageAmountInGB} GB";
+  static String m56(storageAmountInGB) => "${storageAmountInGB} GB";
 
-  static String m58(
+  static String m57(
           usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) =>
       "${usedAmount} ${usedStorageUnit} von ${totalAmount} ${totalStorageUnit} verwendet";
 
-  static String m59(id) =>
+  static String m58(id) =>
       "Ihr ${id} ist bereits mit einem anderen \'ente\'-Konto verknüpft.\nWenn Sie Ihre ${id} mit diesem Konto verwenden möchten, kontaktieren Sie bitte unseren Support\'";
 
-  static String m60(endDate) => "Ihr Abo endet am ${endDate}";
+  static String m59(endDate) => "Ihr Abo endet am ${endDate}";
 
-  static String m61(completed, total) =>
+  static String m60(completed, total) =>
       "${completed}/${total} Erinnerungsstücke gesichert";
 
-  static String m62(storageAmountInGB) =>
+  static String m61(storageAmountInGB) =>
       "Diese erhalten auch ${storageAmountInGB} GB";
 
-  static String m63(email) => "Dies ist ${email}s Verifizierungs-ID";
+  static String m62(email) => "Dies ist ${email}s Verifizierungs-ID";
 
-  static String m64(count) =>
+  static String m63(count) =>
       "${Intl.plural(count, zero: '', one: '1 Tag', other: '${count} Tage')}";
 
-  static String m65(endDate) => "Gültig bis ${endDate}";
+  static String m64(endDate) => "Gültig bis ${endDate}";
 
-  static String m66(email) => "Verifiziere ${email}";
+  static String m65(email) => "Verifiziere ${email}";
 
-  static String m67(email) =>
+  static String m66(email) =>
       "Wir haben eine E-Mail an <green>${email}</green> gesendet";
 
-  static String m68(count) =>
+  static String m67(count) =>
       "${Intl.plural(count, one: 'vor einem Jahr', other: 'vor ${count} Jahren')}";
 
-  static String m69(storageSaved) =>
+  static String m68(storageSaved) =>
       "Du hast ${storageSaved} erfolgreich freigegeben!";
 
   final messages = _notInlinedMessages(_notInlinedMessages);
@@ -1026,7 +1023,6 @@ class MessageLookup extends MessageLookupByLibrary {
         "paymentFailed":
             MessageLookupByLibrary.simpleMessage("Zahlung fehlgeschlagen"),
         "paymentFailedTalkToProvider": m37,
-        "paymentFailedWithReason": m38,
         "pendingItems":
             MessageLookupByLibrary.simpleMessage("Ausstehende Elemente"),
         "pendingSync":
@@ -1053,7 +1049,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "pinAlbum": MessageLookupByLibrary.simpleMessage("Album anheften"),
         "playOnTv": MessageLookupByLibrary.simpleMessage(
             "Album auf dem Fernseher wiedergeben"),
-        "playStoreFreeTrialValidTill": m39,
+        "playStoreFreeTrialValidTill": m38,
         "playstoreSubscription":
             MessageLookupByLibrary.simpleMessage("PlayStore Abo"),
         "pleaseCheckYourInternetConnectionAndTryAgain":
@@ -1065,12 +1061,12 @@ class MessageLookup extends MessageLookupByLibrary {
         "pleaseContactSupportIfTheProblemPersists":
             MessageLookupByLibrary.simpleMessage(
                 "Bitte wenden Sie sich an den Support, falls das Problem weiterhin besteht"),
-        "pleaseEmailUsAt": m40,
+        "pleaseEmailUsAt": m39,
         "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage(
             "Bitte erteile die nötigen Berechtigungen"),
         "pleaseLoginAgain":
             MessageLookupByLibrary.simpleMessage("Bitte logge dich erneut ein"),
-        "pleaseSendTheLogsTo": m41,
+        "pleaseSendTheLogsTo": m40,
         "pleaseTryAgain":
             MessageLookupByLibrary.simpleMessage("Bitte versuche es erneut"),
         "pleaseVerifyTheCodeYouHaveEntered":
@@ -1106,7 +1102,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "raiseTicket": MessageLookupByLibrary.simpleMessage("Ticket erstellen"),
         "rateTheApp": MessageLookupByLibrary.simpleMessage("App bewerten"),
         "rateUs": MessageLookupByLibrary.simpleMessage("Bewerte uns"),
-        "rateUsOnStore": m42,
+        "rateUsOnStore": m41,
         "recover": MessageLookupByLibrary.simpleMessage("Wiederherstellen"),
         "recoverAccount":
             MessageLookupByLibrary.simpleMessage("Konto wiederherstellen"),
@@ -1139,7 +1135,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "1. Gib diesen Code an deine Freunde"),
         "referralStep2": MessageLookupByLibrary.simpleMessage(
             "2. Sie schließen ein bezahltes Abo ab"),
-        "referralStep3": m43,
+        "referralStep3": m42,
         "referrals": MessageLookupByLibrary.simpleMessage("Weiterempfehlungen"),
         "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage(
             "Einlösungen sind derzeit pausiert"),
@@ -1165,7 +1161,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "removeLink": MessageLookupByLibrary.simpleMessage("Link entfernen"),
         "removeParticipant":
             MessageLookupByLibrary.simpleMessage("Teilnehmer entfernen"),
-        "removeParticipantBody": m44,
+        "removeParticipantBody": m43,
         "removePublicLink":
             MessageLookupByLibrary.simpleMessage("Öffentlichen Link entfernen"),
         "removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(
@@ -1179,7 +1175,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "renameFile": MessageLookupByLibrary.simpleMessage("Datei umbenennen"),
         "renewSubscription":
             MessageLookupByLibrary.simpleMessage("Abonnement erneuern"),
-        "renewsOn": m45,
+        "renewsOn": m44,
         "reportABug": MessageLookupByLibrary.simpleMessage("Fehler melden"),
         "reportBug": MessageLookupByLibrary.simpleMessage("Fehler melden"),
         "resendEmail":
@@ -1242,7 +1238,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Gruppiere Fotos, die innerhalb des Radius eines bestimmten Fotos aufgenommen wurden"),
         "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage(
             "Laden Sie Personen ein, damit Sie geteilte Fotos hier einsehen können"),
-        "searchResultCount": m46,
+        "searchResultCount": m45,
         "security": MessageLookupByLibrary.simpleMessage("Sicherheit"),
         "selectALocation":
             MessageLookupByLibrary.simpleMessage("Standort auswählen"),
@@ -1269,8 +1265,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "selectedItemsWillBeDeletedFromAllAlbumsAndMoved":
             MessageLookupByLibrary.simpleMessage(
                 "Ausgewählte Elemente werden aus allen Alben gelöscht und in den Papierkorb verschoben."),
-        "selectedPhotos": m47,
-        "selectedPhotosWithYours": m48,
+        "selectedPhotos": m46,
+        "selectedPhotosWithYours": m47,
         "send": MessageLookupByLibrary.simpleMessage("Absenden"),
         "sendEmail": MessageLookupByLibrary.simpleMessage("E-Mail senden"),
         "sendInvite": MessageLookupByLibrary.simpleMessage("Einladung senden"),
@@ -1293,16 +1289,16 @@ class MessageLookup extends MessageLookupByLibrary {
         "shareAnAlbumNow":
             MessageLookupByLibrary.simpleMessage("Teile jetzt ein Album"),
         "shareLink": MessageLookupByLibrary.simpleMessage("Link teilen"),
-        "shareMyVerificationID": m49,
+        "shareMyVerificationID": m48,
         "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage(
             "Teile mit ausgewählten Personen"),
-        "shareTextConfirmOthersVerificationID": m50,
+        "shareTextConfirmOthersVerificationID": m49,
         "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage(
             "Lade ente herunter, damit wir einfach Fotos und Videos in höchster Qualität teilen können\n\nhttps://ente.io"),
-        "shareTextReferralCode": m51,
+        "shareTextReferralCode": m50,
         "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage(
             "Mit Nicht-Ente-Benutzern teilen"),
-        "shareWithPeopleSectionTitle": m52,
+        "shareWithPeopleSectionTitle": m51,
         "shareYourFirstAlbum":
             MessageLookupByLibrary.simpleMessage("Teile dein erstes Album"),
         "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage(
@@ -1313,7 +1309,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Neue geteilte Fotos"),
         "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage(
             "Erhalte Benachrichtigungen, wenn jemand ein Foto zu einem gemeinsam genutzten Album hinzufügt, dem du angehörst"),
-        "sharedWith": m53,
+        "sharedWith": m52,
         "sharedWithMe": MessageLookupByLibrary.simpleMessage("Mit mir geteilt"),
         "sharedWithYou":
             MessageLookupByLibrary.simpleMessage("Mit dir geteilt"),
@@ -1328,11 +1324,11 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Andere Geräte abmelden"),
         "signUpTerms": MessageLookupByLibrary.simpleMessage(
             "Ich stimme den <u-terms>Nutzungsbedingungen</u-terms> und der <u-policy>Datenschutzerklärung</u-policy> zu"),
-        "singleFileDeleteFromDevice": m54,
+        "singleFileDeleteFromDevice": m53,
         "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage(
             "Es wird aus allen Alben gelöscht."),
-        "singleFileInBothLocalAndRemote": m55,
-        "singleFileInRemoteOnly": m56,
+        "singleFileInBothLocalAndRemote": m54,
+        "singleFileInRemoteOnly": m55,
         "skip": MessageLookupByLibrary.simpleMessage("Überspringen"),
         "social": MessageLookupByLibrary.simpleMessage("Social Media"),
         "someItemsAreInBothEnteAndYourDevice":
@@ -1374,13 +1370,13 @@ class MessageLookup extends MessageLookupByLibrary {
         "storage": MessageLookupByLibrary.simpleMessage("Speicherplatz"),
         "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Familie"),
         "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Sie"),
-        "storageInGB": m57,
+        "storageInGB": m56,
         "storageLimitExceeded": MessageLookupByLibrary.simpleMessage(
             "Speichergrenze überschritten"),
-        "storageUsageInfo": m58,
+        "storageUsageInfo": m57,
         "strongStrength": MessageLookupByLibrary.simpleMessage("Stark"),
-        "subAlreadyLinkedErrMessage": m59,
-        "subWillBeCancelledOn": m60,
+        "subAlreadyLinkedErrMessage": m58,
+        "subWillBeCancelledOn": m59,
         "subscribe": MessageLookupByLibrary.simpleMessage("Abonnieren"),
         "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage(
             "Sieht aus, als sei dein Abonnement abgelaufen. Bitte abonniere, um das Teilen zu aktivieren."),
@@ -1397,7 +1393,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "suggestFeatures":
             MessageLookupByLibrary.simpleMessage("Verbesserung vorschlagen"),
         "support": MessageLookupByLibrary.simpleMessage("Support"),
-        "syncProgress": m61,
+        "syncProgress": m60,
         "syncStopped":
             MessageLookupByLibrary.simpleMessage("Synchronisierung angehalten"),
         "syncing": MessageLookupByLibrary.simpleMessage("Synchronisiere …"),
@@ -1426,7 +1422,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "theseItemsWillBeDeletedFromYourDevice":
             MessageLookupByLibrary.simpleMessage(
                 "Diese Elemente werden von deinem Gerät gelöscht."),
-        "theyAlsoGetXGb": m62,
+        "theyAlsoGetXGb": m61,
         "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage(
             "Sie werden aus allen Alben gelöscht."),
         "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage(
@@ -1442,7 +1438,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Diese E-Mail-Adresse wird bereits verwendet"),
         "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage(
             "Dieses Bild hat keine Exif-Daten"),
-        "thisIsPersonVerificationId": m63,
+        "thisIsPersonVerificationId": m62,
         "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage(
             "Dies ist deine Verifizierungs-ID"),
         "thisWillLogYouOutOfTheFollowingDevice":
@@ -1459,7 +1455,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "total": MessageLookupByLibrary.simpleMessage("Gesamt"),
         "totalSize": MessageLookupByLibrary.simpleMessage("Gesamtgröße"),
         "trash": MessageLookupByLibrary.simpleMessage("Papierkorb"),
-        "trashDaysLeft": m64,
+        "trashDaysLeft": m63,
         "tryAgain": MessageLookupByLibrary.simpleMessage("Erneut versuchen"),
         "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage(
             "Aktiviere die Sicherung, um automatisch neu hinzugefügte Dateien dieses Ordners auf ente hochzuladen."),
@@ -1514,7 +1510,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Ausgewähltes Foto verwenden"),
         "usedSpace":
             MessageLookupByLibrary.simpleMessage("Belegter Speicherplatz"),
-        "validTill": m65,
+        "validTill": m64,
         "verificationFailedPleaseTryAgain":
             MessageLookupByLibrary.simpleMessage(
                 "Verifizierung fehlgeschlagen, bitte versuchen Sie es erneut"),
@@ -1523,7 +1519,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "verify": MessageLookupByLibrary.simpleMessage("Überprüfen"),
         "verifyEmail":
             MessageLookupByLibrary.simpleMessage("E-Mail-Adresse verifizieren"),
-        "verifyEmailID": m66,
+        "verifyEmailID": m65,
         "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Überprüfen"),
         "verifyPasskey":
             MessageLookupByLibrary.simpleMessage("Passkey verifizieren"),
@@ -1556,12 +1552,12 @@ class MessageLookup extends MessageLookupByLibrary {
         "weDontSupportEditingPhotosAndAlbumsThatYouDont":
             MessageLookupByLibrary.simpleMessage(
                 "Wir unterstützen keine Bearbeitung von Fotos und Alben, die du noch nicht besitzt"),
-        "weHaveSendEmailTo": m67,
+        "weHaveSendEmailTo": m66,
         "weakStrength": MessageLookupByLibrary.simpleMessage("Schwach"),
         "welcomeBack":
             MessageLookupByLibrary.simpleMessage("Willkommen zurück!"),
         "yearly": MessageLookupByLibrary.simpleMessage("Jährlich"),
-        "yearsAgo": m68,
+        "yearsAgo": m67,
         "yes": MessageLookupByLibrary.simpleMessage("Ja"),
         "yesCancel": MessageLookupByLibrary.simpleMessage("Ja, kündigen"),
         "yesConvertToViewer": MessageLookupByLibrary.simpleMessage(
@@ -1591,7 +1587,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Du kannst nicht mit dir selbst teilen"),
         "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage(
             "Du hast keine archivierten Elemente."),
-        "youHaveSuccessfullyFreedUp": m69,
+        "youHaveSuccessfullyFreedUp": m68,
         "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage(
             "Dein Benutzerkonto wurde gelöscht"),
         "yourMap": MessageLookupByLibrary.simpleMessage("Deine Karte"),

+ 64 - 66
mobile/lib/generated/intl/messages_en.dart

@@ -129,89 +129,86 @@ class MessageLookup extends MessageLookupByLibrary {
   static String m37(providerName) =>
       "Please talk to ${providerName} support if you were charged";
 
-  static String m38(reason) =>
-      "Unfortunately your payment failed due to ${reason}";
-
-  static String m39(endDate) =>
+  static String m38(endDate) =>
       "Free trial valid till ${endDate}.\nYou can choose a paid plan afterwards.";
 
-  static String m40(toEmail) => "Please email us at ${toEmail}";
+  static String m39(toEmail) => "Please email us at ${toEmail}";
 
-  static String m41(toEmail) => "Please send the logs to \n${toEmail}";
+  static String m40(toEmail) => "Please send the logs to \n${toEmail}";
 
-  static String m42(storeName) => "Rate us on ${storeName}";
+  static String m41(storeName) => "Rate us on ${storeName}";
 
-  static String m43(storageInGB) =>
+  static String m42(storageInGB) =>
       "3. Both of you get ${storageInGB} GB* free";
 
-  static String m44(userEmail) =>
+  static String m43(userEmail) =>
       "${userEmail} will be removed from this shared album\n\nAny photos added by them will also be removed from the album";
 
-  static String m45(endDate) => "Subscription renews on ${endDate}";
+  static String m44(endDate) => "Subscription renews on ${endDate}";
 
-  static String m46(count) =>
+  static String m45(count) =>
       "${Intl.plural(count, one: '${count} result found', other: '${count} results found')}";
 
-  static String m47(count) => "${count} selected";
+  static String m46(count) => "${count} selected";
 
-  static String m48(count, yourCount) =>
+  static String m47(count, yourCount) =>
       "${count} selected (${yourCount} yours)";
 
-  static String m49(verificationID) =>
+  static String m48(verificationID) =>
       "Here\'s my verification ID: ${verificationID} for ente.io.";
 
-  static String m50(verificationID) =>
+  static String m49(verificationID) =>
       "Hey, can you confirm that this is your ente.io verification ID: ${verificationID}";
 
-  static String m51(referralCode, referralStorageInGB) =>
+  static String m50(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 m52(numberOfPeople) =>
+  static String m51(numberOfPeople) =>
       "${Intl.plural(numberOfPeople, zero: 'Share with specific people', one: 'Shared with 1 person', other: 'Shared with ${numberOfPeople} people')}";
 
-  static String m53(emailIDs) => "Shared with ${emailIDs}";
+  static String m52(emailIDs) => "Shared with ${emailIDs}";
 
-  static String m54(fileType) =>
+  static String m53(fileType) =>
       "This ${fileType} will be deleted from your device.";
 
-  static String m55(fileType) =>
+  static String m54(fileType) =>
       "This ${fileType} is in both ente and your device.";
 
-  static String m56(fileType) => "This ${fileType} will be deleted from ente.";
+  static String m55(fileType) => "This ${fileType} will be deleted from ente.";
 
-  static String m57(storageAmountInGB) => "${storageAmountInGB} GB";
+  static String m56(storageAmountInGB) => "${storageAmountInGB} GB";
 
-  static String m58(
+  static String m57(
           usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) =>
       "${usedAmount} ${usedStorageUnit} of ${totalAmount} ${totalStorageUnit} used";
 
-  static String m59(id) =>
+  static String m58(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 m60(endDate) =>
+  static String m59(endDate) =>
       "Your subscription will be cancelled on ${endDate}";
 
-  static String m61(completed, total) =>
+  static String m60(completed, total) =>
       "${completed}/${total} memories preserved";
 
-  static String m62(storageAmountInGB) =>
+  static String m61(storageAmountInGB) =>
       "They also get ${storageAmountInGB} GB";
 
-  static String m63(email) => "This is ${email}\'s Verification ID";
+  static String m62(email) => "This is ${email}\'s Verification ID";
 
-  static String m64(count) =>
+  static String m63(count) =>
       "${Intl.plural(count, zero: '', one: '1 day', other: '${count} days')}";
 
-  static String m65(endDate) => "Valid till ${endDate}";
+  static String m64(endDate) => "Valid till ${endDate}";
 
-  static String m66(email) => "Verify ${email}";
+  static String m65(email) => "Verify ${email}";
 
-  static String m67(email) => "We have sent a mail to <green>${email}</green>";
+  static String m66(email) => "We have sent a mail to <green>${email}</green>";
 
-  static String m68(count) =>
+  static String m67(count) =>
       "${Intl.plural(count, one: '${count} year ago', other: '${count} years ago')}";
 
-  static String m69(storageSaved) =>
+  static String m68(storageSaved) =>
       "You have successfully freed up ${storageSaved}!";
 
   final messages = _notInlinedMessages(_notInlinedMessages);
@@ -982,8 +979,9 @@ class MessageLookup extends MessageLookupByLibrary {
         "paymentDetails":
             MessageLookupByLibrary.simpleMessage("Payment details"),
         "paymentFailed": MessageLookupByLibrary.simpleMessage("Payment failed"),
+        "paymentFailedMessage": MessageLookupByLibrary.simpleMessage(
+            "Unfortunately your payment failed. Please contact support and we\'ll help you out!"),
         "paymentFailedTalkToProvider": m37,
-        "paymentFailedWithReason": m38,
         "pendingItems": MessageLookupByLibrary.simpleMessage("Pending items"),
         "pendingSync": MessageLookupByLibrary.simpleMessage("Pending sync"),
         "peopleUsingYourCode":
@@ -1007,7 +1005,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Pick center point"),
         "pinAlbum": MessageLookupByLibrary.simpleMessage("Pin album"),
         "playOnTv": MessageLookupByLibrary.simpleMessage("Play album on TV"),
-        "playStoreFreeTrialValidTill": m39,
+        "playStoreFreeTrialValidTill": m38,
         "playstoreSubscription":
             MessageLookupByLibrary.simpleMessage("PlayStore subscription"),
         "pleaseCheckYourInternetConnectionAndTryAgain":
@@ -1019,12 +1017,12 @@ class MessageLookup extends MessageLookupByLibrary {
         "pleaseContactSupportIfTheProblemPersists":
             MessageLookupByLibrary.simpleMessage(
                 "Please contact support if the problem persists"),
-        "pleaseEmailUsAt": m40,
+        "pleaseEmailUsAt": m39,
         "pleaseGrantPermissions":
             MessageLookupByLibrary.simpleMessage("Please grant permissions"),
         "pleaseLoginAgain":
             MessageLookupByLibrary.simpleMessage("Please login again"),
-        "pleaseSendTheLogsTo": m41,
+        "pleaseSendTheLogsTo": m40,
         "pleaseTryAgain":
             MessageLookupByLibrary.simpleMessage("Please try again"),
         "pleaseVerifyTheCodeYouHaveEntered":
@@ -1059,7 +1057,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "raiseTicket": MessageLookupByLibrary.simpleMessage("Raise ticket"),
         "rateTheApp": MessageLookupByLibrary.simpleMessage("Rate the app"),
         "rateUs": MessageLookupByLibrary.simpleMessage("Rate us"),
-        "rateUsOnStore": m42,
+        "rateUsOnStore": m41,
         "recover": MessageLookupByLibrary.simpleMessage("Recover"),
         "recoverAccount":
             MessageLookupByLibrary.simpleMessage("Recover account"),
@@ -1090,7 +1088,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "1. Give this code to your friends"),
         "referralStep2": MessageLookupByLibrary.simpleMessage(
             "2. They sign up for a paid plan"),
-        "referralStep3": m43,
+        "referralStep3": m42,
         "referrals": MessageLookupByLibrary.simpleMessage("Referrals"),
         "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage(
             "Referrals are currently paused"),
@@ -1114,7 +1112,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "removeLink": MessageLookupByLibrary.simpleMessage("Remove link"),
         "removeParticipant":
             MessageLookupByLibrary.simpleMessage("Remove participant"),
-        "removeParticipantBody": m44,
+        "removeParticipantBody": m43,
         "removePublicLink":
             MessageLookupByLibrary.simpleMessage("Remove public link"),
         "removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(
@@ -1128,7 +1126,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "renameFile": MessageLookupByLibrary.simpleMessage("Rename file"),
         "renewSubscription":
             MessageLookupByLibrary.simpleMessage("Renew subscription"),
-        "renewsOn": m45,
+        "renewsOn": m44,
         "reportABug": MessageLookupByLibrary.simpleMessage("Report a bug"),
         "reportBug": MessageLookupByLibrary.simpleMessage("Report bug"),
         "resendEmail": MessageLookupByLibrary.simpleMessage("Resend email"),
@@ -1188,7 +1186,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Group photos that are taken within some radius of a photo"),
         "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage(
             "Invite people, and you\'ll see all photos shared by them here"),
-        "searchResultCount": m46,
+        "searchResultCount": m45,
         "security": MessageLookupByLibrary.simpleMessage("Security"),
         "selectALocation":
             MessageLookupByLibrary.simpleMessage("Select a location"),
@@ -1215,8 +1213,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "selectedItemsWillBeDeletedFromAllAlbumsAndMoved":
             MessageLookupByLibrary.simpleMessage(
                 "Selected items will be deleted from all albums and moved to trash."),
-        "selectedPhotos": m47,
-        "selectedPhotosWithYours": m48,
+        "selectedPhotos": m46,
+        "selectedPhotosWithYours": m47,
         "send": MessageLookupByLibrary.simpleMessage("Send"),
         "sendEmail": MessageLookupByLibrary.simpleMessage("Send email"),
         "sendInvite": MessageLookupByLibrary.simpleMessage("Send invite"),
@@ -1238,16 +1236,16 @@ class MessageLookup extends MessageLookupByLibrary {
         "shareAnAlbumNow":
             MessageLookupByLibrary.simpleMessage("Share an album now"),
         "shareLink": MessageLookupByLibrary.simpleMessage("Share link"),
-        "shareMyVerificationID": m49,
+        "shareMyVerificationID": m48,
         "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage(
             "Share only with the people you want"),
-        "shareTextConfirmOthersVerificationID": m50,
+        "shareTextConfirmOthersVerificationID": m49,
         "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage(
             "Download ente so we can easily share original quality photos and videos\n\nhttps://ente.io"),
-        "shareTextReferralCode": m51,
+        "shareTextReferralCode": m50,
         "shareWithNonenteUsers":
             MessageLookupByLibrary.simpleMessage("Share with non-ente users"),
-        "shareWithPeopleSectionTitle": m52,
+        "shareWithPeopleSectionTitle": m51,
         "shareYourFirstAlbum":
             MessageLookupByLibrary.simpleMessage("Share your first album"),
         "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage(
@@ -1258,7 +1256,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("New shared photos"),
         "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage(
             "Receive notifications when someone adds a photo to a shared album that you\'re a part of"),
-        "sharedWith": m53,
+        "sharedWith": m52,
         "sharedWithMe": MessageLookupByLibrary.simpleMessage("Shared with me"),
         "sharedWithYou":
             MessageLookupByLibrary.simpleMessage("Shared with you"),
@@ -1272,11 +1270,11 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Sign out other devices"),
         "signUpTerms": MessageLookupByLibrary.simpleMessage(
             "I agree to the <u-terms>terms of service</u-terms> and <u-policy>privacy policy</u-policy>"),
-        "singleFileDeleteFromDevice": m54,
+        "singleFileDeleteFromDevice": m53,
         "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage(
             "It will be deleted from all albums."),
-        "singleFileInBothLocalAndRemote": m55,
-        "singleFileInRemoteOnly": m56,
+        "singleFileInBothLocalAndRemote": m54,
+        "singleFileInRemoteOnly": m55,
         "skip": MessageLookupByLibrary.simpleMessage("Skip"),
         "social": MessageLookupByLibrary.simpleMessage("Social"),
         "someItemsAreInBothEnteAndYourDevice":
@@ -1314,13 +1312,13 @@ class MessageLookup extends MessageLookupByLibrary {
         "storage": MessageLookupByLibrary.simpleMessage("Storage"),
         "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Family"),
         "storageBreakupYou": MessageLookupByLibrary.simpleMessage("You"),
-        "storageInGB": m57,
+        "storageInGB": m56,
         "storageLimitExceeded":
             MessageLookupByLibrary.simpleMessage("Storage limit exceeded"),
-        "storageUsageInfo": m58,
+        "storageUsageInfo": m57,
         "strongStrength": MessageLookupByLibrary.simpleMessage("Strong"),
-        "subAlreadyLinkedErrMessage": m59,
-        "subWillBeCancelledOn": m60,
+        "subAlreadyLinkedErrMessage": m58,
+        "subWillBeCancelledOn": m59,
         "subscribe": MessageLookupByLibrary.simpleMessage("Subscribe"),
         "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage(
             "Looks like your subscription has expired. Please subscribe to enable sharing."),
@@ -1337,7 +1335,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "suggestFeatures":
             MessageLookupByLibrary.simpleMessage("Suggest features"),
         "support": MessageLookupByLibrary.simpleMessage("Support"),
-        "syncProgress": m61,
+        "syncProgress": m60,
         "syncStopped": MessageLookupByLibrary.simpleMessage("Sync stopped"),
         "syncing": MessageLookupByLibrary.simpleMessage("Syncing..."),
         "systemTheme": MessageLookupByLibrary.simpleMessage("System"),
@@ -1363,7 +1361,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "theseItemsWillBeDeletedFromYourDevice":
             MessageLookupByLibrary.simpleMessage(
                 "These items will be deleted from your device."),
-        "theyAlsoGetXGb": m62,
+        "theyAlsoGetXGb": m61,
         "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage(
             "They will be deleted from all albums."),
         "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage(
@@ -1379,7 +1377,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "This email is already in use"),
         "thisImageHasNoExifData":
             MessageLookupByLibrary.simpleMessage("This image has no exif data"),
-        "thisIsPersonVerificationId": m63,
+        "thisIsPersonVerificationId": m62,
         "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage(
             "This is your Verification ID"),
         "thisWillLogYouOutOfTheFollowingDevice":
@@ -1395,7 +1393,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "total": MessageLookupByLibrary.simpleMessage("total"),
         "totalSize": MessageLookupByLibrary.simpleMessage("Total size"),
         "trash": MessageLookupByLibrary.simpleMessage("Trash"),
-        "trashDaysLeft": m64,
+        "trashDaysLeft": m63,
         "tryAgain": MessageLookupByLibrary.simpleMessage("Try again"),
         "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage(
             "Turn on backup to automatically upload files added to this device folder to ente."),
@@ -1447,7 +1445,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "useSelectedPhoto":
             MessageLookupByLibrary.simpleMessage("Use selected photo"),
         "usedSpace": MessageLookupByLibrary.simpleMessage("Used space"),
-        "validTill": m65,
+        "validTill": m64,
         "verificationFailedPleaseTryAgain":
             MessageLookupByLibrary.simpleMessage(
                 "Verification failed, please try again"),
@@ -1455,7 +1453,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Verification ID"),
         "verify": MessageLookupByLibrary.simpleMessage("Verify"),
         "verifyEmail": MessageLookupByLibrary.simpleMessage("Verify email"),
-        "verifyEmailID": m66,
+        "verifyEmailID": m65,
         "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Verify"),
         "verifyPasskey": MessageLookupByLibrary.simpleMessage("Verify passkey"),
         "verifyPassword":
@@ -1486,11 +1484,11 @@ class MessageLookup extends MessageLookupByLibrary {
         "weDontSupportEditingPhotosAndAlbumsThatYouDont":
             MessageLookupByLibrary.simpleMessage(
                 "We don\'t support editing photos and albums that you don\'t own yet"),
-        "weHaveSendEmailTo": m67,
+        "weHaveSendEmailTo": m66,
         "weakStrength": MessageLookupByLibrary.simpleMessage("Weak"),
         "welcomeBack": MessageLookupByLibrary.simpleMessage("Welcome back!"),
         "yearly": MessageLookupByLibrary.simpleMessage("Yearly"),
-        "yearsAgo": m68,
+        "yearsAgo": m67,
         "yes": MessageLookupByLibrary.simpleMessage("Yes"),
         "yesCancel": MessageLookupByLibrary.simpleMessage("Yes, cancel"),
         "yesConvertToViewer":
@@ -1520,7 +1518,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "You cannot share with yourself"),
         "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage(
             "You don\'t have any archived items."),
-        "youHaveSuccessfullyFreedUp": m69,
+        "youHaveSuccessfullyFreedUp": m68,
         "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage(
             "Your account has been deleted"),
         "yourMap": MessageLookupByLibrary.simpleMessage("Your map"),

+ 54 - 58
mobile/lib/generated/intl/messages_es.dart

@@ -121,79 +121,76 @@ class MessageLookup extends MessageLookupByLibrary {
   static String m37(providerName) =>
       "Por favor hable con el soporte de ${providerName} si se le cobró";
 
-  static String m38(reason) =>
-      "Lamentablemente tu pago falló debido a ${reason}";
-
-  static String m40(toEmail) =>
+  static String m39(toEmail) =>
       "Por favor, envíanos un correo electrónico a ${toEmail}";
 
-  static String m41(toEmail) => "Por favor, envíe los registros a ${toEmail}";
+  static String m40(toEmail) => "Por favor, envíe los registros a ${toEmail}";
 
-  static String m42(storeName) => "Califícanos en ${storeName}";
+  static String m41(storeName) => "Califícanos en ${storeName}";
 
-  static String m43(storageInGB) =>
+  static String m42(storageInGB) =>
       "3. Ambos obtienen ${storageInGB} GB* gratis";
 
-  static String m44(userEmail) =>
+  static String m43(userEmail) =>
       "${userEmail} será eliminado de este álbum compartido\n\nCualquier foto añadida por ellos también será eliminada del álbum";
 
-  static String m45(endDate) => "Se renueva el ${endDate}";
+  static String m44(endDate) => "Se renueva el ${endDate}";
 
-  static String m47(count) => "${count} seleccionados";
+  static String m46(count) => "${count} seleccionados";
 
-  static String m48(count, yourCount) =>
+  static String m47(count, yourCount) =>
       "${count} seleccionados (${yourCount} tuyos)";
 
-  static String m49(verificationID) =>
+  static String m48(verificationID) =>
       "Aquí está mi ID de verificación: ${verificationID} para ente.io.";
 
-  static String m50(verificationID) =>
+  static String m49(verificationID) =>
       "Hola, ¿puedes confirmar que esta es tu ID de verificación ente.io: ${verificationID}?";
 
-  static String m51(referralCode, referralStorageInGB) =>
+  static String m50(referralCode, referralStorageInGB) =>
       "ente código de referencia: ${referralCode} \n\nAplicarlo en Ajustes → General → Referencias para obtener ${referralStorageInGB} GB gratis después de registrarse en un plan de pago\n\nhttps://ente.io";
 
-  static String m52(numberOfPeople) =>
+  static String m51(numberOfPeople) =>
       "${Intl.plural(numberOfPeople, zero: 'Compartir con personas específicas', one: 'Compartido con 1 persona', other: 'Compartido con ${numberOfPeople} personas')}";
 
-  static String m53(emailIDs) => "Compartido con ${emailIDs}";
+  static String m52(emailIDs) => "Compartido con ${emailIDs}";
 
-  static String m54(fileType) =>
+  static String m53(fileType) =>
       "Este ${fileType} se eliminará de tu dispositivo.";
 
-  static String m55(fileType) =>
+  static String m54(fileType) =>
       "Este ${fileType} está tanto en ente como en tu dispositivo.";
 
-  static String m56(fileType) => "Este ${fileType} se eliminará de ente.";
+  static String m55(fileType) => "Este ${fileType} se eliminará de ente.";
 
-  static String m57(storageAmountInGB) => "${storageAmountInGB} GB";
+  static String m56(storageAmountInGB) => "${storageAmountInGB} GB";
 
-  static String m58(
+  static String m57(
           usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) =>
       "${usedAmount} ${usedStorageUnit} de ${totalAmount} ${totalStorageUnit} usados";
 
-  static String m59(id) =>
+  static String m58(id) =>
       "Su ${id} ya está vinculado a otra cuenta ente.\nSi desea utilizar su ${id} con esta cuenta, póngase en contacto con nuestro servicio de asistencia\'\'";
 
-  static String m60(endDate) => "Tu suscripción se cancelará el ${endDate}";
+  static String m59(endDate) => "Tu suscripción se cancelará el ${endDate}";
 
-  static String m61(completed, total) =>
+  static String m60(completed, total) =>
       "${completed}/${total} recuerdos conservados";
 
-  static String m62(storageAmountInGB) =>
+  static String m61(storageAmountInGB) =>
       "También obtienen ${storageAmountInGB} GB";
 
-  static String m63(email) => "Este es el ID de verificación de ${email}";
+  static String m62(email) => "Este es el ID de verificación de ${email}";
 
-  static String m66(email) => "Verificar ${email}";
+  static String m65(email) => "Verificar ${email}";
 
-  static String m67(email) =>
+  static String m66(email) =>
       "Hemos enviado un correo a <green>${email}</green>";
 
-  static String m68(count) =>
+  static String m67(count) =>
       "${Intl.plural(count, one: '${count} hace un año', other: '${count} hace años')}";
 
-  static String m69(storageSaved) => "¡Has liberado ${storageSaved} con éxito!";
+  static String m68(storageSaved) => "¡Has liberado ${storageSaved} con éxito!";
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -875,7 +872,6 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Detalles de pago"),
         "paymentFailed": MessageLookupByLibrary.simpleMessage("Pago fallido"),
         "paymentFailedTalkToProvider": m37,
-        "paymentFailedWithReason": m38,
         "pendingSync":
             MessageLookupByLibrary.simpleMessage("Sincronización pendiente"),
         "peopleUsingYourCode":
@@ -902,12 +898,12 @@ class MessageLookup extends MessageLookupByLibrary {
         "pleaseContactSupportIfTheProblemPersists":
             MessageLookupByLibrary.simpleMessage(
                 "Por favor contacte a soporte técnico si el problema persiste"),
-        "pleaseEmailUsAt": m40,
+        "pleaseEmailUsAt": m39,
         "pleaseGrantPermissions":
             MessageLookupByLibrary.simpleMessage("Por favor, concede permiso"),
         "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage(
             "Por favor, vuelva a iniciar sesión"),
-        "pleaseSendTheLogsTo": m41,
+        "pleaseSendTheLogsTo": m40,
         "pleaseTryAgain": MessageLookupByLibrary.simpleMessage(
             "Por favor, inténtalo nuevamente"),
         "pleaseVerifyTheCodeYouHaveEntered":
@@ -941,7 +937,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "rateTheApp":
             MessageLookupByLibrary.simpleMessage("Evalúa la aplicación"),
         "rateUs": MessageLookupByLibrary.simpleMessage("Califícanos"),
-        "rateUsOnStore": m42,
+        "rateUsOnStore": m41,
         "recover": MessageLookupByLibrary.simpleMessage("Recuperar"),
         "recoverAccount":
             MessageLookupByLibrary.simpleMessage("Recuperar cuenta"),
@@ -973,7 +969,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "1. Dale este código a tus amigos"),
         "referralStep2": MessageLookupByLibrary.simpleMessage(
             "2. Se inscriben a un plan pagado"),
-        "referralStep3": m43,
+        "referralStep3": m42,
         "referrals": MessageLookupByLibrary.simpleMessage("Referidos"),
         "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage(
             "Las referencias están actualmente en pausa"),
@@ -998,7 +994,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "removeLink": MessageLookupByLibrary.simpleMessage("Eliminar enlace"),
         "removeParticipant":
             MessageLookupByLibrary.simpleMessage("Quitar participante"),
-        "removeParticipantBody": m44,
+        "removeParticipantBody": m43,
         "removePublicLink":
             MessageLookupByLibrary.simpleMessage("Quitar enlace público"),
         "removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(
@@ -1012,7 +1008,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "renameFile": MessageLookupByLibrary.simpleMessage("Renombrar archivo"),
         "renewSubscription":
             MessageLookupByLibrary.simpleMessage("Renovar suscripción"),
-        "renewsOn": m45,
+        "renewsOn": m44,
         "reportABug": MessageLookupByLibrary.simpleMessage("Reportar un error"),
         "reportBug": MessageLookupByLibrary.simpleMessage("Reportar error"),
         "resendEmail":
@@ -1074,8 +1070,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "selectedItemsWillBeDeletedFromAllAlbumsAndMoved":
             MessageLookupByLibrary.simpleMessage(
                 "Los archivos seleccionados serán eliminados de todos los álbumes y movidos a la papelera."),
-        "selectedPhotos": m47,
-        "selectedPhotosWithYours": m48,
+        "selectedPhotos": m46,
+        "selectedPhotosWithYours": m47,
         "send": MessageLookupByLibrary.simpleMessage("Enviar"),
         "sendEmail":
             MessageLookupByLibrary.simpleMessage("Enviar correo electrónico"),
@@ -1100,32 +1096,32 @@ class MessageLookup extends MessageLookupByLibrary {
         "shareAnAlbumNow":
             MessageLookupByLibrary.simpleMessage("Compartir un álbum ahora"),
         "shareLink": MessageLookupByLibrary.simpleMessage("Compartir enlace"),
-        "shareMyVerificationID": m49,
+        "shareMyVerificationID": m48,
         "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage(
             "Comparte sólo con la gente que quieres"),
-        "shareTextConfirmOthersVerificationID": m50,
+        "shareTextConfirmOthersVerificationID": m49,
         "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage(
             "Descarga ente para que podamos compartir fácilmente fotos y videos en su calidad original\n\nhttps://ente.io"),
-        "shareTextReferralCode": m51,
+        "shareTextReferralCode": m50,
         "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage(
             "Compartir con usuarios no ente"),
-        "shareWithPeopleSectionTitle": m52,
+        "shareWithPeopleSectionTitle": m51,
         "shareYourFirstAlbum":
             MessageLookupByLibrary.simpleMessage("Comparte tu primer álbum"),
         "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage(
             "Crear álbumes compartidos y colaborativos con otros usuarios ente, incluyendo usuarios en planes gratuitos."),
         "sharedByMe": MessageLookupByLibrary.simpleMessage("Compartido por mí"),
-        "sharedWith": m53,
+        "sharedWith": m52,
         "sharedWithMe":
             MessageLookupByLibrary.simpleMessage("Compartido conmigo"),
         "sharing": MessageLookupByLibrary.simpleMessage("Compartiendo..."),
         "signUpTerms": MessageLookupByLibrary.simpleMessage(
             "Estoy de acuerdo con los <u-terms>términos del servicio</u-terms> y <u-policy> la política de privacidad</u-policy>"),
-        "singleFileDeleteFromDevice": m54,
+        "singleFileDeleteFromDevice": m53,
         "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage(
             "Se borrará de todos los álbumes."),
-        "singleFileInBothLocalAndRemote": m55,
-        "singleFileInRemoteOnly": m56,
+        "singleFileInBothLocalAndRemote": m54,
+        "singleFileInRemoteOnly": m55,
         "skip": MessageLookupByLibrary.simpleMessage("Omitir"),
         "social": MessageLookupByLibrary.simpleMessage("Social"),
         "someItemsAreInBothEnteAndYourDevice":
@@ -1160,13 +1156,13 @@ class MessageLookup extends MessageLookupByLibrary {
         "storage": MessageLookupByLibrary.simpleMessage("Almacenamiento"),
         "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Familia"),
         "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Usted"),
-        "storageInGB": m57,
+        "storageInGB": m56,
         "storageLimitExceeded":
             MessageLookupByLibrary.simpleMessage("Límite de datos excedido"),
-        "storageUsageInfo": m58,
+        "storageUsageInfo": m57,
         "strongStrength": MessageLookupByLibrary.simpleMessage("Segura"),
-        "subAlreadyLinkedErrMessage": m59,
-        "subWillBeCancelledOn": m60,
+        "subAlreadyLinkedErrMessage": m58,
+        "subWillBeCancelledOn": m59,
         "subscribe": MessageLookupByLibrary.simpleMessage("Suscribirse"),
         "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage(
             "Parece que su suscripción ha caducado. Por favor, suscríbase para habilitar el compartir."),
@@ -1179,7 +1175,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "suggestFeatures":
             MessageLookupByLibrary.simpleMessage("Sugerir una característica"),
         "support": MessageLookupByLibrary.simpleMessage("Soporte"),
-        "syncProgress": m61,
+        "syncProgress": m60,
         "syncStopped":
             MessageLookupByLibrary.simpleMessage("Sincronización detenida"),
         "syncing": MessageLookupByLibrary.simpleMessage("Sincronizando..."),
@@ -1207,7 +1203,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "theseItemsWillBeDeletedFromYourDevice":
             MessageLookupByLibrary.simpleMessage(
                 "Estos elementos se eliminarán de tu dispositivo."),
-        "theyAlsoGetXGb": m62,
+        "theyAlsoGetXGb": m61,
         "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage(
             "Se borrarán de todos los álbumes."),
         "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage(
@@ -1223,7 +1219,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Este correo electrónico ya está en uso"),
         "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage(
             "Esta imagen no tiene datos exif"),
-        "thisIsPersonVerificationId": m63,
+        "thisIsPersonVerificationId": m62,
         "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage(
             "Esta es tu ID de verificación"),
         "thisWillLogYouOutOfTheFollowingDevice":
@@ -1293,7 +1289,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "verify": MessageLookupByLibrary.simpleMessage("Verificar"),
         "verifyEmail": MessageLookupByLibrary.simpleMessage(
             "Verificar correo electrónico"),
-        "verifyEmailID": m66,
+        "verifyEmailID": m65,
         "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Verificar"),
         "verifyPassword":
             MessageLookupByLibrary.simpleMessage("Verificar contraseña"),
@@ -1316,12 +1312,12 @@ class MessageLookup extends MessageLookupByLibrary {
         "weDontSupportEditingPhotosAndAlbumsThatYouDont":
             MessageLookupByLibrary.simpleMessage(
                 "No admitimos la edición de fotos y álbunes que aún no son tuyos"),
-        "weHaveSendEmailTo": m67,
+        "weHaveSendEmailTo": m66,
         "weakStrength": MessageLookupByLibrary.simpleMessage("Poco segura"),
         "welcomeBack":
             MessageLookupByLibrary.simpleMessage("¡Bienvenido de nuevo!"),
         "yearly": MessageLookupByLibrary.simpleMessage("Anualmente"),
-        "yearsAgo": m68,
+        "yearsAgo": m67,
         "yes": MessageLookupByLibrary.simpleMessage("Sí"),
         "yesCancel": MessageLookupByLibrary.simpleMessage("Sí, cancelar"),
         "yesConvertToViewer":
@@ -1351,7 +1347,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "No puedes compartir contigo mismo"),
         "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage(
             "No tienes nada de elementos archivados."),
-        "youHaveSuccessfullyFreedUp": m69,
+        "youHaveSuccessfullyFreedUp": m68,
         "yourAccountHasBeenDeleted":
             MessageLookupByLibrary.simpleMessage("Su cuenta ha sido eliminada"),
         "yourMap": MessageLookupByLibrary.simpleMessage("Your map"),

+ 62 - 66
mobile/lib/generated/intl/messages_fr.dart

@@ -126,89 +126,86 @@ class MessageLookup extends MessageLookupByLibrary {
   static String m37(providerName) =>
       "Veuillez contacter le support ${providerName} si vous avez été facturé";
 
-  static String m38(reason) =>
-      "Malheureusement, votre paiement a échoué pour ${reason}";
-
-  static String m39(endDate) =>
+  static String m38(endDate) =>
       "Essai gratuit valable jusqu\'à ${endDate}.\nVous pouvez choisir un plan payant par la suite.";
 
-  static String m40(toEmail) => "Merci de nous envoyer un e-mail à ${toEmail}";
+  static String m39(toEmail) => "Merci de nous envoyer un e-mail à ${toEmail}";
 
-  static String m41(toEmail) => "Envoyez les logs à ${toEmail}";
+  static String m40(toEmail) => "Envoyez les logs à ${toEmail}";
 
-  static String m42(storeName) => "Notez-nous sur ${storeName}";
+  static String m41(storeName) => "Notez-nous sur ${storeName}";
 
-  static String m43(storageInGB) =>
+  static String m42(storageInGB) =>
       "3. Vous recevez tous les deux ${storageInGB} GB* gratuits";
 
-  static String m44(userEmail) =>
+  static String m43(userEmail) =>
       "${userEmail} sera retiré de cet album partagé\n\nToutes les photos ajoutées par eux seront également retirées de l\'album";
 
-  static String m45(endDate) => "Renouvellement le ${endDate}";
+  static String m44(endDate) => "Renouvellement le ${endDate}";
 
-  static String m46(count) =>
+  static String m45(count) =>
       "${Intl.plural(count, one: '${count} résultat trouvé', other: '${count} résultats trouvés')}";
 
-  static String m47(count) => "${count} sélectionné(s)";
+  static String m46(count) => "${count} sélectionné(s)";
 
-  static String m48(count, yourCount) =>
+  static String m47(count, yourCount) =>
       "${count} sélectionné(s) (${yourCount} à vous)";
 
-  static String m49(verificationID) =>
+  static String m48(verificationID) =>
       "Voici mon ID de vérification : ${verificationID} pour ente.io.";
 
-  static String m50(verificationID) =>
+  static String m49(verificationID) =>
       "Hé, pouvez-vous confirmer qu\'il s\'agit de votre ID de vérification ente.io : ${verificationID}";
 
-  static String m51(referralCode, referralStorageInGB) =>
+  static String m50(referralCode, referralStorageInGB) =>
       "code de parrainage ente : ${referralCode} \n\nAppliquez le dans Paramètres → Général → Références pour obtenir ${referralStorageInGB} Go gratuitement après votre inscription à un plan payant\n\nhttps://ente.io";
 
-  static String m52(numberOfPeople) =>
+  static String m51(numberOfPeople) =>
       "${Intl.plural(numberOfPeople, zero: 'Partagez avec des personnes spécifiques', one: 'Partagé avec 1 personne', other: 'Partagé avec ${numberOfPeople} des gens')}";
 
-  static String m53(emailIDs) => "Partagé avec ${emailIDs}";
+  static String m52(emailIDs) => "Partagé avec ${emailIDs}";
 
-  static String m54(fileType) =>
+  static String m53(fileType) =>
       "Elle ${fileType} sera supprimée de votre appareil.";
 
-  static String m55(fileType) =>
+  static String m54(fileType) =>
       "Cette ${fileType} est à la fois sur ente et sur votre appareil.";
 
-  static String m56(fileType) => "Ce ${fileType} sera supprimé de ente.";
+  static String m55(fileType) => "Ce ${fileType} sera supprimé de ente.";
 
-  static String m57(storageAmountInGB) => "${storageAmountInGB} Go";
+  static String m56(storageAmountInGB) => "${storageAmountInGB} Go";
 
-  static String m58(
+  static String m57(
           usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) =>
       "${usedAmount} ${usedStorageUnit} sur ${totalAmount} ${totalStorageUnit} utilisé";
 
-  static String m59(id) =>
+  static String m58(id) =>
       "Votre ${id} est déjà lié à un autre compte ente.\nSi vous souhaitez utiliser votre ${id} avec ce compte, veuillez contacter notre support";
 
-  static String m60(endDate) => "Votre abonnement sera annulé le ${endDate}";
+  static String m59(endDate) => "Votre abonnement sera annulé le ${endDate}";
 
-  static String m61(completed, total) =>
+  static String m60(completed, total) =>
       "${completed}/${total} souvenirs préservés";
 
-  static String m62(storageAmountInGB) =>
+  static String m61(storageAmountInGB) =>
       "Ils obtiennent aussi ${storageAmountInGB} Go";
 
-  static String m63(email) => "Ceci est l\'ID de vérification de ${email}";
+  static String m62(email) => "Ceci est l\'ID de vérification de ${email}";
 
-  static String m64(count) =>
+  static String m63(count) =>
       "${Intl.plural(count, zero: '0 jour', one: '1 jour', other: '${count} jours')}";
 
-  static String m65(endDate) => "Valable jusqu\'au ${endDate}";
+  static String m64(endDate) => "Valable jusqu\'au ${endDate}";
 
-  static String m66(email) => "Vérifier ${email}";
+  static String m65(email) => "Vérifier ${email}";
 
-  static String m67(email) =>
+  static String m66(email) =>
       "Nous avons envoyé un e-mail à <green>${email}</green>";
 
-  static String m68(count) =>
+  static String m67(count) =>
       "${Intl.plural(count, one: 'il y a ${count} an', other: 'il y a ${count} ans')}";
 
-  static String m69(storageSaved) =>
+  static String m68(storageSaved) =>
       "Vous avez libéré ${storageSaved} avec succès !";
 
   final messages = _notInlinedMessages(_notInlinedMessages);
@@ -1000,7 +997,6 @@ class MessageLookup extends MessageLookupByLibrary {
         "paymentFailed":
             MessageLookupByLibrary.simpleMessage("Échec du paiement"),
         "paymentFailedTalkToProvider": m37,
-        "paymentFailedWithReason": m38,
         "pendingSync":
             MessageLookupByLibrary.simpleMessage("Synchronisation en attente"),
         "peopleUsingYourCode": MessageLookupByLibrary.simpleMessage(
@@ -1023,7 +1019,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "pickCenterPoint": MessageLookupByLibrary.simpleMessage(
             "Sélectionner le point central"),
         "pinAlbum": MessageLookupByLibrary.simpleMessage("Épingler l\'album"),
-        "playStoreFreeTrialValidTill": m39,
+        "playStoreFreeTrialValidTill": m38,
         "playstoreSubscription":
             MessageLookupByLibrary.simpleMessage("Abonnement au PlayStore"),
         "pleaseContactSupportAndWeWillBeHappyToHelp":
@@ -1032,12 +1028,12 @@ class MessageLookup extends MessageLookupByLibrary {
         "pleaseContactSupportIfTheProblemPersists":
             MessageLookupByLibrary.simpleMessage(
                 "Merci de contacter l\'assistance si cette erreur persiste"),
-        "pleaseEmailUsAt": m40,
+        "pleaseEmailUsAt": m39,
         "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage(
             "Veuillez accorder la permission"),
         "pleaseLoginAgain":
             MessageLookupByLibrary.simpleMessage("Veuillez vous reconnecter"),
-        "pleaseSendTheLogsTo": m41,
+        "pleaseSendTheLogsTo": m40,
         "pleaseTryAgain":
             MessageLookupByLibrary.simpleMessage("Veuillez réessayer"),
         "pleaseVerifyTheCodeYouHaveEntered":
@@ -1073,7 +1069,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "rateTheApp":
             MessageLookupByLibrary.simpleMessage("Évaluer l\'application"),
         "rateUs": MessageLookupByLibrary.simpleMessage("Évaluez-nous"),
-        "rateUsOnStore": m42,
+        "rateUsOnStore": m41,
         "recover": MessageLookupByLibrary.simpleMessage("Récupérer"),
         "recoverAccount":
             MessageLookupByLibrary.simpleMessage("Récupérer un compte"),
@@ -1104,7 +1100,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "1. Donnez ce code à vos amis"),
         "referralStep2": MessageLookupByLibrary.simpleMessage(
             "2. Ils s\'inscrivent à une offre payante"),
-        "referralStep3": m43,
+        "referralStep3": m42,
         "referrals": MessageLookupByLibrary.simpleMessage("Parrainages"),
         "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage(
             "Les recommandations sont actuellement en pause"),
@@ -1130,7 +1126,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "removeLink": MessageLookupByLibrary.simpleMessage("Supprimer le lien"),
         "removeParticipant":
             MessageLookupByLibrary.simpleMessage("Supprimer le participant"),
-        "removeParticipantBody": m44,
+        "removeParticipantBody": m43,
         "removePublicLink":
             MessageLookupByLibrary.simpleMessage("Supprimer le lien public"),
         "removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(
@@ -1146,7 +1142,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Renommer le fichier"),
         "renewSubscription":
             MessageLookupByLibrary.simpleMessage("Renouveler l’abonnement"),
-        "renewsOn": m45,
+        "renewsOn": m44,
         "reportABug": MessageLookupByLibrary.simpleMessage("Signaler un bug"),
         "reportBug": MessageLookupByLibrary.simpleMessage("Signaler un bug"),
         "resendEmail":
@@ -1211,7 +1207,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Grouper les photos qui sont prises dans un certain angle d\'une photo"),
         "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage(
             "Invitez des gens, et vous verrez ici toutes les photos qu\'ils partagent"),
-        "searchResultCount": m46,
+        "searchResultCount": m45,
         "security": MessageLookupByLibrary.simpleMessage("Sécurité"),
         "selectALocation":
             MessageLookupByLibrary.simpleMessage("Select a location"),
@@ -1240,8 +1236,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "selectedItemsWillBeDeletedFromAllAlbumsAndMoved":
             MessageLookupByLibrary.simpleMessage(
                 "Les éléments sélectionnés seront supprimés de tous les albums et déplacés dans la corbeille."),
-        "selectedPhotos": m47,
-        "selectedPhotosWithYours": m48,
+        "selectedPhotos": m46,
+        "selectedPhotosWithYours": m47,
         "send": MessageLookupByLibrary.simpleMessage("Envoyer"),
         "sendEmail": MessageLookupByLibrary.simpleMessage("Envoyer un e-mail"),
         "sendInvite":
@@ -1267,16 +1263,16 @@ class MessageLookup extends MessageLookupByLibrary {
         "shareAnAlbumNow": MessageLookupByLibrary.simpleMessage(
             "Partagez un album maintenant"),
         "shareLink": MessageLookupByLibrary.simpleMessage("Partager le lien"),
-        "shareMyVerificationID": m49,
+        "shareMyVerificationID": m48,
         "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage(
             "Partager uniquement avec les personnes que vous voulez"),
-        "shareTextConfirmOthersVerificationID": m50,
+        "shareTextConfirmOthersVerificationID": m49,
         "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage(
             "Téléchargez ente pour que nous puissions facilement partager des photos et des vidéos de qualité originale\n\nhttps://ente.io"),
-        "shareTextReferralCode": m51,
+        "shareTextReferralCode": m50,
         "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage(
             "Partager avec des utilisateurs non-ente"),
-        "shareWithPeopleSectionTitle": m52,
+        "shareWithPeopleSectionTitle": m51,
         "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage(
             "Partagez votre premier album"),
         "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage(
@@ -1287,7 +1283,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Nouvelles photos partagées"),
         "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage(
             "Recevoir des notifications quand quelqu\'un ajoute une photo à un album partagé dont vous faites partie"),
-        "sharedWith": m53,
+        "sharedWith": m52,
         "sharedWithMe":
             MessageLookupByLibrary.simpleMessage("Partagés avec moi"),
         "sharedWithYou":
@@ -1297,11 +1293,11 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Montrer les souvenirs"),
         "signUpTerms": MessageLookupByLibrary.simpleMessage(
             "J\'accepte les <u-terms>conditions d\'utilisation</u-terms> et la <u-policy>politique de confidentialité</u-policy>"),
-        "singleFileDeleteFromDevice": m54,
+        "singleFileDeleteFromDevice": m53,
         "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage(
             "Elle sera supprimée de tous les albums."),
-        "singleFileInBothLocalAndRemote": m55,
-        "singleFileInRemoteOnly": m56,
+        "singleFileInBothLocalAndRemote": m54,
+        "singleFileInRemoteOnly": m55,
         "skip": MessageLookupByLibrary.simpleMessage("Ignorer"),
         "social": MessageLookupByLibrary.simpleMessage("Réseaux Sociaux"),
         "someItemsAreInBothEnteAndYourDevice":
@@ -1341,14 +1337,14 @@ class MessageLookup extends MessageLookupByLibrary {
         "storage": MessageLookupByLibrary.simpleMessage("Stockage"),
         "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Famille"),
         "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Vous"),
-        "storageInGB": m57,
+        "storageInGB": m56,
         "storageLimitExceeded":
             MessageLookupByLibrary.simpleMessage("Limite de stockage atteinte"),
-        "storageUsageInfo": m58,
+        "storageUsageInfo": m57,
         "strongStrength":
             MessageLookupByLibrary.simpleMessage("Securité forte"),
-        "subAlreadyLinkedErrMessage": m59,
-        "subWillBeCancelledOn": m60,
+        "subAlreadyLinkedErrMessage": m58,
+        "subWillBeCancelledOn": m59,
         "subscribe": MessageLookupByLibrary.simpleMessage("S\'abonner"),
         "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage(
             "Il semble que votre abonnement ait expiré. Veuillez vous abonner pour activer le partage."),
@@ -1365,7 +1361,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "suggestFeatures": MessageLookupByLibrary.simpleMessage(
             "Suggérer des fonctionnalités"),
         "support": MessageLookupByLibrary.simpleMessage("Support"),
-        "syncProgress": m61,
+        "syncProgress": m60,
         "syncStopped":
             MessageLookupByLibrary.simpleMessage("Synchronisation arrêtée ?"),
         "syncing": MessageLookupByLibrary.simpleMessage(
@@ -1394,7 +1390,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "theseItemsWillBeDeletedFromYourDevice":
             MessageLookupByLibrary.simpleMessage(
                 "Ces éléments seront supprimés de votre appareil."),
-        "theyAlsoGetXGb": m62,
+        "theyAlsoGetXGb": m61,
         "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage(
             "Ils seront supprimés de tous les albums."),
         "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage(
@@ -1410,7 +1406,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Cette adresse mail est déjà utilisé"),
         "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage(
             "Cette image n\'a pas de données exif"),
-        "thisIsPersonVerificationId": m63,
+        "thisIsPersonVerificationId": m62,
         "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage(
             "Ceci est votre ID de vérification"),
         "thisWillLogYouOutOfTheFollowingDevice":
@@ -1426,7 +1422,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "total": MessageLookupByLibrary.simpleMessage("total"),
         "totalSize": MessageLookupByLibrary.simpleMessage("Taille totale"),
         "trash": MessageLookupByLibrary.simpleMessage("Corbeille"),
-        "trashDaysLeft": m64,
+        "trashDaysLeft": m63,
         "tryAgain": MessageLookupByLibrary.simpleMessage("Réessayer"),
         "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage(
             "Activez la sauvegarde pour télécharger automatiquement les fichiers ajoutés à ce dossier de l\'appareil sur ente."),
@@ -1484,7 +1480,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "useSelectedPhoto": MessageLookupByLibrary.simpleMessage(
             "Utiliser la photo sélectionnée"),
         "usedSpace": MessageLookupByLibrary.simpleMessage("Mémoire utilisée"),
-        "validTill": m65,
+        "validTill": m64,
         "verificationFailedPleaseTryAgain":
             MessageLookupByLibrary.simpleMessage(
                 "La vérification a échouée, veuillez réessayer"),
@@ -1493,7 +1489,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "verify": MessageLookupByLibrary.simpleMessage("Vérifier"),
         "verifyEmail":
             MessageLookupByLibrary.simpleMessage("Vérifier l\'email"),
-        "verifyEmailID": m66,
+        "verifyEmailID": m65,
         "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Vérifier"),
         "verifyPassword":
             MessageLookupByLibrary.simpleMessage("Vérifier le mot de passe"),
@@ -1522,11 +1518,11 @@ class MessageLookup extends MessageLookupByLibrary {
         "weDontSupportEditingPhotosAndAlbumsThatYouDont":
             MessageLookupByLibrary.simpleMessage(
                 "Nous ne prenons pas en charge l\'édition des photos et des albums que vous ne possédez pas encore"),
-        "weHaveSendEmailTo": m67,
+        "weHaveSendEmailTo": m66,
         "weakStrength": MessageLookupByLibrary.simpleMessage("Securité Faible"),
         "welcomeBack": MessageLookupByLibrary.simpleMessage("Bienvenue !"),
         "yearly": MessageLookupByLibrary.simpleMessage("Annuel"),
-        "yearsAgo": m68,
+        "yearsAgo": m67,
         "yes": MessageLookupByLibrary.simpleMessage("Oui"),
         "yesCancel": MessageLookupByLibrary.simpleMessage("Oui, annuler"),
         "yesConvertToViewer": MessageLookupByLibrary.simpleMessage(
@@ -1557,7 +1553,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Vous ne pouvez pas partager avec vous-même"),
         "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage(
             "Vous n\'avez aucun élément archivé."),
-        "youHaveSuccessfullyFreedUp": m69,
+        "youHaveSuccessfullyFreedUp": m68,
         "yourAccountHasBeenDeleted":
             MessageLookupByLibrary.simpleMessage("Votre compte a été supprimé"),
         "yourMap": MessageLookupByLibrary.simpleMessage("Votre carte"),

+ 60 - 64
mobile/lib/generated/intl/messages_it.dart

@@ -124,86 +124,83 @@ class MessageLookup extends MessageLookupByLibrary {
   static String m37(providerName) =>
       "Si prega di parlare con il supporto di ${providerName} se ti è stato addebitato qualcosa";
 
-  static String m38(reason) =>
-      "Purtroppo il tuo pagamento non è riuscito a causa di ${reason}";
-
-  static String m39(endDate) =>
+  static String m38(endDate) =>
       "Prova gratuita valida fino al ${endDate}.\nPuoi scegliere un piano a pagamento in seguito.";
 
-  static String m40(toEmail) => "Per favore invia un\'email a ${toEmail}";
+  static String m39(toEmail) => "Per favore invia un\'email a ${toEmail}";
 
-  static String m41(toEmail) => "Invia i log a \n${toEmail}";
+  static String m40(toEmail) => "Invia i log a \n${toEmail}";
 
-  static String m42(storeName) => "Valutaci su ${storeName}";
+  static String m41(storeName) => "Valutaci su ${storeName}";
 
-  static String m43(storageInGB) =>
+  static String m42(storageInGB) =>
       "3. Ottenete entrambi ${storageInGB} GB* gratis";
 
-  static String m44(userEmail) =>
+  static String m43(userEmail) =>
       "${userEmail} verrà rimosso da questo album condiviso\n\nQualsiasi foto aggiunta dall\'utente verrà rimossa dall\'album";
 
-  static String m45(endDate) => "Si rinnova il ${endDate}";
+  static String m44(endDate) => "Si rinnova il ${endDate}";
 
-  static String m47(count) => "${count} selezionati";
+  static String m46(count) => "${count} selezionati";
 
-  static String m48(count, yourCount) =>
+  static String m47(count, yourCount) =>
       "${count} selezionato (${yourCount} tuoi)";
 
-  static String m49(verificationID) =>
+  static String m48(verificationID) =>
       "Ecco il mio ID di verifica: ${verificationID} per ente.io.";
 
-  static String m50(verificationID) =>
+  static String m49(verificationID) =>
       "Hey, puoi confermare che questo è il tuo ID di verifica: ${verificationID} su ente.io";
 
-  static String m51(referralCode, referralStorageInGB) =>
+  static String m50(referralCode, referralStorageInGB) =>
       "ente referral code: ${referralCode} \n\nApplicalo in Impostazioni → Generale → Referral per ottenere ${referralStorageInGB} GB gratis dopo la registrazione di un piano a pagamento\n\nhttps://ente.io";
 
-  static String m52(numberOfPeople) =>
+  static String m51(numberOfPeople) =>
       "${Intl.plural(numberOfPeople, zero: 'Condividi con persone specifiche', one: 'Condividi con una persona', other: 'Condividi con ${numberOfPeople} persone')}";
 
-  static String m53(emailIDs) => "Condiviso con ${emailIDs}";
+  static String m52(emailIDs) => "Condiviso con ${emailIDs}";
 
-  static String m54(fileType) =>
+  static String m53(fileType) =>
       "Questo ${fileType} verrà eliminato dal tuo dispositivo.";
 
-  static String m55(fileType) =>
+  static String m54(fileType) =>
       "Questo ${fileType} è sia su ente che sul tuo dispositivo.";
 
-  static String m56(fileType) => "Questo ${fileType} verrà eliminato su ente.";
+  static String m55(fileType) => "Questo ${fileType} verrà eliminato su ente.";
 
-  static String m57(storageAmountInGB) => "${storageAmountInGB} GB";
+  static String m56(storageAmountInGB) => "${storageAmountInGB} GB";
 
-  static String m58(
+  static String m57(
           usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) =>
       "${usedAmount} ${usedStorageUnit} di ${totalAmount} ${totalStorageUnit} utilizzati";
 
-  static String m59(id) =>
+  static String m58(id) =>
       "Il tuo ${id} è già collegato ad un altro account ente.\nSe desideri utilizzare il tuo ${id} con questo account, contatta il nostro supporto\'\'";
 
-  static String m60(endDate) => "L\'abbonamento verrà cancellato il ${endDate}";
+  static String m59(endDate) => "L\'abbonamento verrà cancellato il ${endDate}";
 
-  static String m61(completed, total) =>
+  static String m60(completed, total) =>
       "${completed}/${total} ricordi conservati";
 
-  static String m62(storageAmountInGB) =>
+  static String m61(storageAmountInGB) =>
       "Anche loro riceveranno ${storageAmountInGB} GB";
 
-  static String m63(email) => "Questo è l\'ID di verifica di ${email}";
+  static String m62(email) => "Questo è l\'ID di verifica di ${email}";
 
-  static String m64(count) =>
+  static String m63(count) =>
       "${Intl.plural(count, zero: '', one: '1 giorno', other: '${count} giorni')}";
 
-  static String m65(endDate) => "Valido fino al ${endDate}";
+  static String m64(endDate) => "Valido fino al ${endDate}";
 
-  static String m66(email) => "Verifica ${email}";
+  static String m65(email) => "Verifica ${email}";
 
-  static String m67(email) =>
+  static String m66(email) =>
       "Abbiamo inviato una mail a <green>${email}</green>";
 
-  static String m68(count) =>
+  static String m67(count) =>
       "${Intl.plural(count, one: '${count} anno fa', other: '${count} anni fa')}";
 
-  static String m69(storageSaved) =>
+  static String m68(storageSaved) =>
       "Hai liberato con successo ${storageSaved}!";
 
   final messages = _notInlinedMessages(_notInlinedMessages);
@@ -967,7 +964,6 @@ class MessageLookup extends MessageLookupByLibrary {
         "paymentFailed":
             MessageLookupByLibrary.simpleMessage("Pagamento non riuscito"),
         "paymentFailedTalkToProvider": m37,
-        "paymentFailedWithReason": m38,
         "pendingSync":
             MessageLookupByLibrary.simpleMessage("Sincronizzazione in sospeso"),
         "peopleUsingYourCode": MessageLookupByLibrary.simpleMessage(
@@ -987,7 +983,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "pickCenterPoint": MessageLookupByLibrary.simpleMessage(
             "Selezionare il punto centrale"),
         "pinAlbum": MessageLookupByLibrary.simpleMessage("Fissa l\'album"),
-        "playStoreFreeTrialValidTill": m39,
+        "playStoreFreeTrialValidTill": m38,
         "playstoreSubscription":
             MessageLookupByLibrary.simpleMessage("Abbonamento su PlayStore"),
         "pleaseContactSupportAndWeWillBeHappyToHelp":
@@ -996,12 +992,12 @@ class MessageLookup extends MessageLookupByLibrary {
         "pleaseContactSupportIfTheProblemPersists":
             MessageLookupByLibrary.simpleMessage(
                 "Riprova. Se il problema persiste, ti invitiamo a contattare l\'assistenza"),
-        "pleaseEmailUsAt": m40,
+        "pleaseEmailUsAt": m39,
         "pleaseGrantPermissions":
             MessageLookupByLibrary.simpleMessage("Concedi i permessi"),
         "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage(
             "Effettua nuovamente l\'accesso"),
-        "pleaseSendTheLogsTo": m41,
+        "pleaseSendTheLogsTo": m40,
         "pleaseTryAgain": MessageLookupByLibrary.simpleMessage("Riprova"),
         "pleaseVerifyTheCodeYouHaveEntered":
             MessageLookupByLibrary.simpleMessage(
@@ -1035,7 +1031,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "raiseTicket": MessageLookupByLibrary.simpleMessage("Invia ticket"),
         "rateTheApp": MessageLookupByLibrary.simpleMessage("Valuta l\'app"),
         "rateUs": MessageLookupByLibrary.simpleMessage("Lascia una recensione"),
-        "rateUsOnStore": m42,
+        "rateUsOnStore": m41,
         "recover": MessageLookupByLibrary.simpleMessage("Recupera"),
         "recoverAccount":
             MessageLookupByLibrary.simpleMessage("Recupera account"),
@@ -1067,7 +1063,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "1. Condividi questo codice con i tuoi amici"),
         "referralStep2": MessageLookupByLibrary.simpleMessage(
             "2. Si iscrivono per un piano a pagamento"),
-        "referralStep3": m43,
+        "referralStep3": m42,
         "referrals": MessageLookupByLibrary.simpleMessage("Invita un Amico"),
         "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage(
             "I referral code sono attualmente in pausa"),
@@ -1091,7 +1087,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "removeLink": MessageLookupByLibrary.simpleMessage("Elimina link"),
         "removeParticipant":
             MessageLookupByLibrary.simpleMessage("Rimuovi partecipante"),
-        "removeParticipantBody": m44,
+        "removeParticipantBody": m43,
         "removePublicLink":
             MessageLookupByLibrary.simpleMessage("Rimuovi link pubblico"),
         "removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(
@@ -1105,7 +1101,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "renameFile": MessageLookupByLibrary.simpleMessage("Rinomina file"),
         "renewSubscription":
             MessageLookupByLibrary.simpleMessage("Rinnova abbonamento"),
-        "renewsOn": m45,
+        "renewsOn": m44,
         "reportABug": MessageLookupByLibrary.simpleMessage("Segnala un bug"),
         "reportBug": MessageLookupByLibrary.simpleMessage("Segnala un bug"),
         "resendEmail": MessageLookupByLibrary.simpleMessage("Rinvia email"),
@@ -1170,8 +1166,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "selectedItemsWillBeDeletedFromAllAlbumsAndMoved":
             MessageLookupByLibrary.simpleMessage(
                 "Gli elementi selezionati verranno eliminati da tutti gli album e spostati nel cestino."),
-        "selectedPhotos": m47,
-        "selectedPhotosWithYours": m48,
+        "selectedPhotos": m46,
+        "selectedPhotosWithYours": m47,
         "send": MessageLookupByLibrary.simpleMessage("Invia"),
         "sendEmail": MessageLookupByLibrary.simpleMessage("Invia email"),
         "sendInvite": MessageLookupByLibrary.simpleMessage("Invita"),
@@ -1195,16 +1191,16 @@ class MessageLookup extends MessageLookupByLibrary {
         "shareAnAlbumNow":
             MessageLookupByLibrary.simpleMessage("Condividi un album"),
         "shareLink": MessageLookupByLibrary.simpleMessage("Condividi link"),
-        "shareMyVerificationID": m49,
+        "shareMyVerificationID": m48,
         "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage(
             "Condividi solo con le persone che vuoi"),
-        "shareTextConfirmOthersVerificationID": m50,
+        "shareTextConfirmOthersVerificationID": m49,
         "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage(
             "Scarica ente in modo da poter facilmente condividere foto e video senza perdita di qualità\n\nhttps://ente.io"),
-        "shareTextReferralCode": m51,
+        "shareTextReferralCode": m50,
         "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage(
             "Condividi con utenti che non hanno un account ente"),
-        "shareWithPeopleSectionTitle": m52,
+        "shareWithPeopleSectionTitle": m51,
         "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage(
             "Condividi il tuo primo album"),
         "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage(
@@ -1215,7 +1211,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Nuove foto condivise"),
         "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage(
             "Ricevi notifiche quando qualcuno aggiunge una foto a un album condiviso, di cui fai parte"),
-        "sharedWith": m53,
+        "sharedWith": m52,
         "sharedWithMe":
             MessageLookupByLibrary.simpleMessage("Condivisi con me"),
         "sharedWithYou":
@@ -1225,11 +1221,11 @@ class MessageLookup extends MessageLookupByLibrary {
         "showMemories": MessageLookupByLibrary.simpleMessage("Mostra ricordi"),
         "signUpTerms": MessageLookupByLibrary.simpleMessage(
             "Accetto i <u-terms>termini di servizio</u-terms> e la <u-policy>politica sulla privacy</u-policy>"),
-        "singleFileDeleteFromDevice": m54,
+        "singleFileDeleteFromDevice": m53,
         "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage(
             "Verrà eliminato da tutti gli album."),
-        "singleFileInBothLocalAndRemote": m55,
-        "singleFileInRemoteOnly": m56,
+        "singleFileInBothLocalAndRemote": m54,
+        "singleFileInRemoteOnly": m55,
         "skip": MessageLookupByLibrary.simpleMessage("Salta"),
         "social": MessageLookupByLibrary.simpleMessage("Social"),
         "someItemsAreInBothEnteAndYourDevice":
@@ -1270,13 +1266,13 @@ class MessageLookup extends MessageLookupByLibrary {
         "storageBreakupFamily":
             MessageLookupByLibrary.simpleMessage("Famiglia"),
         "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Tu"),
-        "storageInGB": m57,
+        "storageInGB": m56,
         "storageLimitExceeded": MessageLookupByLibrary.simpleMessage(
             "Limite d\'archiviazione superato"),
-        "storageUsageInfo": m58,
+        "storageUsageInfo": m57,
         "strongStrength": MessageLookupByLibrary.simpleMessage("Forte"),
-        "subAlreadyLinkedErrMessage": m59,
-        "subWillBeCancelledOn": m60,
+        "subAlreadyLinkedErrMessage": m58,
+        "subWillBeCancelledOn": m59,
         "subscribe": MessageLookupByLibrary.simpleMessage("Iscriviti"),
         "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage(
             "Sembra che il tuo abbonamento sia scaduto. Iscriviti per abilitare la condivisione."),
@@ -1293,7 +1289,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "suggestFeatures":
             MessageLookupByLibrary.simpleMessage("Suggerisci una funzionalità"),
         "support": MessageLookupByLibrary.simpleMessage("Assistenza"),
-        "syncProgress": m61,
+        "syncProgress": m60,
         "syncStopped":
             MessageLookupByLibrary.simpleMessage("Sincronizzazione interrotta"),
         "syncing": MessageLookupByLibrary.simpleMessage(
@@ -1322,7 +1318,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "theseItemsWillBeDeletedFromYourDevice":
             MessageLookupByLibrary.simpleMessage(
                 "Questi file verranno eliminati dal tuo dispositivo."),
-        "theyAlsoGetXGb": m62,
+        "theyAlsoGetXGb": m61,
         "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage(
             "Verranno eliminati da tutti gli album."),
         "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage(
@@ -1339,7 +1335,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Questo indirizzo email è già registrato"),
         "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage(
             "Questa immagine non ha dati EXIF"),
-        "thisIsPersonVerificationId": m63,
+        "thisIsPersonVerificationId": m62,
         "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage(
             "Questo è il tuo ID di verifica"),
         "thisWillLogYouOutOfTheFollowingDevice":
@@ -1355,7 +1351,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "total": MessageLookupByLibrary.simpleMessage("totale"),
         "totalSize": MessageLookupByLibrary.simpleMessage("Dimensioni totali"),
         "trash": MessageLookupByLibrary.simpleMessage("Cestino"),
-        "trashDaysLeft": m64,
+        "trashDaysLeft": m63,
         "tryAgain": MessageLookupByLibrary.simpleMessage("Riprova"),
         "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage(
             "Attiva il backup per caricare automaticamente i file aggiunti in questa cartella del dispositivo su ente."),
@@ -1412,7 +1408,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "useSelectedPhoto":
             MessageLookupByLibrary.simpleMessage("Usa la foto selezionata"),
         "usedSpace": MessageLookupByLibrary.simpleMessage("Spazio utilizzato"),
-        "validTill": m65,
+        "validTill": m64,
         "verificationFailedPleaseTryAgain":
             MessageLookupByLibrary.simpleMessage(
                 "Verifica fallita, per favore prova di nuovo"),
@@ -1420,7 +1416,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("ID di verifica"),
         "verify": MessageLookupByLibrary.simpleMessage("Verifica"),
         "verifyEmail": MessageLookupByLibrary.simpleMessage("Verifica email"),
-        "verifyEmailID": m66,
+        "verifyEmailID": m65,
         "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Verifica"),
         "verifyPassword":
             MessageLookupByLibrary.simpleMessage("Verifica password"),
@@ -1447,11 +1443,11 @@ class MessageLookup extends MessageLookupByLibrary {
         "weDontSupportEditingPhotosAndAlbumsThatYouDont":
             MessageLookupByLibrary.simpleMessage(
                 "Non puoi modificare foto e album che non possiedi"),
-        "weHaveSendEmailTo": m67,
+        "weHaveSendEmailTo": m66,
         "weakStrength": MessageLookupByLibrary.simpleMessage("Debole"),
         "welcomeBack": MessageLookupByLibrary.simpleMessage("Bentornato/a!"),
         "yearly": MessageLookupByLibrary.simpleMessage("Annuale"),
-        "yearsAgo": m68,
+        "yearsAgo": m67,
         "yes": MessageLookupByLibrary.simpleMessage("Si"),
         "yesCancel": MessageLookupByLibrary.simpleMessage("Sì, cancella"),
         "yesConvertToViewer": MessageLookupByLibrary.simpleMessage(
@@ -1481,7 +1477,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Non puoi condividere con te stesso"),
         "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage(
             "Non hai nulla di archiviato."),
-        "youHaveSuccessfullyFreedUp": m69,
+        "youHaveSuccessfullyFreedUp": m68,
         "yourAccountHasBeenDeleted": MessageLookupByLibrary.simpleMessage(
             "Il tuo account è stato eliminato"),
         "yourMap": MessageLookupByLibrary.simpleMessage("Your map"),

+ 62 - 66
mobile/lib/generated/intl/messages_nl.dart

@@ -131,91 +131,88 @@ class MessageLookup extends MessageLookupByLibrary {
   static String m37(providerName) =>
       "Praat met ${providerName} klantenservice als u in rekening bent gebracht";
 
-  static String m38(reason) =>
-      "Helaas is uw betaling mislukt vanwege ${reason}";
-
-  static String m39(endDate) =>
+  static String m38(endDate) =>
       "Gratis proefperiode geldig tot ${endDate}.\nU kunt naderhand een betaald abonnement kiezen.";
 
-  static String m40(toEmail) => "Stuur ons een e-mail op ${toEmail}";
+  static String m39(toEmail) => "Stuur ons een e-mail op ${toEmail}";
 
-  static String m41(toEmail) =>
+  static String m40(toEmail) =>
       "Verstuur de logboeken alstublieft naar ${toEmail}";
 
-  static String m42(storeName) => "Beoordeel ons op ${storeName}";
+  static String m41(storeName) => "Beoordeel ons op ${storeName}";
 
-  static String m43(storageInGB) =>
+  static String m42(storageInGB) =>
       "Jullie krijgen allebei ${storageInGB} GB* gratis";
 
-  static String m44(userEmail) =>
+  static String m43(userEmail) =>
       "${userEmail} zal worden verwijderd uit dit gedeelde album\n\nAlle door hen toegevoegde foto\'s worden ook uit het album verwijderd";
 
-  static String m45(endDate) => "Wordt verlengd op ${endDate}";
+  static String m44(endDate) => "Wordt verlengd op ${endDate}";
 
-  static String m46(count) =>
+  static String m45(count) =>
       "${Intl.plural(count, one: '${count} resultaat gevonden', other: '${count} resultaten gevonden')}";
 
-  static String m47(count) => "${count} geselecteerd";
+  static String m46(count) => "${count} geselecteerd";
 
-  static String m48(count, yourCount) =>
+  static String m47(count, yourCount) =>
       "${count} geselecteerd (${yourCount} van jou)";
 
-  static String m49(verificationID) =>
+  static String m48(verificationID) =>
       "Hier is mijn verificatie-ID: ${verificationID} voor ente.io.";
 
-  static String m50(verificationID) =>
+  static String m49(verificationID) =>
       "Hey, kunt u bevestigen dat dit uw ente.io verificatie-ID is: ${verificationID}";
 
-  static String m51(referralCode, referralStorageInGB) =>
+  static String m50(referralCode, referralStorageInGB) =>
       "ente verwijzingscode: ${referralCode} \n\nPas het toe bij Instellingen → Algemeen → Verwijzingen om ${referralStorageInGB} GB gratis te krijgen nadat je je hebt aangemeld voor een betaald abonnement\n\nhttps://ente.io";
 
-  static String m52(numberOfPeople) =>
+  static String m51(numberOfPeople) =>
       "${Intl.plural(numberOfPeople, zero: 'Deel met specifieke mensen', one: 'Gedeeld met 1 persoon', other: 'Gedeeld met ${numberOfPeople} mensen')}";
 
-  static String m53(emailIDs) => "Gedeeld met ${emailIDs}";
+  static String m52(emailIDs) => "Gedeeld met ${emailIDs}";
 
-  static String m54(fileType) =>
+  static String m53(fileType) =>
       "Deze ${fileType} zal worden verwijderd van jouw apparaat.";
 
-  static String m55(fileType) =>
+  static String m54(fileType) =>
       "Deze ${fileType} staat zowel in ente als op jouw apparaat.";
 
-  static String m56(fileType) =>
+  static String m55(fileType) =>
       "Deze ${fileType} zal worden verwijderd uit ente.";
 
-  static String m57(storageAmountInGB) => "${storageAmountInGB} GB";
+  static String m56(storageAmountInGB) => "${storageAmountInGB} GB";
 
-  static String m58(
+  static String m57(
           usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) =>
       "${usedAmount} ${usedStorageUnit} van ${totalAmount} ${totalStorageUnit} gebruikt";
 
-  static String m59(id) =>
+  static String m58(id) =>
       "Uw ${id} is al aan een ander ente account gekoppeld.\nAls u uw ${id} wilt gebruiken met dit account, neem dan contact op met onze klantenservice";
 
-  static String m60(endDate) => "Uw abonnement loopt af op ${endDate}";
+  static String m59(endDate) => "Uw abonnement loopt af op ${endDate}";
 
-  static String m61(completed, total) =>
+  static String m60(completed, total) =>
       "${completed}/${total} herinneringen bewaard";
 
-  static String m62(storageAmountInGB) =>
+  static String m61(storageAmountInGB) =>
       "Zij krijgen ook ${storageAmountInGB} GB";
 
-  static String m63(email) => "Dit is de verificatie-ID van ${email}";
+  static String m62(email) => "Dit is de verificatie-ID van ${email}";
 
-  static String m64(count) =>
+  static String m63(count) =>
       "${Intl.plural(count, zero: '', one: '1 dag', other: '${count} dagen')}";
 
-  static String m65(endDate) => "Geldig tot ${endDate}";
+  static String m64(endDate) => "Geldig tot ${endDate}";
 
-  static String m66(email) => "Verifieer ${email}";
+  static String m65(email) => "Verifieer ${email}";
 
-  static String m67(email) =>
+  static String m66(email) =>
       "We hebben een e-mail gestuurd naar <green>${email}</green>";
 
-  static String m68(count) =>
+  static String m67(count) =>
       "${Intl.plural(count, one: '${count} jaar geleden', other: '${count} jaar geleden')}";
 
-  static String m69(storageSaved) =>
+  static String m68(storageSaved) =>
       "Je hebt ${storageSaved} succesvol vrijgemaakt!";
 
   final messages = _notInlinedMessages(_notInlinedMessages);
@@ -1020,7 +1017,6 @@ class MessageLookup extends MessageLookupByLibrary {
         "paymentFailed":
             MessageLookupByLibrary.simpleMessage("Betaling mislukt"),
         "paymentFailedTalkToProvider": m37,
-        "paymentFailedWithReason": m38,
         "pendingItems":
             MessageLookupByLibrary.simpleMessage("Bestanden in behandeling"),
         "pendingSync": MessageLookupByLibrary.simpleMessage(
@@ -1048,7 +1044,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Album bovenaan vastzetten"),
         "playOnTv":
             MessageLookupByLibrary.simpleMessage("Album afspelen op TV"),
-        "playStoreFreeTrialValidTill": m39,
+        "playStoreFreeTrialValidTill": m38,
         "playstoreSubscription":
             MessageLookupByLibrary.simpleMessage("PlayStore abonnement"),
         "pleaseCheckYourInternetConnectionAndTryAgain":
@@ -1060,12 +1056,12 @@ class MessageLookup extends MessageLookupByLibrary {
         "pleaseContactSupportIfTheProblemPersists":
             MessageLookupByLibrary.simpleMessage(
                 "Neem contact op met klantenservice als het probleem aanhoudt"),
-        "pleaseEmailUsAt": m40,
+        "pleaseEmailUsAt": m39,
         "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage(
             "Geef alstublieft toestemming"),
         "pleaseLoginAgain":
             MessageLookupByLibrary.simpleMessage("Log opnieuw in"),
-        "pleaseSendTheLogsTo": m41,
+        "pleaseSendTheLogsTo": m40,
         "pleaseTryAgain":
             MessageLookupByLibrary.simpleMessage("Probeer het nog eens"),
         "pleaseVerifyTheCodeYouHaveEntered":
@@ -1100,7 +1096,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "raiseTicket": MessageLookupByLibrary.simpleMessage("Meld probleem"),
         "rateTheApp": MessageLookupByLibrary.simpleMessage("Beoordeel de app"),
         "rateUs": MessageLookupByLibrary.simpleMessage("Beoordeel ons"),
-        "rateUsOnStore": m42,
+        "rateUsOnStore": m41,
         "recover": MessageLookupByLibrary.simpleMessage("Herstellen"),
         "recoverAccount":
             MessageLookupByLibrary.simpleMessage("Account herstellen"),
@@ -1131,7 +1127,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "1. Geef deze code aan je vrienden"),
         "referralStep2": MessageLookupByLibrary.simpleMessage(
             "2. Ze registreren voor een betaald plan"),
-        "referralStep3": m43,
+        "referralStep3": m42,
         "referrals": MessageLookupByLibrary.simpleMessage("Referenties"),
         "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage(
             "Verwijzingen zijn momenteel gepauzeerd"),
@@ -1157,7 +1153,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "removeLink": MessageLookupByLibrary.simpleMessage("Verwijder link"),
         "removeParticipant":
             MessageLookupByLibrary.simpleMessage("Deelnemer verwijderen"),
-        "removeParticipantBody": m44,
+        "removeParticipantBody": m43,
         "removePublicLink":
             MessageLookupByLibrary.simpleMessage("Verwijder publieke link"),
         "removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(
@@ -1173,7 +1169,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Bestandsnaam wijzigen"),
         "renewSubscription":
             MessageLookupByLibrary.simpleMessage("Abonnement verlengen"),
-        "renewsOn": m45,
+        "renewsOn": m44,
         "reportABug": MessageLookupByLibrary.simpleMessage("Een fout melden"),
         "reportBug": MessageLookupByLibrary.simpleMessage("Fout melden"),
         "resendEmail":
@@ -1235,7 +1231,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Foto\'s groeperen die in een bepaalde straal van een foto worden genomen"),
         "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage(
             "Nodig mensen uit, en je ziet alle foto\'s die door hen worden gedeeld hier"),
-        "searchResultCount": m46,
+        "searchResultCount": m45,
         "security": MessageLookupByLibrary.simpleMessage("Beveiliging"),
         "selectALocation":
             MessageLookupByLibrary.simpleMessage("Selecteer een locatie"),
@@ -1262,8 +1258,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "selectedItemsWillBeDeletedFromAllAlbumsAndMoved":
             MessageLookupByLibrary.simpleMessage(
                 "Geselecteerde bestanden worden verwijderd uit alle albums en verplaatst naar de prullenbak."),
-        "selectedPhotos": m47,
-        "selectedPhotosWithYours": m48,
+        "selectedPhotos": m46,
+        "selectedPhotosWithYours": m47,
         "send": MessageLookupByLibrary.simpleMessage("Verzenden"),
         "sendEmail": MessageLookupByLibrary.simpleMessage("E-mail versturen"),
         "sendInvite":
@@ -1287,16 +1283,16 @@ class MessageLookup extends MessageLookupByLibrary {
         "shareAnAlbumNow":
             MessageLookupByLibrary.simpleMessage("Deel nu een album"),
         "shareLink": MessageLookupByLibrary.simpleMessage("Link delen"),
-        "shareMyVerificationID": m49,
+        "shareMyVerificationID": m48,
         "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage(
             "Deel alleen met de mensen die u wilt"),
-        "shareTextConfirmOthersVerificationID": m50,
+        "shareTextConfirmOthersVerificationID": m49,
         "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage(
             "Download ente zodat we gemakkelijk foto\'s en video\'s van originele kwaliteit kunnen delen\n\nhttps://ente.io"),
-        "shareTextReferralCode": m51,
+        "shareTextReferralCode": m50,
         "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage(
             "Delen met niet-ente gebruikers"),
-        "shareWithPeopleSectionTitle": m52,
+        "shareWithPeopleSectionTitle": m51,
         "shareYourFirstAlbum":
             MessageLookupByLibrary.simpleMessage("Deel jouw eerste album"),
         "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage(
@@ -1307,7 +1303,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Nieuwe gedeelde foto\'s"),
         "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage(
             "Ontvang meldingen wanneer iemand een foto toevoegt aan een gedeeld album waar je deel van uitmaakt"),
-        "sharedWith": m53,
+        "sharedWith": m52,
         "sharedWithMe": MessageLookupByLibrary.simpleMessage("Gedeeld met mij"),
         "sharedWithYou":
             MessageLookupByLibrary.simpleMessage("Gedeeld met jou"),
@@ -1322,11 +1318,11 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Log uit op andere apparaten"),
         "signUpTerms": MessageLookupByLibrary.simpleMessage(
             "Ik ga akkoord met de <u-terms>gebruiksvoorwaarden</u-terms> en <u-policy>privacybeleid</u-policy>"),
-        "singleFileDeleteFromDevice": m54,
+        "singleFileDeleteFromDevice": m53,
         "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage(
             "Het wordt uit alle albums verwijderd."),
-        "singleFileInBothLocalAndRemote": m55,
-        "singleFileInRemoteOnly": m56,
+        "singleFileInBothLocalAndRemote": m54,
+        "singleFileInRemoteOnly": m55,
         "skip": MessageLookupByLibrary.simpleMessage("Overslaan"),
         "social": MessageLookupByLibrary.simpleMessage("Sociale media"),
         "someItemsAreInBothEnteAndYourDevice": MessageLookupByLibrary.simpleMessage(
@@ -1364,13 +1360,13 @@ class MessageLookup extends MessageLookupByLibrary {
         "storage": MessageLookupByLibrary.simpleMessage("Opslagruimte"),
         "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Familie"),
         "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Jij"),
-        "storageInGB": m57,
+        "storageInGB": m56,
         "storageLimitExceeded":
             MessageLookupByLibrary.simpleMessage("Opslaglimiet overschreden"),
-        "storageUsageInfo": m58,
+        "storageUsageInfo": m57,
         "strongStrength": MessageLookupByLibrary.simpleMessage("Sterk"),
-        "subAlreadyLinkedErrMessage": m59,
-        "subWillBeCancelledOn": m60,
+        "subAlreadyLinkedErrMessage": m58,
+        "subWillBeCancelledOn": m59,
         "subscribe": MessageLookupByLibrary.simpleMessage("Abonneer"),
         "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage(
             "Het lijkt erop dat je abonnement is verlopen. Abonneer om delen mogelijk te maken."),
@@ -1387,7 +1383,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "suggestFeatures":
             MessageLookupByLibrary.simpleMessage("Features voorstellen"),
         "support": MessageLookupByLibrary.simpleMessage("Ondersteuning"),
-        "syncProgress": m61,
+        "syncProgress": m60,
         "syncStopped":
             MessageLookupByLibrary.simpleMessage("Synchronisatie gestopt"),
         "syncing": MessageLookupByLibrary.simpleMessage("Synchroniseren..."),
@@ -1415,7 +1411,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "theseItemsWillBeDeletedFromYourDevice":
             MessageLookupByLibrary.simpleMessage(
                 "Deze bestanden zullen worden verwijderd van uw apparaat."),
-        "theyAlsoGetXGb": m62,
+        "theyAlsoGetXGb": m61,
         "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage(
             "Ze zullen uit alle albums worden verwijderd."),
         "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage(
@@ -1431,7 +1427,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Dit e-mailadres is al in gebruik"),
         "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage(
             "Deze foto heeft geen exif gegevens"),
-        "thisIsPersonVerificationId": m63,
+        "thisIsPersonVerificationId": m62,
         "thisIsYourVerificationId":
             MessageLookupByLibrary.simpleMessage("Dit is uw verificatie-ID"),
         "thisWillLogYouOutOfTheFollowingDevice":
@@ -1448,7 +1444,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "total": MessageLookupByLibrary.simpleMessage("totaal"),
         "totalSize": MessageLookupByLibrary.simpleMessage("Totale grootte"),
         "trash": MessageLookupByLibrary.simpleMessage("Prullenbak"),
-        "trashDaysLeft": m64,
+        "trashDaysLeft": m63,
         "tryAgain": MessageLookupByLibrary.simpleMessage("Probeer opnieuw"),
         "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage(
             "Schakel back-up in om bestanden die toegevoegd zijn aan deze map op dit apparaat automatisch te uploaden."),
@@ -1504,7 +1500,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "useSelectedPhoto":
             MessageLookupByLibrary.simpleMessage("Gebruik geselecteerde foto"),
         "usedSpace": MessageLookupByLibrary.simpleMessage("Gebruikte ruimte"),
-        "validTill": m65,
+        "validTill": m64,
         "verificationFailedPleaseTryAgain":
             MessageLookupByLibrary.simpleMessage(
                 "Verificatie mislukt, probeer het opnieuw"),
@@ -1512,7 +1508,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Verificatie ID"),
         "verify": MessageLookupByLibrary.simpleMessage("Verifiëren"),
         "verifyEmail": MessageLookupByLibrary.simpleMessage("Bevestig e-mail"),
-        "verifyEmailID": m66,
+        "verifyEmailID": m65,
         "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Verifiëren"),
         "verifyPassword":
             MessageLookupByLibrary.simpleMessage("Bevestig wachtwoord"),
@@ -1541,11 +1537,11 @@ class MessageLookup extends MessageLookupByLibrary {
         "weDontSupportEditingPhotosAndAlbumsThatYouDont":
             MessageLookupByLibrary.simpleMessage(
                 "We ondersteunen het bewerken van foto\'s en albums waar je niet de eigenaar van bent nog niet"),
-        "weHaveSendEmailTo": m67,
+        "weHaveSendEmailTo": m66,
         "weakStrength": MessageLookupByLibrary.simpleMessage("Zwak"),
         "welcomeBack": MessageLookupByLibrary.simpleMessage("Welkom terug!"),
         "yearly": MessageLookupByLibrary.simpleMessage("Jaarlijks"),
-        "yearsAgo": m68,
+        "yearsAgo": m67,
         "yes": MessageLookupByLibrary.simpleMessage("Ja"),
         "yesCancel": MessageLookupByLibrary.simpleMessage("Ja, opzeggen"),
         "yesConvertToViewer":
@@ -1575,7 +1571,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Je kunt niet met jezelf delen"),
         "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage(
             "U heeft geen gearchiveerde bestanden."),
-        "youHaveSuccessfullyFreedUp": m69,
+        "youHaveSuccessfullyFreedUp": m68,
         "yourAccountHasBeenDeleted":
             MessageLookupByLibrary.simpleMessage("Je account is verwijderd"),
         "yourMap": MessageLookupByLibrary.simpleMessage("Jouw kaart"),

+ 62 - 66
mobile/lib/generated/intl/messages_pt.dart

@@ -130,88 +130,85 @@ class MessageLookup extends MessageLookupByLibrary {
   static String m37(providerName) =>
       "Por favor, fale com o suporte ${providerName} se você foi cobrado";
 
-  static String m38(reason) =>
-      "Infelizmente o seu pagamento falhou devido a ${reason}";
-
-  static String m39(endDate) =>
+  static String m38(endDate) =>
       "Teste gratuito válido até ${endDate}.\nVocê pode escolher um plano pago depois.";
 
-  static String m40(toEmail) =>
+  static String m39(toEmail) =>
       "Por favor, envie-nos um e-mail para ${toEmail}";
 
-  static String m41(toEmail) => "Por favor, envie os logs para \n${toEmail}";
+  static String m40(toEmail) => "Por favor, envie os logs para \n${toEmail}";
 
-  static String m42(storeName) => "Avalie-nos em ${storeName}";
+  static String m41(storeName) => "Avalie-nos em ${storeName}";
 
-  static String m43(storageInGB) => "3. Ambos ganham ${storageInGB} GB* grátis";
+  static String m42(storageInGB) => "3. Ambos ganham ${storageInGB} GB* grátis";
 
-  static String m44(userEmail) =>
+  static String m43(userEmail) =>
       "${userEmail} será removido deste álbum compartilhado\n\nQuaisquer fotos adicionadas por eles também serão removidas do álbum";
 
-  static String m45(endDate) => "Renovação de assinatura em ${endDate}";
+  static String m44(endDate) => "Renovação de assinatura em ${endDate}";
 
-  static String m46(count) =>
+  static String m45(count) =>
       "${Intl.plural(count, one: '${count} resultado encontrado', other: '${count} resultado encontrado')}";
 
-  static String m47(count) => "${count} Selecionados";
+  static String m46(count) => "${count} Selecionados";
 
-  static String m48(count, yourCount) =>
+  static String m47(count, yourCount) =>
       "${count} Selecionado (${yourCount} seus)";
 
-  static String m49(verificationID) =>
+  static String m48(verificationID) =>
       "Aqui está meu ID de verificação para o Ente.io: ${verificationID}";
 
-  static String m50(verificationID) =>
+  static String m49(verificationID) =>
       "Ei, você pode confirmar que este é seu ID de verificação do Ente.io? ${verificationID}";
 
-  static String m51(referralCode, referralStorageInGB) =>
+  static String m50(referralCode, referralStorageInGB) =>
       "Código de referência do ente: ${referralCode} \n\nAplique em Configurações → Geral → Indicações para obter ${referralStorageInGB} GB gratuitamente após a sua inscrição em um plano pago\n\nhttps://ente.io";
 
-  static String m52(numberOfPeople) =>
+  static String m51(numberOfPeople) =>
       "${Intl.plural(numberOfPeople, zero: 'Compartilhe com pessoas específicas', one: 'Compartilhado com 1 pessoa', other: 'Compartilhado com ${numberOfPeople} pessoas')}";
 
-  static String m53(emailIDs) => "Compartilhado com ${emailIDs}";
+  static String m52(emailIDs) => "Compartilhado com ${emailIDs}";
 
-  static String m54(fileType) =>
+  static String m53(fileType) =>
       "Este ${fileType} será excluído do seu dispositivo.";
 
-  static String m55(fileType) =>
+  static String m54(fileType) =>
       "Este ${fileType} está em ente e no seu dispositivo.";
 
-  static String m56(fileType) => "Este ${fileType} será excluído do ente.";
+  static String m55(fileType) => "Este ${fileType} será excluído do ente.";
 
-  static String m57(storageAmountInGB) => "${storageAmountInGB} GB";
+  static String m56(storageAmountInGB) => "${storageAmountInGB} GB";
 
-  static String m58(
+  static String m57(
           usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) =>
       "${usedAmount} ${usedStorageUnit} de ${totalAmount} ${totalStorageUnit} usado";
 
-  static String m59(id) =>
+  static String m58(id) =>
       "Seu ${id} já está vinculado a outra conta ente.\nSe você gostaria de usar seu ${id} com esta conta, por favor contate nosso suporte\'\'";
 
-  static String m60(endDate) => "Sua assinatura será cancelada em ${endDate}";
+  static String m59(endDate) => "Sua assinatura será cancelada em ${endDate}";
 
-  static String m61(completed, total) =>
+  static String m60(completed, total) =>
       "${completed}/${total} memórias preservadas";
 
-  static String m62(storageAmountInGB) =>
+  static String m61(storageAmountInGB) =>
       "Eles também recebem ${storageAmountInGB} GB";
 
-  static String m63(email) => "Este é o ID de verificação de ${email}";
+  static String m62(email) => "Este é o ID de verificação de ${email}";
 
-  static String m64(count) =>
+  static String m63(count) =>
       "${Intl.plural(count, zero: '', one: '1 dia', other: '${count} dias')}";
 
-  static String m65(endDate) => "Válido até ${endDate}";
+  static String m64(endDate) => "Válido até ${endDate}";
 
-  static String m66(email) => "Verificar ${email}";
+  static String m65(email) => "Verificar ${email}";
 
-  static String m67(email) => "Enviamos um e-mail à <green>${email}</green>";
+  static String m66(email) => "Enviamos um e-mail à <green>${email}</green>";
 
-  static String m68(count) =>
+  static String m67(count) =>
       "${Intl.plural(count, one: '${count} anos atrás', other: '${count} anos atrás')}";
 
-  static String m69(storageSaved) =>
+  static String m68(storageSaved) =>
       "Você liberou ${storageSaved} com sucesso!";
 
   final messages = _notInlinedMessages(_notInlinedMessages);
@@ -1015,7 +1012,6 @@ class MessageLookup extends MessageLookupByLibrary {
         "paymentFailed":
             MessageLookupByLibrary.simpleMessage("Falha no pagamento"),
         "paymentFailedTalkToProvider": m37,
-        "paymentFailedWithReason": m38,
         "pendingItems": MessageLookupByLibrary.simpleMessage("Itens pendentes"),
         "pendingSync":
             MessageLookupByLibrary.simpleMessage("Sincronização pendente"),
@@ -1041,7 +1037,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "pinAlbum": MessageLookupByLibrary.simpleMessage("Fixar álbum"),
         "playOnTv":
             MessageLookupByLibrary.simpleMessage("Reproduzir álbum na TV"),
-        "playStoreFreeTrialValidTill": m39,
+        "playStoreFreeTrialValidTill": m38,
         "playstoreSubscription":
             MessageLookupByLibrary.simpleMessage("Assinatura da PlayStore"),
         "pleaseCheckYourInternetConnectionAndTryAgain":
@@ -1053,12 +1049,12 @@ class MessageLookup extends MessageLookupByLibrary {
         "pleaseContactSupportIfTheProblemPersists":
             MessageLookupByLibrary.simpleMessage(
                 "Por favor, contate o suporte se o problema persistir"),
-        "pleaseEmailUsAt": m40,
+        "pleaseEmailUsAt": m39,
         "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage(
             "Por favor, conceda as permissões"),
         "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage(
             "Por favor, faça login novamente"),
-        "pleaseSendTheLogsTo": m41,
+        "pleaseSendTheLogsTo": m40,
         "pleaseTryAgain":
             MessageLookupByLibrary.simpleMessage("Por favor, tente novamente"),
         "pleaseVerifyTheCodeYouHaveEntered":
@@ -1095,7 +1091,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "rateTheApp":
             MessageLookupByLibrary.simpleMessage("Avalie o aplicativo"),
         "rateUs": MessageLookupByLibrary.simpleMessage("Avalie-nos"),
-        "rateUsOnStore": m42,
+        "rateUsOnStore": m41,
         "recover": MessageLookupByLibrary.simpleMessage("Recuperar"),
         "recoverAccount":
             MessageLookupByLibrary.simpleMessage("Recuperar conta"),
@@ -1127,7 +1123,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Envie esse código aos seus amigos"),
         "referralStep2": MessageLookupByLibrary.simpleMessage(
             "2. Eles se inscreveram para um plano pago"),
-        "referralStep3": m43,
+        "referralStep3": m42,
         "referrals": MessageLookupByLibrary.simpleMessage("Indicações"),
         "referralsAreCurrentlyPaused": MessageLookupByLibrary.simpleMessage(
             "Referências estão atualmente pausadas"),
@@ -1151,7 +1147,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "removeLink": MessageLookupByLibrary.simpleMessage("Remover link"),
         "removeParticipant":
             MessageLookupByLibrary.simpleMessage("Remover participante"),
-        "removeParticipantBody": m44,
+        "removeParticipantBody": m43,
         "removePublicLink":
             MessageLookupByLibrary.simpleMessage("Remover link público"),
         "removeShareItemsWarning": MessageLookupByLibrary.simpleMessage(
@@ -1165,7 +1161,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "renameFile": MessageLookupByLibrary.simpleMessage("Renomear arquivo"),
         "renewSubscription":
             MessageLookupByLibrary.simpleMessage("Renovar assinatura"),
-        "renewsOn": m45,
+        "renewsOn": m44,
         "reportABug":
             MessageLookupByLibrary.simpleMessage("Reportar um problema"),
         "reportBug":
@@ -1230,7 +1226,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Fotos de grupo que estão sendo tiradas em algum raio da foto"),
         "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage(
             "Convide pessoas e você verá todas as fotos compartilhadas por elas aqui"),
-        "searchResultCount": m46,
+        "searchResultCount": m45,
         "security": MessageLookupByLibrary.simpleMessage("Segurança"),
         "selectALocation":
             MessageLookupByLibrary.simpleMessage("Selecionar um local"),
@@ -1258,8 +1254,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "selectedItemsWillBeDeletedFromAllAlbumsAndMoved":
             MessageLookupByLibrary.simpleMessage(
                 "Os itens selecionados serão excluídos de todos os álbuns e movidos para o lixo."),
-        "selectedPhotos": m47,
-        "selectedPhotosWithYours": m48,
+        "selectedPhotos": m46,
+        "selectedPhotosWithYours": m47,
         "send": MessageLookupByLibrary.simpleMessage("Enviar"),
         "sendEmail": MessageLookupByLibrary.simpleMessage("Enviar e-mail"),
         "sendInvite": MessageLookupByLibrary.simpleMessage("Enviar convite"),
@@ -1283,16 +1279,16 @@ class MessageLookup extends MessageLookupByLibrary {
         "shareAnAlbumNow":
             MessageLookupByLibrary.simpleMessage("Compartilhar um álbum agora"),
         "shareLink": MessageLookupByLibrary.simpleMessage("Compartilhar link"),
-        "shareMyVerificationID": m49,
+        "shareMyVerificationID": m48,
         "shareOnlyWithThePeopleYouWant": MessageLookupByLibrary.simpleMessage(
             "Compartilhar apenas com as pessoas que você quiser"),
-        "shareTextConfirmOthersVerificationID": m50,
+        "shareTextConfirmOthersVerificationID": m49,
         "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage(
             "Baixe o Ente para podermos compartilhar facilmente fotos e vídeos de alta qualidade\n\nhttps://ente.io"),
-        "shareTextReferralCode": m51,
+        "shareTextReferralCode": m50,
         "shareWithNonenteUsers": MessageLookupByLibrary.simpleMessage(
             "Compartilhar com usuários não-Ente"),
-        "shareWithPeopleSectionTitle": m52,
+        "shareWithPeopleSectionTitle": m51,
         "shareYourFirstAlbum": MessageLookupByLibrary.simpleMessage(
             "Compartilhar seu primeiro álbum"),
         "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage(
@@ -1305,7 +1301,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Novas fotos compartilhadas"),
         "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage(
             "Receber notificações quando alguém adicionar uma foto em um álbum compartilhado que você faz parte"),
-        "sharedWith": m53,
+        "sharedWith": m52,
         "sharedWithMe":
             MessageLookupByLibrary.simpleMessage("Compartilhado comigo"),
         "sharedWithYou":
@@ -1321,11 +1317,11 @@ class MessageLookup extends MessageLookupByLibrary {
             "Terminar sessão em outros dispositivos"),
         "signUpTerms": MessageLookupByLibrary.simpleMessage(
             "Eu concordo com os <u-terms>termos de serviço</u-terms> e a <u-policy>política de privacidade</u-policy>"),
-        "singleFileDeleteFromDevice": m54,
+        "singleFileDeleteFromDevice": m53,
         "singleFileDeleteHighlight": MessageLookupByLibrary.simpleMessage(
             "Ele será excluído de todos os álbuns."),
-        "singleFileInBothLocalAndRemote": m55,
-        "singleFileInRemoteOnly": m56,
+        "singleFileInBothLocalAndRemote": m54,
+        "singleFileInRemoteOnly": m55,
         "skip": MessageLookupByLibrary.simpleMessage("Pular"),
         "social": MessageLookupByLibrary.simpleMessage("Redes sociais"),
         "someItemsAreInBothEnteAndYourDevice":
@@ -1366,13 +1362,13 @@ class MessageLookup extends MessageLookupByLibrary {
         "storage": MessageLookupByLibrary.simpleMessage("Armazenamento"),
         "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("Família"),
         "storageBreakupYou": MessageLookupByLibrary.simpleMessage("Você"),
-        "storageInGB": m57,
+        "storageInGB": m56,
         "storageLimitExceeded": MessageLookupByLibrary.simpleMessage(
             "Limite de armazenamento excedido"),
-        "storageUsageInfo": m58,
+        "storageUsageInfo": m57,
         "strongStrength": MessageLookupByLibrary.simpleMessage("Forte"),
-        "subAlreadyLinkedErrMessage": m59,
-        "subWillBeCancelledOn": m60,
+        "subAlreadyLinkedErrMessage": m58,
+        "subWillBeCancelledOn": m59,
         "subscribe": MessageLookupByLibrary.simpleMessage("Assinar"),
         "subscribeToEnableSharing": MessageLookupByLibrary.simpleMessage(
             "Parece que sua assinatura expirou. Por favor inscreva-se para ativar o compartilhamento."),
@@ -1389,7 +1385,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "suggestFeatures":
             MessageLookupByLibrary.simpleMessage("Sugerir funcionalidades"),
         "support": MessageLookupByLibrary.simpleMessage("Suporte"),
-        "syncProgress": m61,
+        "syncProgress": m60,
         "syncStopped":
             MessageLookupByLibrary.simpleMessage("Sincronização interrompida"),
         "syncing": MessageLookupByLibrary.simpleMessage("Sincronizando..."),
@@ -1416,7 +1412,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "theseItemsWillBeDeletedFromYourDevice":
             MessageLookupByLibrary.simpleMessage(
                 "Estes itens serão excluídos do seu dispositivo."),
-        "theyAlsoGetXGb": m62,
+        "theyAlsoGetXGb": m61,
         "theyWillBeDeletedFromAllAlbums": MessageLookupByLibrary.simpleMessage(
             "Ele será excluído de todos os álbuns."),
         "thisActionCannotBeUndone": MessageLookupByLibrary.simpleMessage(
@@ -1432,7 +1428,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Este e-mail já está em uso"),
         "thisImageHasNoExifData": MessageLookupByLibrary.simpleMessage(
             "Esta imagem não tem dados exif"),
-        "thisIsPersonVerificationId": m63,
+        "thisIsPersonVerificationId": m62,
         "thisIsYourVerificationId": MessageLookupByLibrary.simpleMessage(
             "Este é o seu ID de verificação"),
         "thisWillLogYouOutOfTheFollowingDevice":
@@ -1448,7 +1444,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "total": MessageLookupByLibrary.simpleMessage("total"),
         "totalSize": MessageLookupByLibrary.simpleMessage("Tamanho total"),
         "trash": MessageLookupByLibrary.simpleMessage("Lixeira"),
-        "trashDaysLeft": m64,
+        "trashDaysLeft": m63,
         "tryAgain": MessageLookupByLibrary.simpleMessage("Tente novamente"),
         "turnOnBackupForAutoUpload": MessageLookupByLibrary.simpleMessage(
             "Ative o backup para enviar automaticamente arquivos adicionados a esta pasta do dispositivo para o ente."),
@@ -1501,7 +1497,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "useSelectedPhoto":
             MessageLookupByLibrary.simpleMessage("Utilizar foto selecionada"),
         "usedSpace": MessageLookupByLibrary.simpleMessage("Espaço em uso"),
-        "validTill": m65,
+        "validTill": m64,
         "verificationFailedPleaseTryAgain":
             MessageLookupByLibrary.simpleMessage(
                 "Falha na verificação, por favor, tente novamente"),
@@ -1509,7 +1505,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("ID de Verificação"),
         "verify": MessageLookupByLibrary.simpleMessage("Verificar"),
         "verifyEmail": MessageLookupByLibrary.simpleMessage("Verificar email"),
-        "verifyEmailID": m66,
+        "verifyEmailID": m65,
         "verifyIDLabel": MessageLookupByLibrary.simpleMessage("Verificar"),
         "verifyPasskey":
             MessageLookupByLibrary.simpleMessage("Verificar chave de acesso"),
@@ -1542,12 +1538,12 @@ class MessageLookup extends MessageLookupByLibrary {
         "weDontSupportEditingPhotosAndAlbumsThatYouDont":
             MessageLookupByLibrary.simpleMessage(
                 "Não suportamos a edição de fotos e álbuns que você ainda não possui"),
-        "weHaveSendEmailTo": m67,
+        "weHaveSendEmailTo": m66,
         "weakStrength": MessageLookupByLibrary.simpleMessage("Fraca"),
         "welcomeBack":
             MessageLookupByLibrary.simpleMessage("Bem-vindo de volta!"),
         "yearly": MessageLookupByLibrary.simpleMessage("Anual"),
-        "yearsAgo": m68,
+        "yearsAgo": m67,
         "yes": MessageLookupByLibrary.simpleMessage("Sim"),
         "yesCancel": MessageLookupByLibrary.simpleMessage("Sim, cancelar"),
         "yesConvertToViewer": MessageLookupByLibrary.simpleMessage(
@@ -1578,7 +1574,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Você não pode compartilhar consigo mesmo"),
         "youDontHaveAnyArchivedItems": MessageLookupByLibrary.simpleMessage(
             "Você não tem nenhum item arquivado."),
-        "youHaveSuccessfullyFreedUp": m69,
+        "youHaveSuccessfullyFreedUp": m68,
         "yourAccountHasBeenDeleted":
             MessageLookupByLibrary.simpleMessage("Sua conta foi excluída"),
         "yourMap": MessageLookupByLibrary.simpleMessage("Seu mapa"),

+ 62 - 65
mobile/lib/generated/intl/messages_zh.dart

@@ -122,79 +122,77 @@ class MessageLookup extends MessageLookupByLibrary {
 
   static String m37(providerName) => "如果您被收取费用,请用英语与 ${providerName} 的客服聊天";
 
-  static String m38(reason) => "很抱歉,您的支付因 ${reason} 而失败";
+  static String m38(endDate) => "免费试用有效期至 ${endDate}。\n之后您可以选择付费计划。";
 
-  static String m39(endDate) => "免费试用有效期至 ${endDate}。\n之后您可以选择付费计划。";
+  static String m39(toEmail) => "请给我们发送电子邮件至 ${toEmail}";
 
-  static String m40(toEmail) => "请给我们发送电子邮件至 ${toEmail}";
+  static String m40(toEmail) => "请将日志发送至 \n${toEmail}";
 
-  static String m41(toEmail) => "请将日志发送至 \n${toEmail}";
+  static String m41(storeName) => "在 ${storeName} 上给我们评分";
 
-  static String m42(storeName) => "在 ${storeName} 上给我们评分";
+  static String m42(storageInGB) => "3. 你和朋友都将免费获得 ${storageInGB} GB*";
 
-  static String m43(storageInGB) => "3. 你和朋友都将免费获得 ${storageInGB} GB*";
-
-  static String m44(userEmail) =>
+  static String m43(userEmail) =>
       "${userEmail} 将从这个共享相册中删除\n\nTA们添加的任何照片也将从相册中删除";
 
-  static String m45(endDate) => "在 ${endDate} 前续费";
+  static String m44(endDate) => "在 ${endDate} 前续费";
 
-  static String m46(count) =>
+  static String m45(count) =>
       "${Intl.plural(count, other: '已找到 ${count} 个结果')}";
 
-  static String m47(count) => "已选择 ${count} 个";
+  static String m46(count) => "已选择 ${count} 个";
 
-  static String m48(count, yourCount) => "选择了 ${count} 个 (您的 ${yourCount} 个)";
+  static String m47(count, yourCount) => "选择了 ${count} 个 (您的 ${yourCount} 个)";
 
-  static String m49(verificationID) => "这是我的ente.io 的验证 ID: ${verificationID}。";
+  static String m48(verificationID) => "这是我的ente.io 的验证 ID: ${verificationID}。";
 
-  static String m50(verificationID) =>
+  static String m49(verificationID) =>
       "嘿,你能确认这是你的 ente.io 验证 ID吗:${verificationID}";
 
-  static String m51(referralCode, referralStorageInGB) =>
+  static String m50(referralCode, referralStorageInGB) =>
       "ente推荐码: ${referralCode} \n\n注册付费计划后在设置 → 常规 → 推荐中应用它以免费获得 ${referralStorageInGB} GB空间\n\nhttps://ente.io";
 
-  static String m52(numberOfPeople) =>
+  static String m51(numberOfPeople) =>
       "${Intl.plural(numberOfPeople, zero: '与特定人员共享', one: '与 1 人共享', other: '与 ${numberOfPeople} 人共享')}";
 
-  static String m53(emailIDs) => "与 ${emailIDs} 共享";
+  static String m52(emailIDs) => "与 ${emailIDs} 共享";
 
-  static String m54(fileType) => "此 ${fileType} 将从您的设备中删除。";
+  static String m53(fileType) => "此 ${fileType} 将从您的设备中删除。";
 
-  static String m55(fileType) => "此 ${fileType} 同时在ente和您的设备中。";
+  static String m54(fileType) => "此 ${fileType} 同时在ente和您的设备中。";
 
-  static String m56(fileType) => "此 ${fileType} 将从ente中删除。";
+  static String m55(fileType) => "此 ${fileType} 将从ente中删除。";
 
-  static String m57(storageAmountInGB) => "${storageAmountInGB} GB";
+  static String m56(storageAmountInGB) => "${storageAmountInGB} GB";
 
-  static String m58(
+  static String m57(
           usedAmount, usedStorageUnit, totalAmount, totalStorageUnit) =>
       "已使用 ${usedAmount} ${usedStorageUnit} / ${totalAmount} ${totalStorageUnit}";
 
-  static String m59(id) =>
+  static String m58(id) =>
       "您的 ${id} 已经链接到另一个ente账户。\n如果您想要通过此账户使用您的 ${id} ,请联系我们的客服\'\'";
 
-  static String m60(endDate) => "您的订阅将于 ${endDate} 取消";
+  static String m59(endDate) => "您的订阅将于 ${endDate} 取消";
 
-  static String m61(completed, total) => "已保存的回忆 ${completed}/共 ${total}";
+  static String m60(completed, total) => "已保存的回忆 ${completed}/共 ${total}";
 
-  static String m62(storageAmountInGB) => "他们也会获得 ${storageAmountInGB} GB";
+  static String m61(storageAmountInGB) => "他们也会获得 ${storageAmountInGB} GB";
 
-  static String m63(email) => "这是 ${email} 的验证ID";
+  static String m62(email) => "这是 ${email} 的验证ID";
 
-  static String m64(count) =>
+  static String m63(count) =>
       "${Intl.plural(count, zero: '', one: '1天', other: '${count} 天')}";
 
-  static String m65(endDate) => "有效期至 ${endDate}";
+  static String m64(endDate) => "有效期至 ${endDate}";
 
-  static String m66(email) => "验证 ${email}";
+  static String m65(email) => "验证 ${email}";
 
-  static String m67(email) => "我们已经发送邮件到 <green>${email}</green>";
+  static String m66(email) => "我们已经发送邮件到 <green>${email}</green>";
 
-  static String m68(count) =>
+  static String m67(count) =>
       "${Intl.plural(count, one: '${count} 年前', other: '${count} 年前')}";
 
-  static String m69(storageSaved) => "您已成功释放了 ${storageSaved}!";
+  static String m68(storageSaved) => "您已成功释放了 ${storageSaved}!";
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -838,7 +836,6 @@ class MessageLookup extends MessageLookupByLibrary {
         "paymentDetails": MessageLookupByLibrary.simpleMessage("付款明细"),
         "paymentFailed": MessageLookupByLibrary.simpleMessage("支付失败"),
         "paymentFailedTalkToProvider": m37,
-        "paymentFailedWithReason": m38,
         "pendingItems": MessageLookupByLibrary.simpleMessage("待处理项目"),
         "pendingSync": MessageLookupByLibrary.simpleMessage("正在等待同步"),
         "peopleUsingYourCode": MessageLookupByLibrary.simpleMessage("使用您的代码的人"),
@@ -856,7 +853,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "pickCenterPoint": MessageLookupByLibrary.simpleMessage("选择中心点"),
         "pinAlbum": MessageLookupByLibrary.simpleMessage("置顶相册"),
         "playOnTv": MessageLookupByLibrary.simpleMessage("在电视上播放相册"),
-        "playStoreFreeTrialValidTill": m39,
+        "playStoreFreeTrialValidTill": m38,
         "playstoreSubscription":
             MessageLookupByLibrary.simpleMessage("PlayStore 订阅"),
         "pleaseCheckYourInternetConnectionAndTryAgain":
@@ -866,10 +863,10 @@ class MessageLookup extends MessageLookupByLibrary {
                 "请用英语联系 support@ente.io ,我们将乐意提供帮助!"),
         "pleaseContactSupportIfTheProblemPersists":
             MessageLookupByLibrary.simpleMessage("如果问题仍然存在,请联系支持"),
-        "pleaseEmailUsAt": m40,
+        "pleaseEmailUsAt": m39,
         "pleaseGrantPermissions": MessageLookupByLibrary.simpleMessage("请授予权限"),
         "pleaseLoginAgain": MessageLookupByLibrary.simpleMessage("请重新登录"),
-        "pleaseSendTheLogsTo": m41,
+        "pleaseSendTheLogsTo": m40,
         "pleaseTryAgain": MessageLookupByLibrary.simpleMessage("请重试"),
         "pleaseVerifyTheCodeYouHaveEntered":
             MessageLookupByLibrary.simpleMessage("请验证您输入的代码"),
@@ -895,7 +892,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "raiseTicket": MessageLookupByLibrary.simpleMessage("提升工单"),
         "rateTheApp": MessageLookupByLibrary.simpleMessage("为此应用评分"),
         "rateUs": MessageLookupByLibrary.simpleMessage("给我们评分"),
-        "rateUsOnStore": m42,
+        "rateUsOnStore": m41,
         "recover": MessageLookupByLibrary.simpleMessage("恢复"),
         "recoverAccount": MessageLookupByLibrary.simpleMessage("恢复账户"),
         "recoverButton": MessageLookupByLibrary.simpleMessage("恢复"),
@@ -920,7 +917,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("把我们推荐给你的朋友然后获得延长一倍的订阅计划"),
         "referralStep1": MessageLookupByLibrary.simpleMessage("1. 将此代码提供给您的朋友"),
         "referralStep2": MessageLookupByLibrary.simpleMessage("2. 他们注册一个付费计划"),
-        "referralStep3": m43,
+        "referralStep3": m42,
         "referrals": MessageLookupByLibrary.simpleMessage("推荐人"),
         "referralsAreCurrentlyPaused":
             MessageLookupByLibrary.simpleMessage("推荐已暂停"),
@@ -939,7 +936,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "removeFromFavorite": MessageLookupByLibrary.simpleMessage("从收藏中移除"),
         "removeLink": MessageLookupByLibrary.simpleMessage("移除链接"),
         "removeParticipant": MessageLookupByLibrary.simpleMessage("移除参与者"),
-        "removeParticipantBody": m44,
+        "removeParticipantBody": m43,
         "removePublicLink": MessageLookupByLibrary.simpleMessage("删除公开链接"),
         "removeShareItemsWarning":
             MessageLookupByLibrary.simpleMessage("您要删除的某些项目是由其他人添加的,您将无法访问它们"),
@@ -950,7 +947,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "renameAlbum": MessageLookupByLibrary.simpleMessage("重命名相册"),
         "renameFile": MessageLookupByLibrary.simpleMessage("重命名文件"),
         "renewSubscription": MessageLookupByLibrary.simpleMessage("续费订阅"),
-        "renewsOn": m45,
+        "renewsOn": m44,
         "reportABug": MessageLookupByLibrary.simpleMessage("报告错误"),
         "reportBug": MessageLookupByLibrary.simpleMessage("报告错误"),
         "resendEmail": MessageLookupByLibrary.simpleMessage("重新发送电子邮件"),
@@ -997,7 +994,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("在照片的一定半径内拍摄的几组照片"),
         "searchPeopleEmptySection":
             MessageLookupByLibrary.simpleMessage("邀请他人,您将在此看到他们分享的所有照片"),
-        "searchResultCount": m46,
+        "searchResultCount": m45,
         "security": MessageLookupByLibrary.simpleMessage("安全"),
         "selectALocation": MessageLookupByLibrary.simpleMessage("选择一个位置"),
         "selectALocationFirst":
@@ -1017,8 +1014,8 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("所选文件夹将被加密和备份"),
         "selectedItemsWillBeDeletedFromAllAlbumsAndMoved":
             MessageLookupByLibrary.simpleMessage("所选项目将从所有相册中删除并移动到回收站。"),
-        "selectedPhotos": m47,
-        "selectedPhotosWithYours": m48,
+        "selectedPhotos": m46,
+        "selectedPhotosWithYours": m47,
         "send": MessageLookupByLibrary.simpleMessage("发送"),
         "sendEmail": MessageLookupByLibrary.simpleMessage("发送电子邮件"),
         "sendInvite": MessageLookupByLibrary.simpleMessage("发送邀请"),
@@ -1037,16 +1034,16 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("打开相册并点击右上角的分享按钮进行分享"),
         "shareAnAlbumNow": MessageLookupByLibrary.simpleMessage("立即分享相册"),
         "shareLink": MessageLookupByLibrary.simpleMessage("分享链接"),
-        "shareMyVerificationID": m49,
+        "shareMyVerificationID": m48,
         "shareOnlyWithThePeopleYouWant":
             MessageLookupByLibrary.simpleMessage("仅与您想要的人分享"),
-        "shareTextConfirmOthersVerificationID": m50,
+        "shareTextConfirmOthersVerificationID": m49,
         "shareTextRecommendUsingEnte": MessageLookupByLibrary.simpleMessage(
             "下载 ente,以便我们轻松分享原始质量的照片和视频\n\nhttps://ente.io"),
-        "shareTextReferralCode": m51,
+        "shareTextReferralCode": m50,
         "shareWithNonenteUsers":
             MessageLookupByLibrary.simpleMessage("与非ente 用户分享"),
-        "shareWithPeopleSectionTitle": m52,
+        "shareWithPeopleSectionTitle": m51,
         "shareYourFirstAlbum":
             MessageLookupByLibrary.simpleMessage("分享您的第一个相册"),
         "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage(
@@ -1057,7 +1054,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("新共享的照片"),
         "sharedPhotoNotificationsExplanation":
             MessageLookupByLibrary.simpleMessage("当有人将照片添加到您所属的共享相册时收到通知"),
-        "sharedWith": m53,
+        "sharedWith": m52,
         "sharedWithMe": MessageLookupByLibrary.simpleMessage("与我共享"),
         "sharedWithYou": MessageLookupByLibrary.simpleMessage("已与您共享"),
         "sharing": MessageLookupByLibrary.simpleMessage("正在分享..."),
@@ -1069,11 +1066,11 @@ class MessageLookup extends MessageLookupByLibrary {
         "signOutOtherDevices": MessageLookupByLibrary.simpleMessage("登出其他设备"),
         "signUpTerms": MessageLookupByLibrary.simpleMessage(
             "我同意 <u-terms>服务条款</u-terms> 和 <u-policy>隐私政策</u-policy>"),
-        "singleFileDeleteFromDevice": m54,
+        "singleFileDeleteFromDevice": m53,
         "singleFileDeleteHighlight":
             MessageLookupByLibrary.simpleMessage("它将从所有相册中删除。"),
-        "singleFileInBothLocalAndRemote": m55,
-        "singleFileInRemoteOnly": m56,
+        "singleFileInBothLocalAndRemote": m54,
+        "singleFileInRemoteOnly": m55,
         "skip": MessageLookupByLibrary.simpleMessage("跳过"),
         "social": MessageLookupByLibrary.simpleMessage("社交"),
         "someItemsAreInBothEnteAndYourDevice":
@@ -1104,12 +1101,12 @@ class MessageLookup extends MessageLookupByLibrary {
         "storage": MessageLookupByLibrary.simpleMessage("存储空间"),
         "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("家庭"),
         "storageBreakupYou": MessageLookupByLibrary.simpleMessage("您"),
-        "storageInGB": m57,
+        "storageInGB": m56,
         "storageLimitExceeded": MessageLookupByLibrary.simpleMessage("已超出存储限制"),
-        "storageUsageInfo": m58,
+        "storageUsageInfo": m57,
         "strongStrength": MessageLookupByLibrary.simpleMessage("强"),
-        "subAlreadyLinkedErrMessage": m59,
-        "subWillBeCancelledOn": m60,
+        "subAlreadyLinkedErrMessage": m58,
+        "subWillBeCancelledOn": m59,
         "subscribe": MessageLookupByLibrary.simpleMessage("订阅"),
         "subscribeToEnableSharing":
             MessageLookupByLibrary.simpleMessage("您的订阅似乎已过期。请订阅以启用分享。"),
@@ -1122,7 +1119,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "successfullyUnhid": MessageLookupByLibrary.simpleMessage("已成功取消隐藏"),
         "suggestFeatures": MessageLookupByLibrary.simpleMessage("建议新功能"),
         "support": MessageLookupByLibrary.simpleMessage("支持"),
-        "syncProgress": m61,
+        "syncProgress": m60,
         "syncStopped": MessageLookupByLibrary.simpleMessage("同步已停止"),
         "syncing": MessageLookupByLibrary.simpleMessage("正在同步···"),
         "systemTheme": MessageLookupByLibrary.simpleMessage("适应系统"),
@@ -1145,7 +1142,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "theme": MessageLookupByLibrary.simpleMessage("主题"),
         "theseItemsWillBeDeletedFromYourDevice":
             MessageLookupByLibrary.simpleMessage("这些项目将从您的设备中删除。"),
-        "theyAlsoGetXGb": m62,
+        "theyAlsoGetXGb": m61,
         "theyWillBeDeletedFromAllAlbums":
             MessageLookupByLibrary.simpleMessage("他们将从所有相册中删除。"),
         "thisActionCannotBeUndone":
@@ -1159,7 +1156,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("这个邮箱地址已经被使用"),
         "thisImageHasNoExifData":
             MessageLookupByLibrary.simpleMessage("此图像没有Exif 数据"),
-        "thisIsPersonVerificationId": m63,
+        "thisIsPersonVerificationId": m62,
         "thisIsYourVerificationId":
             MessageLookupByLibrary.simpleMessage("这是您的验证 ID"),
         "thisWillLogYouOutOfTheFollowingDevice":
@@ -1173,7 +1170,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "total": MessageLookupByLibrary.simpleMessage("总计"),
         "totalSize": MessageLookupByLibrary.simpleMessage("总大小"),
         "trash": MessageLookupByLibrary.simpleMessage("回收站"),
-        "trashDaysLeft": m64,
+        "trashDaysLeft": m63,
         "tryAgain": MessageLookupByLibrary.simpleMessage("请再试一次"),
         "turnOnBackupForAutoUpload":
             MessageLookupByLibrary.simpleMessage("打开备份以自动上传添加到此设备文件夹的文件。"),
@@ -1216,13 +1213,13 @@ class MessageLookup extends MessageLookupByLibrary {
         "useRecoveryKey": MessageLookupByLibrary.simpleMessage("使用恢复密钥"),
         "useSelectedPhoto": MessageLookupByLibrary.simpleMessage("使用所选照片"),
         "usedSpace": MessageLookupByLibrary.simpleMessage("已用空间"),
-        "validTill": m65,
+        "validTill": m64,
         "verificationFailedPleaseTryAgain":
             MessageLookupByLibrary.simpleMessage("验证失败,请重试"),
         "verificationId": MessageLookupByLibrary.simpleMessage("验证 ID"),
         "verify": MessageLookupByLibrary.simpleMessage("验证"),
         "verifyEmail": MessageLookupByLibrary.simpleMessage("验证电子邮件"),
-        "verifyEmailID": m66,
+        "verifyEmailID": m65,
         "verifyIDLabel": MessageLookupByLibrary.simpleMessage("验证"),
         "verifyPasskey": MessageLookupByLibrary.simpleMessage("验证通行密钥"),
         "verifyPassword": MessageLookupByLibrary.simpleMessage("验证密码"),
@@ -1246,11 +1243,11 @@ class MessageLookup extends MessageLookupByLibrary {
         "weAreOpenSource": MessageLookupByLibrary.simpleMessage("我们是开源的 !"),
         "weDontSupportEditingPhotosAndAlbumsThatYouDont":
             MessageLookupByLibrary.simpleMessage("我们不支持编辑您尚未拥有的照片和相册"),
-        "weHaveSendEmailTo": m67,
+        "weHaveSendEmailTo": m66,
         "weakStrength": MessageLookupByLibrary.simpleMessage("弱"),
         "welcomeBack": MessageLookupByLibrary.simpleMessage("欢迎回来!"),
         "yearly": MessageLookupByLibrary.simpleMessage("每年"),
-        "yearsAgo": m68,
+        "yearsAgo": m67,
         "yes": MessageLookupByLibrary.simpleMessage("是"),
         "yesCancel": MessageLookupByLibrary.simpleMessage("是的,取消"),
         "yesConvertToViewer": MessageLookupByLibrary.simpleMessage("是的,转换为查看者"),
@@ -1276,7 +1273,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("莫开玩笑,您不能与自己分享"),
         "youDontHaveAnyArchivedItems":
             MessageLookupByLibrary.simpleMessage("您没有任何存档的项目。"),
-        "youHaveSuccessfullyFreedUp": m69,
+        "youHaveSuccessfullyFreedUp": m68,
         "yourAccountHasBeenDeleted":
             MessageLookupByLibrary.simpleMessage("您的账户已删除"),
         "yourMap": MessageLookupByLibrary.simpleMessage("您的地图"),

+ 5 - 5
mobile/lib/generated/l10n.dart

@@ -4465,13 +4465,13 @@ class S {
     );
   }
 
-  /// `Unfortunately your payment failed due to {reason}`
-  String paymentFailedWithReason(Object reason) {
+  /// `Unfortunately your payment failed. Please contact support and we'll help you out!`
+  String get paymentFailedMessage {
     return Intl.message(
-      'Unfortunately your payment failed due to $reason',
-      name: 'paymentFailedWithReason',
+      'Unfortunately your payment failed. Please contact support and we\'ll help you out!',
+      name: 'paymentFailedMessage',
       desc: '',
-      args: [reason],
+      args: [],
     );
   }
 

+ 1 - 1
mobile/lib/l10n/intl_en.arb

@@ -640,7 +640,7 @@
   "thankYou": "Thank you",
   "failedToVerifyPaymentStatus": "Failed to verify payment status",
   "pleaseWaitForSometimeBeforeRetrying": "Please wait for sometime before retrying",
-  "paymentFailedWithReason": "Unfortunately your payment failed due to {reason}",
+  "paymentFailedMessage": "Unfortunately your payment failed. Please contact support and we'll help you out!",
   "youAreOnAFamilyPlan": "You are on a family plan!",
   "contactFamilyAdmin": "Please contact <green>{familyAdminEmail}</green> to manage your subscription",
   "leaveFamily": "Leave family",

+ 7 - 7
mobile/lib/l10n/intl_pt.arb

@@ -338,11 +338,11 @@
   "disableLinkMessage": "Isso removerá o link público para acessar \"{albumName}\".",
   "sharing": "Compartilhando...",
   "youCannotShareWithYourself": "Você não pode compartilhar consigo mesmo",
-  "archive": "Arquivo",
+  "archive": "Arquivado",
   "createAlbumActionHint": "Pressione e segure para selecionar fotos e clique em + para criar um álbum",
   "importing": "Importando....",
   "failedToLoadAlbums": "Falha ao carregar álbuns",
-  "hidden": "Escondido",
+  "hidden": "Oculto",
   "authToViewYourHiddenFiles": "Autentique-se para visualizar seus arquivos ocultos",
   "trash": "Lixeira",
   "uncategorized": "Sem categoria",
@@ -545,7 +545,7 @@
   "yourStorageDetailsCouldNotBeFetched": "Seus detalhes de armazenamento não puderam ser obtidos",
   "reportABug": "Reportar um problema",
   "reportBug": "Reportar um problema",
-  "suggestFeatures": "Sugerir funcionalidades",
+  "suggestFeatures": "Sugerir recurso",
   "support": "Suporte",
   "theme": "Tema",
   "lightTheme": "Claro",
@@ -839,7 +839,7 @@
   "pressAndHoldToPlayVideo": "Pressione e segure para reproduzir o vídeo",
   "pressAndHoldToPlayVideoDetailed": "Pressione e segure na imagem para reproduzir o vídeo",
   "downloadFailed": "Falha ao baixar",
-  "deduplicateFiles": "Arquivos Deduplicados",
+  "deduplicateFiles": "Arquivos duplicados",
   "deselectAll": "Desmarcar todos",
   "reviewDeduplicateItems": "Por favor, reveja e exclua os itens que você acredita serem duplicados.",
   "clubByCaptureTime": "Agrupar por tempo de captura",
@@ -1200,7 +1200,7 @@
   "joinDiscord": "Junte-se ao Discord",
   "locations": "Locais",
   "descriptions": "Descrições",
-  "addViewers": "{count, plural, zero {Add viewer} one {Add viewer} other {Add viewers}}",
-  "addCollaborators": "{count, plural, zero {Add collaborator} one {Add collaborator} other {Add collaborators}}",
-  "longPressAnEmailToVerifyEndToEndEncryption": "Long press an email to verify end to end encryption."
+  "addViewers": "{count, plural, zero {Adicionar visualizador} one {Adicionar visualizador} other {Adicionar Visualizadores}}",
+  "addCollaborators": "{count, plural, zero {Adicionar colaborador} one {Adicionar coloborador} other {Adicionar colaboradores}}",
+  "longPressAnEmailToVerifyEndToEndEncryption": "Pressione e segure um e-mail para verificar a criptografia de ponta a ponta."
 }

+ 3 - 3
mobile/lib/l10n/intl_zh.arb

@@ -1200,7 +1200,7 @@
   "joinDiscord": "加入 Discord",
   "locations": "位置",
   "descriptions": "描述",
-  "addViewers": "{count, plural, zero {Add viewer} one {Add viewer} other {Add viewers}}",
-  "addCollaborators": "{count, plural, zero {Add collaborator} one {Add collaborator} other {Add collaborators}}",
-  "longPressAnEmailToVerifyEndToEndEncryption": "Long press an email to verify end to end encryption."
+  "addViewers": "{count, plural, zero {添加查看者} one {添加查看者} other {添加查看者}}",
+  "addCollaborators": "{count, plural, zero {添加协作者} one {添加协作者} other {添加协作者}}",
+  "longPressAnEmailToVerifyEndToEndEncryption": "长按电子邮件以验证端到端加密。"
 }

+ 13 - 0
mobile/lib/models/subscription.dart

@@ -30,6 +30,19 @@ class Subscription {
     return expiryTime > DateTime.now().microsecondsSinceEpoch;
   }
 
+  bool isCancelled() {
+    return attributes?.isCancelled ?? false;
+  }
+
+  bool isPastDue() {
+    return !isCancelled() &&
+        expiryTime < DateTime.now().microsecondsSinceEpoch &&
+        expiryTime >=
+            DateTime.now()
+                .subtract(const Duration(days: 30))
+                .microsecondsSinceEpoch;
+  }
+
   bool isYearlyPlan() {
     return 'year' == period;
   }

+ 14 - 25
mobile/lib/ui/payment/payment_web_page.dart

@@ -5,14 +5,15 @@ import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_inappwebview/flutter_inappwebview.dart';
 import 'package:logging/logging.dart';
+import "package:photos/core/constants.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';
 import 'package:photos/ui/common/loading_widget.dart';
-import 'package:photos/ui/common/progress_dialog.dart';
 import 'package:photos/utils/dialog_util.dart';
+import "package:photos/utils/email_util.dart";
 
 class PaymentWebPage extends StatefulWidget {
   final String? planId;
@@ -30,7 +31,6 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
   final UserService userService = UserService.instance;
   final BillingService billingService = BillingService.instance;
   final String basePaymentUrl = kWebPaymentBaseEndpoint;
-  late ProgressDialog _dialog;
   InAppWebViewController? webView;
   double progress = 0;
   Uri? initPaymentUrl;
@@ -49,11 +49,6 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
 
   @override
   Widget build(BuildContext context) {
-    _dialog = createProgressDialog(
-      context,
-      S.of(context).pleaseWait,
-      isDismissible: true,
-    );
     if (initPaymentUrl == null) {
       return const EnteLoadingWidget();
     }
@@ -93,27 +88,20 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
                   return NavigationActionPolicy.ALLOW;
                 },
                 onConsoleMessage: (controller, consoleMessage) {
-                  _logger.info(consoleMessage);
+                  _logger.info("onConsoleMessage $consoleMessage");
                 },
                 onLoadStart: (controller, navigationAction) async {
-                  if (!_dialog.isShowing()) {
-                    await _dialog.show();
-                  }
+                  _logger.info("onLoadStart $navigationAction");
                 },
                 onLoadError: (controller, navigationAction, code, msg) async {
-                  if (_dialog.isShowing()) {
-                    await _dialog.hide();
-                  }
+                  _logger.severe("onLoadError $navigationAction $code $msg");
                 },
                 onLoadHttpError:
                     (controller, navigationAction, code, msg) async {
                   _logger.info("onHttpError with $code and msg = $msg");
                 },
                 onLoadStop: (controller, navigationAction) async {
-                  _logger.info("loadStart" + navigationAction.toString());
-                  if (_dialog.isShowing()) {
-                    await _dialog.hide();
-                  }
+                  _logger.info("onLoadStop $navigationAction");
                 },
               ),
             ),
@@ -125,7 +113,6 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
 
   @override
   void dispose() {
-    _dialog.hide();
     super.dispose();
   }
 
@@ -207,12 +194,17 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
       barrierDismissible: false,
       builder: (context) => AlertDialog(
         title: Text(S.of(context).paymentFailed),
-        content: Text(S.of(context).paymentFailedWithReason(reason)),
+        content: Text(S.of(context).paymentFailedMessage),
         actions: <Widget>[
           TextButton(
-            child: Text(S.of(context).ok),
-            onPressed: () {
+            child: Text(S.of(context).contactSupport),
+            onPressed: () async {
               Navigator.of(context).pop('dialog');
+              await sendEmail(
+                context,
+                to: supportEmail,
+                subject: "Billing issue",
+              );
             },
           ),
         ],
@@ -224,7 +216,6 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
   // return true if verifySubscription didn't throw any exceptions
   Future<void> _handlePaymentSuccess(Map<String, String> queryParams) async {
     final checkoutSessionID = queryParams['session_id'] ?? '';
-    await _dialog.show();
     try {
       // ignore: unused_local_variable
       final response = await billingService.verifySubscription(
@@ -232,7 +223,6 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
         checkoutSessionID,
         paymentProvider: stripe,
       );
-      await _dialog.hide();
       final content = widget.actionType == 'buy'
           ? S.of(context).yourPurchaseWasSuccessful
           : S.of(context).yourSubscriptionWasUpdatedSuccessfully;
@@ -242,7 +232,6 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
       );
     } catch (error) {
       _logger.severe(error);
-      await _dialog.hide();
       await _showExitPageDialog(
         title: S.of(context).failedToVerifyPaymentStatus,
         content: S.of(context).pleaseWaitForSometimeBeforeRetrying,

+ 8 - 3
mobile/lib/ui/payment/stripe_subscription_page.dart

@@ -81,6 +81,11 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
               userDetails.hasPaidAddon();
       _hasActiveSubscription = _currentSubscription!.isValid();
       _isStripeSubscriber = _currentSubscription!.paymentProvider == stripe;
+
+      if (_isStripeSubscriber && _currentSubscription!.isPastDue()) {
+        _redirectToPaymentPortal();
+      }
+
       return _filterStripeForUI().then((value) {
         _hasLoadedData = true;
         setState(() {});
@@ -254,7 +259,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
             singleBorderRadius: 4,
             alignCaptionedTextToLeft: true,
             onTap: () async {
-              _onStripSupportedPaymentDetailsTap();
+              _redirectToPaymentPortal();
             },
           ),
         ),
@@ -295,9 +300,9 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
     );
   }
 
-  // _onStripSupportedPaymentDetailsTap action allows the user to update
+  // _redirectToPaymentPortal action allows the user to update
   // their stripe payment details
-  void _onStripSupportedPaymentDetailsTap() async {
+  void _redirectToPaymentPortal() async {
     final String paymentProvider = _currentSubscription!.paymentProvider;
     switch (_currentSubscription!.paymentProvider) {
       case stripe:

+ 12 - 5
server/README.md

@@ -38,7 +38,13 @@ And ping again
 This time you'll see the updated message.
 
 For more details about how to get museum up and running, see
-[RUNNING.md](RUNNING.md).
+[RUNNING](RUNNING.md).
+
+> [!TIP]
+>
+> Also, there is a way to use our pre-built Docker images to directly start a
+> cluster without needing to clone this repository - see
+> [docs/docker](docs/docker.md).
 
 ## Architecture
 
@@ -84,10 +90,11 @@ And it is built with containerization in mind - both during development and
 deployment. Just use the provided Dockerfile, configure to taste and you're off
 to the races.
 
-> [!CAUTION]
->
-> We don't publish any official docker images (yet). For self-hosters, the
-> recommendation is to build your own image using the provided `Dockerfile`.
+Overall, there are [three approaches](RUNNING.md) you can take:
+
+* Run using Docker using a pre-built Docker image
+* Run using Docker but build an image from source
+* Run without Docker
 
 Everything that you might needed to run museum is all in here, since this is the
 setup we ourselves use in production.

+ 8 - 7
server/RUNNING.md

@@ -8,13 +8,14 @@ environment that doesn't clutter your machine.
 You can also run museum directly on your machine if you wish - it is a single
 static go binary.
 
-This document describes both these approaches, and also outlines configuration.
+This document describes these approaches, and also outlines configuration.
 
-- [Running using Docker](#docker)
-- [Running without Docker](#without-docker)
+- [Run using Docker using a pre-built Docker image](docs/docker.md)
+- [Run using Docker but build an image from source](#build-and-run-using-docker)
+- [Running without Docker](#run-without-docker)
 - [Configuration](#configuration)
 
-## Docker
+## Build and run using Docker
 
 Start the cluster
 
@@ -70,7 +71,7 @@ Each time museum gets rebuilt from source, a new image gets created but the old
 one is retained as a dangling image. You can use `docker image prune --force`,
 or `docker system prune` if that's fine with you, to remove these.
 
-## Without Docker
+## Running without Docker
 
 The museum binary can be run by using `go run cmd/museum/main.go`. But first,
 you'll need to prepare your machine for development. Here we give the steps,
@@ -132,7 +133,7 @@ pg_ctl -D /usr/local/var/postgres -l logfile start
 createuser -s postgres
 ```
 
-## Start museum
+### Start museum
 
 ```sh
 export ENTE_DB_USER=postgres
@@ -148,7 +149,7 @@ ENTE_DB_USER=ente_user
 air
 ```
 
-## Testing
+### Testing
 
 Set up a local database for testing. This is not required for running the server.
 Create a test database with the following name and credentials:

+ 83 - 0
server/docs/docker.md

@@ -0,0 +1,83 @@
+# Running using published Docker images
+
+Here we describe a way to run an Ente instance using a starter Docker compose
+file and using the pre-built Docker images that we publish. This method does not
+require you to clone the repository or build any images.
+
+1. Create a directory where you'll run Ente
+
+    ```sh
+    mkdir ente && cd ente
+    ```
+
+2. Copy the starter compose.yaml and two of its support files from the
+   repository onto your directory. You can do it by hand, or use (e.g.) curl
+
+    ```sh
+    # compose.yaml
+    curl -LO https://raw.githubusercontent.com/ente-io/ente/main/server/compose.yaml
+
+    mkdir -p scripts/compose
+    cd scripts/compose
+
+    # scripts/compose/credentials.yaml
+    curl -LO https://raw.githubusercontent.com/ente-io/ente/main/server/scripts/compose/credentials.yaml
+
+    # scripts/compose/minio-provision.sh
+    curl -LO https://raw.githubusercontent.com/ente-io/ente/main/server/scripts/compose/minio-provision.sh
+
+    cd ../..
+    ```
+
+3. Modify `compose.yaml`. Instead of building from source, we want directly use
+   the published Docker image from `ghcr.io/ente-io/server`
+
+    ```diff
+    --- a/server/compose.yaml
+    +++ b/server/compose.yaml
+    @@ -1,9 +1,6 @@
+     services:
+       museum:
+    -    build:
+    -      context: .
+    -      args:
+    -        GIT_COMMIT: development-cluster
+    +    image: ghcr.io/ente-io/server
+    ```
+
+4. Create an (empty) configuration file. Yyou can later put your custom
+   configuration in this if needed.
+
+   ```sh
+   touch museum.yaml
+   ```
+
+5. That is all. You can now start everything.
+
+   ```sh
+   docker compose up
+   ```
+
+This will start a cluster containing:
+
+* Ente's own server
+* PostgresQL (DB)
+* MinIO (the S3 layer)
+
+For each of these, it'll use the latest published Docker image.
+
+You can do a quick smoke test by pinging the API:
+
+```sh
+curl localhost:8080/ping
+```
+
+## Only the server
+
+Alternatively, if you have setup the database and object storage externally and
+only want to run Ente's server, you can skip the steps above and directly pull
+and run the image from **`ghcr.io/ente-io/server`**.
+
+```sh
+docker pull ghcr.io/ente-io/server
+```

+ 41 - 0
server/docs/publish.md

@@ -0,0 +1,41 @@
+# Publishing images
+
+There are two different images we publish - internal and external.
+
+## Internal
+
+The internal images can be built and run by triggering the "Server (release)"
+workflow. You can trigger it either from GitHub's UI on the Actions tab, or use
+the following command:
+
+    gh workflow run server-release.yml
+
+This will take the latest main, package it into a Docker image, and publish it
+to our Scaleway registry. From there, we can update our production instances to
+use this new image (see [deploy/README](../scripts/deploy/README.md)).
+
+## External
+
+Periodically, we can republish a new image from an existing known-to-be-good
+commit to the GitHub Container Registry (GHCR) so that it can be used by folks
+without needing to clone our repository just for building an image. For more
+details about the use case, see [docker.md](docker.md).
+
+To publish such an external image, firstly find the commit of the currently
+running production instance.
+
+    curl -s https://api.ente.io/ping | jq -r '.id'
+
+> We can publish from any arbitrary commit really, but by using the commit
+> that's already seen production for a few days, we avoid externally publishing
+> images with issues.
+
+Then, trigger the "Publish (server)" workflow, providing it the commit. You can
+trigger it either from GitHub's UI or using the `gh cli`. With the CLI, we can
+combine both these steps too.
+
+    gh workflow run server-publish.yml -F commit=`curl -s https://api.ente.io/ping | jq -r '.id'`
+
+Once the workflow completes, the resultant image will be available at
+`ghcr.io/ente-io/server`. The image will be tagged by the commit SHA. The latest
+image will also be tagged, well, "latest".

+ 1 - 1
server/ente/billing.go

@@ -42,7 +42,7 @@ const (
 	OnHoldTemplate = "on_hold.html"
 
 	// AccountOnHoldEmailSubject is the subject of account on hold email
-	AccountOnHoldEmailSubject = "ente account on hold"
+	AccountOnHoldEmailSubject = "Ente account on hold"
 
 	// Template for the email we send out when the user's subscription ends,
 	// either because the user cancelled their subscription, or because it

+ 3 - 3
server/mail-templates/on_hold.html

@@ -215,11 +215,11 @@
                                                                                                     has informed us that
                                                                                                     they were
                                                                                                     unable to renew your
-                                                                                                    ente subscription.
+                                                                                                    subscription.
                                                                                                     Please update your
                                                                                                     payment method
                                                                                                     within
-                                                                                                    {{.PaymentProvider}}
+                                                                                                    the app
                                                                                                     so that your
                                                                                                     subscription can be
                                                                                                     renewed.</div>
@@ -234,7 +234,7 @@
                                                                                                     from
                                                                                                     {{.PaymentProvider}}
                                                                                                     within the next
-                                                                                                    30 days, our systems
+                                                                                                    31 days, our systems
                                                                                                     may remove your
                                                                                                     account and all
                                                                                                     associated data with

+ 171 - 142
server/pkg/controller/stripe.go

@@ -1,14 +1,15 @@
 package controller
 
 import (
-	"context"
 	"database/sql"
 	"encoding/json"
 	"errors"
 	"fmt"
-	"github.com/ente-io/museum/pkg/controller/commonbilling"
 	"net/http"
 	"strconv"
+	"time"
+
+	"github.com/ente-io/museum/pkg/controller/commonbilling"
 
 	"github.com/ente-io/museum/pkg/controller/discord"
 	"github.com/ente-io/museum/pkg/controller/offer"
@@ -24,7 +25,6 @@ import (
 	"github.com/spf13/viper"
 	"github.com/stripe/stripe-go/v72"
 	"github.com/stripe/stripe-go/v72/client"
-	"github.com/stripe/stripe-go/v72/invoice"
 	"github.com/stripe/stripe-go/v72/webhook"
 	"golang.org/x/text/currency"
 )
@@ -43,12 +43,7 @@ type StripeController struct {
 	CommonBillCtrl         *commonbilling.Controller
 }
 
-// A flag we set on Stripe subscriptions to indicate that we should skip on
-// sending out the email when the subscription has been cancelled.
-//
-// This is needed e.g. if this cancellation was as part of a user initiated
-// account deletion.
-const SkipMailKey = "skip_mail"
+const BufferPeriodOnPaymentFailureInDays = 7
 
 // Return a new instance of StripeController
 func NewStripeController(plans ente.BillingPlansPerAccount, stripeClients ente.StripeClientPerAccount, billingRepo *repo.BillingRepository, fileRepo *repo.FileRepository, userRepo *repo.UserRepository, storageBonusRepo *storagebonus.Repository, discordController *discord.DiscordController, emailNotificationController *emailCtrl.EmailNotificationController, offerController *offer.OfferController, commonBillCtrl *commonbilling.Controller) *StripeController {
@@ -85,12 +80,15 @@ func (c *StripeController) GetCheckoutSession(productID string, userID int64, re
 			return "", stacktrace.Propagate(ente.ErrBadRequest, "")
 		}
 	}
-	if subscription.PaymentProvider == ente.Stripe && !subscription.Attributes.IsCancelled {
-		// user had bought a stripe subscription earlier,
-		err := c.cancelExistingStripeSubscription(subscription, userID)
+	if hasStripeSubscription {
+		client := c.StripeClients[subscription.Attributes.StripeAccountCountry]
+		stripeSubscription, err := client.Subscriptions.Get(subscription.OriginalTransactionID, nil)
 		if err != nil {
 			return "", stacktrace.Propagate(err, "")
 		}
+		if stripeSubscription.Status != stripe.SubscriptionStatusCanceled {
+			return "", stacktrace.Propagate(ente.ErrBadRequest, "")
+		}
 	}
 	stripeSuccessURL := redirectRootURL + viper.GetString("stripe.path.success")
 	stripeCancelURL := redirectRootURL + viper.GetString("stripe.path.cancel")
@@ -160,7 +158,7 @@ func (c *StripeController) HandleUSNotification(payload []byte, header string) e
 	if err != nil {
 		return stacktrace.Propagate(err, "")
 	}
-	return c.handleWebhookEvent(event)
+	return c.handleWebhookEvent(event, ente.StripeUS)
 }
 
 func (c *StripeController) HandleINNotification(payload []byte, header string) error {
@@ -168,10 +166,10 @@ func (c *StripeController) HandleINNotification(payload []byte, header string) e
 	if err != nil {
 		return stacktrace.Propagate(err, "")
 	}
-	return c.handleWebhookEvent(event)
+	return c.handleWebhookEvent(event, ente.StripeIN)
 }
 
-func (c *StripeController) handleWebhookEvent(event stripe.Event) error {
+func (c *StripeController) handleWebhookEvent(event stripe.Event, country ente.StripeAccountCountry) error {
 	// The event body would already have been logged by the upper layers by the
 	// time we get here, so we can only handle the events that we care about. In
 	// case we receive an unexpected event, we do log an error though.
@@ -180,7 +178,7 @@ func (c *StripeController) handleWebhookEvent(event stripe.Event) error {
 		log.Error("Received an unexpected webhook from stripe:", event.Type)
 		return nil
 	}
-	eventLog, err := handler(event)
+	eventLog, err := handler(event, country)
 	if err != nil {
 		return stacktrace.Propagate(err, "")
 	}
@@ -196,16 +194,16 @@ func (c *StripeController) handleWebhookEvent(event stripe.Event) error {
 	return stacktrace.Propagate(err, "")
 }
 
-func (c *StripeController) findHandlerForEvent(event stripe.Event) func(event stripe.Event) (ente.StripeEventLog, error) {
+func (c *StripeController) findHandlerForEvent(event stripe.Event) func(event stripe.Event, country ente.StripeAccountCountry) (ente.StripeEventLog, error) {
 	switch event.Type {
 	case "checkout.session.completed":
 		return c.handleCheckoutSessionCompleted
-	case "customer.subscription.deleted":
-		return c.handleCustomerSubscriptionDeleted
 	case "customer.subscription.updated":
 		return c.handleCustomerSubscriptionUpdated
 	case "invoice.paid":
 		return c.handleInvoicePaid
+	case "payment_intent.payment_failed":
+		return c.handlePaymentIntentFailed
 	default:
 		return nil
 	}
@@ -213,7 +211,7 @@ func (c *StripeController) findHandlerForEvent(event stripe.Event) func(event st
 
 // Payment is successful and the subscription is created.
 // You should provision the subscription.
-func (c *StripeController) handleCheckoutSessionCompleted(event stripe.Event) (ente.StripeEventLog, error) {
+func (c *StripeController) handleCheckoutSessionCompleted(event stripe.Event, country ente.StripeAccountCountry) (ente.StripeEventLog, error) {
 	var session stripe.CheckoutSession
 	json.Unmarshal(event.Data.Raw, &session)
 	if session.ClientReferenceID != "" { // via payments.ente.io, where we inserted the userID
@@ -268,112 +266,57 @@ func (c *StripeController) handleCheckoutSessionCompleted(event stripe.Event) (e
 	return ente.StripeEventLog{}, nil
 }
 
-// Occurs whenever a customer's subscription ends.
-func (c *StripeController) handleCustomerSubscriptionDeleted(event stripe.Event) (ente.StripeEventLog, error) {
+// Stripe fires this when a subscription starts or changes. For example,
+// renewing a subscription, adding a coupon, applying a discount, adding an
+// invoice item, and changing plans all trigger this event. In our case, we use
+// this only to track plan changes and renewal failures resulting in
+// subscriptions going past due.
+func (c *StripeController) handleCustomerSubscriptionUpdated(event stripe.Event, country ente.StripeAccountCountry) (ente.StripeEventLog, error) {
 	var stripeSubscription stripe.Subscription
 	json.Unmarshal(event.Data.Raw, &stripeSubscription)
 	currentSubscription, err := c.BillingRepo.GetSubscriptionForTransaction(stripeSubscription.ID, ente.Stripe)
 	if err != nil {
-		// Ignore webhooks received before user has been created
-		//
-		// This would happen when we get webhook events out of order, e.g. we
-		// get a "customer.subscription.updated" before
-		// "checkout.session.completed", and the customer has not yet been
-		// created in our database.
 		if errors.Is(err, sql.ErrNoRows) {
+			// See: Ignore webhooks received before user has been created
 			log.Warn("Webhook is reporting an event for un-verified subscription stripeSubscriptionID:", stripeSubscription.ID)
 			return ente.StripeEventLog{}, nil
 		}
 		return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
 	}
 	userID := currentSubscription.UserID
-	user, err := c.UserRepo.Get(userID)
+	newSubscription, err := c.getEnteSubscriptionFromStripeSubscription(userID, stripeSubscription)
 	if err != nil {
-		if errors.Is(err, ente.ErrUserDeleted) {
-			// no-op user has already been deleted
-			return ente.StripeEventLog{UserID: userID, StripeSubscription: stripeSubscription, Event: event}, nil
-		}
 		return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
 	}
-
-	err = c.BillingRepo.UpdateSubscriptionCancellationStatus(userID, true)
-	if err != nil {
-		return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
+	// If the customer has changed the plan, we update state in the database. If
+	// the plan has not changed, we will ignore this webhook and rely on other
+	// events to update the state
+	if currentSubscription.ProductID != newSubscription.ProductID {
+		c.BillingRepo.ReplaceSubscription(currentSubscription.ID, newSubscription)
 	}
 
-	skipMail := stripeSubscription.Metadata[SkipMailKey]
-	// Send a cancellation notification email for folks who are either on
-	// individual plan or admin of a family plan.
-	if skipMail != "true" &&
-		(user.FamilyAdminID == nil || *user.FamilyAdminID == userID) {
-		storage, surpErr := c.StorageBonusRepo.GetPaidAddonSurplusStorage(context.Background(), userID)
-		if surpErr != nil {
-			return ente.StripeEventLog{}, stacktrace.Propagate(surpErr, "")
-		}
-		if storage == nil || *storage <= 0 {
-			err = email.SendTemplatedEmail([]string{user.Email}, "ente", "support@ente.io",
-				ente.SubscriptionEndedEmailSubject, ente.SubscriptionEndedEmailTemplate,
-				map[string]interface{}{}, nil)
-			if err != nil {
-				return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
-			}
-		} else {
-			log.WithField("storage", storage).Info("User has surplus storage, not sending email")
-		}
-	}
-	// TODO: Add cron to delete files of users with expired subscriptions
-	return ente.StripeEventLog{UserID: userID, StripeSubscription: stripeSubscription, Event: event}, nil
-}
-
-// Occurs whenever a subscription changes (e.g., switching from one plan to
-// another, or changing the status from trial to active).
-func (c *StripeController) handleCustomerSubscriptionUpdated(event stripe.Event) (ente.StripeEventLog, error) {
-	var stripeSubscription stripe.Subscription
-	json.Unmarshal(event.Data.Raw, &stripeSubscription)
-	currentSubscription, err := c.BillingRepo.GetSubscriptionForTransaction(stripeSubscription.ID, ente.Stripe)
+	fullStripeSub, err := c.getStripeSubscriptionWithPaymentMethod(currentSubscription)
 	if err != nil {
-		if errors.Is(err, sql.ErrNoRows) {
-			// See: Ignore webhooks received before user has been created
-			log.Warn("Webhook is reporting an event for un-verified subscription stripeSubscriptionID:", stripeSubscription.ID)
-			return ente.StripeEventLog{}, nil
-		}
 		return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
 	}
+	isSEPA := isSEPASubscription(fullStripeSub)
 
-	userID := currentSubscription.UserID
-	switch stripeSubscription.Status {
-	case stripe.SubscriptionStatusPastDue:
-		user, err := c.UserRepo.Get(userID)
+	if stripeSubscription.Status == stripe.SubscriptionStatusPastDue && !isSEPA {
+		// Unfortunately, customer.subscription.updated is only fired for SEPA
+		// payments in case of updation failures (not for purchase or renewal
+		// failures). So for consistency (and to avoid duplicate mails), we
+		// trigger on-hold emails for SEPA within handlePaymentIntentFailed.
+		err = c.sendAccountOnHoldEmail(userID)
 		if err != nil {
 			return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
 		}
-		err = email.SendTemplatedEmail([]string{user.Email}, "ente", "support@ente.io",
-			ente.AccountOnHoldEmailSubject, ente.OnHoldTemplate, map[string]interface{}{
-				"PaymentProvider": "Stripe",
-			}, nil)
-		if err != nil {
-			return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
-		}
-	case stripe.SubscriptionStatusActive:
-		newSubscription, err := c.getEnteSubscriptionFromStripeSubscription(userID, stripeSubscription)
-		if err != nil {
-			return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
-		}
-		if currentSubscription.ProductID == newSubscription.ProductID {
-			// Webhook is reporting an outdated update that was already verified
-			// no-op
-			log.Warn("Webhook is reporting an outdated purchase that was already verified stripeSubscriptionID:", stripeSubscription.ID)
-			return ente.StripeEventLog{UserID: userID, StripeSubscription: stripeSubscription, Event: event}, nil
-		}
-		if newSubscription.ProductID != currentSubscription.ProductID {
-			c.BillingRepo.ReplaceSubscription(currentSubscription.ID, newSubscription)
-		}
 	}
+
 	return ente.StripeEventLog{UserID: userID, StripeSubscription: stripeSubscription, Event: event}, nil
 }
 
 // Continue to provision the subscription as payments continue to be made.
-func (c *StripeController) handleInvoicePaid(event stripe.Event) (ente.StripeEventLog, error) {
+func (c *StripeController) handleInvoicePaid(event stripe.Event, country ente.StripeAccountCountry) (ente.StripeEventLog, error) {
 	var invoice stripe.Invoice
 	json.Unmarshal(event.Data.Raw, &invoice)
 	stripeSubscriptionID := invoice.Subscription.ID
@@ -409,6 +352,74 @@ func (c *StripeController) handleInvoicePaid(event stripe.Event) (ente.StripeEve
 	return ente.StripeEventLog{UserID: userID, StripeSubscription: *stripeSubscription, Event: event}, nil
 }
 
+// Event used to ONLY handle failures to SEPA payments, since we set
+// SubscriptionPaymentBehaviorAllowIncomplete only for SEPA. Other payment modes
+// will fail and will be handled synchronously
+func (c *StripeController) handlePaymentIntentFailed(event stripe.Event, country ente.StripeAccountCountry) (ente.StripeEventLog, error) {
+	var paymentIntent stripe.PaymentIntent
+	json.Unmarshal(event.Data.Raw, &paymentIntent)
+	isSEPA := paymentIntent.LastPaymentError.PaymentMethod.Type == stripe.PaymentMethodTypeSepaDebit
+	if !isSEPA {
+		// Ignore events for other payment methods, since they will be handled
+		// synchronously
+		log.Info("Ignoring payment intent failed event for non-SEPA payment method")
+		return ente.StripeEventLog{}, nil
+	}
+
+	client := c.StripeClients[country]
+	invoiceID := paymentIntent.Invoice.ID
+	invoice, err := client.Invoices.Get(invoiceID, nil)
+	if err != nil {
+		return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
+	}
+	stripeSubscriptionID := invoice.Subscription.ID
+
+	currentSubscription, err := c.BillingRepo.GetSubscriptionForTransaction(stripeSubscriptionID, ente.Stripe)
+	if err != nil {
+		if errors.Is(err, sql.ErrNoRows) {
+			// See: Ignore webhooks received before user has been created
+			log.Warn("Webhook is reporting an event for un-verified subscription stripeSubscriptionID:", stripeSubscriptionID)
+		}
+		return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
+	}
+	userID := currentSubscription.UserID
+
+	stripeSubscription, err := client.Subscriptions.Get(stripeSubscriptionID, nil)
+	if err != nil {
+		return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
+	}
+
+	productID := stripeSubscription.Items.Data[0].Price.ID
+	// If the current subscription is not the same as the one in the webhook,
+	// then ignore
+	fmt.Printf("productID: %s, currentSubscription.ProductID: %s\n", productID, currentSubscription.ProductID)
+	if currentSubscription.ProductID != productID {
+		// no-op
+		log.Warn("Webhook is reporting un-verified subscription update", stripeSubscription.ID, "invoiceID:", invoiceID)
+		return ente.StripeEventLog{UserID: userID, StripeSubscription: *stripeSubscription, Event: event}, nil
+	}
+	// If the current subscription is the same as the one in the webhook, then
+	// we need to expire the subscription, and send an email to the user.
+	newExpiryTime := time.Now().UnixMicro()
+	err = c.BillingRepo.UpdateSubscriptionExpiryTime(
+		currentSubscription.ID, newExpiryTime)
+	if err != nil {
+		return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
+	}
+
+	err = c.BillingRepo.UpdateSubscriptionCancellationStatus(userID, true)
+	if err != nil {
+		return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
+	}
+
+	err = c.sendAccountOnHoldEmail(userID)
+	if err != nil {
+		return ente.StripeEventLog{}, stacktrace.Propagate(err, "")
+	}
+
+	return ente.StripeEventLog{UserID: userID, StripeSubscription: *stripeSubscription, Event: event}, nil
+}
+
 func (c *StripeController) UpdateSubscription(stripeID string, userID int64) (ente.SubscriptionUpdateResponse, error) {
 	subscription, err := c.BillingRepo.GetUserSubscription(userID)
 	if err != nil {
@@ -432,11 +443,17 @@ func (c *StripeController) UpdateSubscription(stripeID string, userID int64) (en
 		log.Info("Usage is good")
 
 	}
-	client := c.StripeClients[subscription.Attributes.StripeAccountCountry]
-	stripeSubscription, err := client.Subscriptions.Get(subscription.OriginalTransactionID, nil)
+	stripeSubscription, err := c.getStripeSubscriptionWithPaymentMethod(subscription)
 	if err != nil {
 		return ente.SubscriptionUpdateResponse{}, stacktrace.Propagate(err, "")
 	}
+	isSEPA := isSEPASubscription(stripeSubscription)
+	var paymentBehavior stripe.SubscriptionPaymentBehavior
+	if isSEPA {
+		paymentBehavior = stripe.SubscriptionPaymentBehaviorAllowIncomplete
+	} else {
+		paymentBehavior = stripe.SubscriptionPaymentBehaviorPendingIfIncomplete
+	}
 	params := stripe.SubscriptionParams{
 		ProrationBehavior: stripe.String(string(stripe.SubscriptionProrationBehaviorAlwaysInvoice)),
 		Items: []*stripe.SubscriptionItemsParams{
@@ -445,9 +462,10 @@ func (c *StripeController) UpdateSubscription(stripeID string, userID int64) (en
 				Price: stripe.String(stripeID),
 			},
 		},
-		PaymentBehavior: stripe.String(string(stripe.SubscriptionPaymentBehaviorPendingIfIncomplete)),
+		PaymentBehavior: stripe.String(string(paymentBehavior)),
 	}
 	params.AddExpand("latest_invoice.payment_intent")
+	client := c.StripeClients[subscription.Attributes.StripeAccountCountry]
 	newStripeSubscription, err := client.Subscriptions.Update(subscription.OriginalTransactionID, &params)
 	if err != nil {
 		stripeError := err.(*stripe.Error)
@@ -458,19 +476,31 @@ func (c *StripeController) UpdateSubscription(stripeID string, userID int64) (en
 			return ente.SubscriptionUpdateResponse{}, stacktrace.Propagate(err, "")
 		}
 	}
-	if newStripeSubscription.PendingUpdate != nil {
-		switch newStripeSubscription.LatestInvoice.PaymentIntent.Status {
-		case stripe.PaymentIntentStatusRequiresAction:
-			return ente.SubscriptionUpdateResponse{Status: "requires_action", ClientSecret: newStripeSubscription.LatestInvoice.PaymentIntent.ClientSecret}, nil
-		case stripe.PaymentIntentStatusRequiresPaymentMethod:
-			inv := newStripeSubscription.LatestInvoice
-			invoice.VoidInvoice(inv.ID, nil)
-			return ente.SubscriptionUpdateResponse{Status: "requires_payment_method"}, nil
+	if isSEPA {
+		if newStripeSubscription.Status == stripe.SubscriptionStatusPastDue {
+			if newStripeSubscription.LatestInvoice.PaymentIntent.Status == stripe.PaymentIntentStatusRequiresAction {
+				return ente.SubscriptionUpdateResponse{Status: "requires_action", ClientSecret: newStripeSubscription.LatestInvoice.PaymentIntent.ClientSecret}, nil
+			} else if newStripeSubscription.LatestInvoice.PaymentIntent.Status == stripe.PaymentIntentStatusRequiresPaymentMethod {
+				return ente.SubscriptionUpdateResponse{Status: "requires_payment_method"}, nil
+			} else if newStripeSubscription.LatestInvoice.PaymentIntent.Status == stripe.PaymentIntentStatusProcessing {
+				return ente.SubscriptionUpdateResponse{Status: "success"}, nil
+			}
+			return ente.SubscriptionUpdateResponse{}, stacktrace.Propagate(ente.ErrBadRequest, "")
+		}
+	} else {
+		if newStripeSubscription.PendingUpdate != nil {
+			switch newStripeSubscription.LatestInvoice.PaymentIntent.Status {
+			case stripe.PaymentIntentStatusRequiresAction:
+				return ente.SubscriptionUpdateResponse{Status: "requires_action", ClientSecret: newStripeSubscription.LatestInvoice.PaymentIntent.ClientSecret}, nil
+			case stripe.PaymentIntentStatusRequiresPaymentMethod:
+				inv := newStripeSubscription.LatestInvoice
+				client.Invoices.VoidInvoice(inv.ID, nil)
+				return ente.SubscriptionUpdateResponse{Status: "requires_payment_method"}, nil
+			}
+			return ente.SubscriptionUpdateResponse{}, stacktrace.Propagate(ente.ErrBadRequest, "")
 		}
-		return ente.SubscriptionUpdateResponse{}, stacktrace.Propagate(ente.ErrBadRequest, "")
 	}
 	return ente.SubscriptionUpdateResponse{Status: "success"}, nil
-
 }
 
 func (c *StripeController) UpdateSubscriptionCancellationStatus(userID int64, status bool) (ente.Subscription, error) {
@@ -525,6 +555,29 @@ func (c *StripeController) GetStripeCustomerPortal(userID int64, redirectRootURL
 	return ps.URL, nil
 }
 
+func (c *StripeController) getStripeSubscriptionWithPaymentMethod(subscription ente.Subscription) (stripe.Subscription, error) {
+	client := c.StripeClients[subscription.Attributes.StripeAccountCountry]
+	params := &stripe.SubscriptionParams{}
+	params.AddExpand("default_payment_method")
+	stripeSubscription, err := client.Subscriptions.Get(subscription.OriginalTransactionID, params)
+	if err != nil {
+		return stripe.Subscription{}, stacktrace.Propagate(err, "")
+	}
+	return *stripeSubscription, nil
+}
+
+func (c *StripeController) sendAccountOnHoldEmail(userID int64) error {
+	user, err := c.UserRepo.Get(userID)
+	if err != nil {
+		return stacktrace.Propagate(err, "")
+	}
+	err = email.SendTemplatedEmail([]string{user.Email}, "ente", "support@ente.io",
+		ente.AccountOnHoldEmailSubject, ente.OnHoldTemplate, map[string]interface{}{
+			"PaymentProvider": "Stripe",
+		}, nil)
+	return err
+}
+
 func (c *StripeController) getStripeSubscriptionFromSession(userID int64, checkoutSessionID string) (stripe.Subscription, error) {
 	subscription, err := c.BillingRepo.GetUserSubscription(userID)
 	if err != nil {
@@ -624,9 +677,7 @@ func (c *StripeController) CancelSubAndDeleteCustomer(subscription ente.Subscrip
 	if !subscription.Attributes.IsCancelled {
 		prorateRefund := true
 		logger.Info("cancelling sub with prorated refund")
-		updateParams := &stripe.SubscriptionParams{}
-		updateParams.AddMetadata(SkipMailKey, "true")
-		_, err := client.Subscriptions.Update(subscription.OriginalTransactionID, updateParams)
+		_, err := client.Subscriptions.Update(subscription.OriginalTransactionID, nil)
 		if err != nil {
 			stripeError := err.(*stripe.Error)
 			errorMsg := fmt.Sprintf("subscription updation failed during account deletion: %s, %s", stripeError.Msg, stripeError.Code)
@@ -677,34 +728,12 @@ func (c *StripeController) CancelSubAndDeleteCustomer(subscription ente.Subscrip
 	return nil
 }
 
-// cancel the earlier past_due subscription
-// and add skip mail metadata entry to avoid sending account deletion mail while re-subscription
-func (c *StripeController) cancelExistingStripeSubscription(subscription ente.Subscription, userID int64) error {
-	updateParams := &stripe.SubscriptionParams{}
-	updateParams.AddMetadata(SkipMailKey, "true")
-	client := c.StripeClients[subscription.Attributes.StripeAccountCountry]
-	_, err := client.Subscriptions.Update(subscription.OriginalTransactionID, updateParams)
-	if err != nil {
-		stripeError := err.(*stripe.Error)
-		log.Warn(fmt.Sprintf("subscription updation failed msg= %s for userID=%d", stripeError.Msg, userID))
-		// ignore if subscription doesn't exist, already deleted
-		if stripeError.HTTPStatusCode != 404 {
-			return stacktrace.Propagate(err, "")
-		}
+func isSEPASubscription(stripeSubscription stripe.Subscription) bool {
+	isSEPA := false
+	if stripeSubscription.DefaultPaymentMethod != nil {
+		isSEPA = stripeSubscription.DefaultPaymentMethod.Type == stripe.PaymentMethodTypeSepaDebit
 	} else {
-		_, err = client.Subscriptions.Cancel(subscription.OriginalTransactionID, nil)
-		if err != nil {
-			stripeError := err.(*stripe.Error)
-			log.Warn(fmt.Sprintf("subscription cancel failed msg= %s for userID=%d", stripeError.Msg, userID))
-			// ignore if subscription doesn't exist, already deleted
-			if stripeError.HTTPStatusCode != 404 {
-				return stacktrace.Propagate(err, "")
-			}
-		}
-		err = c.BillingRepo.UpdateSubscriptionCancellationStatus(userID, true)
-		if err != nil {
-			return stacktrace.Propagate(err, "")
-		}
+		log.Info("No default payment method found")
 	}
-	return nil
+	return isSEPA
 }

+ 5 - 1
web/apps/photos/src/components/Sidebar/SubscriptionStatus/index.tsx

@@ -12,6 +12,7 @@ import {
     isOnFreePlan,
     isSubscriptionActive,
     isSubscriptionCancelled,
+    isSubscriptionPastDue,
 } from "utils/billing";
 
 import { Typography } from "@mui/material";
@@ -54,7 +55,10 @@ export default function SubscriptionStatus({
                         showPlanSelectorModal();
                     }
                 } else {
-                    if (hasStripeSubscription(userDetails.subscription)) {
+                    if (
+                        hasStripeSubscription(userDetails.subscription) &&
+                        isSubscriptionPastDue(userDetails.subscription)
+                    ) {
                         billingService.redirectToCustomerPortal();
                     } else {
                         showPlanSelectorModal();

+ 16 - 3
web/apps/photos/src/components/Sidebar/userDetailsSection.tsx

@@ -4,8 +4,10 @@ import { Box, Skeleton } from "@mui/material";
 import Typography from "@mui/material/Typography";
 import { GalleryContext } from "pages/gallery";
 import { useContext, useEffect, useMemo, useState } from "react";
+import billingService from "services/billingService";
 import { getUserDetailsV2 } from "services/userService";
 import { UserDetails } from "types/user";
+import { hasStripeSubscription, isSubscriptionPastDue } from "utils/billing";
 import { isFamilyAdmin, isPartOfFamily } from "utils/user/family";
 import { MemberSubscriptionManage } from "../MemberSubscriptionManage";
 import SubscriptionCard from "./SubscriptionCard";
@@ -50,9 +52,20 @@ export default function UserDetailsSection({ sidebarView }) {
         [userDetails],
     );
 
-    const handleSubscriptionCardClick = isMemberSubscription
-        ? openMemberSubscriptionManage
-        : galleryContext.showPlanSelectorModal;
+    const handleSubscriptionCardClick = () => {
+        if (isMemberSubscription) {
+            openMemberSubscriptionManage();
+        } else {
+            if (
+                hasStripeSubscription(userDetails.subscription) &&
+                isSubscriptionPastDue(userDetails.subscription)
+            ) {
+                billingService.redirectToCustomerPortal();
+            } else {
+                galleryContext.showPlanSelectorModal();
+            }
+        }
+    };
 
     return (
         <>

+ 10 - 0
web/apps/photos/src/utils/billing/index.ts

@@ -17,6 +17,7 @@ const PAYMENT_PROVIDER_STRIPE = "stripe";
 const PAYMENT_PROVIDER_APPSTORE = "appstore";
 const PAYMENT_PROVIDER_PLAYSTORE = "playstore";
 const FREE_PLAN = "free";
+const THIRTY_DAYS_IN_MICROSECONDS = 30 * 24 * 60 * 60 * 1000 * 1000;
 
 enum FAILURE_REASON {
     AUTHENTICATION_FAILED = "authentication_failed",
@@ -151,6 +152,15 @@ export function hasExceededStorageQuota(userDetails: UserDetails) {
     }
 }
 
+export function isSubscriptionPastDue(subscription: Subscription) {
+    const currentTime = Date.now() * 1000;
+    return (
+        !isSubscriptionCancelled(subscription) &&
+        subscription.expiryTime < currentTime &&
+        subscription.expiryTime >= currentTime - THIRTY_DAYS_IN_MICROSECONDS
+    );
+}
+
 export function isPopularPlan(plan: Plan) {
     return plan.storage === 100 * ONE_GB;
 }