From fabd8c830c843cb47068f64e06cf94ea4f577ace Mon Sep 17 00:00:00 2001 From: phantomptr Date: Sat, 10 Oct 2026 23:11:17 -0700 Subject: [PATCH] Upload: one blue button, the next step (#439) - The confirm's "Start upload" was a grey card with a faint outline while Resume was filled; it is filled again, and the three choices share one shape (Override stays plain: with files there it is the risky one). - "Cancel" before anything started only cleared the source: it says "Change source" now. - "Build the image, then upload it" was a second filled button next to Upload; it is plain, the alternative path. - Add to queue is filled while the queue runs (Upload is disabled then), and Retry is filled after a failed upload or destination check. 7.0.2-7.0.4 were never published; the changelog ships it all as 7.0.5. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9 --- CHANGELOG.md | 7 ++- client/src/i18n/locales/ar.ts | 2 +- client/src/i18n/locales/bn.ts | 2 +- client/src/i18n/locales/de.ts | 2 +- client/src/i18n/locales/en.ts | 2 +- client/src/i18n/locales/es.ts | 2 +- client/src/i18n/locales/fa.ts | 2 +- client/src/i18n/locales/fr.ts | 2 +- client/src/i18n/locales/hi.ts | 2 +- client/src/i18n/locales/hu.ts | 2 +- client/src/i18n/locales/id.ts | 2 +- client/src/i18n/locales/it.ts | 2 +- client/src/i18n/locales/ja.ts | 2 +- client/src/i18n/locales/ko.ts | 2 +- client/src/i18n/locales/pl.ts | 2 +- client/src/i18n/locales/pt-BR.ts | 2 +- client/src/i18n/locales/ru.ts | 2 +- client/src/i18n/locales/th.ts | 2 +- client/src/i18n/locales/tr.ts | 2 +- client/src/i18n/locales/vi.ts | 2 +- client/src/i18n/locales/zh-CN.ts | 2 +- client/src/i18n/locales/zh-TW.ts | 2 +- client/src/screens/Upload/SendAsImageCard.tsx | 3 +- client/src/screens/Upload/index.tsx | 43 ++++++++++++------- 24 files changed, 56 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66626dc5..1d23e4d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ What's new in ps5upload, written for humans. --- -## 7.0.4 +## 7.0.5 - **OLED theme is back, and there's a new Peach theme.** OLED is dark on pure black, so an OLED screen's pixels stay off; Peach is a warmer light theme with a cream window and a burnt-peach @@ -17,6 +17,11 @@ What's new in ps5upload, written for humans. - **7z uploads on 32-bit Android:** archives with more than 4 GiB in one block (most game backups) failed with "dist overflow", and files over 4 GiB inside an archive were cut short. They upload in full now. +- **Upload's buttons say what they do.** The next step is the one blue button: "Start upload" + in the confirm is blue again, Retry is blue after a failure, and Add to queue is blue while + the queue runs (Upload waits then). "Cancel" before an upload has started is now "Change + source", and "Build the image, then upload it" is no longer a second blue button competing + with Upload. - Remote Play names the signed-in account by its slot ("Slot 7"), the same as Profile. - **Upload: the "exfat" destination is a folder, not a conversion.** Its hint is now shown as text (phones have no hover) and says so, and sending a game folder there warns that it will diff --git a/client/src/i18n/locales/ar.ts b/client/src/i18n/locales/ar.ts index 772eed61..7fbc685b 100644 --- a/client/src/i18n/locales/ar.ts +++ b/client/src/i18n/locales/ar.ts @@ -949,7 +949,7 @@ queue_raw_error: "خطأ خام", upload_detected_label: "مكشاف", upload_inspecting: "الفحص", upload_choose_diff_source: "اختيار مصدر مختلف", -upload_cancel: "إلغاء", +upload_change_source: "تغيير المصدر", upload_add_to_queue: "إضافة إلى قائمة الانتظار", upload_dialog_upload_to: "الارسال إلى:", upload_dialog_resume: "استئناف", diff --git a/client/src/i18n/locales/bn.ts b/client/src/i18n/locales/bn.ts index fa7ac396..44905757 100644 --- a/client/src/i18n/locales/bn.ts +++ b/client/src/i18n/locales/bn.ts @@ -963,7 +963,7 @@ smp_blank_delete: "(খালি=মুছুন)", upload_add_to_queue: "সারিতে যোগ করুন", upload_add_to_queue_tooltip: "এই আপলোডটি শুরু না করে সারিতে যোগ করুন", upload_apply_exclude_rules: "বাদ দেওয়ার নিয়ম প্রয়োগ করুন", -upload_cancel: "বাতিল করুন", +upload_change_source: "উৎস পরিবর্তন করুন", upload_choose_diff_source: "একটি ভিন্ন উৎস বেছে নিন", upload_dest_auto: "(ডিফল্ট — /data)", upload_dest_card_title: "গন্তব্য", diff --git a/client/src/i18n/locales/de.ts b/client/src/i18n/locales/de.ts index c5af820c..2e5936fd 100644 --- a/client/src/i18n/locales/de.ts +++ b/client/src/i18n/locales/de.ts @@ -964,7 +964,7 @@ smp_blank_delete: "(leer = löschen)", upload_add_to_queue: "Zur Warteschlange hinzufügen", upload_add_to_queue_tooltip: "Diesen Upload zur Warteschlange hinzufügen, ohne ihn zu starten", upload_apply_exclude_rules: "Ausschlussregeln anwenden", -upload_cancel: "Abbrechen", +upload_change_source: "Quelle ändern", upload_choose_diff_source: "Andere Quelle wählen", upload_dest_auto: "(Standard — /data)", upload_dest_card_title: "Ziel", diff --git a/client/src/i18n/locales/en.ts b/client/src/i18n/locales/en.ts index 75fb18b2..a91b4725 100644 --- a/client/src/i18n/locales/en.ts +++ b/client/src/i18n/locales/en.ts @@ -1749,7 +1749,7 @@ upload_scanning_archive_hint: upload_disabled_scanning: "Scanning game folder — wait for the scan to finish, then this button enables.", upload_choose_diff_source: "Choose a different source", -upload_cancel: "Cancel", +upload_change_source: "Change source", upload_add_to_queue: "Add to queue", upload_now: "Upload", upload_checking: "Checking…", diff --git a/client/src/i18n/locales/es.ts b/client/src/i18n/locales/es.ts index 8f90c28b..b5405c3d 100644 --- a/client/src/i18n/locales/es.ts +++ b/client/src/i18n/locales/es.ts @@ -963,7 +963,7 @@ smp_blank_delete: "(vacío = eliminar)", upload_add_to_queue: "Añadir a la cola", upload_add_to_queue_tooltip: "Añadir esta subida a la cola sin iniciarla", upload_apply_exclude_rules: "Aplicar reglas de exclusión", -upload_cancel: "Cancelar", +upload_change_source: "Cambiar origen", upload_choose_diff_source: "Elegir una fuente diferente", upload_dest_auto: "(predeterminado — /data)", upload_dest_card_title: "Destino", diff --git a/client/src/i18n/locales/fa.ts b/client/src/i18n/locales/fa.ts index a7d4533d..d0c9ca99 100644 --- a/client/src/i18n/locales/fa.ts +++ b/client/src/i18n/locales/fa.ts @@ -1611,7 +1611,7 @@ upload_scanning_archive_hint: upload_disabled_scanning: "در حال اسکن پوشه‌ی بازی — منتظر پایان اسکن بمانید، سپس این دکمه فعال می‌شود.", upload_choose_diff_source: "انتخاب منبع متفاوت", -upload_cancel: "لغو", +upload_change_source: "تغییر منبع", upload_add_to_queue: "افزودن به صف", upload_now: "بارگذاری", upload_checking: "در حال بررسی…", diff --git a/client/src/i18n/locales/fr.ts b/client/src/i18n/locales/fr.ts index 83dad32e..3ef8f906 100644 --- a/client/src/i18n/locales/fr.ts +++ b/client/src/i18n/locales/fr.ts @@ -963,7 +963,7 @@ smp_blank_delete: "(vide = supprimer)", upload_add_to_queue: "Ajouter à la file d'attente", upload_add_to_queue_tooltip: "Ajouter cet envoi à la file d'attente sans le démarrer", upload_apply_exclude_rules: "Appliquer les règles d'exclusion", -upload_cancel: "Annuler", +upload_change_source: "Changer de source", upload_choose_diff_source: "Choisir une autre source", upload_dest_auto: "(par défaut — /data)", upload_dest_card_title: "Destination", diff --git a/client/src/i18n/locales/hi.ts b/client/src/i18n/locales/hi.ts index 594821b1..1f5aea77 100644 --- a/client/src/i18n/locales/hi.ts +++ b/client/src/i18n/locales/hi.ts @@ -964,7 +964,7 @@ smp_blank_delete: "(खाली=हटाएँ)", upload_add_to_queue: "कतार में जोड़ें", upload_add_to_queue_tooltip: "इस अपलोड को शुरू किए बिना कतार में जोड़ें", upload_apply_exclude_rules: "बहिष्करण नियम लागू करें", -upload_cancel: "रद्द करें", +upload_change_source: "स्रोत बदलें", upload_choose_diff_source: "एक अलग स्रोत चुनें", upload_dest_auto: "(डिफ़ॉल्ट — /data)", upload_dest_card_title: "गंतव्य", diff --git a/client/src/i18n/locales/hu.ts b/client/src/i18n/locales/hu.ts index 84aedad2..2ac0d71d 100644 --- a/client/src/i18n/locales/hu.ts +++ b/client/src/i18n/locales/hu.ts @@ -1553,7 +1553,7 @@ upload_scanning_archive_hint: upload_disabled_scanning: "Játékmappa pásztázása — várd meg, amíg a pásztázás befejeződik, utána válik elérhetővé ez a gomb.", upload_choose_diff_source: "Válassz más forrást", -upload_cancel: "Mégse", +upload_change_source: "Forrás módosítása", upload_add_to_queue: "Hozzáadás a várólistához", upload_now: "Feltöltés", upload_checking: "Ellenőrzés…", diff --git a/client/src/i18n/locales/id.ts b/client/src/i18n/locales/id.ts index fa2a1c12..72c1fdb5 100644 --- a/client/src/i18n/locales/id.ts +++ b/client/src/i18n/locales/id.ts @@ -963,7 +963,7 @@ smp_blank_delete: "(kosong=hapus)", upload_add_to_queue: "Tambah ke antrean", upload_add_to_queue_tooltip: "Tambahkan unggahan ini ke antrean tanpa memulainya", upload_apply_exclude_rules: "Terapkan aturan pengecualian", -upload_cancel: "Batal", +upload_change_source: "Ganti sumber", upload_choose_diff_source: "Pilih sumber yang berbeda", upload_dest_auto: "(bawaan — /data)", upload_dest_card_title: "Tujuan", diff --git a/client/src/i18n/locales/it.ts b/client/src/i18n/locales/it.ts index cc052f7d..c517cfe8 100644 --- a/client/src/i18n/locales/it.ts +++ b/client/src/i18n/locales/it.ts @@ -963,7 +963,7 @@ smp_blank_delete: "(vuoto = elimina)", upload_add_to_queue: "Aggiungi alla coda", upload_add_to_queue_tooltip: "Aggiungi questo caricamento alla coda senza avviarlo", upload_apply_exclude_rules: "Applica regole di esclusione", -upload_cancel: "Annulla", +upload_change_source: "Cambia origine", upload_choose_diff_source: "Scegli un'altra origine", upload_dest_auto: "(predefinito — /data)", upload_dest_card_title: "Destinazione", diff --git a/client/src/i18n/locales/ja.ts b/client/src/i18n/locales/ja.ts index e3c8a069..c60311e0 100644 --- a/client/src/i18n/locales/ja.ts +++ b/client/src/i18n/locales/ja.ts @@ -964,7 +964,7 @@ smp_blank_delete: "(空欄=削除)", upload_add_to_queue: "キューに追加", upload_add_to_queue_tooltip: "このアップロードを開始せずにキューに追加します", upload_apply_exclude_rules: "除外ルールを適用", -upload_cancel: "キャンセル", +upload_change_source: "ソースを変更", upload_choose_diff_source: "別のソースを選択", upload_dest_auto: "(既定 — /data)", upload_dest_card_title: "保存先", diff --git a/client/src/i18n/locales/ko.ts b/client/src/i18n/locales/ko.ts index 01a39ea9..0bb030b2 100644 --- a/client/src/i18n/locales/ko.ts +++ b/client/src/i18n/locales/ko.ts @@ -964,7 +964,7 @@ smp_blank_delete: "(공백=삭제)", upload_add_to_queue: "대기열에 추가", upload_add_to_queue_tooltip: "이 업로드를 시작하지 않고 대기열에 추가합니다", upload_apply_exclude_rules: "제외 규칙 적용", -upload_cancel: "취소", +upload_change_source: "소스 변경", upload_choose_diff_source: "다른 소스 선택", upload_dest_auto: "(기본값 — /data)", upload_dest_card_title: "대상", diff --git a/client/src/i18n/locales/pl.ts b/client/src/i18n/locales/pl.ts index a24a9233..a94fda9b 100644 --- a/client/src/i18n/locales/pl.ts +++ b/client/src/i18n/locales/pl.ts @@ -1359,7 +1359,7 @@ upload_scanning_archive_hint: upload_disabled_scanning: "Skanowanie folderu gry — poczekaj na zakończenie skanowania, aby aktywować ten przycisk.", upload_choose_diff_source: "Wybierz inne źródło", -upload_cancel: "Anuluj", +upload_change_source: "Zmień źródło", upload_add_to_queue: "Dodaj do kolejki", upload_now: "Prześlij", upload_checking: "Sprawdzanie…", diff --git a/client/src/i18n/locales/pt-BR.ts b/client/src/i18n/locales/pt-BR.ts index 913f0fba..7b8bb83c 100644 --- a/client/src/i18n/locales/pt-BR.ts +++ b/client/src/i18n/locales/pt-BR.ts @@ -963,7 +963,7 @@ smp_blank_delete: "(em branco=excluir)", upload_add_to_queue: "Adicionar à fila", upload_add_to_queue_tooltip: "Adicionar este envio à fila sem iniciá-lo", upload_apply_exclude_rules: "Aplicar regras de exclusão", -upload_cancel: "Cancelar", +upload_change_source: "Trocar origem", upload_choose_diff_source: "Escolher uma origem diferente", upload_dest_auto: "(padrão — /data)", upload_dest_card_title: "Destino", diff --git a/client/src/i18n/locales/ru.ts b/client/src/i18n/locales/ru.ts index 1f6c223e..9c5b4c9d 100644 --- a/client/src/i18n/locales/ru.ts +++ b/client/src/i18n/locales/ru.ts @@ -963,7 +963,7 @@ smp_blank_delete: "(пусто=удалить)", upload_add_to_queue: "Добавить в очередь", upload_add_to_queue_tooltip: "Добавить эту загрузку в очередь, не запуская её", upload_apply_exclude_rules: "Применить правила исключения", -upload_cancel: "Отмена", +upload_change_source: "Сменить источник", upload_choose_diff_source: "Выбрать другой источник", upload_dest_auto: "(по умолчанию — /data)", upload_dest_card_title: "Назначение", diff --git a/client/src/i18n/locales/th.ts b/client/src/i18n/locales/th.ts index 7b0a45b8..50ab03e9 100644 --- a/client/src/i18n/locales/th.ts +++ b/client/src/i18n/locales/th.ts @@ -963,7 +963,7 @@ smp_blank_delete: "(ว่าง=ลบ)", upload_add_to_queue: "เพิ่มลงในคิว", upload_add_to_queue_tooltip: "เพิ่มการอัปโหลดนี้ลงในคิวโดยไม่เริ่มทันที", upload_apply_exclude_rules: "ใช้กฎการยกเว้น", -upload_cancel: "ยกเลิก", +upload_change_source: "เปลี่ยนต้นทาง", upload_choose_diff_source: "เลือกแหล่งที่มาอื่น", upload_dest_auto: "(ค่าเริ่มต้น — /data)", upload_dest_card_title: "ปลายทาง", diff --git a/client/src/i18n/locales/tr.ts b/client/src/i18n/locales/tr.ts index dac2c9d4..0580c5ce 100644 --- a/client/src/i18n/locales/tr.ts +++ b/client/src/i18n/locales/tr.ts @@ -963,7 +963,7 @@ smp_blank_delete: "(boş=sil)", upload_add_to_queue: "Kuyruğa ekle", upload_add_to_queue_tooltip: "Bu yüklemeyi başlatmadan kuyruğa ekle", upload_apply_exclude_rules: "Hariç tutma kurallarını uygula", -upload_cancel: "İptal", +upload_change_source: "Kaynağı değiştir", upload_choose_diff_source: "Farklı bir kaynak seç", upload_dest_auto: "(varsayılan — /data)", upload_dest_card_title: "Hedef", diff --git a/client/src/i18n/locales/vi.ts b/client/src/i18n/locales/vi.ts index dc1528f7..7951583e 100644 --- a/client/src/i18n/locales/vi.ts +++ b/client/src/i18n/locales/vi.ts @@ -965,7 +965,7 @@ smp_blank_delete: "(để trống=xóa)", upload_add_to_queue: "Thêm vào hàng đợi", upload_add_to_queue_tooltip: "Thêm lần tải lên này vào hàng đợi mà không bắt đầu", upload_apply_exclude_rules: "Áp dụng quy tắc loại trừ", -upload_cancel: "Hủy", +upload_change_source: "Đổi nguồn", upload_choose_diff_source: "Chọn nguồn khác", upload_dest_auto: "(mặc định — /data)", upload_dest_card_title: "Đích đến", diff --git a/client/src/i18n/locales/zh-CN.ts b/client/src/i18n/locales/zh-CN.ts index 5624b9ec..ec7355c3 100644 --- a/client/src/i18n/locales/zh-CN.ts +++ b/client/src/i18n/locales/zh-CN.ts @@ -970,7 +970,7 @@ smp_blank_delete: "(留空=删除)", upload_add_to_queue: "加入队列", upload_add_to_queue_tooltip: "将此上传加入队列但不立即开始", upload_apply_exclude_rules: "应用排除规则", -upload_cancel: "取消", +upload_change_source: "更换来源", upload_choose_diff_source: "选择其他来源", upload_dest_auto: "(默认 — /data)", upload_dest_card_title: "目标位置", diff --git a/client/src/i18n/locales/zh-TW.ts b/client/src/i18n/locales/zh-TW.ts index ac55aecf..1cd2af1a 100644 --- a/client/src/i18n/locales/zh-TW.ts +++ b/client/src/i18n/locales/zh-TW.ts @@ -964,7 +964,7 @@ smp_blank_delete: "(留空=刪除)", upload_add_to_queue: "加入佇列", upload_add_to_queue_tooltip: "將此上傳加入佇列但不立即開始", upload_apply_exclude_rules: "套用排除規則", -upload_cancel: "取消", +upload_change_source: "更換來源", upload_choose_diff_source: "選擇其他來源", upload_dest_auto: "(預設 — /data)", upload_dest_card_title: "目標位置", diff --git a/client/src/screens/Upload/SendAsImageCard.tsx b/client/src/screens/Upload/SendAsImageCard.tsx index cad76f16..8138a4d5 100644 --- a/client/src/screens/Upload/SendAsImageCard.tsx +++ b/client/src/screens/Upload/SendAsImageCard.tsx @@ -93,8 +93,9 @@ export function SendAsImageCard({ }, ]} /> + {/* The alternative to the Upload button below, so not filled: one primary per screen. */} {/* Add-to-queue: capture the current source + options into the persisted upload queue without starting the transfer. The @@ -1556,7 +1557,8 @@ function Step2Options(props: { type="button" onClick={() => onAddToQueue("overwrite")} disabled={detecting || preflightBusy || !!detectError} - className="rounded-full border shadow-[var(--edge-highlight),var(--shadow-1)] hover:bg-[var(--color-float)] border-[var(--glass-edge)] bg-[var(--color-surface-raised)] px-4 py-2 text-sm disabled:opacity-50" + // While the queue runs, Upload is disabled and this is the way forward. + className={queueRunning && source.kind !== "pkg" ? ACTION_PRIMARY : ACTION_PLAIN} title={ detecting ? tr( @@ -1594,9 +1596,7 @@ function Step2Options(props: { className={ // For a package, Stream & install (on its card) is the main // action; uploading it first is the fallback. - source.kind === "pkg" - ? "rounded-full border border-[var(--glass-edge)] bg-[var(--color-surface-raised)] px-6 py-2 text-sm font-medium text-[var(--color-text)] shadow-[var(--edge-highlight),var(--shadow-1)] hover:bg-[var(--color-float)] disabled:opacity-50" - : "rounded-full bg-[image:var(--accent-fill)] px-6 py-2 text-sm font-semibold text-[var(--color-accent-contrast)] shadow-[var(--accent-glow)] hover:brightness-105 disabled:opacity-50" + source.kind === "pkg" || queueRunning ? ACTION_PLAIN : ACTION_PRIMARY } > {preflightBusy @@ -1620,7 +1620,7 @@ function Step2Options(props: { `Couldn't check the destination: ${preflightError}. Make sure the PS5 is reachable, then try again.`, )} action={ - } @@ -1751,6 +1751,20 @@ function MirrorToRosterButton({ ); } +/** The action row under the form: the next step filled, the rest plain. */ +const ACTION_PLAIN = + "rounded-full border border-[var(--glass-edge)] bg-[var(--color-surface-raised)] px-5 py-2 text-sm font-medium text-[var(--color-text)] shadow-[var(--edge-highlight),var(--shadow-1)] hover:bg-[var(--color-float)] disabled:opacity-50"; +const ACTION_PRIMARY = + "rounded-full bg-[image:var(--accent-fill)] px-6 py-2 text-sm font-semibold text-[var(--color-accent-contrast)] shadow-[var(--accent-glow)] hover:brightness-105 disabled:opacity-50"; + +/** The upload confirm's choices: one shape for all, the primary one filled with the accent. */ +const DIALOG_OPTION = + "flex items-start gap-3 rounded-[var(--radius-card)] border p-3.5 text-left text-sm transition"; +const DIALOG_PRIMARY = + "border-transparent bg-[image:var(--accent-fill)] text-[var(--color-accent-contrast)] shadow-[var(--accent-glow)] hover:brightness-105"; +const DIALOG_PLAIN = + "border-[var(--glass-edge)] bg-[var(--color-surface)] hover:bg-[var(--color-surface-raised)]"; + function ExistingDestinationDialog({ entryCount, dest, @@ -1807,7 +1821,7 @@ function ExistingDestinationDialog({ )} + {/* Start is the primary action in a clean destination (filled, like Resume); + with files already there Override is the risky one, so it stays plain. */}