tiny-rdm/backend/services/system_service.go

167 lines
3.6 KiB
Go

package services
import (
"context"
"github.com/wailsapp/wails/v2/pkg/runtime"
runtime2 "runtime"
"sync"
"time"
"tinyrdm/backend/consts"
"tinyrdm/backend/types"
sliceutil "tinyrdm/backend/utils/slice"
)
type systemService struct {
ctx context.Context
appVersion string
}
var system *systemService
var onceSystem sync.Once
func System() *systemService {
if system == nil {
onceSystem.Do(func() {
system = &systemService{
appVersion: "0.0.0",
}
go system.loopWindowEvent()
})
}
return system
}
func (s *systemService) Start(ctx context.Context, version string) {
s.ctx = ctx
s.appVersion = version
// maximize the window if screen size is lower than the minimum window size
if screen, err := runtime.ScreenGetAll(ctx); err == nil && len(screen) > 0 {
for _, sc := range screen {
if sc.IsCurrent {
if sc.Size.Width < consts.MIN_WINDOW_WIDTH || sc.Size.Height < consts.MIN_WINDOW_HEIGHT {
runtime.WindowMaximise(ctx)
break
}
}
}
}
}
func (s *systemService) Info() (resp types.JSResp) {
resp.Success = true
resp.Data = struct {
OS string `json:"os"`
Arch string `json:"arch"`
Version string `json:"version"`
}{
OS: runtime2.GOOS,
Arch: runtime2.GOARCH,
Version: s.appVersion,
}
return
}
// SelectFile open file dialog to select a file
func (s *systemService) SelectFile(title string, extensions []string) (resp types.JSResp) {
filters := sliceutil.Map(extensions, func(i int) runtime.FileFilter {
return runtime.FileFilter{
Pattern: "*." + extensions[i],
}
})
filepath, err := runtime.OpenFileDialog(s.ctx, runtime.OpenDialogOptions{
Title: title,
ShowHiddenFiles: true,
Filters: filters,
})
if err != nil {
resp.Msg = err.Error()
return
}
resp.Success = true
resp.Data = map[string]any{
"path": filepath,
}
return
}
// SaveFile open file dialog to save a file
func (s *systemService) SaveFile(title string, defaultName string, extensions []string) (resp types.JSResp) {
filters := sliceutil.Map(extensions, func(i int) runtime.FileFilter {
return runtime.FileFilter{
Pattern: "*." + extensions[i],
}
})
filepath, err := runtime.SaveFileDialog(s.ctx, runtime.SaveDialogOptions{
Title: title,
ShowHiddenFiles: true,
DefaultFilename: defaultName,
Filters: filters,
})
if err != nil {
resp.Msg = err.Error()
return
}
resp.Success = true
resp.Data = map[string]any{
"path": filepath,
}
return
}
func (s *systemService) loopWindowEvent() {
var fullscreen, maximised, minimised, normal bool
var width, height int
var dirty bool
for {
time.Sleep(300 * time.Millisecond)
if s.ctx == nil {
continue
}
dirty = false
if f := runtime.WindowIsFullscreen(s.ctx); f != fullscreen {
// full-screen switched
fullscreen = f
dirty = true
}
if w, h := runtime.WindowGetSize(s.ctx); w != width || h != height {
// window size changed
width, height = w, h
dirty = true
}
if m := runtime.WindowIsMaximised(s.ctx); m != maximised {
maximised = m
dirty = true
}
if m := runtime.WindowIsMinimised(s.ctx); m != minimised {
minimised = m
dirty = true
}
if n := runtime.WindowIsNormal(s.ctx); n != normal {
normal = n
dirty = true
}
if dirty {
runtime.EventsEmit(s.ctx, "window_changed", map[string]any{
"fullscreen": fullscreen,
"width": width,
"height": height,
"maximised": maximised,
"minimised": minimised,
"normal": normal,
})
if !fullscreen && !minimised {
// save window size and position
Preferences().SaveWindowSize(width, height, maximised)
}
}
}
}