feat(t101): 托盤刪除語意取代看守語意——leo 實測裁定
「沒有看守這件事,只要列入就是看守,不想同步就刪掉」: 子選單「停止看守這個資料夾」→「刪除這個知識庫」(按下從列表剔除、冪等); 「+ 建立新資料夾並看守…」整項刪除。tray go test 綠(總管親跑)。 (實作=子 CC;驗證+commit=總管。此案原被誤擱置害 v0.13 漏裝=mistakes c947e5a)
This commit is contained in:
+2
-49
@@ -494,7 +494,7 @@ func main() {
|
||||
desk, hasTray := a.(desktop.App)
|
||||
|
||||
// rebuildTray 依現況重建整個 tray 選單(daemon-beta t7 多資料夾):
|
||||
// 每個看守中的資料夾一列(點=在 Finder 打開)+各自的「停止看守」項;
|
||||
// 每個列入的資料夾一列(點=在 Finder 打開)+各自的「刪除這個知識庫」項;
|
||||
// 重設選單=刷新(比 (*Menu).Refresh() 跨版本更穩)。
|
||||
var rebuildTray func()
|
||||
|
||||
@@ -599,51 +599,6 @@ func main() {
|
||||
}, win)
|
||||
}
|
||||
|
||||
// t17:fyne 內建 folder picker 無法輸入名稱建新資料夾(leo 07-24 親測)——
|
||||
// 補一條「建立新資料夾並看守…」:文字輸入+確定 → 在 ~/ 底下 mkdir(已存在則沿用)→ 看守。
|
||||
newFolderAction := func() {
|
||||
win.Show()
|
||||
win.RequestFocus()
|
||||
entry := widget.NewEntry()
|
||||
entry.SetPlaceHolder("例如:我的知識庫")
|
||||
content := container.NewVBox(
|
||||
widget.NewLabel("輸入新資料夾名稱(會建立在你的家目錄底下):"),
|
||||
entry,
|
||||
)
|
||||
dialog.ShowCustomConfirm("建立新資料夾並看守", "確定", "取消", content, func(ok bool) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
name := strings.TrimSpace(entry.Text)
|
||||
if name == "" {
|
||||
return
|
||||
}
|
||||
// 只收「單層名稱」:擋路徑分隔與 ..(避免建到家目錄之外)
|
||||
if strings.ContainsAny(name, `/\`) || name == "." || name == ".." {
|
||||
dialog.ShowError(errors.New("名稱不能包含 / 或 \\,也不能是 . 或 .."), win)
|
||||
return
|
||||
}
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
dialog.ShowError(err, win)
|
||||
return
|
||||
}
|
||||
p := filepath.Join(home, name)
|
||||
if err := os.MkdirAll(p, 0o755); err != nil { // 已存在=直接沿用
|
||||
dialog.ShowError(err, win)
|
||||
return
|
||||
}
|
||||
addWatchFolder(cfg, p)
|
||||
if err := saveConfig(cfg); err != nil {
|
||||
dialog.ShowError(err, win)
|
||||
return
|
||||
}
|
||||
restartWatch()
|
||||
rebuildTray()
|
||||
win.Hide()
|
||||
}, win)
|
||||
}
|
||||
|
||||
// t98:立刻同步——寫訊號檔觸發 collector 立即跑一輪,無需等下一個定時週期。
|
||||
// syncNowItem 宣告在 rebuildTray 外,確保 click handler 的 goroutine 能還原標籤後重建選單。
|
||||
var syncNowItem *fyne.MenuItem
|
||||
@@ -719,7 +674,7 @@ func main() {
|
||||
}
|
||||
})
|
||||
it.ChildMenu = fyne.NewMenu("",
|
||||
fyne.NewMenuItem("停止看守這個資料夾", func() {
|
||||
fyne.NewMenuItem("刪除這個知識庫", func() {
|
||||
removeWatchFolder(cfg, folder)
|
||||
if err := saveConfig(cfg); err != nil {
|
||||
dialog.ShowError(err, win)
|
||||
@@ -733,7 +688,6 @@ func main() {
|
||||
}
|
||||
items = append(items,
|
||||
fyne.NewMenuItem("+ 新增知識資料夾…", addAction),
|
||||
fyne.NewMenuItem("+ 建立新資料夾並看守…", newFolderAction), // t17
|
||||
fyne.NewMenuItem("🔗 連上知識庫…(換帳號/重新連線)", func() { showConnectWizard() }), // t54
|
||||
fyne.NewMenuItemSeparator(),
|
||||
syncNowItem, // t98:立刻同步
|
||||
@@ -774,7 +728,6 @@ func main() {
|
||||
widget.NewLabelWithStyle("Arcrun RAG 知識同步", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
|
||||
widget.NewLabel("把檔案丟進你選的資料夾,就會自動進你的知識庫。\n這個程式會待在選單列/系統匣,關掉視窗它仍在背景看守。"),
|
||||
widget.NewButton("新增知識資料夾…", func() { addAction() }),
|
||||
widget.NewButton("建立新資料夾並看守…", func() { newFolderAction() }), // t17
|
||||
))
|
||||
|
||||
// 開機即看守(若已連上知識庫)
|
||||
|
||||
@@ -246,6 +246,44 @@ func TestSyncNowSignalPath(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// ── t101:removeWatchFolder 刪除邏輯 ─────────────────────────────────────────
|
||||
|
||||
// TestRemoveWatchFolder_removesEntry:移除後 WatchFolders 不含該路徑,WatchFolder 同步更新。
|
||||
func TestRemoveWatchFolder_removesEntry(t *testing.T) {
|
||||
cfg := &directConfig{
|
||||
WatchFolder: "/a",
|
||||
WatchFolders: []string{"/a", "/b", "/c"},
|
||||
}
|
||||
removeWatchFolder(cfg, "/b")
|
||||
for _, f := range cfg.WatchFolders {
|
||||
if f == "/b" {
|
||||
t.Errorf("移除後 WatchFolders 仍含 /b:%v", cfg.WatchFolders)
|
||||
}
|
||||
}
|
||||
if cfg.WatchFolder == "/b" {
|
||||
t.Errorf("移除後 WatchFolder 不應是 /b")
|
||||
}
|
||||
// 移除中間項不影響剩餘項
|
||||
if len(cfg.WatchFolders) != 2 {
|
||||
t.Errorf("移除一項後應剩 2 項,got %d:%v", len(cfg.WatchFolders), cfg.WatchFolders)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRemoveWatchFolder_idempotent:對不在清單中的路徑呼叫,清單保持不變(冪等)。
|
||||
func TestRemoveWatchFolder_idempotent(t *testing.T) {
|
||||
cfg := &directConfig{
|
||||
WatchFolder: "/a",
|
||||
WatchFolders: []string{"/a", "/b"},
|
||||
}
|
||||
removeWatchFolder(cfg, "/nonexistent")
|
||||
if len(cfg.WatchFolders) != 2 {
|
||||
t.Errorf("重複刪除不存在路徑後清單應不變,got %v", cfg.WatchFolders)
|
||||
}
|
||||
if cfg.WatchFolder != "/a" {
|
||||
t.Errorf("WatchFolder 不應改變,got %q", cfg.WatchFolder)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDirectConfigPreservesClaudeBin:config JSON round-trip 保留 claude_bin 欄位(t92 回寫驗收)。
|
||||
func TestDirectConfigPreservesClaudeBin(t *testing.T) {
|
||||
c := &directConfig{
|
||||
|
||||
Reference in New Issue
Block a user