diff --git a/electron/main/index.ts b/electron/main/index.ts index 1c83c533..ab771229 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -19,6 +19,28 @@ import { isLoaded } from "../global.js"; import { tasks } from "./backend/install-manager.js"; import { sendTelemetryOnce } from "./backend/telemetry.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +process.env.APP_ROOT = path.join(__dirname, "../.."); + +/** 与项目 package.json 一致的版本号:打包用 app.getVersion(),未打包时读 package.json */ +function getAppVersion(): string { + if (app.isPackaged) return app.getVersion(); + const pkgPath = path.join(process.env.APP_ROOT ?? __dirname, "package.json"); + try { + const raw = fs.readFileSync(pkgPath, "utf8"); + const pkg = JSON.parse(raw) as { version?: string }; + return typeof pkg.version === "string" ? pkg.version : "dev"; + } catch { + return "dev"; + } +} + +// 处理 --version 参数(在单实例检查之前) +if (process.argv.includes("--version") || process.argv.includes("-v")) { + console.log(getAppVersion()); + process.exit(0); +} + // Assure single instance application if (!app.requestSingleInstanceLock()) { app.exit(0); @@ -28,7 +50,6 @@ import "./backend/install-manager.js"; import "./handle-url-scheme.js"; const logger = pino({ name: "index.ts" }); -const __dirname = path.dirname(fileURLToPath(import.meta.url)); // The built directory structure // @@ -40,8 +61,6 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); // ├─┬ dist // │ └── index.html > Electron-Renderer // -process.env.APP_ROOT = path.join(__dirname, "../.."); - export const MAIN_DIST = path.join(process.env.APP_ROOT, "dist-electron"); export const RENDERER_DIST = path.join(process.env.APP_ROOT, "dist"); export const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL; @@ -64,18 +83,6 @@ if (!app.requestSingleInstanceLock()) { let win: BrowserWindow | null = null; const preload = path.join(__dirname, "../preload/index.mjs"); const indexHtml = path.join(RENDERER_DIST, "index.html"); -/** 与项目 package.json 一致的版本号:打包用 app.getVersion(),未打包时读 package.json */ -function getAppVersion(): string { - if (app.isPackaged) return app.getVersion(); - const pkgPath = path.join(process.env.APP_ROOT ?? __dirname, "package.json"); - try { - const raw = fs.readFileSync(pkgPath, "utf8"); - const pkg = JSON.parse(raw) as { version?: string }; - return typeof pkg.version === "string" ? pkg.version : "dev"; - } catch { - return "dev"; - } -} const getUserAgent = (): string => { return `Spark-Store/${getAppVersion()}`; diff --git a/electron/preload/index.ts b/electron/preload/index.ts index aab78e57..ef9543a0 100644 --- a/electron/preload/index.ts +++ b/electron/preload/index.ts @@ -36,6 +36,15 @@ contextBridge.exposeInMainWorld("apm_store", { return arch; } })(), + version: (() => { + // 从 package.json 读取版本号 + try { + const pkg = require("../../package.json"); + return pkg.version || "unknown"; + } catch { + return "unknown"; + } + })(), }); // --------- Preload scripts loading --------- diff --git a/src/App.vue b/src/App.vue index 0555d3bd..f7cf0438 100644 --- a/src/App.vue +++ b/src/App.vue @@ -23,6 +23,7 @@ @toggle-theme="toggleTheme" @select-category="selectCategory" @close="isSidebarOpen = false" + @open-about="openAboutModal" /> @@ -132,6 +133,11 @@ @close="closeUninstallModal" @success="onUninstallSuccess" /> + + @@ -150,6 +156,7 @@ import DownloadDetail from "./components/DownloadDetail.vue"; import InstalledAppsModal from "./components/InstalledAppsModal.vue"; import UpdateAppsModal from "./components/UpdateAppsModal.vue"; import UninstallConfirmModal from "./components/UninstallConfirmModal.vue"; +import AboutModal from "./components/AboutModal.vue"; import { APM_STORE_BASE_URL, currentApp, @@ -240,6 +247,7 @@ const updateLoading = ref(false); const updateError = ref(""); const showUninstallModal = ref(false); const uninstallTargetApp: Ref = ref(null); +const showAboutModal = ref(false); /** 启动参数 --no-apm => 仅 Spark;--no-spark => 仅 APM;由主进程 IPC 提供 */ const storeFilter = ref<"spark" | "apm" | "both">("both"); @@ -834,6 +842,14 @@ const uninstallInstalledApp = (app: App) => { requestUninstall(app); }; +const openAboutModal = () => { + showAboutModal.value = true; +}; + +const closeAboutModal = () => { + showAboutModal.value = false; +}; + // TODO: 目前 APM 商店不能暂停下载 const pauseDownload = (id: DownloadItem) => { const download = downloads.value.find((d) => d.id === id.id); diff --git a/src/components/AboutModal.vue b/src/components/AboutModal.vue new file mode 100644 index 00000000..677ebb0c --- /dev/null +++ b/src/components/AboutModal.vue @@ -0,0 +1,116 @@ + + + + + + + + + + + + 星火应用商店 + + + Spark Store + + + 版本号 + {{ version }} + + + 星火应用商店是专为 Linux 设计的应用商店,提供丰富的应用资源和便捷的安装体验。 + + + + + Gitee + + + + GitHub + + + + + + 确定 + + + + + + + + + + diff --git a/src/components/AppSidebar.vue b/src/components/AppSidebar.vue index 6f66c95e..dd922758 100644 --- a/src/components/AppSidebar.vue +++ b/src/components/AppSidebar.vue @@ -17,17 +17,19 @@ > - - - + + + + + + - @@ -84,6 +86,17 @@ > + + + + + 关于 + + @@ -103,6 +116,7 @@ const emit = defineEmits<{ (e: "toggle-theme"): void; (e: "select-category", category: string): void; (e: "close"): void; + (e: "open-about"): void; }>(); const toggleTheme = () => { @@ -112,4 +126,8 @@ const toggleTheme = () => { const selectCategory = (category: string) => { emit("select-category", category); }; + +const openAbout = () => { + emit("open-about"); +}; diff --git a/src/components/ThemeToggle.vue b/src/components/ThemeToggle.vue index 573ad361..d89196d1 100644 --- a/src/components/ThemeToggle.vue +++ b/src/components/ThemeToggle.vue @@ -1,24 +1,12 @@ - - - {{ label }} - - - - + @@ -37,21 +25,15 @@ const toggle = () => { emit("toggle"); }; -const label = computed(() => { - if (props.themeMode === "auto") return "跟随系统"; - if (props.themeMode === "dark") return "深色主题"; - return "浅色主题"; +const title = computed(() => { + if (props.themeMode === "auto") return "自动模式"; + if (props.themeMode === "dark") return "深色模式"; + return "浅色模式"; }); const iconClass = computed(() => { - if (props.themeMode === "auto") return "fa-adjust text-slate-500"; - if (props.themeMode === "dark") return "fa-moon text-amber-200"; - return "fa-sun text-amber-400"; -}); - -const togglePosition = computed(() => { - if (props.themeMode === "auto") return "translate-x-4"; - if (props.themeMode === "dark") return "translate-x-7"; - return "translate-x-1"; + if (props.themeMode === "auto") return "fa-adjust"; + if (props.themeMode === "dark") return "fa-moon"; + return "fa-sun"; });
+ Spark Store +
+ 星火应用商店是专为 Linux 设计的应用商店,提供丰富的应用资源和便捷的安装体验。 +