This commit is contained in:
Kang committed 2026-10-01 11:04:13 +08:00
commit 540784da95
17 files changed
+80 -19

No files matched your search

+2
View File
@@ -146,6 +146,8 @@ $env:NYATERM_GITHUB_GIST_CLIENT_ID = "your_client_id"
pnpm tauri build
```
第三方发行包可以在构建时设置 `NYATERM_PACKAGE_MANAGER` 标识包管理器。应用会将该值写入支持信息,并把应用内更新交由外部包管理器处理;普通开发构建应保持未设置。
## 文档开发提示
如果你在修改 README 或 `docs-site/docs/` / `docs-site/i18n/en/` 下的文档,建议至少执行:
@@ -88,6 +88,8 @@ $env:NYATERM_GITHUB_GIST_CLIENT_ID = "your_client_id"
pnpm tauri build
```
Third-party distributors can set `NYATERM_PACKAGE_MANAGER` at build time to identify the package manager. The app includes this value in support information and leaves updates to the external package manager; leave it unset for ordinary development builds.
## Available Scripts
| Command | Description |
+5
View File
@@ -1,9 +1,14 @@
fn main() {
println!("cargo:rerun-if-env-changed=NYATERM_GITHUB_GIST_CLIENT_ID");
println!("cargo:rerun-if-env-changed=NYATERM_PACKAGE_MANAGER");
if let Ok(client_id) = std::env::var("NYATERM_GITHUB_GIST_CLIENT_ID") {
println!("cargo:rustc-env=NYATERM_GITHUB_GIST_CLIENT_ID={client_id}");
}
if let Ok(package_manager) = std::env::var("NYATERM_PACKAGE_MANAGER") {
println!("cargo:rustc-env=NYATERM_PACKAGE_MANAGER={package_manager}");
}
tauri_build::build();
}
+4 -2
View File
@@ -110,17 +110,19 @@ pub struct AppSupportInfo {
os: String,
architecture: String,
runtime: String,
package_manager: Option<String>,
#[cfg(windows)]
conpty: crate::platform::windows_conpty::LocalConptyInfo,
}
#[tauri::command]
pub fn get_support_info(state: tauri::State<'_, crate::runtime::AppRuntime>) -> AppSupportInfo {
let runtime = state.info().mode;
let info = state.info();
AppSupportInfo {
os: operating_system_label(),
architecture: std::env::consts::ARCH.to_string(),
runtime,
runtime: info.mode,
package_manager: info.package_manager,
#[cfg(windows)]
conpty: crate::platform::windows_conpty::support_info(),
}
+18
View File
@@ -12,9 +12,12 @@ const PORTABLE_KEY_FILE: &str = "portable.key";
#[cfg(all(windows, target_vendor = "win7"))]
const WIN7_WEBVIEW2_FIXED_RUNTIME_DIR: &str = "webview2-fixed-runtime";
const PACKAGE_MANAGER: Option<&str> = option_env!("NYATERM_PACKAGE_MANAGER");
#[derive(Clone, Debug)]
pub struct AppRuntime {
portable: bool,
package_manager: Option<String>,
executable_dir: PathBuf,
data_dir: PathBuf,
config_dir: PathBuf,
@@ -30,6 +33,7 @@ pub struct AppRuntime {
pub struct AppRuntimeInfo {
pub portable: bool,
pub mode: String,
pub package_manager: Option<String>,
pub executable_dir: String,
pub data_dir: String,
pub config_dir: String,
@@ -43,6 +47,10 @@ impl AppRuntime {
self.portable
}
pub fn package_manager(&self) -> Option<&str> {
self.package_manager.as_deref()
}
pub fn executable_dir(&self) -> &Path {
&self.executable_dir
}
@@ -82,6 +90,7 @@ impl AppRuntime {
} else {
"installed".to_string()
},
package_manager: self.package_manager.clone(),
executable_dir: path_to_string(&self.executable_dir),
data_dir: path_to_string(&self.data_dir),
config_dir: path_to_string(&self.config_dir),
@@ -95,6 +104,13 @@ impl AppRuntime {
}
}
fn package_manager_name() -> Option<String> {
PACKAGE_MANAGER
.map(str::trim)
.filter(|name| !name.is_empty())
.map(ToOwned::to_owned)
}
pub fn resolve() -> AppResult<AppRuntime> {
let executable_dir = executable_dir()?;
let portable_marker_path = executable_dir.join(PORTABLE_MARKER_FILE);
@@ -184,6 +200,7 @@ fn resolve_portable(
Ok(AppRuntime {
portable: true,
package_manager: package_manager_name(),
executable_dir,
data_dir,
config_dir,
@@ -204,6 +221,7 @@ fn resolve_installed(executable_dir: PathBuf) -> AppResult<AppRuntime> {
Ok(AppRuntime {
portable: false,
package_manager: package_manager_name(),
executable_dir,
data_dir: config_dir.clone(),
config_dir,
+6 -1
View File
@@ -371,6 +371,9 @@ fn rebuild_root_menu(
settings.general.minimize_to_tray,
None::<&str>,
)?;
let is_package_managed = app
.try_state::<crate::runtime::AppRuntime>()
.is_some_and(|runtime| runtime.package_manager().is_some());
let check_updates = new_menu_item(app, MENU_CHECK_UPDATES, strings.check_updates, true)?;
let separator_3 = PredefinedMenuItem::separator(app)?;
let quit = new_menu_item(app, MENU_QUIT, strings.quit, true)?;
@@ -390,7 +393,9 @@ fn rebuild_root_menu(
menu.append(&lock_screen)?;
}
menu.append(&check_updates)?;
if !is_package_managed {
menu.append(&check_updates)?;
}
menu.append(&separator_3)?;
menu.append(&quit)?;
Ok(())
+2 -2
View File
@@ -364,7 +364,7 @@ function App() {
// Background update check on startup
useEffect(() => {
if (!runtimeInfoLoaded) return;
if (!runtimeInfoLoaded || runtimeInfo.packageManager) return;
const timer = setTimeout(() => {
checkForUpdate(portable)
@@ -377,7 +377,7 @@ function App() {
.catch(() => {});
}, 3000);
return () => clearTimeout(timer);
}, [portable, runtimeInfoLoaded]);
}, [portable, runtimeInfo.packageManager, runtimeInfoLoaded]);
const closeFloatingPanel = useCallback(
(side: "left" | "right") => {
+10 -2
View File
@@ -87,20 +87,27 @@ export default function AboutDialog({ open, onClose }: AboutDialogProps) {
: conpty.lastUsed
? t("about.conptyLastUsed", {
source: conpty.lastUsed === "bundled" ? bundledLabel : systemLabel,
})
})
: t("about.conptyNotStarted");
const packageManagerDisplay = supportInfo?.packageManager
? `${supportInfo.packageManager.charAt(0).toUpperCase()}${supportInfo.packageManager.slice(1)}`
: null;
const copySupportInfo = async () => {
if (!appVersion || !supportInfo) {
return;
}
const runtimeLabel =
supportInfo.runtime === "portable" ? t("about.portable") : t("about.installed");
const text = [
"NyaTerm Support Information",
`Version: ${appVersion}`,
`Operating System: ${supportInfo.os}`,
`Application Architecture: ${supportInfo.architecture}`,
`Runtime: ${supportInfo.runtime === "portable" ? t("about.portable") : t("about.installed")}`,
`Runtime: ${runtimeLabel}`,
...(packageManagerDisplay ? [`Package Manager: ${packageManagerDisplay}`] : []),
...(conptyDisplay ? [`Local Terminal ConPTY: ${conptyDisplay}`] : []),
].join("\n");
try {
@@ -133,6 +140,7 @@ export default function AboutDialog({ open, onClose }: AboutDialogProps) {
[t("about.operatingSystem"), osDisplay],
[t("about.architecture"), architectureDisplay],
[t("about.runtime"), runtimeDisplay],
...(packageManagerDisplay ? [[t("about.packageManager"), packageManagerDisplay]] : []),
...(conptyDisplay ? [[t("about.conpty"), conptyDisplay]] : []),
];
+5 -5
View File
@@ -147,7 +147,7 @@ function MarkdownContent({ content }: { content: string }) {
export default function UpdateDialog({ open, onClose, onUpdateFound }: UpdateDialogProps) {
const { t } = useTranslation();
const { runtimeInfo } = useApp();
const { runtimeInfo, runtimeInfoLoaded } = useApp();
const [status, setStatus] = useState<UpdateStatus>("checking");
const [progress, setProgress] = useState<UpdateProgress>({ downloaded: 0, total: 0 });
const [error, setError] = useState<string>("");
@@ -158,7 +158,7 @@ export default function UpdateDialog({ open, onClose, onUpdateFound }: UpdateDia
onUpdateFoundRef.current = onUpdateFound;
useEffect(() => {
if (!open) return;
if (!open || !runtimeInfoLoaded || runtimeInfo.packageManager) return;
getVersion()
.then(setCurrentVersion)
@@ -191,10 +191,10 @@ export default function UpdateDialog({ open, onClose, onUpdateFound }: UpdateDia
return () => {
cancelled = true;
};
}, [open, runtimeInfo.portable]);
}, [open, runtimeInfo.packageManager, runtimeInfo.portable, runtimeInfoLoaded]);
const handleUpdate = useCallback(async () => {
if (isUpdating.current) return;
if (isUpdating.current || runtimeInfo.packageManager) return;
isUpdating.current = true;
setStatus("downloading");
setError("");
@@ -209,7 +209,7 @@ export default function UpdateDialog({ open, onClose, onUpdateFound }: UpdateDia
setStatus("error");
isUpdating.current = false;
}
}, [runtimeInfo.portable]);
}, [runtimeInfo.packageManager, runtimeInfo.portable]);
const handleRelaunch = useCallback(async () => {
try {
+18 -7
View File
@@ -756,7 +756,14 @@ export default function Header({
}: HeaderProps) {
const [appWindow] = useState(() => getCurrentWindow());
const { themeName, setTheme, themeNames, terminalThemeName, setTerminalTheme } = useTheme();
const { updateAppSettings, updateUi, appSettings, tabs } = useApp();
const {
updateAppSettings,
updateUi,
appSettings,
tabs,
runtimeInfo,
runtimeInfoLoaded,
} = useApp();
const [showImportDialog, setShowImportDialog] = useState(false);
const [isMaximized, setIsMaximized] = useState(false);
const [showCloseConfirm, setShowCloseConfirm] = useState(false);
@@ -1242,12 +1249,16 @@ export default function Header({
icon: "menu_book",
action: () => openUrl(`${packageJson.docspage}`),
},
{
id: "help.checkUpdates",
label: t("menu.checkForUpdates"),
icon: hasUpdate ? "upgrade" : "update",
action: onCheckForUpdates,
},
...(!runtimeInfoLoaded || runtimeInfo.packageManager
? []
: [
{
id: "help.checkUpdates",
label: t("menu.checkForUpdates"),
icon: hasUpdate ? "upgrade" : "update",
action: onCheckForUpdates,
},
]),
{
id: "help.viewLogs",
label: t("menu.viewLogs"),
+1
View File
@@ -276,6 +276,7 @@ const RECENT_CONNECTION_LIMIT = 10;
const DEFAULT_RUNTIME_INFO: AppRuntimeInfo = {
portable: false,
mode: "installed",
packageManager: null,
executableDir: "",
dataDir: "",
configDir: "",
+1
View File
@@ -233,6 +233,7 @@ const DEFAULT_APP_SETTINGS: AppSettings = {
const DEFAULT_RUNTIME_INFO: AppRuntimeInfo = {
portable: false,
mode: "installed",
packageManager: null,
executableDir: "",
dataDir: "",
configDir: "",
+1
View File
@@ -15,6 +15,7 @@
"installed": "Installed",
"issues": "Issues",
"operatingSystem": "Operating system",
"packageManager": "Package manager",
"portable": "Portable",
"runtime": "Runtime",
"supportInfo": "Support information",
+1
View File
@@ -15,6 +15,7 @@
"installed": "설치 버전",
"issues": "이슈",
"operatingSystem": "운영 체제",
"packageManager": "패키지 관리자",
"portable": "포터블 버전",
"runtime": "실행 환경",
"supportInfo": "지원 정보",
+1
View File
@@ -15,6 +15,7 @@
"installed": "安装版",
"issues": "问题反馈",
"operatingSystem": "操作系统",
"packageManager": "包管理器",
"portable": "便携版",
"runtime": "运行环境",
"supportInfo": "支持信息",
+1
View File
@@ -15,6 +15,7 @@
"installed": "安裝版",
"issues": "問題回報",
"operatingSystem": "作業系統",
"packageManager": "套件管理器",
"portable": "便攜版",
"runtime": "執行環境",
"supportInfo": "支援資訊",
+2
View File
@@ -30,6 +30,7 @@ export type { TemporaryLinkConfig } from "@/types/temporaryConnection";
export interface AppRuntimeInfo {
portable: boolean;
mode: "installed" | "portable";
packageManager?: string | null;
executableDir: string;
dataDir: string;
configDir: string;
@@ -42,6 +43,7 @@ export interface AppSupportInfo {
os: string;
architecture: string;
runtime: "portable" | "installed";
packageManager?: string | null;
conpty?: {
available: boolean;
activeBundled: number;