Skip to content

Commit d9001ca

Browse files
committed
Release v1.9.8-Alpha
1 parent 5d77f7a commit d9001ca

File tree

47 files changed

+1126
-791
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1126
-791
lines changed

.github/workflows/release.yml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,30 @@ jobs:
4242
- name: Set up Go
4343
uses: actions/setup-go@v5
4444
with:
45-
go-version-file: ./go.mod
45+
go-version-file: go.mod
46+
check-latest: true
4647
- run: go version
4748
- name: Set up pnpm
4849
uses: pnpm/action-setup@v4
4950
with:
50-
version: 9
51-
- run: pnpm -v
51+
version: latest
5252
- name: Set up Node.js
5353
uses: actions/setup-node@v4
5454
with:
5555
node-version: "latest"
5656
cache: "pnpm"
5757
cache-dependency-path: frontend/pnpm-lock.yaml
58-
- run: node -v
5958
- name: Install dependencies
6059
run: |
61-
cd frontend && pnpm install
60+
cd frontend && pnpm install --frozen-lockfile
6261
go install github.com/wailsapp/wails/v2/cmd/wails@latest
6362
6463
# Dependencies: GNU/Linux
6564
- name: Update system and dependencies
6665
if: runner.os == 'Linux'
6766
run: |
6867
sudo apt-get update
69-
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev
68+
sudo apt-get install libgtk-3-dev libwebkit2gtk-4.1-dev
7069
7170
# Hide dock bar icon: macOS
7271
- name: Update system and dependencies
@@ -125,6 +124,6 @@ jobs:
125124
release_name: ${{ github.ref_name }}
126125
overwrite: true
127126
draft: false
128-
prerelease: false
127+
prerelease: true
129128
body: |
130129
Auto-generated release from GitHub Actions.

.github/workflows/rolling-release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ jobs:
1919
- name: Set up pnpm
2020
uses: pnpm/action-setup@v4
2121
with:
22-
version: 9
22+
version: latest
2323
- name: Set up Node.js
2424
uses: actions/setup-node@v4
2525
with:
2626
node-version: "latest"
2727
cache: "pnpm"
2828
cache-dependency-path: frontend/pnpm-lock.yaml
2929
- name: Install dependencies
30-
run: cd frontend && pnpm install
30+
run: cd frontend && pnpm install --frozen-lockfile
3131
- name: Build Frontend
3232
run: cd frontend && pnpm build-only
3333
- name: Create a compressed file

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ git clone https://github.com/GUI-for-Cores/GUI.for.Clash.git
3434

3535
cd GUI.for.Clash/frontend
3636

37-
pnpm install
38-
39-
pnpm build
37+
pnpm install --frozen-lockfile && pnpm build
4038

4139
cd ..
4240

bridge/exec.go

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import (
1010
"os/exec"
1111
"strconv"
1212
"strings"
13-
"sync"
14-
"sync/atomic"
1513
"time"
1614

1715
"github.com/shirou/gopsutil/process"
@@ -50,7 +48,7 @@ func (a *App) Exec(path string, args []string, options ExecOptions) FlagResult {
5048
}
5149

5250
func (a *App) ExecBackground(path string, args []string, outEvent string, endEvent string, options ExecOptions) FlagResult {
53-
log.Printf("ExecBackground: %s %s %v", path, args, options)
51+
log.Printf("ExecBackground: %s %s %s %s %v", path, args, outEvent, endEvent, options)
5452

5553
exePath := GetPath(path)
5654

@@ -70,45 +68,36 @@ func (a *App) ExecBackground(path string, args []string, outEvent string, endEve
7068
return FlagResult{false, err.Error()}
7169
}
7270

73-
stderr, err := cmd.StderrPipe()
74-
if err != nil {
75-
return FlagResult{false, err.Error()}
76-
}
71+
cmd.Stderr = cmd.Stdout
7772

7873
if err := cmd.Start(); err != nil {
7974
return FlagResult{false, err.Error()}
8075
}
8176

8277
if outEvent != "" {
83-
var keywordFound int32 = 0
84-
wg := &sync.WaitGroup{}
85-
wg.Add(2)
86-
8778
scanAndEmit := func(reader io.Reader) {
88-
defer wg.Done()
8979
scanner := bufio.NewScanner(reader)
80+
stopOutput := false
9081
for scanner.Scan() {
91-
if atomic.LoadInt32(&keywordFound) == 1 {
92-
continue
93-
}
9482
text := scanner.Text()
95-
if options.StopOutputKeyword != "" && strings.Contains(text, options.StopOutputKeyword) {
96-
atomic.StoreInt32(&keywordFound, 1)
83+
84+
if !stopOutput {
9785
runtime.EventsEmit(a.Ctx, outEvent, text)
98-
continue
86+
87+
if options.StopOutputKeyword != "" && strings.Contains(text, options.StopOutputKeyword) {
88+
stopOutput = true
89+
}
9990
}
100-
runtime.EventsEmit(a.Ctx, outEvent, text)
10191
}
10292
}
10393

10494
go scanAndEmit(stdout)
105-
go scanAndEmit(stderr)
95+
}
10696

97+
if endEvent != "" {
10798
go func() {
108-
wg.Wait()
109-
if endEvent != "" {
110-
runtime.EventsEmit(a.Ctx, endEvent)
111-
}
99+
cmd.Wait()
100+
runtime.EventsEmit(a.Ctx, endEvent)
112101
}()
113102
}
114103

@@ -133,8 +122,8 @@ func (a *App) ProcessInfo(pid int32) FlagResult {
133122
return FlagResult{true, name}
134123
}
135124

136-
func (a *App) KillProcess(pid int) FlagResult {
137-
log.Printf("KillProcess: %d", pid)
125+
func (a *App) KillProcess(pid int, timeout int) FlagResult {
126+
log.Printf("KillProcess: %d %d", pid, timeout)
138127

139128
process, err := os.FindProcess(pid)
140129
if err != nil {
@@ -145,26 +134,27 @@ func (a *App) KillProcess(pid int) FlagResult {
145134
log.Printf("SendExitSignal Err: %s", err.Error())
146135
}
147136

148-
if err := waitForProcessExitWithTimeout(process, 10); err != nil {
137+
if err := waitForProcessExitWithTimeout(process, timeout); err != nil {
149138
return FlagResult{false, err.Error()}
150139
}
151140

152141
return FlagResult{true, "Success"}
153142
}
154143

155-
func waitForProcessExitWithTimeout(process *os.Process, timeoutSeconds int64) error {
144+
func waitForProcessExitWithTimeout(process *os.Process, timeoutSeconds int) error {
156145
done := make(chan error, 1)
157146
go func() {
158147
_, err := process.Wait()
159148
done <- err
160149
}()
161150

162-
timeout := time.After(time.Duration(timeoutSeconds) * time.Second)
151+
timer := time.NewTimer(time.Duration(timeoutSeconds) * time.Second)
152+
defer timer.Stop()
163153

164154
select {
165155
case err := <-done:
166156
return err
167-
case <-timeout:
157+
case <-timer.C:
168158
if killErr := process.Kill(); killErr != nil {
169159
return fmt.Errorf("timeout reached and failed to kill process: %w", killErr)
170160
}

bridge/net.go

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ func (a *App) Requests(method string, url string, headers map[string]string, bod
2727

2828
req.Header = GetHeader(headers)
2929

30-
runtime.EventsOn(a.Ctx, options.CancelId, func(data ...any) {
31-
log.Printf("Requests Canceled: %v %v", method, url)
32-
cancel()
33-
})
34-
defer runtime.EventsOff(a.Ctx, options.CancelId)
30+
if options.CancelId != "" {
31+
runtime.EventsOn(a.Ctx, options.CancelId, func(data ...any) {
32+
log.Printf("Requests Canceled: %v %v", method, url)
33+
cancel()
34+
})
35+
defer runtime.EventsOff(a.Ctx, options.CancelId)
36+
}
3537

3638
resp, err := client.Do(req)
3739
if err != nil {
@@ -47,23 +49,25 @@ func (a *App) Requests(method string, url string, headers map[string]string, bod
4749
return HTTPResult{true, resp.StatusCode, resp.Header, string(b)}
4850
}
4951

50-
func (a *App) Download(url string, path string, headers map[string]string, event string, options RequestOptions) HTTPResult {
51-
log.Printf("Download: %v %v %v, %v", url, path, headers, options)
52+
func (a *App) Download(method string, url string, path string, headers map[string]string, event string, options RequestOptions) HTTPResult {
53+
log.Printf("Download: %s %s %s %v %s %v", method, url, path, headers, event, options)
5254

5355
client, ctx, cancel := withRequestOptionsClient(options)
5456

55-
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
57+
req, err := http.NewRequestWithContext(ctx, method, url, nil)
5658
if err != nil {
5759
return HTTPResult{false, 500, nil, err.Error()}
5860
}
5961

6062
req.Header = GetHeader(headers)
6163

62-
runtime.EventsOn(a.Ctx, options.CancelId, func(data ...any) {
63-
log.Printf("Download Canceled: %v %v", url, path)
64-
cancel()
65-
})
66-
defer runtime.EventsOff(a.Ctx, options.CancelId)
64+
if options.CancelId != "" {
65+
runtime.EventsOn(a.Ctx, options.CancelId, func(data ...any) {
66+
log.Printf("Download Canceled: %v %v", url, path)
67+
cancel()
68+
})
69+
defer runtime.EventsOff(a.Ctx, options.CancelId)
70+
}
6771

6872
resp, err := client.Do(req)
6973
if err != nil {
@@ -84,12 +88,7 @@ func (a *App) Download(url string, path string, headers map[string]string, event
8488
}
8589
defer file.Close()
8690

87-
reader := io.TeeReader(resp.Body, &WriteTracker{
88-
Total: resp.ContentLength,
89-
EmitThreshold: 128 * 1024, // 128KB
90-
ProgressChange: event,
91-
App: a,
92-
})
91+
reader := wrapWithProgress(resp.Body, resp.ContentLength, event, a)
9392

9493
_, err = io.Copy(file, reader)
9594
if err != nil {
@@ -99,8 +98,8 @@ func (a *App) Download(url string, path string, headers map[string]string, event
9998
return HTTPResult{true, resp.StatusCode, resp.Header, "Success"}
10099
}
101100

102-
func (a *App) Upload(url string, path string, headers map[string]string, event string, options RequestOptions) HTTPResult {
103-
log.Printf("Upload: %v %v %v %v", url, path, headers, options)
101+
func (a *App) Upload(method string, url string, path string, headers map[string]string, event string, options RequestOptions) HTTPResult {
102+
log.Printf("Upload: %s %s %s %v %s %v", method, url, path, headers, event, options)
104103

105104
path = GetPath(path)
106105

@@ -123,12 +122,7 @@ func (a *App) Upload(url string, path string, headers map[string]string, event s
123122
return HTTPResult{false, 500, nil, err.Error()}
124123
}
125124

126-
reader := io.TeeReader(file, &WriteTracker{
127-
Total: fileStat.Size(),
128-
EmitThreshold: 128 * 1024, // 128KB
129-
ProgressChange: event,
130-
App: a,
131-
})
125+
reader := wrapWithProgress(file, fileStat.Size(), event, a)
132126

133127
_, err = io.Copy(part, reader)
134128
if err != nil {
@@ -142,13 +136,15 @@ func (a *App) Upload(url string, path string, headers map[string]string, event s
142136

143137
client, ctx, cancel := withRequestOptionsClient(options)
144138

145-
runtime.EventsOn(a.Ctx, options.CancelId, func(data ...any) {
146-
log.Printf("Upload Canceled: %v %v", url, path)
147-
cancel()
148-
})
149-
defer runtime.EventsOff(a.Ctx, options.CancelId)
139+
if options.CancelId != "" {
140+
runtime.EventsOn(a.Ctx, options.CancelId, func(data ...any) {
141+
log.Printf("Upload Canceled: %v %v", url, path)
142+
cancel()
143+
})
144+
defer runtime.EventsOff(a.Ctx, options.CancelId)
145+
}
150146

151-
req, err := http.NewRequestWithContext(ctx, "POST", url, body)
147+
req, err := http.NewRequestWithContext(ctx, method, url, body)
152148
if err != nil {
153149
return HTTPResult{false, 500, nil, err.Error()}
154150
}
@@ -174,10 +170,6 @@ func (wt *WriteTracker) Write(p []byte) (n int, err error) {
174170
n = len(p)
175171
wt.Progress += int64(n)
176172

177-
if wt.ProgressChange == "" {
178-
return n, nil
179-
}
180-
181173
shouldEmit := wt.Total <= 0 || wt.Progress-wt.LastEmitted >= wt.EmitThreshold || wt.Progress == wt.Total
182174
if shouldEmit {
183175
runtime.EventsEmit(wt.App.Ctx, wt.ProgressChange, wt.Progress, wt.Total)
@@ -187,6 +179,18 @@ func (wt *WriteTracker) Write(p []byte) (n int, err error) {
187179
return n, nil
188180
}
189181

182+
func wrapWithProgress(r io.Reader, size int64, event string, a *App) io.Reader {
183+
if event == "" {
184+
return r
185+
}
186+
return io.TeeReader(r, &WriteTracker{
187+
Total: size,
188+
EmitThreshold: 128 * 1024,
189+
ProgressChange: event,
190+
App: a,
191+
})
192+
}
193+
190194
func withRequestOptionsClient(options RequestOptions) (*http.Client, context.Context, context.CancelFunc) {
191195
client := &http.Client{
192196
Timeout: GetTimeout(options.Timeout),

bridge/notification.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,17 @@ import (
44
"github.com/gen2brain/beeep"
55
)
66

7-
func (a *App) Notify(title string, message string, icon string) FlagResult {
7+
func (a *App) Notify(title string, message string, icon string, options NotifyOptions) FlagResult {
88
fullPath := GetPath(icon)
99

10-
err := beeep.Notify(title, message, fullPath)
10+
beeep.AppName = options.AppName
11+
12+
var err error
13+
if options.Beep {
14+
err = beeep.Alert(title, message, fullPath)
15+
} else {
16+
err = beeep.Notify(title, message, fullPath)
17+
}
1118
if err != nil {
1219
return FlagResult{false, err.Error()}
1320
}

bridge/types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ type ServerOptions struct {
5757
MaxUploadSize int64 `json:"MaxUploadSize"`
5858
}
5959

60+
type NotifyOptions struct {
61+
AppName string `json:"AppName"`
62+
Beep bool `json:"Beep"`
63+
}
64+
6065
type HTTPResult struct {
6166
Flag bool `json:"flag"`
6267
Status int `json:"status"`

bridge/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func RollingRelease(next http.Handler) http.Handler {
6666

6767
log.Printf("[Rolling Release] %v %v\n", r.Method, url)
6868

69-
file := GetPath("data/rolling-release" + url)
69+
file := GetPath("data/rolling-release-alpha" + url)
7070

7171
bytes, err := os.ReadFile(file)
7272
if err != nil {

frontend/.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
VITE_APP_TITLE = GUI.for.Clash
2-
VITE_APP_VERSION = v1.9.7
2+
VITE_APP_VERSION = v1.9.8-Alpha
33
VITE_APP_PROJECT_URL = https://github.com/GUI-for-Cores
44
VITE_APP_VERSION_API = https://api.github.com/repos/GUI-for-Cores/GUI.for.Clash/releases/latest
55
VITE_APP_TG_GROUP = https://t.me/GUI_for_Cores

0 commit comments

Comments
 (0)