Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions apps/config/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,6 @@ async fn verhub_announcements(limit: u32) -> Result<Vec<verhub::Announcement>, S
.map_err(|e| e.to_string())
}

/// `contact` 可空——留了才好回复用户。
#[tauri::command]
async fn verhub_submit_feedback(
content: String,
Expand All @@ -501,7 +500,6 @@ async fn verhub_submit_feedback(
.map_err(|e| e.to_string())
}

/// 上报一段日志
#[tauri::command]
async fn verhub_upload_log(content: String) -> Result<(), String> {
let device_info = serde_json::json!({
Expand Down
4 changes: 2 additions & 2 deletions apps/config/src-tauri/src/verhub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ pub async fn upload_log(content: &str, device_info: serde_json::Value) -> Result
Ok(())
}

/// 项目公开链接(主页 / 仓库 / 文档等)的缓存有效期。链接极少变动,一天刷新一次足够
/// 项目公开链接的缓存有效期
const PROJECT_CACHE_TTL_SECS: i64 = 24 * 60 * 60;

/// 项目公开链接。所有字段都可能缺省(Verhub 上未填写);前端须自备回退链接。
Expand Down Expand Up @@ -259,7 +259,7 @@ fn unix_now() -> i64 {
}

/// 项目公开链接:内存缓存 → 磁盘缓存(`cache_path`)→ Verhub API 逐级回退。
/// API 拉取失败时退回过期缓存(有旧数据总比没有强),完全没有缓存才报错。
/// API 拉取失败时退回过期缓存,完全没有缓存才报错。
pub async fn project_links(cache_path: &Path) -> Result<ProjectLinks> {
let now = unix_now();
if let Some(cached) = cache_get()
Expand Down
4 changes: 2 additions & 2 deletions apps/config/ui/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@
});

onMount(() => {
// 主题:main.js 已在挂载前应用过一次(免得启动屏配色跳变),这里只负责跟随系统变化。
// main.js 已在挂载前应用过一次,这里只负责跟随系统变化。
const media = matchMedia("(prefers-color-scheme: dark)");
const onSystemTheme = () => applyTheme(loadPreference());
media.addEventListener("change", onSystemTheme);

// 配置到手、界面有内容可看了,才把启动屏淡掉;失败时也得淡掉,否则永远卡在启动屏
// 配置到手后才淡掉启动屏;失败时同样要淡掉,否则会一直卡住
loadAll()
.then(() => {
autoSaveReady = true;
Expand Down
2 changes: 1 addition & 1 deletion apps/config/ui/src/components/DataNoticeModal.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
// 便携版写不进程序目录时的提示:说明设置存到了哪里,以及怎么改回去
// 便携版写不进程序目录时的提示:设置存到了哪里、如何改回去
import IconAlert from "~icons/lucide/triangle-alert";
import Modal from "./Modal.svelte";
import { app } from "../lib/state.svelte.js";
Expand Down
3 changes: 1 addition & 2 deletions apps/config/ui/src/components/Markdown.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

const html = $derived(renderMarkdown(source));

// 链接一律交给系统浏览器:webview 里真导航走了就回不到配置界面了
// 链接一律交给系统浏览器:webview 内真导航后回不到配置界面
function onClick(e) {
const a = e.target.closest?.("a[href]");
if (!a) return;
Expand Down Expand Up @@ -70,7 +70,6 @@
.md :global(h6) {
font-size: 13px;
}
/* GitHub 的一二级标题带下边线 */
.md :global(h1),
.md :global(h2) {
padding-bottom: 5px;
Expand Down
5 changes: 2 additions & 3 deletions apps/config/ui/src/components/UpdateModal.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script>
// 更新提示。强制更新(Verhub 的 required=true)时**不能关**:没有右上角的叉、
// Esc 和点遮罩都不管用,只能去下载或退出程序——这正是「强制」的含义。
// 因此这里不用通用的 Modal 组件(那个总是可关闭的)。
// 更新提示。强制更新(required=true)时不可关闭:无关闭按钮,Esc 与点遮罩均无效。
// 故不复用总是可关闭的 Modal 组件。
import IconDownload from "~icons/lucide/download";
import IconTriangleAlert from "~icons/lucide/triangle-alert";
import IconX from "~icons/lucide/x";
Expand Down
1 change: 0 additions & 1 deletion apps/config/ui/src/lib/license.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// MIT 协议全文,逐字取自仓库根目录的 LICENSE 文件。
// 关于页直接展示它——开源软件应当把协议原文摆出来,而不只是写个「MIT」。

export const MIT_LICENSE = `MIT License

Expand Down
2 changes: 1 addition & 1 deletion apps/config/ui/src/lib/pointer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const MAX_CLICKS = 3;
export const MIN_MULTI_CLICK_MS = 150;
export const MAX_MULTI_CLICK_MS = 1000;

/** 把一颗键的触发条件写成人话,如「Ctrl + 三击」。 */
/** 把一颗键的触发条件格式化为可读文本,如「Ctrl + 三击」。 */
export function describeTrigger(button) {
if (!button?.enabled) return t("mouse.notEnabled");
const clicks = t(
Expand Down
8 changes: 4 additions & 4 deletions apps/config/ui/src/lib/state.svelte.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export function openRestoreTool() {
app.restoreOpen = true;
}

/** 重新检测程序目录下的 pssuspend64.exe(放入文件后无需重启即可点亮增强冻结)。 */
/** 重新检测 pssuspend64.exe;放入文件后无需重启即可启用增强冻结。 */
export async function refreshPssuspend() {
try {
app.pssuspend = !!(await invoke("pssuspend_available"));
Expand Down Expand Up @@ -146,11 +146,11 @@ export async function loadAll() {
invoke("pssuspend_available").then((v) => (app.pssuspend = !!v)),
invoke("data_location").then((loc) => {
app.dataLocation = loc;
// 便携版本该把设置放在程序目录里,回退了就说明那里写不进去,得让用户知道
// 回退即程序目录写不进去,须提示用户
app.dataNoticeOpen = loc?.kind === "portable_fallback";
}),
];
// 项目链接拉不到时静默——「关于」页有内置回退链接,不值得打扰用户
// 拉取失败静默:「关于」页有内置回退链接。
verhub
.projectLinks()
.then((p) => (app.project = p))
Expand Down Expand Up @@ -294,7 +294,7 @@ export async function loadAnnouncements({ popNew = false } = {}) {
}
}

/** 记住这条公告已读——下次启动不再弹它。 */
/** 记住这条公告已读,下次启动不再弹出。 */
export function markAnnouncementSeen(id) {
app.pendingAnnouncement = null;
if (!app.config || !id) return;
Expand Down
12 changes: 5 additions & 7 deletions crates/common/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn default_language() -> String {

#[derive(Debug, thiserror::Error)]
pub enum ConfigError {
/// 带上出错的路径:用户据此才能判断是装在了不可写的目录,还是被杀软拦了
/// 带上出错的路径,便于区分目录不可写与被拦截
#[error("配置文件读写错误: {source}(路径: {path})")]
Io {
path: String,
Expand Down Expand Up @@ -283,7 +283,7 @@ impl Default for TrayBadges {
}

impl TrayBadges {
/// 未知状态源一律归一为置空(不显示),避免手改配置后角标行为不可预测。幂等。
/// 未知状态源归一为置空,避免手改配置后角标行为不可预测。幂等。
pub fn normalize(&mut self) {
for v in [
&mut self.red,
Expand Down Expand Up @@ -525,9 +525,7 @@ impl Config {
}

/// 同 [`Config::load`],但额外报告「文件存在却解析失败、已回退默认值」的情况。
///
/// 损坏文件回退默认值是刻意行为(保证核心总能启动),代价是用户的规则会「凭空消失」。
/// 调用方据第二个返回值把解析错误写进日志,否则这一幕无迹可循。
/// 回退保证核心总能启动,代价是用户的规则会凭空消失,故须由调用方记进日志。
/// 返回 `(配置, 解析错误)`;解析成功或文件不存在时第二项为 `None`。
pub fn load_reporting(path: &Path) -> Result<(Self, Option<String>), ConfigError> {
match std::fs::read_to_string(path) {
Expand Down Expand Up @@ -557,8 +555,8 @@ impl Config {
self.setting.normalize();
}

/// 写入配置。先写同目录下的临时文件再原子替换:写到一半失败(磁盘满、
/// 杀软拦截)也不会把原文件截断成半截,用户的规则不会因此丢光
/// 写入配置。先写同目录下的临时文件再原子替换,写到一半失败也不会
/// 把原文件截断成半截
pub fn save(&self, path: &Path) -> Result<(), ConfigError> {
let json = self.to_json()?;
if let Some(parent) = path.parent()
Expand Down
19 changes: 5 additions & 14 deletions crates/common/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
//!
//! - **安装版**用 `%APPDATA%\BossKey`。安装包可以装进 `Program Files`,那里普通权限
//! 进程不可写,配置程序每次保存都会得到 `os error 5`。
//! - **便携版**用 exe 同目录,拷走整个文件夹就带走了全部设置。
//! 目录写不进去时退回 `%APPDATA%\BossKey`,程序照常能用,界面据此提示这是权限问题。
//! - **便携版**用 exe 同目录;写不进去时退回 `%APPDATA%\BossKey`,界面据此提示权限问题。
//!
//! 靠程序目录里有没有安装痕迹来分辨:安装包会放一份 [`INSTALLED_MARKER`],
//! 卸载程序 `unins*.exe` 也在同一目录,便携版压缩包里两者都没有。
Expand All @@ -15,9 +14,7 @@

use std::path::{Path, PathBuf};

/// 配置文件名。
pub const CONFIG_FILE_NAME: &str = "config.json";
/// 数据目录在 `%APPDATA%` 下的名字。
pub const USER_DIR_NAME: &str = "BossKey";
/// 安装版标记文件,由安装包放进程序目录,卸载时随之移除。
pub const INSTALLED_MARKER: &str = "installed.marker";
Expand Down Expand Up @@ -59,11 +56,8 @@ pub fn user_data_dir() -> PathBuf {
}
}

/// 程序目录里有没有安装痕迹。
///
/// 认两样东西:安装包放的 [`INSTALLED_MARKER`],以及卸载程序 `unins*.exe`。
/// 后者是兜底——标记文件被误删时仍认得出是安装版,不至于把数据写回 `Program Files`。
/// 卸载程序的序号会随重复安装递增(`unins000` / `unins001`…),故按前缀匹配。
/// 程序目录里有没有安装痕迹:安装包放的 [`INSTALLED_MARKER`],或卸载程序 `unins*.exe`。
/// 后者是标记文件被误删时的兜底;其序号随重复安装递增,故按前缀匹配。
pub fn is_installed(program_dir: &Path) -> bool {
if program_dir.join(INSTALLED_MARKER).exists() {
return true;
Expand Down Expand Up @@ -92,9 +86,8 @@ pub fn dir_writable(dir: &Path) -> bool {

/// 把程序目录里的旧配置搬到用户目录:先复制,再尽力删掉原文件。
///
/// 目标已有配置就不动它——那是当前在用的一份,旧文件不得覆盖,也不去删。
/// 删不掉(`Program Files` 下没有写权限、文件被占用)就留在原处:安装版只认用户目录,
/// 旧文件不会再被读到。
/// 目标已有配置就不动它,那是当前在用的一份。删不掉就留在原处:
/// 安装版只认用户目录,旧文件不会再被读到。
fn migrate_config(program_dir: &Path, user_dir: &Path) {
let old = program_dir.join(CONFIG_FILE_NAME);
let new = user_dir.join(CONFIG_FILE_NAME);
Expand Down Expand Up @@ -146,12 +139,10 @@ pub fn locate() -> DataDir {
resolve_data_dir(&program_dir, &user_data_dir(), installed, portable_writable)
}

/// 本次运行使用的数据目录路径。
pub fn data_dir() -> PathBuf {
locate().dir
}

/// 配置文件路径。
pub fn config_path() -> PathBuf {
data_dir().join(CONFIG_FILE_NAME)
}
Expand Down
Loading
Loading