Skip to content

Commit 1de6baf

Browse files
committed
refactor
1 parent d7e0636 commit 1de6baf

File tree

6 files changed

+486
-485
lines changed

6 files changed

+486
-485
lines changed

autostart.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package main
2+
3+
import (
4+
"golang.org/x/sys/windows/registry"
5+
"os"
6+
)
7+
8+
func isAutoStartEnabled() bool {
9+
k, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.QUERY_VALUE)
10+
if err != nil {
11+
return false
12+
}
13+
defer k.Close()
14+
15+
val, _, err := k.GetStringValue("HIDELL")
16+
if err != nil {
17+
return false
18+
}
19+
20+
exePath, err := os.Executable()
21+
if err != nil {
22+
return false
23+
}
24+
25+
return val == exePath
26+
}
27+
28+
func enableAutoStart() {
29+
exePath, err := os.Executable()
30+
if err != nil {
31+
return
32+
}
33+
34+
k, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.SET_VALUE)
35+
if err != nil {
36+
return
37+
}
38+
defer k.Close()
39+
40+
_ = k.SetStringValue("HIDELL", exePath)
41+
}
42+
43+
func disableAutoStart() {
44+
k, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.SET_VALUE)
45+
if err != nil {
46+
return
47+
}
48+
defer k.Close()
49+
50+
_ = k.DeleteValue("HIDELL")
51+
}

config.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"os"
6+
"path/filepath"
7+
)
8+
9+
func LoadConfig() {
10+
configPath := filepath.Join(getUserHome(), ".hidell", "config.json")
11+
data, err := os.ReadFile(configPath)
12+
if err != nil {
13+
if os.IsNotExist(err) {
14+
customDirs = []CustomDir{}
15+
return
16+
}
17+
panic(err)
18+
}
19+
20+
err = json.Unmarshal(data, &customDirs)
21+
if err != nil {
22+
panic(err)
23+
}
24+
}
25+
26+
func saveConfig() {
27+
configPath := filepath.Join(getUserHome(), ".hidell", "config.json")
28+
data, err := json.MarshalIndent(customDirs, "", " ")
29+
if err != nil {
30+
panic(err)
31+
}
32+
33+
err = os.MkdirAll(filepath.Dir(configPath), 0755)
34+
if err != nil {
35+
panic(err)
36+
}
37+
38+
err = os.WriteFile(configPath, data, 0644)
39+
if err != nil {
40+
panic(err)
41+
}
42+
}

custom_dir.go

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
package main
2+
3+
import (
4+
"github.com/fsnotify/fsnotify"
5+
"github.com/getlantern/systray"
6+
"github.com/ncruces/zenity"
7+
"path/filepath"
8+
"strings"
9+
)
10+
11+
type CustomDir struct {
12+
Path string `json:"path"`
13+
Alias string `json:"alias"`
14+
Active bool `json:"active"`
15+
Hidden bool `json:"hidden"`
16+
watcher *fsnotify.Watcher
17+
done chan struct{}
18+
}
19+
20+
var customDirs []CustomDir
21+
22+
func addCustomDirMenu(dir *CustomDir, parentMenu *systray.MenuItem) {
23+
menuName := dir.Alias
24+
if menuName == "" {
25+
menuName = dir.Path
26+
}
27+
dirMenu := parentMenu.AddSubMenuItem(menuName, "")
28+
mActivate := dirMenu.AddSubMenuItem("激活", "")
29+
mShow := dirMenu.AddSubMenuItem("显示", "")
30+
mHide := dirMenu.AddSubMenuItem("隐藏", "")
31+
mRemove := dirMenu.AddSubMenuItem("移除", "")
32+
33+
if dir.Active {
34+
mActivate.Check()
35+
dir.startWatching()
36+
}
37+
if dir.Hidden {
38+
mHide.Check()
39+
} else {
40+
mShow.Check()
41+
}
42+
43+
go func() {
44+
for {
45+
select {
46+
case <-mActivate.ClickedCh:
47+
toggleActivate(dir, mActivate)
48+
case <-mShow.ClickedCh:
49+
showCustomDir(dir, mShow, mHide)
50+
case <-mHide.ClickedCh:
51+
hideCustomDir(dir, mShow, mHide)
52+
case <-mRemove.ClickedCh:
53+
removeCustomDir(dir, dirMenu, parentMenu)
54+
return
55+
}
56+
}
57+
}()
58+
}
59+
60+
func addNewCustomDir(parentMenu *systray.MenuItem) {
61+
path, err := zenity.SelectFile(
62+
zenity.Title("选择目录"),
63+
zenity.Directory(),
64+
)
65+
if err != nil {
66+
if err == zenity.ErrCanceled {
67+
return
68+
}
69+
zenity.Error("选择目录时出错: " + err.Error())
70+
return
71+
}
72+
73+
alias, err := zenity.Entry(
74+
"为这个目录输入一个别名(可选)",
75+
zenity.Title("设置别名"),
76+
)
77+
if err != nil {
78+
if err == zenity.ErrCanceled {
79+
alias = ""
80+
} else {
81+
zenity.Error("输入别名时出错: " + err.Error())
82+
return
83+
}
84+
}
85+
86+
newDir := CustomDir{
87+
Path: path,
88+
Alias: alias,
89+
Active: true,
90+
Hidden: true,
91+
watcher: nil,
92+
done: make(chan struct{}),
93+
}
94+
customDirs = append(customDirs, newDir)
95+
addCustomDirMenu(&customDirs[len(customDirs)-1], parentMenu)
96+
hideDotFiles(path)
97+
customDirs[len(customDirs)-1].startWatching()
98+
saveConfig()
99+
}
100+
101+
func toggleActivate(dir *CustomDir, menuItem *systray.MenuItem) {
102+
dir.Active = !dir.Active
103+
if dir.Active {
104+
menuItem.Check()
105+
dir.startWatching()
106+
} else {
107+
menuItem.Uncheck()
108+
dir.stopWatching()
109+
}
110+
saveConfig()
111+
}
112+
113+
func showCustomDir(dir *CustomDir, showItem, hideItem *systray.MenuItem) {
114+
dir.Hidden = false
115+
showItem.Check()
116+
hideItem.Uncheck()
117+
unhideDotFiles(dir.Path)
118+
saveConfig()
119+
}
120+
121+
func hideCustomDir(dir *CustomDir, showItem, hideItem *systray.MenuItem) {
122+
dir.Hidden = true
123+
hideItem.Check()
124+
showItem.Uncheck()
125+
hideDotFiles(dir.Path)
126+
saveConfig()
127+
}
128+
129+
func removeCustomDir(dir *CustomDir, dirMenu, parentMenu *systray.MenuItem) {
130+
dir.stopWatching()
131+
for i, d := range customDirs {
132+
if d.Path == dir.Path {
133+
customDirs = append(customDirs[:i], customDirs[i+1:]...)
134+
break
135+
}
136+
}
137+
dirMenu.Hide()
138+
saveConfig()
139+
}
140+
141+
func (dir *CustomDir) startWatching() {
142+
if dir.watcher != nil {
143+
return
144+
}
145+
146+
watcher, err := fsnotify.NewWatcher()
147+
if err != nil {
148+
zenity.Error("创建监视器时出错: " + err.Error())
149+
return
150+
}
151+
152+
dir.watcher = watcher
153+
dir.done = make(chan struct{})
154+
155+
go func() {
156+
defer watcher.Close()
157+
dir.watchDir()
158+
}()
159+
160+
err = watcher.Add(dir.Path)
161+
if err != nil {
162+
zenity.Error("添加监视目录时出错: " + err.Error())
163+
dir.stopWatching()
164+
}
165+
}
166+
167+
func (dir *CustomDir) stopWatching() {
168+
if dir.watcher == nil {
169+
return
170+
}
171+
172+
close(dir.done)
173+
dir.watcher.Close()
174+
dir.watcher = nil
175+
}
176+
177+
func (dir *CustomDir) watchDir() {
178+
for {
179+
select {
180+
case <-dir.done:
181+
return
182+
case event, ok := <-dir.watcher.Events:
183+
if !ok {
184+
return
185+
}
186+
if event.Op&fsnotify.Create == fsnotify.Create {
187+
if strings.HasPrefix(filepath.Base(event.Name), ".") {
188+
hideFile(event.Name)
189+
}
190+
}
191+
case err, ok := <-dir.watcher.Errors:
192+
if !ok {
193+
return
194+
}
195+
zenity.Error("监视目录时出错: " + err.Error())
196+
}
197+
}
198+
}

file_operations.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package main
2+
3+
import (
4+
"github.com/fsnotify/fsnotify"
5+
"os"
6+
"path/filepath"
7+
"strings"
8+
"syscall"
9+
)
10+
11+
func hideDotFiles(dir string) {
12+
files, err := os.ReadDir(dir)
13+
if err != nil {
14+
panic(err)
15+
}
16+
for _, file := range files {
17+
if strings.HasPrefix(file.Name(), ".") {
18+
hideFile(filepath.Join(dir, file.Name()))
19+
}
20+
}
21+
}
22+
23+
func unhideDotFiles(dir string) {
24+
files, err := os.ReadDir(dir)
25+
if err != nil {
26+
panic(err)
27+
}
28+
for _, file := range files {
29+
if strings.HasPrefix(file.Name(), ".") {
30+
unhideFile(filepath.Join(dir, file.Name()))
31+
}
32+
}
33+
}
34+
35+
func hideFile(path string) {
36+
ptr, err := syscall.UTF16PtrFromString(path)
37+
if err != nil {
38+
panic(err)
39+
}
40+
attrs, err := syscall.GetFileAttributes(ptr)
41+
if err != nil {
42+
panic(err)
43+
}
44+
_ = syscall.SetFileAttributes(ptr, attrs|syscall.FILE_ATTRIBUTE_HIDDEN)
45+
}
46+
47+
func unhideFile(path string) {
48+
ptr, err := syscall.UTF16PtrFromString(path)
49+
if err != nil {
50+
panic(err)
51+
}
52+
attrs, err := syscall.GetFileAttributes(ptr)
53+
if err != nil {
54+
panic(err)
55+
}
56+
_ = syscall.SetFileAttributes(ptr, attrs&^syscall.FILE_ATTRIBUTE_HIDDEN)
57+
}
58+
59+
func watchDir(dir string, done chan struct{}) {
60+
watcher, err := fsnotify.NewWatcher()
61+
if err != nil {
62+
panic(err)
63+
}
64+
defer watcher.Close()
65+
66+
err = watcher.Add(dir)
67+
if err != nil {
68+
panic(err)
69+
}
70+
71+
for {
72+
select {
73+
case <-done:
74+
return
75+
case event, ok := <-watcher.Events:
76+
if !ok {
77+
return
78+
}
79+
if event.Op&fsnotify.Create == fsnotify.Create {
80+
if strings.HasPrefix(filepath.Base(event.Name), ".") {
81+
hideFile(event.Name)
82+
}
83+
}
84+
case err, ok := <-watcher.Errors:
85+
if !ok {
86+
return
87+
}
88+
panic(err)
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)