mirror of
https://github.com/koho/frpmgr.git
synced 2025-10-20 16:03:47 +08:00
Show service status in config list
This commit is contained in:
@ -8,7 +8,7 @@ set PATH=%BUILDDIR%.deps;%PATH%
|
||||
echo [+] Rendering icons
|
||||
for %%a in ("icon\*.svg") do convert -density 1000 -background none "%%~fa" -define icon:auto-resize="256,192,128,96,64,48,32,24,16" "%%~dpna.ico" || exit /b 1
|
||||
echo [+] Building resources
|
||||
rsrc -manifest frpmgr.exe.manifest -ico icon/app.ico -o rsrc.syso || exit /b 1
|
||||
rsrc -manifest frpmgr.exe.manifest -ico icon/app.ico,icon/dot.ico -o rsrc.syso || exit /b 1
|
||||
echo [+] Patching files
|
||||
go mod tidy || exit /b 1
|
||||
for %%f in (patches\*.patch) do patch -N -r - -d %GOPATH% -p0 < %%f
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type AuthInfo struct {
|
||||
@ -47,15 +48,18 @@ type Section struct {
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Name string `ini:"-"`
|
||||
cfg *ini.File
|
||||
Path string
|
||||
Name string `ini:"-"`
|
||||
cfg *ini.File
|
||||
Path string
|
||||
Status ServiceState
|
||||
Common
|
||||
Items []*Section
|
||||
}
|
||||
|
||||
var notOmitEmpty = []string{"login_fail_exit"}
|
||||
var Configurations []*Config
|
||||
var ConfMutex sync.Mutex
|
||||
var StatusChan = make(chan bool)
|
||||
|
||||
func LoadConfig() ([]*Config, error) {
|
||||
files, err := filepath.Glob("*.ini")
|
||||
@ -92,6 +96,7 @@ func (c *Config) GetSectionNames() []string {
|
||||
func (c *Config) Load(source string) error {
|
||||
c.Name = NameFromPath(source)
|
||||
c.Path = source
|
||||
c.Status = StateStopped
|
||||
cfg, err := ini.Load(source)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -1,4 +1,4 @@
|
||||
package ui
|
||||
package config
|
||||
|
||||
type ServiceState int
|
||||
|
2
icon/dot.svg
Normal file
2
icon/dot.svg
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="256" height="256" version="1.1" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg"><g><circle cx="128" cy="128" r="120" fill="#e1e1e1" stroke="#cacaca" stroke-linecap="square" stroke-width="8"/></g></svg>
|
After Width: | Height: | Size: 262 B |
@ -4,6 +4,7 @@ import (
|
||||
"frpmgr/config"
|
||||
"github.com/lxn/walk"
|
||||
. "github.com/lxn/walk/declarative"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ConfPage struct {
|
||||
@ -74,6 +75,30 @@ func (t *ConfPage) Initialize() {
|
||||
t.DetailView.Initialize()
|
||||
t.onConfigChanged(len(config.Configurations))
|
||||
t.ConfView.ConfListView.view.SetCurrentIndex(0)
|
||||
t.startQueryStatus()
|
||||
}
|
||||
|
||||
func (t *ConfPage) startQueryStatus() {
|
||||
ticker := time.NewTicker(time.Second * 1)
|
||||
go func() {
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-config.StatusChan:
|
||||
case <-ticker.C:
|
||||
}
|
||||
config.ConfMutex.Lock()
|
||||
for _, conf := range config.Configurations {
|
||||
if t.queryState(conf.Name) {
|
||||
conf.Status = config.StateStarted
|
||||
} else {
|
||||
conf.Status = config.StateStopped
|
||||
}
|
||||
}
|
||||
config.ConfMutex.Unlock()
|
||||
t.ConfListView.view.Invalidate()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (t *ConfPage) UpdateDetailView() {
|
||||
|
@ -33,7 +33,10 @@ func (t *ConfView) reloadConf() {
|
||||
walk.MsgBox(t.ConfListView.view.Form(), "错误", "读取配置文件失败", walk.MsgBoxOK|walk.MsgBoxIconError)
|
||||
return
|
||||
}
|
||||
config.ConfMutex.Lock()
|
||||
config.Configurations = confList
|
||||
config.ConfMutex.Unlock()
|
||||
config.StatusChan <- true
|
||||
if t.ConfigChanged != nil {
|
||||
t.ConfigChanged(len(confList))
|
||||
}
|
||||
@ -225,6 +228,14 @@ func (t *ConfListView) View() Widget {
|
||||
Action{AssignTo: &t.importAction, Text: "从文件导入配置"},
|
||||
Action{AssignTo: &t.deleteAction, Text: "删除配置"},
|
||||
},
|
||||
StyleCell: func(style *walk.CellStyle) {
|
||||
row := style.Row()
|
||||
if row < 0 || row >= len(config.Configurations) {
|
||||
return
|
||||
}
|
||||
conf := config.Configurations[row]
|
||||
style.Image = iconForState(conf.Status, 14)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,16 +45,16 @@ func (t *DetailView) toggleService(restart bool) {
|
||||
}
|
||||
utils.EnsurePath(t.conf.LogFile)
|
||||
if t.running {
|
||||
t.statusImage.SetImage(iconForState(StateStopping, 14))
|
||||
t.statusImage.SetImage(iconForState(config.StateStopping, 14))
|
||||
t.status.SetText("正在停止")
|
||||
err = services.UninstallService(config.NameFromPath(confPath))
|
||||
if restart {
|
||||
t.statusImage.SetImage(iconForState(StateStarting, 14))
|
||||
t.statusImage.SetImage(iconForState(config.StateStarting, 14))
|
||||
t.status.SetText("正在启动")
|
||||
err = services.InstallService(confPath)
|
||||
}
|
||||
} else {
|
||||
t.statusImage.SetImage(iconForState(StateStarting, 14))
|
||||
t.statusImage.SetImage(iconForState(config.StateStarting, 14))
|
||||
t.status.SetText("正在启动")
|
||||
err = services.InstallService(confPath)
|
||||
}
|
||||
@ -323,11 +323,11 @@ func (t *ConfStatusView) UpdateStatus(name string, running bool) {
|
||||
if running {
|
||||
t.status.SetText("正在运行")
|
||||
t.toggle.SetText("停止")
|
||||
t.statusImage.SetImage(iconForState(StateStarted, 14))
|
||||
t.statusImage.SetImage(iconForState(config.StateStarted, 14))
|
||||
} else {
|
||||
t.status.SetText("已停止")
|
||||
t.toggle.SetText("启动")
|
||||
t.statusImage.SetImage(iconForState(StateStopped, 14))
|
||||
t.statusImage.SetImage(iconForState(config.StateStopped, 14))
|
||||
}
|
||||
}
|
||||
|
||||
|
15
ui/icon.go
15
ui/icon.go
@ -1,6 +1,9 @@
|
||||
package ui
|
||||
|
||||
import "github.com/lxn/walk"
|
||||
import (
|
||||
"frpmgr/config"
|
||||
"github.com/lxn/walk"
|
||||
)
|
||||
|
||||
var cachedSystemIconsForWidthAndDllIdx = make(map[widthDllIdx]*walk.Icon)
|
||||
|
||||
@ -25,21 +28,21 @@ type widthDllIdx struct {
|
||||
|
||||
type widthAndState struct {
|
||||
width int
|
||||
state ServiceState
|
||||
state config.ServiceState
|
||||
}
|
||||
|
||||
var cachedIconsForWidthAndState = make(map[widthAndState]*walk.Icon)
|
||||
|
||||
func iconForState(state ServiceState, size int) (icon *walk.Icon) {
|
||||
func iconForState(state config.ServiceState, size int) (icon *walk.Icon) {
|
||||
icon = cachedIconsForWidthAndState[widthAndState{size, state}]
|
||||
if icon != nil {
|
||||
return
|
||||
}
|
||||
switch state {
|
||||
case StateStarted:
|
||||
case config.StateStarted:
|
||||
icon = loadSysIcon("imageres", 101, size)
|
||||
case StateStopped:
|
||||
icon = loadSysIcon("imageres", 100, size)
|
||||
case config.StateStopped:
|
||||
icon, _ = walk.NewIconFromResourceIdWithSize(21, walk.Size{size, size})
|
||||
default:
|
||||
icon = loadSysIcon("shell32", 238, size)
|
||||
}
|
||||
|
Reference in New Issue
Block a user