Skip to content

Commit 6360ba3

Browse files
committed
add i18n
1 parent 02e071b commit 6360ba3

File tree

24 files changed

+678
-479
lines changed

24 files changed

+678
-479
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ windows-arm64:
3737

3838
# go install gioui.org/cmd/gogio@latest
3939
android:
40-
gogio -x -work -target android -minsdk 33 -version $(VERSION).2 -signkey build/sign.keystore -signpass android -appid gost.plus -o $(BINDIR)/$(NAME)-$(VERSION).aab .
40+
gogio -x -work -target android -minsdk 33 -version $(VERSION).3 -signkey build/sign.keystore -signpass android -appid gost.plus -o $(BINDIR)/$(NAME)-$(VERSION).aab .
4141

4242
gz_releases=$(addsuffix .gz, $(PLATFORM_LIST))
4343
zip_releases=$(addsuffix .zip, $(WINDOWS_ARCH_LIST))

main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package main
22

33
import (
4-
"log"
54
_ "net"
65
"os"
76

87
"gioui.org/app"
98
_ "gioui.org/app/permission/storage"
109
"gioui.org/io/key"
1110
"gioui.org/op"
11+
"github.com/go-gost/core/logger"
1212
"github.com/go-gost/gost.plus/config"
1313
"github.com/go-gost/gost.plus/tunnel"
1414
"github.com/go-gost/gost.plus/tunnel/entrypoint"
@@ -26,7 +26,7 @@ func main() {
2626
)
2727
err := run(w)
2828
if err != nil {
29-
log.Fatal(err)
29+
logger.Default().Fatal(err)
3030
}
3131
os.Exit(0)
3232
}()

ui/i18n/en_us.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package i18n
2+
3+
var en_US = map[Key]string{
4+
Tunnel: "Tunnel",
5+
Entrypoint: "Entrypoint",
6+
Type: "Type",
7+
Name: "Name",
8+
Address: "Address",
9+
Endpoint: "Endpoint",
10+
BasicAuth: "Basic auth",
11+
Username: "Username",
12+
Password: "Password",
13+
DirectoryPath: "Directory path",
14+
CustomHostname: "Custom hostname (rewrite HTTP Host header)",
15+
Hostname: "Hostname",
16+
EnableTLS: "Enalbe TLS",
17+
TunnelID: "Tunnel ID",
18+
Keepalive: "Keepalive",
19+
FileTunnelDesc: "Expose local files to public network",
20+
HTTPTunnelDesc: "Expose local HTTP service to public network",
21+
TCPTunnelDesc: "Expose local TCP service to public network",
22+
UDPTunnelDesc: "Expose local UDP service to public network",
23+
TCPEntrypointDesc: "Create an entrypoint to the specified TCP tunnel",
24+
UDPEntrypointDesc: "Create an entrypoint to the specified UDP tunnel",
25+
Settings: "Settings",
26+
Language: "Language",
27+
Theme: "Theme",
28+
Light: "Light",
29+
Dark: "Dark",
30+
OK: "OK",
31+
Cancel: "Cancel",
32+
DeleteTunnel: "Delete tunnel?",
33+
DeleteEntrypoint: "Delete entrypoint?",
34+
ErrInvalidTunnelID: "invalid tunnel ID, should be a valid UUID",
35+
ErrInvalidAddr: "invalid address format, should be [IP]:PORT or [HOST]:PORT",
36+
ErrDigitOnly: "Must contain only digits",
37+
ErrDirectory: "is not a directory",
38+
39+
English: "English",
40+
Chinese: "Chinese",
41+
}

ui/i18n/lang.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package i18n
2+
3+
import "sync"
4+
5+
type Lang struct {
6+
Name Key
7+
Value string
8+
content map[Key]string
9+
}
10+
11+
var langs = []Lang{
12+
{
13+
Name: English,
14+
Value: "en_US",
15+
content: en_US,
16+
},
17+
{
18+
Name: Chinese,
19+
Value: "zh_CN",
20+
content: zh_CN,
21+
},
22+
}
23+
24+
func Langs() []Lang {
25+
return langs
26+
}
27+
28+
var (
29+
currentLang Lang = langs[0]
30+
mux sync.RWMutex
31+
)
32+
33+
func Current() Lang {
34+
mux.RLock()
35+
defer mux.RUnlock()
36+
37+
return currentLang
38+
}
39+
40+
func Set(lang string) {
41+
mux.Lock()
42+
defer mux.Unlock()
43+
44+
for i := range langs {
45+
if langs[i].Value == lang {
46+
currentLang = langs[i]
47+
return
48+
}
49+
}
50+
currentLang = langs[0]
51+
}
52+
53+
const (
54+
Tunnel Key = "tunnel"
55+
Entrypoint Key = "entrypoint"
56+
Type Key = "type"
57+
Name Key = "name"
58+
Address Key = "address"
59+
Endpoint Key = "endpoint"
60+
BasicAuth Key = "basicAuth"
61+
Username Key = "username"
62+
Password Key = "password"
63+
DirectoryPath Key = "dirPath"
64+
CustomHostname Key = "customHostname"
65+
Hostname Key = "hostname"
66+
EnableTLS Key = "enableTLS"
67+
TunnelID Key = "tunnelID"
68+
Keepalive Key = "keepalive"
69+
FileTunnelDesc Key = "fileTunnelDesc"
70+
HTTPTunnelDesc Key = "httpTunnelDesc"
71+
TCPTunnelDesc Key = "tcpTunnelDesc"
72+
UDPTunnelDesc Key = "udpTunnelDesc"
73+
TCPEntrypointDesc Key = "tcpEntrypointDesc"
74+
UDPEntrypointDesc Key = "udpEntrypointDesc"
75+
Settings Key = "settings"
76+
Language Key = "language"
77+
Theme Key = "theme"
78+
Light Key = "light"
79+
Dark Key = "dark"
80+
OK Key = "ok"
81+
Cancel Key = "cancel"
82+
DeleteTunnel Key = "deleteTunnel"
83+
DeleteEntrypoint Key = "deleteEntrypoint"
84+
ErrInvalidTunnelID Key = "errInvalidTunnelID"
85+
ErrInvalidAddr Key = "errInvalidAddr"
86+
ErrDigitOnly Key = "errDigitOnly"
87+
ErrDirectory Key = "errDir"
88+
89+
English Key = "english"
90+
Chinese Key = "chinese"
91+
)
92+
93+
type Key string
94+
95+
func (k Key) Value() string {
96+
return Get(k)
97+
}
98+
99+
func Get(key Key) string {
100+
mux.RLock()
101+
defer mux.RUnlock()
102+
103+
if v := currentLang.content[key]; v != "" {
104+
return v
105+
}
106+
107+
return langs[0].content[key]
108+
}

ui/i18n/zh_cn.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package i18n
2+
3+
var zh_CN = map[Key]string{
4+
Tunnel: "隧道",
5+
Entrypoint: "入口点",
6+
Type: "类型",
7+
Name: "名称",
8+
Address: "地址",
9+
Endpoint: "端点",
10+
BasicAuth: "基本认证",
11+
Username: "用户名",
12+
Password: "密码",
13+
DirectoryPath: "文件目录路径",
14+
CustomHostname: "自定义主机名(重写HTTP Host头)",
15+
Hostname: "主机名",
16+
EnableTLS: "开启TLS",
17+
TunnelID: "隧道ID",
18+
Keepalive: "保持连接",
19+
FileTunnelDesc: "将本地文件系统暴露到公网",
20+
HTTPTunnelDesc: "将本地的一个HTTP服务暴露到公网",
21+
TCPTunnelDesc: "将本地的一个TCP服务暴露到公网",
22+
UDPTunnelDesc: "将本地的一个UDP服务暴露到公网",
23+
TCPEntrypointDesc: "创建一个指定TCP隧道的入口点",
24+
UDPEntrypointDesc: "创建一个指定UDP隧道的入口点",
25+
Settings: "设置",
26+
Language: "语言",
27+
Theme: "主题",
28+
Light: "浅色",
29+
Dark: "深色",
30+
OK: "确认",
31+
Cancel: "取消",
32+
DeleteTunnel: "删除隧道?",
33+
DeleteEntrypoint: "删除入口点?",
34+
ErrInvalidTunnelID: "无效的隧道ID, 仅支持合法的UUID格式,例如:6bcb409c-dd0f-4ce7-9869-651c52c09d1c",
35+
ErrInvalidAddr: "无效的地址格式,仅支持[IP]:PORT或[HOST]:PORT",
36+
ErrDigitOnly: "仅能输入数字",
37+
ErrDirectory: "不是一个目录",
38+
39+
English: "英语",
40+
Chinese: "中文",
41+
}

ui/page/entrypoint/page.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"gioui.org/layout"
77
"gioui.org/widget"
88
"gioui.org/widget/material"
9+
"github.com/go-gost/gost.plus/ui/i18n"
910
"github.com/go-gost/gost.plus/ui/icons"
1011
"github.com/go-gost/gost.plus/ui/page"
1112
"github.com/go-gost/gost.plus/ui/theme"
@@ -18,7 +19,7 @@ type D = layout.Dimensions
1819
type navButton struct {
1920
btn widget.Clickable
2021
name string
21-
desc string
22+
desc i18n.Key
2223
path page.PagePath
2324
}
2425

@@ -39,15 +40,16 @@ func NewPage(r *page.Router) page.Page {
3940
Axis: layout.Vertical,
4041
},
4142
},
43+
4244
navs: []navButton{
4345
{
4446
name: "TCP",
45-
desc: "Create an entrypoint to the specified TCP tunnel",
47+
desc: i18n.TCPEntrypointDesc,
4648
path: page.PageEntrypointTCP,
4749
},
4850
{
4951
name: "UDP",
50-
desc: "Create an entrypoint to the specified UDP tunnel",
52+
desc: i18n.UDPEntrypointDesc,
5153
path: page.PageEntrypointUDP,
5254
},
5355
},
@@ -85,7 +87,7 @@ func (p *entrypointPage) Layout(gtx C) D {
8587
}),
8688
layout.Rigid(layout.Spacer{Width: 8}.Layout),
8789
layout.Rigid(func(gtx C) D {
88-
title := material.H6(th, "Entrypoint")
90+
title := material.H6(th, i18n.Get(i18n.Entrypoint))
8991
return title.Layout(gtx)
9092
}),
9193
layout.Rigid(layout.Spacer{Width: 8}.Layout),
@@ -111,12 +113,7 @@ func (p *entrypointPage) Layout(gtx C) D {
111113
CornerRadius: 12,
112114
Button: &p.navs[index].btn,
113115
}.Layout(gtx, func(gtx C) D {
114-
return layout.Inset{
115-
Top: 8,
116-
Bottom: 8,
117-
Left: 8,
118-
Right: 8,
119-
}.Layout(gtx, func(gtx C) D {
116+
return layout.UniformInset(16).Layout(gtx, func(gtx C) D {
120117
return layout.Flex{
121118
Alignment: layout.Middle,
122119
Spacing: layout.SpaceBetween,
@@ -127,7 +124,7 @@ func (p *entrypointPage) Layout(gtx C) D {
127124
}.Layout(gtx,
128125
layout.Rigid(material.Body1(th, p.navs[index].name).Layout),
129126
layout.Rigid(layout.Spacer{Height: 8}.Layout),
130-
layout.Rigid(material.Body2(th, p.navs[index].desc).Layout),
127+
layout.Rigid(material.Body2(th, p.navs[index].desc.Value()).Layout),
131128
)
132129
}),
133130
layout.Rigid(layout.Spacer{Width: 8}.Layout),

ui/page/entrypoint/tcp/page.go

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/go-gost/core/logger"
1414
"github.com/go-gost/gost.plus/tunnel"
1515
"github.com/go-gost/gost.plus/tunnel/entrypoint"
16+
"github.com/go-gost/gost.plus/ui/i18n"
1617
"github.com/go-gost/gost.plus/ui/icons"
1718
"github.com/go-gost/gost.plus/ui/page"
1819
"github.com/go-gost/gost.plus/ui/theme"
@@ -71,7 +72,7 @@ func NewPage(r *page.Router) page.Page {
7172
},
7273
},
7374
delDialog: ui_widget.Dialog{
74-
Title: "Delete entrypoint?",
75+
Title: i18n.Get(i18n.DeleteEntrypoint),
7576
},
7677
}
7778
}
@@ -267,17 +268,12 @@ func (p *tcpPage) layout(gtx C, th *material.Theme) D {
267268
},
268269
Fill: theme.Current().ContentSurfaceBg,
269270
}.Layout(gtx, func(gtx C) D {
270-
return layout.Inset{
271-
Top: 8,
272-
Bottom: 8,
273-
Left: 8,
274-
Right: 8,
275-
}.Layout(gtx, func(gtx C) D {
271+
return layout.UniformInset(16).Layout(gtx, func(gtx C) D {
276272
return layout.Flex{
277273
Axis: layout.Vertical,
278274
}.Layout(gtx,
279275
layout.Rigid(func(gtx C) D {
280-
return material.Body1(th, "Tunnel ID").Layout(gtx)
276+
return material.Body1(th, i18n.Get(i18n.TunnelID)).Layout(gtx)
281277
}),
282278
layout.Rigid(func(gtx C) D {
283279
if err := func() error {
@@ -286,7 +282,7 @@ func (p *tcpPage) layout(gtx C, th *material.Theme) D {
286282
return nil
287283
}
288284
if _, err := uuid.Parse(tid); err != nil {
289-
return fmt.Errorf("invalid tunnel ID, should be a valid UUID")
285+
return fmt.Errorf(i18n.Get(i18n.ErrInvalidTunnelID))
290286
}
291287
return nil
292288
}(); err != nil {
@@ -303,15 +299,15 @@ func (p *tcpPage) layout(gtx C, th *material.Theme) D {
303299
layout.Rigid(layout.Spacer{Height: 16}.Layout),
304300

305301
layout.Rigid(func(gtx C) D {
306-
return material.Body1(th, "Name").Layout(gtx)
302+
return material.Body1(th, i18n.Get(i18n.Name)).Layout(gtx)
307303
}),
308304
layout.Rigid(func(gtx C) D {
309305
return p.name.Layout(gtx, th, "")
310306
}),
311307
layout.Rigid(layout.Spacer{Height: 16}.Layout),
312308

313309
layout.Rigid(func(gtx C) D {
314-
return material.Body1(th, "Entrypoint").Layout(gtx)
310+
return material.Body1(th, i18n.Get(i18n.Entrypoint)).Layout(gtx)
315311
}),
316312
layout.Rigid(func(gtx C) D {
317313
if err := func() error {
@@ -320,7 +316,7 @@ func (p *tcpPage) layout(gtx C, th *material.Theme) D {
320316
return nil
321317
}
322318
if _, err := net.ResolveTCPAddr("tcp", addr); err != nil {
323-
return fmt.Errorf("invalid address format, should be [IP]:PORT or [HOST]:PORT")
319+
return fmt.Errorf(i18n.Get(i18n.ErrInvalidAddr))
324320
}
325321
return nil
326322
}(); err != nil {
@@ -329,7 +325,7 @@ func (p *tcpPage) layout(gtx C, th *material.Theme) D {
329325
p.entrypoint.ClearError()
330326
}
331327

332-
return p.entrypoint.Layout(gtx, th, "Address")
328+
return p.entrypoint.Layout(gtx, th, i18n.Get(i18n.Address))
333329
}),
334330
layout.Rigid(layout.Spacer{Height: 8}.Layout),
335331
)

0 commit comments

Comments
 (0)