feat: 提交详情能看 diff,也能丢给 AI 审这一次改动。文件检查可单独排除路径,TODO 只认大写,避免把 todo 表和模块当成待办标记。

热力图按容器宽度铺满一年,不再横向滚动。托盘右键换成可换皮肤的弹层;更新下载显示进度,退出后再由脚本拉起安装器,避免还占着 exe。
This commit is contained in:
李琦
2026-08-19 15:46:03 +08:00
parent 1694397245
commit 7c4109f687
38 changed files with 2618 additions and 129 deletions

View File

@@ -72,10 +72,14 @@ func shellTexts(locale string) shellText {
// shellState 保存原生外壳(窗口/托盘/菜单)的运行引用。
type shellState struct {
wapp *application.App
win *application.WebviewWindow
tray *application.SystemTray
quitting atomic.Bool
wapp *application.App
win *application.WebviewWindow
tray *application.SystemTray
popup *application.WebviewWindow
popupReady atomic.Bool
popupScheduled atomic.Bool
popupShownAt atomic.Int64
quitting atomic.Bool
}
// SetupShell 在窗口创建后接管关闭行为,并挂载原生菜单与系统托盘。
@@ -109,8 +113,21 @@ func (a *App) SetupShell(wapp *application.App, win *application.WebviewWindow)
a.shell.tray.SetIcon(appIcon)
a.shell.tray.OnClick(a.showMainWindow)
a.shell.tray.OnDoubleClick(a.showMainWindow)
a.shell.tray.OnRightClick(a.onTrayRightClick)
a.wireNotificationClicks()
a.RefreshShell()
a.scheduleTrayPopup()
}
func (a *App) onTrayRightClick() {
if a.trayMenuStyle() != "native" && a.shell != nil && a.shell.popupReady.Load() {
a.showTrayPopup()
return
}
a.hideTrayPopup()
if a.shell != nil && a.shell.tray != nil {
a.shell.tray.OpenMenu()
}
}
// wireNotificationClicks 点击系统通知时唤起窗口并跳到对应页面。
@@ -180,9 +197,14 @@ func (a *App) refreshTray(t shellText, locale string) {
st := a.collectTrayStatus()
a.shell.tray.SetTooltip(st.tooltip(locale))
a.shell.tray.SetIcon(trayIconWithBadge(appIcon, st.badgeColor()))
// 原生菜单始终挂上:自定义弹层没就绪时右键仍走 OpenMenu。刷新图标时不重绑点击、不藏已打开的弹层。
a.shell.tray.SetMenu(a.buildTrayMenu(t, st))
a.shell.tray.OnClick(a.showMainWindow)
a.shell.tray.OnDoubleClick(a.showMainWindow)
if a.trayMenuStyle() == "native" {
a.hideTrayPopup()
} else {
a.scheduleTrayPopup()
}
a.emit("tray:refresh", nil)
}
// RefreshTrayStatus 轻量刷新托盘状态(同步/消息变更时调用,不重建应用菜单)。
@@ -377,6 +399,7 @@ func (a *App) navigateTo(path string) {
}
func (a *App) showMainWindow() {
a.hideTrayPopup()
if a.shell == nil || a.shell.win == nil {
return
}