diff --git a/.maestro/features/03-compose-send.yaml b/.maestro/features/03-compose-send.yaml index b115bd5a7..2b3ac3b38 100644 --- a/.maestro/features/03-compose-send.yaml +++ b/.maestro/features/03-compose-send.yaml @@ -9,7 +9,8 @@ tags: - evalScript: ${output.subject = 'E2E compose ' + DEVICE + '-' + APPEARANCE + '-' + ORIENTATION + ' ' + Date.now()} - tapOn: "Compose" - extendedWaitUntil: - visible: "New Message" + visible: + id: "compose-header" timeout: 15000 - tapOn: "Recipient email addresses" - inputText: "userb@example.org" @@ -28,13 +29,13 @@ tags: # The attach sheet offers its options one by one (it used to be a single # accessibility element, and picking one opened no picker on iOS). - tapOn: "Attach" +# iOS keeps "Photos & Videos"; Android names the same row "Gallery". - extendedWaitUntil: visible: "Photos & Videos" timeout: 10000 - assertVisible: "Camera" -# A server with Files offers "Upload from this device" and "Attach from -# Files" instead of a plain "Files". -- assertVisible: "Upload from this device|Files" +# The phone's own files; a server with Files adds "Bulwark Files" below. +- assertVisible: "This device" - takeScreenshot: compose-02-attach-sheet - evalScript: ${output.pickPhoto = ORIENTATION != 'landscape'} # The system photo picker runs in another process: XCTest sees none of its @@ -52,7 +53,8 @@ tags: commands: - tapOn: "Photos & Videos" - extendedWaitUntil: - notVisible: "Draft saved|New Message" + notVisible: + id: "compose-header" timeout: 10000 optional: true - waitForAnimationToEnd: @@ -79,7 +81,8 @@ tags: - tapOn: point: "90%,13%" - extendedWaitUntil: - visible: "New Message" + visible: + id: "compose-header" timeout: 20000 - waitForAnimationToEnd: timeout: 5000 diff --git a/.maestro/features/08-scheduled-send.yaml b/.maestro/features/08-scheduled-send.yaml index 777b217ae..de40c2fc0 100644 --- a/.maestro/features/08-scheduled-send.yaml +++ b/.maestro/features/08-scheduled-send.yaml @@ -9,7 +9,8 @@ tags: - evalScript: ${output.subject = 'E2E scheduled ' + DEVICE + '-' + APPEARANCE + '-' + ORIENTATION + ' ' + Date.now()} - tapOn: "Compose" - extendedWaitUntil: - visible: "New Message" + visible: + id: "compose-header" timeout: 15000 - tapOn: "Recipient email addresses" - inputText: "userb@example.org" diff --git a/.maestro/perf/3-compose.yaml b/.maestro/perf/3-compose.yaml index 49651559d..0aa1f871e 100644 --- a/.maestro/perf/3-compose.yaml +++ b/.maestro/perf/3-compose.yaml @@ -9,7 +9,8 @@ name: Perf compose open commands: - tapOn: "Compose" - extendedWaitUntil: - visible: "New Message" + visible: + id: "compose-header" timeout: 20000 - waitForAnimationToEnd: timeout: 3000 diff --git a/locales/rn/ar.json b/locales/rn/ar.json index 77ff076c4..ea271fd99 100644 --- a/locales/rn/ar.json +++ b/locales/rn/ar.json @@ -322,7 +322,10 @@ "signing_out": "جارٍ إزالة جهات الاتصال والتقويمات المتزامنة من هذا الجهاز…" }, "email_composer": { + "attach_bulwark_files": "ملفات Bulwark", "attach_camera": "الكاميرا", + "attach_gallery": "المعرض", + "attach_this_device": "هذا الجهاز", "attachment_reminder_body": "تذكر رسالتك \"{keyword}\" لكن لم يتم إرفاق أي ملف. هل تريد الإرسال على أي حال؟", "attachment_reminder_title": "هل نسيت إرفاق ملف؟", "attachments_too_large_total": "ستتجاوز المرفقات الحد {max} الذي يسمح به هذا الخادم لكل رسالة.", diff --git a/locales/rn/ca.json b/locales/rn/ca.json index 838217699..0345ef70c 100644 --- a/locales/rn/ca.json +++ b/locales/rn/ca.json @@ -322,7 +322,10 @@ "signing_out": "S'estan eliminant d'aquest dispositiu els contactes i calendaris sincronitzats…" }, "email_composer": { + "attach_bulwark_files": "Fitxers de Bulwark", "attach_camera": "Càmera", + "attach_gallery": "Galeria", + "attach_this_device": "Aquest dispositiu", "attachment_reminder_body": "El vostre missatge esmenta «{keyword}», però no hi ha cap fitxer adjunt. Voleu enviar-lo igualment?", "attachment_reminder_title": "Us heu oblidat d'un fitxer adjunt?", "attachments_too_large_total": "Els fitxers adjunts superarien els {max} que aquest servidor permet per missatge.", diff --git a/locales/rn/cs.json b/locales/rn/cs.json index 8438860a9..b7fb06c77 100644 --- a/locales/rn/cs.json +++ b/locales/rn/cs.json @@ -322,7 +322,10 @@ "signing_out": "Odebírání synchronizovaných kontaktů a kalendářů z tohoto zařízení…" }, "email_composer": { + "attach_bulwark_files": "Soubory Bulwark", "attach_camera": "Fotoaparát", + "attach_gallery": "Galerie", + "attach_this_device": "Toto zařízení", "attachment_reminder_body": "Vaše zpráva obsahuje slovo „{keyword}“, ale není k ní připojen žádný soubor. Přesto odeslat?", "attachment_reminder_title": "Nezapomněli jste přílohu?", "attachments_too_large_total": "Přílohy by překročily limit {max}, který tento server povoluje na jednu zprávu.", diff --git a/locales/rn/da.json b/locales/rn/da.json index 32aab6412..78cd880b6 100644 --- a/locales/rn/da.json +++ b/locales/rn/da.json @@ -322,7 +322,10 @@ "signing_out": "Fjerner synkroniserede kontakter og kalendere fra denne enhed…" }, "email_composer": { + "attach_bulwark_files": "Bulwark-filer", "attach_camera": "Kamera", + "attach_gallery": "Galleri", + "attach_this_device": "Denne enhed", "attachment_reminder_body": "Din besked nævner \"{keyword}\", men ingen fil er vedhæftet. Send alligevel?", "attachment_reminder_title": "Glemt en vedhæftning?", "attachments_too_large_total": "Vedhæftningerne ville overskride de {max}, som denne server tillader pr. besked.", diff --git a/locales/rn/de.json b/locales/rn/de.json index a8cf809f2..331b5fe4d 100644 --- a/locales/rn/de.json +++ b/locales/rn/de.json @@ -325,7 +325,10 @@ "signing_out": "Synchronisierte Kontakte und Kalender werden von diesem Gerät entfernt…" }, "email_composer": { + "attach_bulwark_files": "Bulwark-Dateien", "attach_camera": "Kamera", + "attach_gallery": "Galerie", + "attach_this_device": "Dieses Gerät", "attachment_reminder_body": "Ihre Nachricht erwähnt \"{keyword}\", aber es ist keine Datei angehängt. Trotzdem senden?", "attachment_reminder_title": "Anhang vergessen?", "attachments_too_large_total": "Die Anhänge würden die {max} überschreiten, die dieser Server pro Nachricht erlaubt.", diff --git a/locales/rn/en.json b/locales/rn/en.json index 41171eb30..19d81d349 100644 --- a/locales/rn/en.json +++ b/locales/rn/en.json @@ -348,7 +348,10 @@ "signing_out": "Removing synced contacts and calendars from this device…" }, "email_composer": { + "attach_bulwark_files": "Bulwark Files", "attach_camera": "Camera", + "attach_gallery": "Gallery", + "attach_this_device": "This device", "attachment_reminder_body": "Your message mentions \"{keyword}\" but no file is attached. Send anyway?", "attachment_reminder_title": "Forgot an attachment?", "attachments_too_large_total": "The attachments would exceed the {max} this server allows per message.", diff --git a/locales/rn/es.json b/locales/rn/es.json index 99a48255f..f2012348e 100644 --- a/locales/rn/es.json +++ b/locales/rn/es.json @@ -322,7 +322,10 @@ "signing_out": "Quitando de este dispositivo los contactos y calendarios sincronizados…" }, "email_composer": { + "attach_bulwark_files": "Archivos de Bulwark", "attach_camera": "Cámara", + "attach_gallery": "Galería", + "attach_this_device": "Este dispositivo", "attachment_reminder_body": "Tu mensaje menciona \"{keyword}\" pero no hay ningún archivo adjunto. ¿Enviar de todos modos?", "attachment_reminder_title": "¿Olvidaste un adjunto?", "attachments_too_large_total": "Los adjuntos superarían los {max} que este servidor permite por mensaje.", diff --git a/locales/rn/et.json b/locales/rn/et.json index ff57ca097..74adaa627 100644 --- a/locales/rn/et.json +++ b/locales/rn/et.json @@ -1194,7 +1194,10 @@ "signing_out": "Sünkroonitud kontaktide ja kalendrite eemaldamine sellest seadmest…" }, "email_composer": { + "attach_bulwark_files": "Bulwarki failid", "attach_camera": "Kaamera", + "attach_gallery": "Galerii", + "attach_this_device": "See seade", "attachment_reminder_body": "Sinu sõnumis mainitakse \"{keyword}\", kuid ühtegi faili pole lisatud. Kas saata ikkagi?", "attachment_reminder_title": "Kas manus ununes?", "attachments_too_large_total": "Manused ületaksid selle serveri lubatud piiri {max} kirja kohta.", diff --git a/locales/rn/fa.json b/locales/rn/fa.json index bdb944504..7c9281f31 100644 --- a/locales/rn/fa.json +++ b/locales/rn/fa.json @@ -322,7 +322,10 @@ "signing_out": "در حال حذف مخاطبین و تقویم‌های همگام‌سازی‌شده از این دستگاه…" }, "email_composer": { + "attach_bulwark_files": "فایل‌های Bulwark", "attach_camera": "دوربین", + "attach_gallery": "گالری", + "attach_this_device": "این دستگاه", "attachment_reminder_body": "در پیام شما به «{keyword}» اشاره شده اما فایلی پیوست نشده است. با این حال ارسال شود؟", "attachment_reminder_title": "پیوست را فراموش کرده‌اید؟", "attachments_too_large_total": "پیوست‌ها از سقف {max} که این سرور برای هر پیام مجاز می‌داند بیشتر می‌شوند.", diff --git a/locales/rn/fr.json b/locales/rn/fr.json index b56e1d874..92c605f08 100644 --- a/locales/rn/fr.json +++ b/locales/rn/fr.json @@ -322,7 +322,10 @@ "signing_out": "Suppression des contacts et calendriers synchronisés de cet appareil…" }, "email_composer": { + "attach_bulwark_files": "Fichiers Bulwark", "attach_camera": "Appareil photo", + "attach_gallery": "Galerie", + "attach_this_device": "Cet appareil", "attachment_reminder_body": "Votre message mentionne « {keyword} » mais aucun fichier n'est joint. Envoyer quand même ?", "attachment_reminder_title": "Pièce jointe oubliée ?", "attachments_too_large_total": "Les pièces jointes dépasseraient les {max} autorisés par ce serveur pour un message.", diff --git a/locales/rn/he.json b/locales/rn/he.json index 0a78c29e6..7bacfd9ba 100644 --- a/locales/rn/he.json +++ b/locales/rn/he.json @@ -322,7 +322,10 @@ "signing_out": "מסיר מהמכשיר הזה את אנשי הקשר ולוחות השנה המסונכרנים…" }, "email_composer": { + "attach_bulwark_files": "קבצי Bulwark", "attach_camera": "מצלמה", + "attach_gallery": "גלריה", + "attach_this_device": "מכשיר זה", "attachment_reminder_body": "ההודעה שלך מזכירה \"{keyword}\" אבל לא צורף קובץ. לשלוח בכל זאת?", "attachment_reminder_title": "שכחת קובץ מצורף?", "attachments_too_large_total": "הקבצים המצורפים יחרגו מהמגבלה של {max} להודעה שהשרת הזה מאפשר.", diff --git a/locales/rn/hu.json b/locales/rn/hu.json index 85ba2eab8..84cbe31ae 100644 --- a/locales/rn/hu.json +++ b/locales/rn/hu.json @@ -322,7 +322,10 @@ "signing_out": "A szinkronizált névjegyek és naptárak eltávolítása erről az eszközről…" }, "email_composer": { + "attach_bulwark_files": "Bulwark-fájlok", "attach_camera": "Kamera", + "attach_gallery": "Galéria", + "attach_this_device": "Ez az eszköz", "attachment_reminder_body": "Az üzeneted említi a(z) „{keyword}” kifejezést, de nincs fájl csatolva. Elküldöd így is?", "attachment_reminder_title": "Elfelejtetted a csatolmányt?", "attachments_too_large_total": "A csatolmányok túllépnék a szerver által üzenetenként engedélyezett méretet ({max}).", diff --git a/locales/rn/it.json b/locales/rn/it.json index ced0f08ea..3943d77b4 100644 --- a/locales/rn/it.json +++ b/locales/rn/it.json @@ -322,7 +322,10 @@ "signing_out": "Rimozione dei contatti e dei calendari sincronizzati da questo dispositivo…" }, "email_composer": { + "attach_bulwark_files": "File di Bulwark", "attach_camera": "Fotocamera", + "attach_gallery": "Galleria", + "attach_this_device": "Questo dispositivo", "attachment_reminder_body": "Il tuo messaggio menziona \"{keyword}\" ma nessun file è allegato. Inviare comunque?", "attachment_reminder_title": "Hai dimenticato un allegato?", "attachments_too_large_total": "Gli allegati supererebbero i {max} consentiti da questo server per messaggio.", diff --git a/locales/rn/ja.json b/locales/rn/ja.json index c707429fa..bdc7932de 100644 --- a/locales/rn/ja.json +++ b/locales/rn/ja.json @@ -322,7 +322,10 @@ "signing_out": "同期した連絡先とカレンダーをこのデバイスから削除しています…" }, "email_composer": { + "attach_bulwark_files": "Bulwark ファイル", "attach_camera": "カメラ", + "attach_gallery": "ギャラリー", + "attach_this_device": "このデバイス", "attachment_reminder_body": "メッセージに「{keyword}」が含まれていますが、ファイルが添付されていません。このまま送信しますか?", "attachment_reminder_title": "添付ファイルを忘れていませんか?", "attachments_too_large_total": "添付ファイルがサーバーの上限(1 通あたり {max})を超えます。", diff --git a/locales/rn/ko.json b/locales/rn/ko.json index e339356ad..07bc4dc18 100644 --- a/locales/rn/ko.json +++ b/locales/rn/ko.json @@ -322,7 +322,10 @@ "signing_out": "동기화된 연락처와 캘린더를 이 기기에서 삭제하는 중…" }, "email_composer": { + "attach_bulwark_files": "Bulwark 파일", "attach_camera": "카메라", + "attach_gallery": "갤러리", + "attach_this_device": "이 기기", "attachment_reminder_body": "메시지에 \"{keyword}\"이(가) 언급되어 있지만 첨부된 파일이 없어요. 그래도 보낼까요?", "attachment_reminder_title": "첨부 파일을 잊으셨나요?", "attachments_too_large_total": "첨부 파일이 이 서버의 메시지당 한도({max})를 넘어요.", diff --git a/locales/rn/lv.json b/locales/rn/lv.json index bfbab989b..6ff34c1b9 100644 --- a/locales/rn/lv.json +++ b/locales/rn/lv.json @@ -322,7 +322,10 @@ "signing_out": "Sinhronizētie kontakti un kalendāri tiek noņemti no šīs ierīces…" }, "email_composer": { + "attach_bulwark_files": "Bulwark faili", "attach_camera": "Kamera", + "attach_gallery": "Galerija", + "attach_this_device": "Šī ierīce", "attachment_reminder_body": "Jūsu ziņojumā minēts \"{keyword}\", bet nav pievienots neviens fails. Vai tomēr sūtīt?", "attachment_reminder_title": "Aizmirsāt pielikumu?", "attachments_too_large_total": "Pielikumi pārsniegtu {max}, ko šis serveris atļauj vienam ziņojumam.", diff --git a/locales/rn/mn.json b/locales/rn/mn.json index 545763ec6..1de055967 100644 --- a/locales/rn/mn.json +++ b/locales/rn/mn.json @@ -322,7 +322,10 @@ "signing_out": "Синк хийсэн харилцагчид болон хуанлиудыг энэ төхөөрөмжөөс устгаж байна…" }, "email_composer": { + "attach_bulwark_files": "Bulwark файл", "attach_camera": "Камер", + "attach_gallery": "Галерей", + "attach_this_device": "Энэ төхөөрөмж", "attachment_reminder_body": "Таны имэйлд \"{keyword}\" гэж дурдсан ч файл хавсаргаагүй байна. Ямар ч байсан илгээх үү?", "attachment_reminder_title": "Хавсралтаа мартсан уу?", "attachments_too_large_total": "Хавсралтууд энэ серверийн нэг имэйлд зөвшөөрөх {max} хэмжээнээс хэтэрнэ.", diff --git a/locales/rn/nb.json b/locales/rn/nb.json index f577863ec..d8ac49c35 100644 --- a/locales/rn/nb.json +++ b/locales/rn/nb.json @@ -322,7 +322,10 @@ "signing_out": "Fjerner synkroniserte kontakter og kalendere fra denne enheten…" }, "email_composer": { + "attach_bulwark_files": "Bulwark-filer", "attach_camera": "Kamera", + "attach_gallery": "Galleri", + "attach_this_device": "Denne enheten", "attachment_reminder_body": "Meldingen din nevner «{keyword}», men ingen fil er vedlagt. Sende likevel?", "attachment_reminder_title": "Glemt et vedlegg?", "attachments_too_large_total": "Vedleggene ville overskride grensen på {max} per melding som denne serveren tillater.", diff --git a/locales/rn/nl.json b/locales/rn/nl.json index 0305eeb25..6feffbdbf 100644 --- a/locales/rn/nl.json +++ b/locales/rn/nl.json @@ -322,7 +322,10 @@ "signing_out": "Gesynchroniseerde contacten en agenda's worden van dit apparaat verwijderd…" }, "email_composer": { + "attach_bulwark_files": "Bulwark-bestanden", "attach_camera": "Camera", + "attach_gallery": "Galerij", + "attach_this_device": "Dit apparaat", "attachment_reminder_body": "Uw bericht vermeldt \"{keyword}\" maar er is geen bestand bijgevoegd. Toch verzenden?", "attachment_reminder_title": "Bijlage vergeten?", "attachments_too_large_total": "De bijlagen zouden de {max} overschrijden die deze server per bericht toestaat.", diff --git a/locales/rn/pl.json b/locales/rn/pl.json index 16974c1b4..b87ceee0f 100644 --- a/locales/rn/pl.json +++ b/locales/rn/pl.json @@ -322,7 +322,10 @@ "signing_out": "Usuwanie zsynchronizowanych kontaktów i kalendarzy z tego urządzenia…" }, "email_composer": { + "attach_bulwark_files": "Pliki Bulwark", "attach_camera": "Aparat", + "attach_gallery": "Galeria", + "attach_this_device": "To urządzenie", "attachment_reminder_body": "Twoja wiadomość wspomina o „{keyword}”, ale nie załączono żadnego pliku. Wysłać mimo to?", "attachment_reminder_title": "Zapomniano o załączniku?", "attachments_too_large_total": "Załączniki przekroczyłyby limit {max} na wiadomość obowiązujący na tym serwerze.", diff --git a/locales/rn/pt.json b/locales/rn/pt.json index a8ddcbfea..74decdc26 100644 --- a/locales/rn/pt.json +++ b/locales/rn/pt.json @@ -322,7 +322,10 @@ "signing_out": "Removendo contatos e calendários sincronizados deste dispositivo…" }, "email_composer": { + "attach_bulwark_files": "Arquivos do Bulwark", "attach_camera": "Câmera", + "attach_gallery": "Galeria", + "attach_this_device": "Este dispositivo", "attachment_reminder_body": "Sua mensagem menciona \"{keyword}\", mas nenhum arquivo está anexado. Enviar mesmo assim?", "attachment_reminder_title": "Esqueceu um anexo?", "attachments_too_large_total": "Os anexos excederiam o limite de {max} por mensagem permitido por este servidor.", diff --git a/locales/rn/ro.json b/locales/rn/ro.json index b950ba299..c6ca1dda5 100644 --- a/locales/rn/ro.json +++ b/locales/rn/ro.json @@ -322,7 +322,10 @@ "signing_out": "Se elimină de pe acest dispozitiv contactele și calendarele sincronizate…" }, "email_composer": { + "attach_bulwark_files": "Fișiere Bulwark", "attach_camera": "Cameră", + "attach_gallery": "Galerie", + "attach_this_device": "Acest dispozitiv", "attachment_reminder_body": "Mesajul dvs. menționează „{keyword}”, dar nu este atașat niciun fișier. Doriți să trimiteți oricum?", "attachment_reminder_title": "Ați uitat un atașament?", "attachments_too_large_total": "Atașamentele ar depăși limita de {max} per mesaj permisă de acest server.", diff --git a/locales/rn/ru.json b/locales/rn/ru.json index ef07729ba..e89bc7828 100644 --- a/locales/rn/ru.json +++ b/locales/rn/ru.json @@ -322,7 +322,10 @@ "signing_out": "Удаление синхронизированных контактов и календарей с этого устройства…" }, "email_composer": { + "attach_bulwark_files": "Файлы Bulwark", "attach_camera": "Камера", + "attach_gallery": "Галерея", + "attach_this_device": "Это устройство", "attachment_reminder_body": "В письме упоминается «{keyword}», но файл не прикреплён. Всё равно отправить?", "attachment_reminder_title": "Забыли вложение?", "attachments_too_large_total": "Вложения превысят лимит {max} на одно письмо, установленный этим сервером.", diff --git a/locales/rn/sk.json b/locales/rn/sk.json index 0a28af946..5721d7821 100644 --- a/locales/rn/sk.json +++ b/locales/rn/sk.json @@ -322,7 +322,10 @@ "signing_out": "Odstraňujú sa synchronizované kontakty a kalendáre z tohto zariadenia…" }, "email_composer": { + "attach_bulwark_files": "Súbory Bulwark", "attach_camera": "Fotoaparát", + "attach_gallery": "Galéria", + "attach_this_device": "Toto zariadenie", "attachment_reminder_body": "Vaša správa spomína „{keyword}“, ale nie je priložený žiadny súbor. Odoslať aj tak?", "attachment_reminder_title": "Nezabudli ste prílohu?", "attachments_too_large_total": "Prílohy by prekročili limit {max}, ktorý tento server povoľuje na jednu správu.", diff --git a/locales/rn/th.json b/locales/rn/th.json index 30edd6db5..740b82b16 100644 --- a/locales/rn/th.json +++ b/locales/rn/th.json @@ -324,7 +324,10 @@ "signing_out": "กำลังนำผู้ติดต่อและปฏิทินที่ซิงค์ไว้ออกจากอุปกรณ์นี้…" }, "email_composer": { + "attach_bulwark_files": "ไฟล์ Bulwark", "attach_camera": "กล้อง", + "attach_gallery": "แกลเลอรี", + "attach_this_device": "อุปกรณ์นี้", "attachment_reminder_body": "ข้อความของคุณมีคำว่า “{keyword}” แต่ไม่มีไฟล์แนบ ต้องการส่งต่อไปหรือไม่?", "attachment_reminder_title": "ลืมแนบไฟล์หรือไม่?", "attachments_too_large_total": "ไฟล์แนบจะเกิน {max} ที่เซิร์ฟเวอร์นี้อนุญาตต่อข้อความ", diff --git a/locales/rn/tr.json b/locales/rn/tr.json index 9430954a6..d820da0ab 100644 --- a/locales/rn/tr.json +++ b/locales/rn/tr.json @@ -322,7 +322,10 @@ "signing_out": "Senkronize edilen kişiler ve takvimler bu cihazdan kaldırılıyor…" }, "email_composer": { + "attach_bulwark_files": "Bulwark Dosyaları", "attach_camera": "Kamera", + "attach_gallery": "Galeri", + "attach_this_device": "Bu cihaz", "attachment_reminder_body": "İletinizde \"{keyword}\" geçiyor ancak hiçbir dosya eklenmemiş. Yine de gönderilsin mi?", "attachment_reminder_title": "Ek eklemeyi mi unuttunuz?", "attachments_too_large_total": "Ekler, bu sunucunun ileti başına izin verdiği {max} sınırını aşacak.", diff --git a/locales/rn/uk.json b/locales/rn/uk.json index 215ec54b1..d8000800d 100644 --- a/locales/rn/uk.json +++ b/locales/rn/uk.json @@ -322,7 +322,10 @@ "signing_out": "Видалення синхронізованих контактів і календарів із цього пристрою…" }, "email_composer": { + "attach_bulwark_files": "Файли Bulwark", "attach_camera": "Камера", + "attach_gallery": "Галерея", + "attach_this_device": "Цей пристрій", "attachment_reminder_body": "У листі згадано «{keyword}», але файл не вкладено. Усе одно надіслати?", "attachment_reminder_title": "Забули вкладення?", "attachments_too_large_total": "Вкладення перевищать ліміт {max} на один лист, встановлений цим сервером.", diff --git a/locales/rn/zh-TW.json b/locales/rn/zh-TW.json index cb2cee9fc..d6eca7163 100644 --- a/locales/rn/zh-TW.json +++ b/locales/rn/zh-TW.json @@ -322,7 +322,10 @@ "signing_out": "正在從此裝置移除已同步的聯絡人和行事曆…" }, "email_composer": { + "attach_bulwark_files": "Bulwark 檔案", "attach_camera": "相機", + "attach_gallery": "圖庫", + "attach_this_device": "此裝置", "attachment_reminder_body": "您的郵件提到「{keyword}」,但沒有附加檔案。仍要傳送嗎?", "attachment_reminder_title": "忘記新增附件了嗎?", "attachments_too_large_total": "附件將超過此伺服器每封郵件 {max} 的上限。", diff --git a/locales/rn/zh.json b/locales/rn/zh.json index cfa66f457..cd297db7e 100644 --- a/locales/rn/zh.json +++ b/locales/rn/zh.json @@ -322,7 +322,10 @@ "signing_out": "正在从此设备移除已同步的联系人和日历…" }, "email_composer": { + "attach_bulwark_files": "Bulwark 文件", "attach_camera": "相机", + "attach_gallery": "图库", + "attach_this_device": "此设备", "attachment_reminder_body": "您的邮件中提到了“{keyword}”,但未附加任何文件。仍然发送吗?", "attachment_reminder_title": "忘记添加附件了吗?", "attachments_too_large_total": "附件将超过此服务器每封邮件 {max} 的上限。", diff --git a/src/lib/__tests__/compose-send-queue-wiring.test.ts b/src/lib/__tests__/compose-send-queue-wiring.test.ts index bf2f126e1..f9eeb8b57 100644 --- a/src/lib/__tests__/compose-send-queue-wiring.test.ts +++ b/src/lib/__tests__/compose-send-queue-wiring.test.ts @@ -8,7 +8,7 @@ const compose = fs.readFileSync(path.resolve(__dirname, '../../screens/ComposeSc const banner = fs.readFileSync(path.resolve(__dirname, '../../components/OfflineBanner.tsx'), 'utf8'); describe('ComposeScreen offline send', () => { - const send = compose.slice(compose.indexOf('const performSendInner'), compose.indexOf('const titleKey')); + const send = compose.slice(compose.indexOf('const performSendInner'), compose.indexOf('const headerTitle')); it('queues the message instead of trying while offline', () => { const offline = send.indexOf('if (!useNetworkStore.getState().online && queueForLater(outgoing, false)) return;'); diff --git a/src/screens/ComposeScreen.tsx b/src/screens/ComposeScreen.tsx index bfd65d20b..995905cf3 100644 --- a/src/screens/ComposeScreen.tsx +++ b/src/screens/ComposeScreen.tsx @@ -11,7 +11,7 @@ import { List, ListOrdered, Link2, Link2Off, Image as ImageIcon, Quote, Heading1, Heading2, AlignLeft, AlignCenter, AlignRight, RemoveFormatting, Undo2, Redo2, FileText, Clock, Check, Palette, Table, LayoutTemplate, MailCheck, - Tag, Type, Highlighter, Trash2, Settings, + Tag, Type, Highlighter, Trash2, Settings, Camera, Smartphone, FolderOpen, } from '../components/icons'; import DateTimePicker, { type DateTimePickerEvent } from '@react-native-community/datetimepicker'; import * as ImagePicker from 'expo-image-picker'; @@ -323,6 +323,7 @@ function ToolbarButton({ interface SheetOption { label: string; + icon?: React.ReactNode; destructive?: boolean; onPress: () => void; } @@ -360,6 +361,7 @@ function OptionsSheet({ style={styles.scheduleRow} onPress={() => { onClose(); afterDismiss.run(opt.onPress); }} > + {opt.icon} {opt.label} ))} @@ -2149,17 +2151,21 @@ export default function ComposeScreen({ route, navigation }: Props) { const [filesPickerOpen, setFilesPickerOpen] = React.useState(false); const hasServerFiles = supportsFiles(); const attachOptions: SheetOption[] = [ - { label: t('email_composer.attach_photos', 'Photos & Videos'), onPress: () => { void pickPhotoAttachments(); } }, - { label: t('email_composer.attach_camera', 'Camera'), onPress: () => { void takePhotoAttachment(); } }, { - // Next to "Attach from Files" a plain "Files" would read as the same. - label: hasServerFiles - ? t('email_composer.attach_from_device', 'Upload from this device') - : t('email_composer.attach_files', 'Files'), - onPress: () => { void pickFileAttachments(); }, + // iOS calls its library Photos; "Gallery" is the Android word. + label: Platform.OS === 'ios' + ? t('email_composer.attach_photos', 'Photos & Videos') + : t('email_composer.attach_gallery', 'Gallery'), + icon: , + onPress: () => { void pickPhotoAttachments(); }, }, + { label: t('email_composer.attach_camera', 'Camera'), icon: , onPress: () => { void takePhotoAttachment(); } }, + // "This device" and "Bulwark Files" keep the phone's files and the + // server's Files apart. + { label: t('email_composer.attach_this_device', 'This device'), icon: , onPress: () => { void pickFileAttachments(); } }, ...(hasServerFiles ? [{ - label: t('email_composer.attach_from_files', 'Attach from Files'), + label: t('email_composer.attach_bulwark_files', 'Bulwark Files'), + icon: , onPress: () => { if (!refuseAttachAfterSwitch()) setFilesPickerOpen(true); }, }] : []), ]; @@ -2944,11 +2950,12 @@ export default function ComposeScreen({ route, navigation }: Props) { } }; - const titleKey = - mode === 'forward' ? 'email_composer.forward' - : mode === 'replyAll' ? 'email_composer.reply_all' - : replyTo ? 'email_composer.reply' - : 'email_composer.new_message'; + // A new message has no title: the empty fields already say what it is. + const headerTitle = + mode === 'forward' ? t('email_composer.forward', 'Forward') + : mode === 'replyAll' ? t('email_composer.reply_all', 'Reply All') + : replyTo ? t('email_composer.reply', 'Reply') + : ''; const fromDisplay = React.useMemo(() => { if (!primaryIdentity) return identityError ? t('email_composer.identity_unavailable', 'Identity unavailable') : t('common.loading', 'Loading...'); @@ -3118,7 +3125,8 @@ export default function ComposeScreen({ route, navigation }: Props) { const composer = ( - + {/* The Maestro flows wait for this id: a new message has no title to wait for. */} + {savingDraft ? : } - - - {t(titleKey, mode === 'forward' ? 'Forward' : mode === 'replyAll' ? 'Reply All' : replyTo ? 'Reply' : 'New Message')} - + + {!!headerTitle && {headerTitle}} {!!draftStatusText && !typingInShortWindow && ( {draftStatusText} )} @@ -3959,6 +3975,7 @@ function makeStyles(c: ThemePalette) { borderRadius: radius.full, }, headerTitleWrap: { flex: 1, minWidth: 0 }, + headerTitleWrapUntitled: { alignSelf: 'stretch', justifyContent: 'center' }, headerTitle: { ...typography.h3, color: c.text }, headerSubtitle: { ...typography.caption, color: c.textMuted, marginTop: -2 }, headerRight: { flexDirection: 'row', alignItems: 'center', gap: spacing.sm },