修复: 协议层与体验缺陷六件
- temperature 按模型适配,仅收 1 的模型不再 400 - 流式 error 帧不再被 choices 必填整帧丢弃 - 只读缓存写后失效 - git diff 中文截断撞 UTF-8 边界 panic - 非视觉模型纯图片直接拒绝 - 全局快捷键补输入焦点守卫
This commit is contained in:
+50
-6
@@ -4,6 +4,9 @@
|
||||
//! - 托盘菜单「显示主窗口」唤起 / 「退出」app.exit(0) 真正结束
|
||||
//! - TrayHandle 经 app.manage 保活,防托盘图标被 GC 移除
|
||||
//! - P1 bg 化:运行态菜单项 + tooltip 随 ConvState 迁移刷新(guard.transition 挂钩 update_tray_runtime)
|
||||
//! - i18n:文案按系统 locale 取中/英双语静态映射(locale 判定一次缓存),无 Rust i18n 机制的最小实现
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use tauri::{
|
||||
AppHandle, Manager,
|
||||
menu::{Menu, MenuItem},
|
||||
@@ -12,6 +15,45 @@ use tauri::{
|
||||
|
||||
use crate::state::AppState;
|
||||
|
||||
/// 托盘文案双语映射(系统 locale 判定一次,进程内缓存;判定失败回退中文——应用主语言)。
|
||||
/// 菜单项与运行态文本分两处消费,映射同源防两处漂移。
|
||||
struct TrayTexts {
|
||||
status_idle: &'static str,
|
||||
status_running: &'static str,
|
||||
show: &'static str,
|
||||
quit: &'static str,
|
||||
tooltip_running: &'static str,
|
||||
}
|
||||
|
||||
/// 按系统 locale 取托盘文案(判定一次缓存)。zh* → 中文,其余(含判定失败)→ 中文/英文
|
||||
/// 各取其一:locale 明确非 zh 用英文,判定失败(None)回退中文(应用主语言)。
|
||||
fn tray_texts() -> &'static TrayTexts {
|
||||
static TEXTS: OnceLock<TrayTexts> = OnceLock::new();
|
||||
TEXTS.get_or_init(|| {
|
||||
let zh = sys_locale::get_locale()
|
||||
.map(|l| l.to_ascii_lowercase().starts_with("zh"))
|
||||
// None = 系统locale不可得,回退中文(应用默认语言),与首次安装体验一致
|
||||
.unwrap_or(true);
|
||||
if zh {
|
||||
TrayTexts {
|
||||
status_idle: "无运行中会话",
|
||||
status_running: "运行中 {} 个会话",
|
||||
show: "显示主窗口",
|
||||
quit: "退出",
|
||||
tooltip_running: "DevFlow (运行中 {} 个会话)",
|
||||
}
|
||||
} else {
|
||||
TrayTexts {
|
||||
status_idle: "No running sessions",
|
||||
status_running: "{} session(s) running",
|
||||
show: "Show Main Window",
|
||||
quit: "Quit",
|
||||
tooltip_running: "DevFlow ({} session(s) running)",
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// managed state 保活,防 GC 移除托盘图标。
|
||||
/// tray 持 TrayIcon 本体(保活为主,update_tray_runtime 借用刷 tooltip);
|
||||
/// status 为运行态纯展示项句柄,供 update_tray_runtime 刷文本。
|
||||
@@ -24,10 +66,11 @@ pub struct TrayHandle {
|
||||
|
||||
/// 创建托盘:图标 + 菜单(运行态/显示主窗口/退出)。
|
||||
pub fn setup_tray(app: &AppHandle) -> tauri::Result<()> {
|
||||
let t = tray_texts();
|
||||
// 运行态纯展示项:enabled=false 置灰不响应点击,文本由 update_tray_runtime 维护
|
||||
let status = MenuItem::with_id(app, "status", "无运行中会话", false, None::<&str>)?;
|
||||
let show = MenuItem::with_id(app, "show", "显示主窗口", true, None::<&str>)?;
|
||||
let quit = MenuItem::with_id(app, "quit", "退出", true, None::<&str>)?;
|
||||
let status = MenuItem::with_id(app, "status", t.status_idle, false, None::<&str>)?;
|
||||
let show = MenuItem::with_id(app, "show", t.show, true, None::<&str>)?;
|
||||
let quit = MenuItem::with_id(app, "quit", t.quit, true, None::<&str>)?;
|
||||
let menu = Menu::with_items(app, &[&status, &show, &quit])?;
|
||||
// 复用窗口图标(tauri.conf.json bundle.icon 已配置),缺则 panic 提示配置
|
||||
let icon = app
|
||||
@@ -60,14 +103,15 @@ pub fn update_tray_runtime(app: &AppHandle) {
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let t = tray_texts();
|
||||
let n = state.conv_states.active_convs().len();
|
||||
let text = if n > 0 {
|
||||
format!("运行中 {} 个会话", n)
|
||||
t.status_running.replace("{}", &n.to_string())
|
||||
} else {
|
||||
"无运行中会话".to_string()
|
||||
t.status_idle.to_string()
|
||||
};
|
||||
let tooltip = if n > 0 {
|
||||
format!("DevFlow (运行中 {} 个会话)", n)
|
||||
t.tooltip_running.replace("{}", &n.to_string())
|
||||
} else {
|
||||
"DevFlow (MCP server running)".to_string()
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user