🔀 Commit

fixed sticker upload issues for non xmpp.tel accounts. warning for non xmpp.tel ephemeral attachments
Commit6ebdc09287470312e231ac01eb46352ee27482fa
AuthorJabJab <noreply@xmpp.tel>
Date2026-07-19
Parent35883b2d
commit 6ebdc09287470312e231ac01eb46352ee27482fa
Author: JabJab <noreply@xmpp.tel>
Date:   Sun Jul 19 08:19:03 2026 +0300

    fixed sticker upload issues for non xmpp.tel accounts. warning for non xmpp.tel ephemeral attachments
---
 build.gradle                                       |  2 +-
 .../tel/xmpp/jabjab/http/HttpUploadConnection.java | 17 ++++++--
 .../tel/xmpp/jabjab/ui/ConversationFragment.java   | 34 ++++++++++++++++
 .../ui/util/EphemeralUploadConsentDialog.java      | 46 ++++++++++++++++++++++
 .../jabjab/ui/util/EphemeralUploadSettings.java    | 36 +++++++++++++++++
 .../java/tel/xmpp/jabjab/ui/util/StickerStore.java | 13 ++++++
 .../layout/dialog_ephemeral_upload_fallback.xml    | 25 ++++++++++++
 src/main/res/values-ar/strings.xml                 |  4 ++
 src/main/res/values-cs/strings.xml                 |  4 ++
 src/main/res/values-da-rDK/strings.xml             |  4 ++
 src/main/res/values-de/strings.xml                 |  4 ++
 src/main/res/values-es/strings.xml                 |  4 ++
 src/main/res/values-et/strings.xml                 |  4 ++
 src/main/res/values-fi/strings.xml                 |  4 ++
 src/main/res/values-fr/strings.xml                 |  4 ++
 src/main/res/values-it/strings.xml                 |  4 ++
 src/main/res/values-ja/strings.xml                 |  4 ++
 src/main/res/values-nl/strings.xml                 |  4 ++
 src/main/res/values-pl/strings.xml                 |  4 ++
 src/main/res/values-pt-rBR/strings.xml             |  4 ++
 src/main/res/values-pt/strings.xml                 |  4 ++
 src/main/res/values-ro-rRO/strings.xml             |  4 ++
 src/main/res/values-ru/strings.xml                 |  4 ++
 src/main/res/values-sr/strings.xml                 |  4 ++
 src/main/res/values-sv/strings.xml                 |  4 ++
 src/main/res/values-zh-rCN/strings.xml             |  4 ++
 src/main/res/values-zh-rTW/strings.xml             |  4 ++
 src/main/res/values/strings.xml                    |  4 ++
 28 files changed, 253 insertions(+), 4 deletions(-)

diff --git a/build.gradle b/build.gradle
index a42434d..15480a9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -113,7 +113,7 @@ android {
 
     defaultConfig {
         minSdkVersion 23
-        versionCode 42294
+        versionCode 42295
         versionName "1.0.1"
         applicationId "tel.xmpp.jabjab"
         resValue "string", "applicationId", applicationId
diff --git a/src/main/java/tel/xmpp/jabjab/http/HttpUploadConnection.java b/src/main/java/tel/xmpp/jabjab/http/HttpUploadConnection.java
index cad7743..4466115 100644
--- a/src/main/java/tel/xmpp/jabjab/http/HttpUploadConnection.java
+++ b/src/main/java/tel/xmpp/jabjab/http/HttpUploadConnection.java
@@ -141,10 +141,21 @@ public class HttpUploadConnection
         // Ephemeral attachments bypass Prosody and go to the ephemeral/ category directly,
         // so the server can delete the file after the timer expires + a safety buffer.
         // Sticker attachments also bypass Prosody and go to the stickers/ category directly,
-        // so they are stored permanently and SHA-256 deduped on the server.
-        if (message.isEphemeral()) {
+        // so they are stored permanently and SHA-256 deduped on the server. Both bypasses are
+        // gated on xmpp.tel accounts only, which are the only ones with credentials/allowance
+        // to write there. Accounts on other servers fall through to their own server's
+        // standard XEP-0363 upload component instead, same as StoriesManager.uploadStory()
+        // already does for stories — without this check, non-xmpp.tel accounts hit
+        // "unable to resolve host upload.xmpp.tel" trying to use a bypass that was never meant
+        // for them. For ephemeral specifically, the UI layer (ConversationFragment's
+        // needsEphemeralUploadConsent gate) already warned the user before send that a
+        // non-bypass account's attachment won't auto-delete — this is what actually delivers
+        // on that: falling through to a normal upload instead of crashing.
+        final boolean isBypassAccount =
+                Config.UPLOAD_BYPASS_DOMAIN.equals(account.getJid().getDomain().toString());
+        if (message.isEphemeral() && isBypassAccount) {
             this.slotFuture = Futures.immediateFuture(buildEphemeralSlot(account, file.getName()));
-        } else if (message.getStickerFilePath() != null) {
+        } else if (message.getStickerFilePath() != null && isBypassAccount) {
             this.slotFuture = Futures.immediateFuture(buildStickerSlot(account, file.getName()));
         } else {
             this.slotFuture =
diff --git a/src/main/java/tel/xmpp/jabjab/ui/ConversationFragment.java b/src/main/java/tel/xmpp/jabjab/ui/ConversationFragment.java
index 90ef1cc..cf089c2 100644
--- a/src/main/java/tel/xmpp/jabjab/ui/ConversationFragment.java
+++ b/src/main/java/tel/xmpp/jabjab/ui/ConversationFragment.java
@@ -1342,6 +1342,16 @@ public class ConversationFragment extends XmppFragment
 
     private void commitAttachments(final List<Attachment> attachments) {
         setAttachmentChoicesVisibility(false);
+        if (needsEphemeralUploadConsent(attachments)
+                && !tel.xmpp.jabjab.ui.util.EphemeralUploadSettings.getInstance(requireContext())
+                        .isAlwaysAllowNonAutoDeleteUpload()) {
+            tel.xmpp.jabjab.ui.util.EphemeralUploadConsentDialog.show(
+                    requireActivity(),
+                    requireActivity().getLayoutInflater(),
+                    () -> commitAttachments(attachments),
+                    () -> {});
+            return;
+        }
         if (anyNeedsExternalStoragePermission(attachments)
                 && !hasPermissions(
                         REQUEST_COMMIT_ATTACHMENTS, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
@@ -1410,6 +1420,17 @@ public class ConversationFragment extends XmppFragment
         return false;
     }
 
+    // True only when this send would otherwise silently break the disappearing-messages
+    // promise: ephemeral is on, the account isn't one whose server can actually auto-delete
+    // the upload, and at least one attachment isn't a LOCATION share (which never uploads).
+    private boolean needsEphemeralUploadConsent(final Collection<Attachment> attachments) {
+        return conversation != null
+                && conversation.getEphemeralMessageTimer() > 0
+                && !Config.UPLOAD_BYPASS_DOMAIN.equals(
+                        conversation.getAccount().getJid().getDomain().toString())
+                && anyNeedsExternalStoragePermission(attachments);
+    }
+
     public void toggleInputMethod() {
         final var hasAttachments = mediaPreviewAdapter.hasAttachments();
         binding.textInput.setVisibility(hasAttachments ? View.GONE : View.VISIBLE);
@@ -3258,6 +3279,19 @@ public class ConversationFragment extends XmppFragment
     private void attachStickerToConversation(
             final Conversation conversation, final android.net.Uri uri,
             final String stickerPackNode, final String stickerFilePath) {
+        if (conversation.getEphemeralMessageTimer() > 0
+                && !Config.UPLOAD_BYPASS_DOMAIN.equals(
+                        conversation.getAccount().getJid().getDomain().toString())
+                && !tel.xmpp.jabjab.ui.util.EphemeralUploadSettings.getInstance(requireContext())
+                        .isAlwaysAllowNonAutoDeleteUpload()) {
+            tel.xmpp.jabjab.ui.util.EphemeralUploadConsentDialog.show(
+                    requireActivity(),
+                    requireActivity().getLayoutInflater(),
+                    () -> attachStickerToConversation(
+                            conversation, uri, stickerPackNode, stickerFilePath),
+                    () -> {});
+            return;
+        }
         final Toast prepareFileToast =
                 Toast.makeText(getActivity(), getText(R.string.preparing_file), Toast.LENGTH_LONG);
         prepareFileToast.show();
diff --git a/src/main/java/tel/xmpp/jabjab/ui/util/EphemeralUploadConsentDialog.java b/src/main/java/tel/xmpp/jabjab/ui/util/EphemeralUploadConsentDialog.java
new file mode 100644
index 0000000..651443c
--- /dev/null
+++ b/src/main/java/tel/xmpp/jabjab/ui/util/EphemeralUploadConsentDialog.java
@@ -0,0 +1,46 @@
+package tel.xmpp.jabjab.ui.util;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import androidx.databinding.DataBindingUtil;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import tel.xmpp.jabjab.R;
+import tel.xmpp.jabjab.databinding.DialogEphemeralUploadFallbackBinding;
+
+/**
+ * "Send without auto-delete?" consent prompt shown before sending an attachment in a
+ * disappearing-messages conversation when the recipient's/sender's account isn't on
+ * xmpp.tel (whose server is the only one that knows how to auto-delete the upload).
+ * Same shape as {@link TranslationConsentDialog}: one dialog, one persisted "always
+ * allow" preference ({@link EphemeralUploadSettings}), asked every time otherwise.
+ */
+public final class EphemeralUploadConsentDialog {
+
+    private EphemeralUploadConsentDialog() {}
+
+    public static void show(
+            final Context context,
+            final LayoutInflater inflater,
+            final Runnable proceedWithUpload,
+            final Runnable cancel) {
+        final DialogEphemeralUploadFallbackBinding viewBinding =
+                DataBindingUtil.inflate(
+                        inflater, R.layout.dialog_ephemeral_upload_fallback, null, false);
+        new MaterialAlertDialogBuilder(context)
+                .setTitle(R.string.ephemeral_upload_fallback_title)
+                .setView(viewBinding.getRoot())
+                .setPositiveButton(
+                        R.string.ephemeral_upload_fallback_allow,
+                        (dialog, which) -> {
+                            if (viewBinding.alwaysAllow.isChecked()) {
+                                EphemeralUploadSettings.getInstance(context)
+                                        .setAlwaysAllowNonAutoDeleteUpload(true);
+                            }
+                            proceedWithUpload.run();
+                        })
+                .setNegativeButton(R.string.cancel, (dialog, which) -> cancel.run())
+                .setOnCancelListener(dialog -> cancel.run())
+                .create()
+                .show();
+    }
+}
diff --git a/src/main/java/tel/xmpp/jabjab/ui/util/EphemeralUploadSettings.java b/src/main/java/tel/xmpp/jabjab/ui/util/EphemeralUploadSettings.java
new file mode 100644
index 0000000..76cadbd
--- /dev/null
+++ b/src/main/java/tel/xmpp/jabjab/ui/util/EphemeralUploadSettings.java
@@ -0,0 +1,36 @@
+package tel.xmpp.jabjab.ui.util;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+/** Persisted "always allow" preference for the ephemeral-attachment-won't-auto-delete
+ * consent dialog — same single-boolean, SharedPreferences-backed shape as
+ * {@link TranslationSettings}'s Google Translate fallback preference. */
+public class EphemeralUploadSettings {
+
+    private static final String PREFS_NAME = "jabjab_upload";
+    private static final String KEY_ALWAYS_ALLOW = "always_allow_non_auto_delete_upload";
+    private static EphemeralUploadSettings instance;
+    private final SharedPreferences prefs;
+
+    private EphemeralUploadSettings(final Context context) {
+        this.prefs =
+                context.getApplicationContext()
+                        .getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+    }
+
+    public static synchronized EphemeralUploadSettings getInstance(final Context context) {
+        if (instance == null) {
+            instance = new EphemeralUploadSettings(context);
+        }
+        return instance;
+    }
+
+    public boolean isAlwaysAllowNonAutoDeleteUpload() {
+        return prefs.getBoolean(KEY_ALWAYS_ALLOW, false);
+    }
+
+    public void setAlwaysAllowNonAutoDeleteUpload(final boolean enabled) {
+        prefs.edit().putBoolean(KEY_ALWAYS_ALLOW, enabled).apply();
+    }
+}
diff --git a/src/main/java/tel/xmpp/jabjab/ui/util/StickerStore.java b/src/main/java/tel/xmpp/jabjab/ui/util/StickerStore.java
index 41f181c..2752c14 100644
--- a/src/main/java/tel/xmpp/jabjab/ui/util/StickerStore.java
+++ b/src/main/java/tel/xmpp/jabjab/ui/util/StickerStore.java
@@ -513,6 +513,19 @@ public class StickerStore {
                         "STICKER evicting stale prosody-filer URL for " + accountJid + ": " + url);
                 return null;
             }
+            // Reject cached upload.xmpp.tel URLs for accounts that were never supposed to
+            // use that bypass (HttpUploadConnection now gates it on UPLOAD_BYPASS_DOMAIN,
+            // but a URL cached from before that check existed sticks around here forever
+            // and would keep bypassing the fix on every resend of the same sticker).
+            final boolean isBypassAccount =
+                    accountJid != null
+                            && accountJid.endsWith("@" + Config.UPLOAD_BYPASS_DOMAIN);
+            if (!isBypassAccount && url.contains(Config.UPLOAD_BYPASS_DOMAIN)) {
+                Log.d(Config.LOGTAG,
+                        "STICKER evicting non-bypass-account URL cached against "
+                                + Config.UPLOAD_BYPASS_DOMAIN + " for " + accountJid + ": " + url);
+                return null;
+            }
             return url;
         }
         return null;
diff --git a/src/main/res/layout/dialog_ephemeral_upload_fallback.xml b/src/main/res/layout/dialog_ephemeral_upload_fallback.xml
new file mode 100644
index 0000000..f638f67
--- /dev/null
+++ b/src/main/res/layout/dialog_ephemeral_upload_fallback.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:padding="?dialogPreferredPadding">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/ephemeral_upload_fallback_explained"
+            android:textAppearance="?textAppearanceBodyMedium" />
+
+        <CheckBox
+            android:layout_marginTop="16sp"
+            android:id="@+id/always_allow"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:checked="false"
+            android:text="@string/ephemeral_upload_always_allow" />
+
+    </LinearLayout>
+</layout>
diff --git a/src/main/res/values-ar/strings.xml b/src/main/res/values-ar/strings.xml
index 5d71248..6e9b6f6 100644
--- a/src/main/res/values-ar/strings.xml
+++ b/src/main/res/values-ar/strings.xml
@@ -736,6 +736,10 @@
     <string name="translation_do_not_ask_again">السماح دائمًا باستخدام ترجمة جوجل كبديل</string>
     <string name="translate_choose_language">ترجمة إلى…</string>
     <string name="translate_more_languages">المزيد…</string>
+    <string name="ephemeral_upload_fallback_title">إرسال بدون حذف تلقائي؟</string>
+    <string name="ephemeral_upload_fallback_explained">خادم جهة الاتصال هذه لا يدعم المرفقات في الرسائل المؤقتة. سيتم رفع الملف بشكل عادي ولن يُحذف تلقائيًا.</string>
+    <string name="ephemeral_upload_fallback_allow">إرسال على أي حال</string>
+    <string name="ephemeral_upload_always_allow">الإرسال دائمًا دون سؤال</string>
     <string name="translation_failed">فشلت الترجمة</string>
     <string name="translation_in_progress">جارٍ الترجمة…</string>
     <string name="translation_title">الترجمة</string>
diff --git a/src/main/res/values-cs/strings.xml b/src/main/res/values-cs/strings.xml
index 966f5f1..5041fac 100644
--- a/src/main/res/values-cs/strings.xml
+++ b/src/main/res/values-cs/strings.xml
@@ -1437,6 +1437,10 @@
     <string name="translation_do_not_ask_again">Vždy povolit záložní Překladač Google</string>
     <string name="translate_choose_language">Přeložit do…</string>
     <string name="translate_more_languages">Více…</string>
+    <string name="ephemeral_upload_fallback_title">Odeslat bez automatického mazání?</string>
+    <string name="ephemeral_upload_fallback_explained">Server tohoto kontaktu nepodporuje přílohy v mizejících zprávách. Soubor bude nahrán běžným způsobem a nebude automaticky smazán.</string>
+    <string name="ephemeral_upload_fallback_allow">Přesto odeslat</string>
+    <string name="ephemeral_upload_always_allow">Vždy odesílat bez dotazu</string>
     <string name="story_caption_hint">Přidat popisek…</string>
     <string name="story_post_button">Publikovat</string>
 </resources>
diff --git a/src/main/res/values-da-rDK/strings.xml b/src/main/res/values-da-rDK/strings.xml
index 59043c8..9fb8abf 100644
--- a/src/main/res/values-da-rDK/strings.xml
+++ b/src/main/res/values-da-rDK/strings.xml
@@ -1406,6 +1406,10 @@
     <string name="translation_do_not_ask_again">Tillad altid tilbagefald til Google Oversæt</string>
     <string name="translate_choose_language">Oversæt til…</string>
     <string name="translate_more_languages">Mere…</string>
+    <string name="ephemeral_upload_fallback_title">Send uden automatisk sletning?</string>
+    <string name="ephemeral_upload_fallback_explained">Denne kontakts server understøtter ikke vedhæftede filer i selvdestruerende beskeder. Filen uploades normalt og slettes ikke automatisk.</string>
+    <string name="ephemeral_upload_fallback_allow">Send alligevel</string>
+    <string name="ephemeral_upload_always_allow">Send altid uden at spørge</string>
     <string name="story_caption_hint">Tilføj en billedtekst…</string>
     <string name="story_post_button">Udgiv</string>
 </resources>
diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml
index 18f5616..bf9c801 100644
--- a/src/main/res/values-de/strings.xml
+++ b/src/main/res/values-de/strings.xml
@@ -1310,6 +1310,10 @@
     <string name="translation_do_not_ask_again">Rückgriff auf Google Übersetzer immer erlauben</string>
     <string name="translate_choose_language">Übersetzen nach…</string>
     <string name="translate_more_languages">Mehr…</string>
+    <string name="ephemeral_upload_fallback_title">Ohne automatisches Löschen senden?</string>
+    <string name="ephemeral_upload_fallback_explained">Der Server dieses Kontakts unterstützt keine Anhänge in selbstlöschenden Nachrichten. Die Datei wird normal hochgeladen und wird nicht automatisch gelöscht.</string>
+    <string name="ephemeral_upload_fallback_allow">Trotzdem senden</string>
+    <string name="ephemeral_upload_always_allow">Immer ohne Nachfrage senden</string>
     <string name="translation_failed">Übersetzung fehlgeschlagen</string>
     <string name="translation_in_progress">Wird übersetzt…</string>
     <string name="translation_title">Übersetzung</string>
diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml
index 9816d5d..f20e833 100644
--- a/src/main/res/values-es/strings.xml
+++ b/src/main/res/values-es/strings.xml
@@ -1447,6 +1447,10 @@
     <string name="translation_do_not_ask_again">Permitir siempre el uso de Google Translate</string>
     <string name="translate_choose_language">Traducir a…</string>
     <string name="translate_more_languages">Más…</string>
+    <string name="ephemeral_upload_fallback_title">¿Enviar sin eliminación automática?</string>
+    <string name="ephemeral_upload_fallback_explained">El servidor de este contacto no admite archivos adjuntos en mensajes efímeros. El archivo se subirá normalmente y no se eliminará automáticamente.</string>
+    <string name="ephemeral_upload_fallback_allow">Enviar de todos modos</string>
+    <string name="ephemeral_upload_always_allow">Enviar siempre sin preguntar</string>
     <string name="story_caption_hint">Añade un pie de foto…</string>
     <string name="story_post_button">Publicar</string>
 </resources>
diff --git a/src/main/res/values-et/strings.xml b/src/main/res/values-et/strings.xml
index 5656cd8..222806b 100644
--- a/src/main/res/values-et/strings.xml
+++ b/src/main/res/values-et/strings.xml
@@ -1448,6 +1448,10 @@
     <string name="translation_do_not_ask_again">Luba alati varuvariandina Google Tõlge</string>
     <string name="translate_choose_language">Tõlgi keelde…</string>
     <string name="translate_more_languages">Rohkem…</string>
+    <string name="ephemeral_upload_fallback_title">Kas saata ilma automaatse kustutamiseta?</string>
+    <string name="ephemeral_upload_fallback_explained">Selle kontakti server ei toeta manuseid kaduvates sõnumites. Fail laaditakse üles tavapäraselt ega kustutata automaatselt.</string>
+    <string name="ephemeral_upload_fallback_allow">Saada ikkagi</string>
+    <string name="ephemeral_upload_always_allow">Saada alati ilma küsimata</string>
     <string name="story_caption_hint">Lisa pealdis…</string>
     <string name="story_post_button">Avalda</string>
 </resources>
diff --git a/src/main/res/values-fi/strings.xml b/src/main/res/values-fi/strings.xml
index 9468b1c..7e79ca9 100644
--- a/src/main/res/values-fi/strings.xml
+++ b/src/main/res/values-fi/strings.xml
@@ -1406,6 +1406,10 @@
     <string name="translation_do_not_ask_again">Salli aina varautuminen Google Kääntäjään</string>
     <string name="translate_choose_language">Käännä kielelle…</string>
     <string name="translate_more_languages">Lisää…</string>
+    <string name="ephemeral_upload_fallback_title">Lähetetäänkö ilman automaattista poistoa?</string>
+    <string name="ephemeral_upload_fallback_explained">Tämän yhteystiedon palvelin ei tue liitteitä katoavissa viesteissä. Tiedosto ladataan normaalisti eikä sitä poisteta automaattisesti.</string>
+    <string name="ephemeral_upload_fallback_allow">Lähetä silti</string>
+    <string name="ephemeral_upload_always_allow">Lähetä aina kysymättä</string>
     <string name="story_caption_hint">Lisää kuvateksti…</string>
     <string name="story_post_button">Julkaise</string>
 </resources>
diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml
index e64e176..b242e21 100644
--- a/src/main/res/values-fr/strings.xml
+++ b/src/main/res/values-fr/strings.xml
@@ -1439,6 +1439,10 @@
     <string name="translation_do_not_ask_again">Toujours autoriser le recours à Google Traduction</string>
     <string name="translate_choose_language">Traduire en…</string>
     <string name="translate_more_languages">Plus…</string>
+    <string name="ephemeral_upload_fallback_title">Envoyer sans suppression automatique ?</string>
+    <string name="ephemeral_upload_fallback_explained">Le serveur de ce contact ne prend pas en charge les pièces jointes dans les messages éphémères. Le fichier sera envoyé normalement et ne sera pas supprimé automatiquement.</string>
+    <string name="ephemeral_upload_fallback_allow">Envoyer quand même</string>
+    <string name="ephemeral_upload_always_allow">Toujours envoyer sans demander</string>
     <string name="story_caption_hint">Ajouter une légende…</string>
     <string name="story_post_button">Publier</string>
 </resources>
diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml
index df1cb3d..6b090db 100644
--- a/src/main/res/values-it/strings.xml
+++ b/src/main/res/values-it/strings.xml
@@ -1449,6 +1449,10 @@
     <string name="translation_do_not_ask_again">Consenti sempre il ricorso a Google Traduttore</string>
     <string name="translate_choose_language">Traduci in…</string>
     <string name="translate_more_languages">Altro…</string>
+    <string name="ephemeral_upload_fallback_title">Inviare senza eliminazione automatica?</string>
+    <string name="ephemeral_upload_fallback_explained">Il server di questo contatto non supporta gli allegati nei messaggi effimeri. Il file verrà caricato normalmente e non verrà eliminato automaticamente.</string>
+    <string name="ephemeral_upload_fallback_allow">Invia comunque</string>
+    <string name="ephemeral_upload_always_allow">Invia sempre senza chiedere</string>
     <string name="story_caption_hint">Aggiungi una didascalia…</string>
     <string name="story_post_button">Pubblica</string>
 </resources>
diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml
index 161f1d9..3d61f56 100644
--- a/src/main/res/values-ja/strings.xml
+++ b/src/main/res/values-ja/strings.xml
@@ -1404,6 +1404,10 @@
     <string name="translation_do_not_ask_again">常にGoogle翻訳へのフォールバックを許可</string>
     <string name="translate_choose_language">翻訳先…</string>
     <string name="translate_more_languages">その他…</string>
+    <string name="ephemeral_upload_fallback_title">自動削除なしで送信しますか?</string>
+    <string name="ephemeral_upload_fallback_explained">この連絡先のサーバーは消える添付ファイルに対応していません。ファイルは通常どおりアップロードされ、自動的には削除されません。</string>
+    <string name="ephemeral_upload_fallback_allow">このまま送信</string>
+    <string name="ephemeral_upload_always_allow">常に確認せず送信</string>
     <string name="story_caption_hint">キャプションを追加…</string>
     <string name="story_post_button">投稿</string>
 </resources>
diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml
index cf92ce8..8692708 100644
--- a/src/main/res/values-nl/strings.xml
+++ b/src/main/res/values-nl/strings.xml
@@ -1424,6 +1424,10 @@
     <string name="translation_do_not_ask_again">Terugvallen op Google Translate altijd toestaan</string>
     <string name="translate_choose_language">Vertalen naar…</string>
     <string name="translate_more_languages">Meer…</string>
+    <string name="ephemeral_upload_fallback_title">Verzenden zonder automatisch verwijderen?</string>
+    <string name="ephemeral_upload_fallback_explained">De server van dit contact ondersteunt geen bijlagen bij verlopende berichten. Het bestand wordt normaal geüpload en wordt niet automatisch verwijderd.</string>
+    <string name="ephemeral_upload_fallback_allow">Toch verzenden</string>
+    <string name="ephemeral_upload_always_allow">Altijd verzenden zonder te vragen</string>
     <string name="story_caption_hint">Bijschrift toevoegen…</string>
     <string name="story_post_button">Plaatsen</string>
 </resources>
diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml
index 91b348d..6d39d1c 100644
--- a/src/main/res/values-pl/strings.xml
+++ b/src/main/res/values-pl/strings.xml
@@ -1462,6 +1462,10 @@
     <string name="translation_do_not_ask_again">Zawsze zezwalaj na korzystanie z Tłumacza Google</string>
     <string name="translate_choose_language">Przetłumacz na…</string>
     <string name="translate_more_languages">Więcej…</string>
+    <string name="ephemeral_upload_fallback_title">Wysłać bez automatycznego usuwania?</string>
+    <string name="ephemeral_upload_fallback_explained">Serwer tego kontaktu nie obsługuje załączników w znikających wiadomościach. Plik zostanie przesłany normalnie i nie zostanie automatycznie usunięty.</string>
+    <string name="ephemeral_upload_fallback_allow">Wyślij mimo to</string>
+    <string name="ephemeral_upload_always_allow">Zawsze wysyłaj bez pytania</string>
     <string name="story_caption_hint">Dodaj podpis…</string>
     <string name="story_post_button">Opublikuj</string>
 </resources>
diff --git a/src/main/res/values-pt-rBR/strings.xml b/src/main/res/values-pt-rBR/strings.xml
index ee61ad8..e663d6a 100644
--- a/src/main/res/values-pt-rBR/strings.xml
+++ b/src/main/res/values-pt-rBR/strings.xml
@@ -1439,6 +1439,10 @@
     <string name="translation_do_not_ask_again">Permitir sempre o recurso ao Google Tradutor</string>
     <string name="translate_choose_language">Traduzir para…</string>
     <string name="translate_more_languages">Mais…</string>
+    <string name="ephemeral_upload_fallback_title">Enviar sem exclusão automática?</string>
+    <string name="ephemeral_upload_fallback_explained">O servidor deste contato não oferece suporte a anexos em mensagens efêmeras. O arquivo será enviado normalmente e não será excluído automaticamente.</string>
+    <string name="ephemeral_upload_fallback_allow">Enviar mesmo assim</string>
+    <string name="ephemeral_upload_always_allow">Sempre enviar sem perguntar</string>
     <string name="story_caption_hint">Adicionar uma legenda…</string>
     <string name="story_post_button">Publicar</string>
 </resources>
diff --git a/src/main/res/values-pt/strings.xml b/src/main/res/values-pt/strings.xml
index 1c14e3b..0b57e8b 100644
--- a/src/main/res/values-pt/strings.xml
+++ b/src/main/res/values-pt/strings.xml
@@ -1439,6 +1439,10 @@
     <string name="translation_do_not_ask_again">Permitir sempre o recurso ao Google Tradutor</string>
     <string name="translate_choose_language">Traduzir para…</string>
     <string name="translate_more_languages">Mais…</string>
+    <string name="ephemeral_upload_fallback_title">Enviar sem eliminação automática?</string>
+    <string name="ephemeral_upload_fallback_explained">O servidor deste contacto não suporta anexos em mensagens efémeras. O ficheiro será carregado normalmente e não será eliminado automaticamente.</string>
+    <string name="ephemeral_upload_fallback_allow">Enviar mesmo assim</string>
+    <string name="ephemeral_upload_always_allow">Enviar sempre sem perguntar</string>
     <string name="story_caption_hint">Adicionar uma legenda…</string>
     <string name="story_post_button">Publicar</string>
 </resources>
diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml
index ebffc34..97d0304 100644
--- a/src/main/res/values-ro-rRO/strings.xml
+++ b/src/main/res/values-ro-rRO/strings.xml
@@ -1450,6 +1450,10 @@
     <string name="translation_do_not_ask_again">Permite întotdeauna revenirea la Google Traducere</string>
     <string name="translate_choose_language">Traduceți în…</string>
     <string name="translate_more_languages">Mai mult…</string>
+    <string name="ephemeral_upload_fallback_title">Trimiteți fără ștergere automată?</string>
+    <string name="ephemeral_upload_fallback_explained">Serverul acestui contact nu acceptă atașamente în mesajele efemere. Fișierul va fi încărcat normal și nu va fi șters automat.</string>
+    <string name="ephemeral_upload_fallback_allow">Trimite oricum</string>
+    <string name="ephemeral_upload_always_allow">Trimite întotdeauna fără a întreba</string>
     <string name="story_caption_hint">Adaugă o legendă…</string>
     <string name="story_post_button">Publică</string>
 </resources>
diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml
index e7bd972..64f9894 100644
--- a/src/main/res/values-ru/strings.xml
+++ b/src/main/res/values-ru/strings.xml
@@ -1485,6 +1485,10 @@
     <string name="translation_do_not_ask_again">Всегда разрешать резервный Google Переводчик</string>
     <string name="translate_choose_language">Перевести на…</string>
     <string name="translate_more_languages">Ещё…</string>
+    <string name="ephemeral_upload_fallback_title">Отправить без автоудаления?</string>
+    <string name="ephemeral_upload_fallback_explained">Сервер этого контакта не поддерживает вложения в исчезающих сообщениях. Файл будет загружен обычным способом и не будет удалён автоматически.</string>
+    <string name="ephemeral_upload_fallback_allow">Всё равно отправить</string>
+    <string name="ephemeral_upload_always_allow">Всегда отправлять без вопроса</string>
     <string name="story_caption_hint">Добавить подпись…</string>
     <string name="story_post_button">Опубликовать</string>
 </resources>
diff --git a/src/main/res/values-sr/strings.xml b/src/main/res/values-sr/strings.xml
index 42ce8c1..15f94a2 100644
--- a/src/main/res/values-sr/strings.xml
+++ b/src/main/res/values-sr/strings.xml
@@ -1467,6 +1467,10 @@
     <string name="translation_do_not_ask_again">Увек дозволи резервни Google преводилац</string>
     <string name="translate_choose_language">Преведи на…</string>
     <string name="translate_more_languages">Више…</string>
+    <string name="ephemeral_upload_fallback_title">Послати без аутоматског брисања?</string>
+    <string name="ephemeral_upload_fallback_explained">Сервер овог контакта не подржава прилоге у нестајућим порукама. Датотека ће бити отпремљена на уобичајен начин и неће бити аутоматски обрисана.</string>
+    <string name="ephemeral_upload_fallback_allow">Ипак пошаљи</string>
+    <string name="ephemeral_upload_always_allow">Увек пошаљи без питања</string>
     <string name="story_caption_hint">Dodaj natpis…</string>
     <string name="story_post_button">Objavi</string>
 </resources>
diff --git a/src/main/res/values-sv/strings.xml b/src/main/res/values-sv/strings.xml
index 91cf82a..b1f3a8a 100644
--- a/src/main/res/values-sv/strings.xml
+++ b/src/main/res/values-sv/strings.xml
@@ -1443,6 +1443,10 @@
     <string name="translation_do_not_ask_again">Tillåt alltid reserv till Google Translate</string>
     <string name="translate_choose_language">Översätt till…</string>
     <string name="translate_more_languages">Mer…</string>
+    <string name="ephemeral_upload_fallback_title">Skicka utan automatisk radering?</string>
+    <string name="ephemeral_upload_fallback_explained">Den här kontaktens server stöder inte bilagor i självförstörande meddelanden. Filen laddas upp som vanligt och raderas inte automatiskt.</string>
+    <string name="ephemeral_upload_fallback_allow">Skicka ändå</string>
+    <string name="ephemeral_upload_always_allow">Skicka alltid utan att fråga</string>
     <string name="story_caption_hint">Lägg till en bildtext…</string>
     <string name="story_post_button">Publicera</string>
 </resources>
diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml
index 40b62f7..4a64c3d 100644
--- a/src/main/res/values-zh-rCN/strings.xml
+++ b/src/main/res/values-zh-rCN/strings.xml
@@ -1403,6 +1403,10 @@
     <string name="translation_do_not_ask_again">始终允许回退到 Google 翻译</string>
     <string name="translate_choose_language">翻译为…</string>
     <string name="translate_more_languages">更多…</string>
+    <string name="ephemeral_upload_fallback_title">在没有自动删除的情况下发送?</string>
+    <string name="ephemeral_upload_fallback_explained">此联系人的服务器不支持阅后即焚消息中的附件。文件将正常上传,且不会自动删除。</string>
+    <string name="ephemeral_upload_fallback_allow">仍然发送</string>
+    <string name="ephemeral_upload_always_allow">始终发送且不再询问</string>
     <string name="story_caption_hint">添加说明文字…</string>
     <string name="story_post_button">发布</string>
 </resources>
diff --git a/src/main/res/values-zh-rTW/strings.xml b/src/main/res/values-zh-rTW/strings.xml
index a40d2c8..a09cc3a 100644
--- a/src/main/res/values-zh-rTW/strings.xml
+++ b/src/main/res/values-zh-rTW/strings.xml
@@ -1413,6 +1413,10 @@
     <string name="translation_do_not_ask_again">永遠允許回退至 Google 翻譯</string>
     <string name="translate_choose_language">翻譯為…</string>
     <string name="translate_more_languages">更多…</string>
+    <string name="ephemeral_upload_fallback_title">要在沒有自動刪除的情況下傳送嗎?</string>
+    <string name="ephemeral_upload_fallback_explained">此聯絡人的伺服器不支援閱後即焚訊息中的附件。檔案將正常上傳,且不會自動刪除。</string>
+    <string name="ephemeral_upload_fallback_allow">仍要傳送</string>
+    <string name="ephemeral_upload_always_allow">永遠傳送且不再詢問</string>
     <string name="story_caption_hint">新增說明文字…</string>
     <string name="story_post_button">發佈</string>
 </resources>
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 5e4cab0..2fec653 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -1510,6 +1510,10 @@
     <string name="translation_do_not_ask_again">Always allow Google Translate fallback</string>
     <string name="translate_choose_language">Translate to…</string>
     <string name="translate_more_languages">More…</string>
+    <string name="ephemeral_upload_fallback_title">Send without auto-delete?</string>
+    <string name="ephemeral_upload_fallback_explained">This contact\'s server doesn\'t support disappearing-message attachments. The file will be uploaded normally and will not delete automatically.</string>
+    <string name="ephemeral_upload_fallback_allow">Send anyway</string>
+    <string name="ephemeral_upload_always_allow">Always send without asking</string>
     <string name="story_caption_hint">Add a caption…</string>
     <string name="story_post_button">Post</string>
     <string name="share_to_story_label">JabJab Stories</string>

Built with passion for open-source software, XMPP, privacy, and security —
the belief that people deserve communication tools that serve them, not surveil them.

Dedicated to every brave man and woman who stands up against tyranny and oppression across the world.
And in memory of those who were silenced before they could speak freely.