mirror of
https://github.com/phantomptr/ps5upload.git
synced 2026-10-19 02:20:02 -05:00
Updates: give packaged Linux installs the command that installs them (#456)
The updater downloads the new package and opens its folder. On Bazzite and other rpm-ostree systems that left people to work out `rpm-ostree uninstall` plus `rpm-ostree install` by hand. A packaged Linux copy now gets the one command to run, with a Copy button: `rpm-ostree uninstall <pkg> --install <rpm> && systemctl reboot` on rpm-ostree (the package name read from the rpm database), `sudo dnf install` for rpm, `sudo apt install` for deb. The README's Bazzite row says the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EU1Z2mdhAxBrH1yb48pxik
This commit is contained in:
1 parent
ccdd5b1e28
commit
f534ab020f
25 files changed
+129
-5
No files matched your search
@@ -64,7 +64,7 @@ Pre-built downloads land on the
|
||||
| macOS (Apple Silicon / Intel) | `PS5Upload-<ver>-mac-{arm64,x64}.dmg` | Open the `.dmg`, drag PS5Upload into Applications. See **First launch on macOS** below — Gatekeeper blocks downloaded apps the first time. |
|
||||
| Windows (x64 / ARM64) | `PS5Upload-<ver>-win-{x64,arm64}.zip` | Unzip, double-click `PS5Upload.exe` — portable, no installer. See **First launch on Windows** — SmartScreen warns on first run. |
|
||||
| Linux — Debian / Ubuntu (x64 / ARM64) | `PS5Upload-<ver>-linux-{x64,arm64}.deb` | `sudo apt install ./PS5Upload-<ver>-linux-<arch>.deb` — installs a normal app with a menu entry; pulls in the WebKitGTK deps automatically. |
|
||||
| Linux — Fedora / RHEL / Bazzite (x64 / ARM64) | `PS5Upload-<ver>-linux-{x64,arm64}.rpm` | `sudo dnf install ./PS5Upload-<ver>-linux-<arch>.rpm` (Bazzite/Silverblue: `rpm-ostree install`) — menu entry + auto deps. |
|
||||
| Linux — Fedora / RHEL / Bazzite (x64 / ARM64) | `PS5Upload-<ver>-linux-{x64,arm64}.rpm` | `sudo dnf install ./PS5Upload-<ver>-linux-<arch>.rpm` (Bazzite/Silverblue: `rpm-ostree install`; to update, `rpm-ostree uninstall ps5-upload --install ./<new>.rpm` and reboot, which Settings → Updates shows ready to copy) — menu entry + auto deps. |
|
||||
| Linux — any distro (x64 / ARM64) | `PS5Upload-<ver>-linux-{x64,arm64}.zip` | Universal fallback (no install). Unzip, then `chmod +x PS5Upload.sh PS5Upload.AppImage` and run **`./PS5Upload.sh`** (the wrapper — handles the FUSE-less and WebKit white-screen cases for you). Running `./PS5Upload.AppImage` directly also works if your system has libfuse2 and a happy WebKitGTK. |
|
||||
| Linux — NixOS (x64 / ARM64) | no release artifact | Packaged in [NUR](https://github.com/GriefNorth/nur-packages) as `ps5upload` — see **NixOS** below. |
|
||||
| Android | `PS5Upload-<ver>-android.apk` | Enable "install unknown apps" for your browser/file manager, then open the `.apk`. Same interface, mobile-friendly; connects to and manages your PS5 over Wi-Fi. On Android 17, allow local network access ("nearby devices") when asked. |
|
||||
|
||||
@@ -289,9 +289,28 @@ fn is_newer(current: &str, latest: &str) -> bool {
|
||||
#[cfg(test)]
|
||||
mod is_newer_tests {
|
||||
use super::{
|
||||
is_newer, is_safe_update_url, UpdateChannel, DEFAULT_MANIFEST_URL, PRERELEASE_LIST_URL,
|
||||
install_command_for, is_newer, is_safe_update_url, UpdateChannel, DEFAULT_MANIFEST_URL,
|
||||
PRERELEASE_LIST_URL,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn a_packaged_linux_install_gets_its_own_command() {
|
||||
let p = "/home/me/Downloads/PS5Upload-7.0.23-linux-x64.rpm";
|
||||
assert_eq!(
|
||||
install_command_for(p, Some("rpm"), true, Some("ps5-upload")).as_deref(),
|
||||
Some("rpm-ostree uninstall ps5-upload --install '/home/me/Downloads/PS5Upload-7.0.23-linux-x64.rpm' && systemctl reboot")
|
||||
);
|
||||
assert_eq!(
|
||||
install_command_for(p, Some("rpm"), false, None).as_deref(),
|
||||
Some("sudo dnf install '/home/me/Downloads/PS5Upload-7.0.23-linux-x64.rpm'")
|
||||
);
|
||||
assert_eq!(
|
||||
install_command_for("/tmp/it's.deb", Some("deb"), false, None).as_deref(),
|
||||
Some("sudo apt install '/tmp/it'\\''s.deb'")
|
||||
);
|
||||
assert_eq!(install_command_for(p, None, true, None), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn higher_numeric_is_newer() {
|
||||
assert!(is_newer("2.2.0", "2.2.1"));
|
||||
@@ -537,6 +556,65 @@ pub struct UpdateDownload {
|
||||
pub path: String,
|
||||
/// Total bytes written to disk.
|
||||
pub bytes: u64,
|
||||
/// For a packaged Linux install: the one command that installs the download, to copy into
|
||||
/// a terminal (#456: on Bazzite, `rpm-ostree uninstall ps5-upload --install <rpm>`).
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub install_command: Option<String>,
|
||||
}
|
||||
|
||||
/// `path` quoted for a POSIX shell.
|
||||
fn shell_quote(path: &str) -> String {
|
||||
format!("'{}'", path.replace('\'', "'\\''"))
|
||||
}
|
||||
|
||||
/// The command that installs `path` over this packaged Linux copy, or None (portable copy,
|
||||
/// another OS). An rpm-ostree system (Bazzite, Silverblue, Kinoite) cannot `dnf install`; its
|
||||
/// layered package is swapped in one transaction that applies on the next boot.
|
||||
fn install_command_for(
|
||||
path: &str,
|
||||
kind: Option<&str>,
|
||||
ostree: bool,
|
||||
package: Option<&str>,
|
||||
) -> Option<String> {
|
||||
let q = shell_quote(path);
|
||||
match kind? {
|
||||
"rpm" if ostree => Some(format!(
|
||||
"rpm-ostree uninstall {} --install {q} && systemctl reboot",
|
||||
package.unwrap_or("ps5-upload")
|
||||
)),
|
||||
"rpm" => Some(format!("sudo dnf install {q}")),
|
||||
"deb" => Some(format!("sudo apt install {q}")),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn install_command(path: &str) -> Option<String> {
|
||||
let kind = linux_package_kind();
|
||||
let ostree = std::path::Path::new("/run/ostree-booted").exists();
|
||||
let package = (kind == Some("rpm"))
|
||||
.then(|| {
|
||||
let exe = std::env::current_exe().ok()?;
|
||||
let exe = std::fs::canonicalize(&exe).unwrap_or(exe);
|
||||
let out = std::process::Command::new("rpm")
|
||||
.args(["-qf", "--qf", "%{NAME}"])
|
||||
.arg(&exe)
|
||||
.output()
|
||||
.ok()?;
|
||||
let name = String::from_utf8(out.stdout).ok()?;
|
||||
let name = name.trim();
|
||||
(out.status.success() && !name.is_empty() && !name.contains(char::is_whitespace))
|
||||
.then(|| name.to_string())
|
||||
})
|
||||
.flatten();
|
||||
install_command_for(path, kind, ostree, package.as_deref())
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn install_command(path: &str) -> Option<String> {
|
||||
let _ = install_command_for;
|
||||
let _ = path;
|
||||
None
|
||||
}
|
||||
|
||||
/// Download the platform-specific asset from the URL returned by
|
||||
@@ -649,8 +727,10 @@ pub async fn update_download(
|
||||
if let Err(e) = reveal(&app, &target).await {
|
||||
eprintln!("[updates] cached bundle at {target:?} but reveal failed: {e}");
|
||||
}
|
||||
let path = target.to_string_lossy().into_owned();
|
||||
return Ok(UpdateDownload {
|
||||
path: target.to_string_lossy().into_owned(),
|
||||
install_command: install_command(&path),
|
||||
path,
|
||||
bytes: meta.len(),
|
||||
});
|
||||
}
|
||||
@@ -712,8 +792,10 @@ pub async fn update_download(
|
||||
eprintln!("[updates] download saved to {target:?} but reveal failed: {e}");
|
||||
}
|
||||
|
||||
let path = target.to_string_lossy().into_owned();
|
||||
Ok(UpdateDownload {
|
||||
path: target.to_string_lossy().into_owned(),
|
||||
install_command: install_command(&path),
|
||||
path,
|
||||
bytes: total,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4628,6 +4628,8 @@ export interface UpdateDownload {
|
||||
path: string;
|
||||
/** Total bytes written. Handy for "Downloaded N MB" status lines. */
|
||||
bytes: number;
|
||||
/** A packaged Linux install: the command that installs the download (#456). */
|
||||
install_command?: string;
|
||||
}
|
||||
|
||||
/** Ask GitHub for the latest-release manifest and compare to our
|
||||
|
||||
@@ -195,6 +195,7 @@ update_downloaded_status: "تم تنزيل v{version} — تم فتح المثب
|
||||
update_download_error: "فشل التنزيل: {message}",
|
||||
update_downloaded_title: "تم التنزيل. أكمل التثبيت:",
|
||||
update_step_quit: "اخرج من PS5Upload.",
|
||||
update_step_run_command: "شغّل هذا في الطرفية:",
|
||||
update_step_launch: "ابدأ تشغيل الإصدار الجديد.",
|
||||
update_dismiss: "إغلاق",
|
||||
install_hint_dmg: "انقر نقرًا مزدوجًا فوق .dmg، واسحب PS5Upload إلى Applications، واستبدله عند المطالبة.",
|
||||
|
||||
@@ -200,6 +200,7 @@ update_downloaded_status: "v{version} ডাউনলোড হয়েছে
|
||||
update_download_error: "ডাউনলোড ব্যর্থ: {message}",
|
||||
update_downloaded_title: "ডাউনলোড হয়েছে। ইনস্টলেশন সম্পূর্ণ করুন:",
|
||||
update_step_quit: "PS5Upload থেকে প্রস্থান করুন।",
|
||||
update_step_run_command: "এটি একটি টার্মিনালে চালান:",
|
||||
update_step_launch: "নতুন সংস্করণ চালু করুন।",
|
||||
update_dismiss: "বন্ধ করুন",
|
||||
install_hint_dmg: ".dmg-তে ডাবল-ক্লিক করুন, PS5Upload-কে Applications-এ টানুন, জিজ্ঞাসা করা হলে প্রতিস্থাপন করুন।",
|
||||
|
||||
@@ -201,6 +201,7 @@ update_downloaded_status: "v{version} heruntergeladen — Installer geöffnet.",
|
||||
update_download_error: "Download fehlgeschlagen: {message}",
|
||||
update_downloaded_title: "Heruntergeladen. Installation abschließen:",
|
||||
update_step_quit: "PS5Upload beenden.",
|
||||
update_step_run_command: "Führe das in einem Terminal aus:",
|
||||
update_step_launch: "Neue Version starten.",
|
||||
update_dismiss: "Schließen",
|
||||
install_hint_dmg: ".dmg doppelklicken, PS5Upload in Programme ziehen, beim Nachfragen ersetzen.",
|
||||
|
||||
@@ -401,6 +401,7 @@ update_autocheck_hint:
|
||||
update_channel_prerelease_label: "Get pre-release versions",
|
||||
update_channel_prerelease_hint: "Offers new releases as soon as they are published, before they have been checked on real hardware. Leave this off to be offered only releases that have been verified.",
|
||||
update_step_quit: "Quit PS5Upload.",
|
||||
update_step_run_command: "Run this in a terminal:",
|
||||
update_step_launch: "Launch the new version.",
|
||||
update_dismiss: "Dismiss",
|
||||
install_hint_dmg: "Double-click the .dmg, drag PS5Upload into Applications, replace when asked.",
|
||||
|
||||
@@ -195,6 +195,7 @@ update_downloaded_status: "v{version} descargada — instalador abierto.",
|
||||
update_download_error: "Descarga fallida: {message}",
|
||||
update_downloaded_title: "Descargado. Termina la instalación:",
|
||||
update_step_quit: "Sal de PS5Upload.",
|
||||
update_step_run_command: "Ejecuta esto en una terminal:",
|
||||
update_step_launch: "Lanza la nueva versión.",
|
||||
update_dismiss: "Cerrar",
|
||||
install_hint_dmg: "Haz doble clic en el .dmg, arrastra PS5Upload a Aplicaciones, reemplaza cuando se pregunte.",
|
||||
|
||||
@@ -373,6 +373,7 @@ update_autocheck_hint:
|
||||
update_channel_prerelease_label: "دریافت نسخههای پیشانتشار",
|
||||
update_channel_prerelease_hint: "نسخههای جدید را بهمحض انتشار ارائه میدهد، پیش از آزمایش روی سختافزار واقعی. خاموش بگذارید تا تنها نسخههای تأییدشده ارائه شوند.",
|
||||
update_step_quit: "PS5Upload را ببندید.",
|
||||
update_step_run_command: "این را در ترمینال اجرا کنید:",
|
||||
update_step_launch: "نسخهی جدید را اجرا کنید.",
|
||||
update_dismiss: "نادیده گرفتن",
|
||||
install_hint_dmg: "روی .dmg دوبار کلیک کنید، PS5Upload را به Applications بکشید، در صورت درخواست جایگزین کنید.",
|
||||
|
||||
@@ -195,6 +195,7 @@ update_downloaded_status: "v{version} téléchargée — installateur ouvert.",
|
||||
update_download_error: "Échec du téléchargement : {message}",
|
||||
update_downloaded_title: "Téléchargé. Terminez l'installation :",
|
||||
update_step_quit: "Quittez PS5Upload.",
|
||||
update_step_run_command: "Exécutez ceci dans un terminal :",
|
||||
update_step_launch: "Lancez la nouvelle version.",
|
||||
update_dismiss: "Ignorer",
|
||||
install_hint_dmg: "Double-cliquez sur le .dmg, glissez PS5Upload dans Applications, remplacez si demandé.",
|
||||
|
||||
@@ -200,6 +200,7 @@ update_downloaded_status: "v{version} डाउनलोड किया गय
|
||||
update_download_error: "डाउनलोड विफल: {message}",
|
||||
update_downloaded_title: "डाउनलोड किया गया। इंस्टॉलेशन पूरा करें:",
|
||||
update_step_quit: "PS5Upload से बाहर निकलें।",
|
||||
update_step_run_command: "इसे टर्मिनल में चलाएँ:",
|
||||
update_step_launch: "नया संस्करण लॉन्च करें।",
|
||||
update_dismiss: "बंद करें",
|
||||
install_hint_dmg: ".dmg पर डबल-क्लिक करें, PS5Upload को Applications पर खींचें, संकेत मिलने पर बदलें।",
|
||||
|
||||
@@ -376,6 +376,7 @@ update_autocheck_hint:
|
||||
update_channel_prerelease_label: "Pre-release verziók kérése",
|
||||
update_channel_prerelease_hint: "Az új kiadásokat azonnal felajánlja, ahogy megjelennek, mielőtt valódi hardveren ellenőrizték volna. Hagyd kikapcsolva, hogy csak ellenőrzött kiadásokat kapj.",
|
||||
update_step_quit: "Zárd be a PS5Uploadot.",
|
||||
update_step_run_command: "Futtasd ezt egy terminálban:",
|
||||
update_step_launch: "Indítsd el az új verziót.",
|
||||
update_dismiss: "Elvetés",
|
||||
install_hint_dmg: "Dupla kattintás a .dmg-re, húzd a PS5Uploadot az Alkalmazásokba, cseréld le, ha kérdezi.",
|
||||
|
||||
@@ -200,6 +200,7 @@ update_downloaded_status: "v{version} diunduh — pemasang dibuka.",
|
||||
update_download_error: "Unduhan gagal: {message}",
|
||||
update_downloaded_title: "Diunduh. Selesaikan pemasangan:",
|
||||
update_step_quit: "Keluar dari PS5Upload.",
|
||||
update_step_run_command: "Jalankan ini di terminal:",
|
||||
update_step_launch: "Luncurkan versi baru.",
|
||||
update_dismiss: "Tutup",
|
||||
install_hint_dmg: "Klik dua kali .dmg, seret PS5Upload ke Applications, ganti saat diminta.",
|
||||
|
||||
@@ -200,6 +200,7 @@ update_downloaded_status: "v{version} scaricata — installer aperto.",
|
||||
update_download_error: "Download fallito: {message}",
|
||||
update_downloaded_title: "Scaricato. Termina l'installazione:",
|
||||
update_step_quit: "Esci da PS5Upload.",
|
||||
update_step_run_command: "Esegui questo in un terminale:",
|
||||
update_step_launch: "Avvia la nuova versione.",
|
||||
update_dismiss: "Chiudi",
|
||||
install_hint_dmg: "Doppio clic sul .dmg, trascina PS5Upload in Applicazioni, sostituisci se richiesto.",
|
||||
|
||||
@@ -201,6 +201,7 @@ update_downloaded_status: "v{version} ダウンロード完了 — インスト
|
||||
update_download_error: "ダウンロード失敗: {message}",
|
||||
update_downloaded_title: "ダウンロード完了。インストールを完了:",
|
||||
update_step_quit: "PS5Upload を終了。",
|
||||
update_step_run_command: "ターミナルでこれを実行してください:",
|
||||
update_step_launch: "新バージョンを起動。",
|
||||
update_dismiss: "閉じる",
|
||||
install_hint_dmg: ".dmg をダブルクリックし、PS5Upload を Applications にドラッグ、確認時に置き換え。",
|
||||
|
||||
@@ -201,6 +201,7 @@ update_downloaded_status: "v{version} 다운로드 완료 — 설치 프로그
|
||||
update_download_error: "다운로드 실패: {message}",
|
||||
update_downloaded_title: "다운로드 완료. 설치 마무리:",
|
||||
update_step_quit: "PS5Upload 종료.",
|
||||
update_step_run_command: "터미널에서 다음을 실행하세요:",
|
||||
update_step_launch: "새 버전 실행.",
|
||||
update_dismiss: "닫기",
|
||||
install_hint_dmg: ".dmg 더블클릭, PS5Upload를 Applications로 드래그, 묻는 메시지에서 교체.",
|
||||
|
||||
@@ -359,6 +359,7 @@ update_autocheck_label: "Sprawdzaj aktualizacje automatycznie",
|
||||
update_autocheck_hint:
|
||||
"Sprawdza nowe wydania przy uruchomieniu (co najwyżej raz dziennie) i informuje cię, jeśli jest dostępne.",
|
||||
update_step_quit: "Wyjdź z PS5Upload.",
|
||||
update_step_run_command: "Uruchom to w terminalu:",
|
||||
update_step_launch: "Uruchom nową wersję.",
|
||||
update_dismiss: "Odrzuć",
|
||||
install_hint_dmg: "Kliknij dwa razy na .dmg, przeciągnij PS5Upload do Aplikacji, podmień jeśli zostaniesz zapytany/a.",
|
||||
|
||||
@@ -200,6 +200,7 @@ update_downloaded_status: "v{version} baixada — instalador aberto.",
|
||||
update_download_error: "Falha no download: {message}",
|
||||
update_downloaded_title: "Baixado. Conclua a instalação:",
|
||||
update_step_quit: "Saia do PS5Upload.",
|
||||
update_step_run_command: "Execute isto em um terminal:",
|
||||
update_step_launch: "Inicie a nova versão.",
|
||||
update_dismiss: "Fechar",
|
||||
install_hint_dmg: "Clique duas vezes no .dmg, arraste o PS5Upload para Aplicativos, substitua quando solicitado.",
|
||||
|
||||
@@ -200,6 +200,7 @@ update_downloaded_status: "v{version} загружена — установщи
|
||||
update_download_error: "Сбой загрузки: {message}",
|
||||
update_downloaded_title: "Загружено. Завершите установку:",
|
||||
update_step_quit: "Закройте PS5Upload.",
|
||||
update_step_run_command: "Выполните это в терминале:",
|
||||
update_step_launch: "Запустите новую версию.",
|
||||
update_dismiss: "Закрыть",
|
||||
install_hint_dmg: "Дважды щёлкните .dmg, перетащите PS5Upload в Программы, замените при запросе.",
|
||||
|
||||
@@ -200,6 +200,7 @@ update_downloaded_status: "ดาวน์โหลด v{version} แล้ว
|
||||
update_download_error: "ดาวน์โหลดล้มเหลว: {message}",
|
||||
update_downloaded_title: "ดาวน์โหลดแล้ว ดำเนินการติดตั้งให้เสร็จ:",
|
||||
update_step_quit: "ออกจาก PS5Upload",
|
||||
update_step_run_command: "รันคำสั่งนี้ในเทอร์มินัล:",
|
||||
update_step_launch: "เปิดเวอร์ชันใหม่",
|
||||
update_dismiss: "ปิด",
|
||||
install_hint_dmg: "ดับเบิลคลิก .dmg ลาก PS5Upload ไปยัง Applications แทนที่เมื่อถูกถาม",
|
||||
|
||||
@@ -200,6 +200,7 @@ update_downloaded_status: "v{version} indirildi — yükleyici açıldı.",
|
||||
update_download_error: "İndirme başarısız: {message}",
|
||||
update_downloaded_title: "İndirildi. Yüklemeyi tamamlayın:",
|
||||
update_step_quit: "PS5Upload'dan çıkın.",
|
||||
update_step_run_command: "Bunu bir terminalde çalıştırın:",
|
||||
update_step_launch: "Yeni sürümü başlatın.",
|
||||
update_dismiss: "Kapat",
|
||||
install_hint_dmg: ".dmg'ye çift tıklayın, PS5Upload'ı Applications klasörüne sürükleyin, sorulduğunda değiştirin.",
|
||||
|
||||
@@ -201,6 +201,7 @@ update_downloaded_status: "v{version} đã tải — trình cài đặt đã m
|
||||
update_download_error: "Tải về thất bại: {message}",
|
||||
update_downloaded_title: "Đã tải xong. Hoàn tất cài đặt:",
|
||||
update_step_quit: "Thoát PS5Upload.",
|
||||
update_step_run_command: "Chạy lệnh này trong terminal:",
|
||||
update_step_launch: "Khởi chạy phiên bản mới.",
|
||||
update_dismiss: "Bỏ qua",
|
||||
install_hint_dmg: "Nhấp đúp .dmg, kéo PS5Upload vào Applications, thay thế khi được hỏi.",
|
||||
|
||||
@@ -202,6 +202,7 @@ update_downloaded_status: "v{version} 已下载 — 安装器已打开。",
|
||||
update_download_error: "下载失败: {message}",
|
||||
update_downloaded_title: "已下载。完成安装:",
|
||||
update_step_quit: "退出 PS5Upload。",
|
||||
update_step_run_command: "在终端中运行:",
|
||||
update_step_launch: "启动新版本。",
|
||||
update_dismiss: "关闭",
|
||||
install_hint_dmg: "双击 .dmg,将 PS5Upload 拖入应用程序,询问时替换。",
|
||||
|
||||
@@ -196,6 +196,7 @@ update_downloaded_status: "v{version} 已下載 — 安裝程式已開啟。",
|
||||
update_download_error: "下載失敗: {message}",
|
||||
update_downloaded_title: "已下載。完成安裝:",
|
||||
update_step_quit: "結束 PS5Upload。",
|
||||
update_step_run_command: "在終端機中執行:",
|
||||
update_step_launch: "啟動新版本。",
|
||||
update_dismiss: "關閉",
|
||||
install_hint_dmg: "按兩下 .dmg,將 PS5Upload 拖入應用程式,詢問時替換。",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { writeClipboard } from "../../lib/clipboard";
|
||||
import { EMPTY_CORPUS, deleteFakelibSet, loadFakelibCorpus, type FakelibCorpus } from "../../state/fakelibCorpus";
|
||||
import { LibrarySourcePicker } from "../InstalledApps/LibrarySourcePicker";
|
||||
import {
|
||||
@@ -1801,7 +1802,25 @@ function UpdatesPanel() {
|
||||
</div>
|
||||
<ol className="list-inside list-decimal space-y-0.5 text-[var(--color-muted)]">
|
||||
<li>{tr("update_step_quit", undefined, "Quit PS5Upload.")}</li>
|
||||
<li>{pickInstallHint(phase.download.path, tr)}</li>
|
||||
{phase.download.install_command ? (
|
||||
<li>
|
||||
{tr("update_step_run_command", undefined, "Run this in a terminal:")}
|
||||
<span className="mt-1 flex items-start gap-2">
|
||||
<code className="min-w-0 flex-1 break-all rounded bg-[var(--color-surface-3)] px-2 py-1 font-mono text-[var(--color-text)]">
|
||||
{phase.download.install_command}
|
||||
</code>
|
||||
<button
|
||||
type="button"
|
||||
className="shrink-0 underline-offset-2 hover:underline"
|
||||
onClick={() => void writeClipboard(phase.download.install_command ?? "")}
|
||||
>
|
||||
{tr("copy", undefined, "Copy")}
|
||||
</button>
|
||||
</span>
|
||||
</li>
|
||||
) : (
|
||||
<li>{pickInstallHint(phase.download.path, tr)}</li>
|
||||
)}
|
||||
<li>
|
||||
{tr("update_step_launch", undefined, "Launch the new version.")}
|
||||
</li>
|
||||
|
||||
Reference in new issue
Block a user