tiny-rdm/backend/services/preferences_service.go

249 lines
6.1 KiB
Go
Raw Normal View History

package services
import (
"context"
"encoding/json"
"github.com/adrg/sysfont"
runtime2 "github.com/wailsapp/wails/v2/pkg/runtime"
"net/http"
"sort"
"strings"
"sync"
"tinyrdm/backend/consts"
storage2 "tinyrdm/backend/storage"
"tinyrdm/backend/types"
"tinyrdm/backend/utils/coll"
convutil "tinyrdm/backend/utils/convert"
sliceutil "tinyrdm/backend/utils/slice"
)
type preferencesService struct {
pref *storage2.PreferencesStorage
clientVersion string
}
var preferences *preferencesService
var oncePreferences sync.Once
func Preferences() *preferencesService {
if preferences == nil {
oncePreferences.Do(func() {
preferences = &preferencesService{
pref: storage2.NewPreferences(),
clientVersion: "",
}
})
}
return preferences
}
func (p *preferencesService) GetPreferences() (resp types.JSResp) {
resp.Data = p.pref.GetPreferences()
resp.Success = true
return
}
func (p *preferencesService) SetPreferences(pf types.Preferences) (resp types.JSResp) {
err := p.pref.SetPreferences(&pf)
if err != nil {
resp.Msg = err.Error()
return
}
resp.Success = true
return
}
func (p *preferencesService) UpdatePreferences(value map[string]any) (resp types.JSResp) {
err := p.pref.UpdatePreferences(value)
if err != nil {
resp.Msg = err.Error()
return
}
resp.Success = true
return
}
func (p *preferencesService) RestorePreferences() (resp types.JSResp) {
defaultPref := p.pref.RestoreDefault()
resp.Data = map[string]any{
"pref": defaultPref,
}
resp.Success = true
return
}
type FontItem struct {
Name string `json:"name"`
Path string `json:"path"`
}
func (p *preferencesService) GetFontList() (resp types.JSResp) {
finder := sysfont.NewFinder(nil)
fontSet := coll.NewSet[string]()
var fontList []FontItem
for _, font := range finder.List() {
if len(font.Family) > 0 && !strings.HasPrefix(font.Family, ".") && fontSet.Add(font.Family) {
fontList = append(fontList, FontItem{
Name: font.Family,
Path: font.Filename,
})
}
}
sort.Slice(fontList, func(i, j int) bool {
return fontList[i].Name < fontList[j].Name
})
resp.Data = map[string]any{
"fonts": fontList,
}
resp.Success = true
return
}
func (p *preferencesService) GetBuildInDecoder() (resp types.JSResp) {
buildinDecoder := make([]string, 0, len(convutil.BuildInDecoders))
for name, convert := range convutil.BuildInDecoders {
if convert.Enable() {
buildinDecoder = append(buildinDecoder, name)
}
}
resp.Data = map[string]any{
"decoder": buildinDecoder,
}
resp.Success = true
return
}
2023-09-22 18:31:50 +08:00
func (p *preferencesService) SetAppVersion(ver string) {
2023-09-17 01:15:55 +08:00
if !strings.HasPrefix(ver, "v") {
p.clientVersion = "v" + ver
} else {
p.clientVersion = ver
}
}
2023-09-22 18:31:50 +08:00
func (p *preferencesService) GetAppVersion() (resp types.JSResp) {
resp.Success = true
resp.Data = map[string]any{
"version": p.clientVersion,
}
return
}
2023-11-24 11:49:59 +08:00
func (p *preferencesService) SaveWindowSize(width, height int, maximised bool) {
if maximised {
// do not update window size if maximised state
p.UpdatePreferences(map[string]any{
2023-11-24 11:49:59 +08:00
"behavior.windowMaximised": true,
})
} else if width >= consts.MIN_WINDOW_WIDTH && height >= consts.MIN_WINDOW_HEIGHT {
p.UpdatePreferences(map[string]any{
"behavior.windowWidth": width,
"behavior.windowHeight": height,
"behavior.windowMaximised": false,
})
}
}
2023-11-24 11:49:59 +08:00
func (p *preferencesService) GetWindowSize() (width, height int, maximised bool) {
data := p.pref.GetPreferences()
2023-11-24 11:49:59 +08:00
width, height, maximised = data.Behavior.WindowWidth, data.Behavior.WindowHeight, data.Behavior.WindowMaximised
if width <= 0 {
width = consts.DEFAULT_WINDOW_WIDTH
}
if height <= 0 {
height = consts.DEFAULT_WINDOW_HEIGHT
}
return
}
func (p *preferencesService) GetWindowPosition(ctx context.Context) (x, y int) {
data := p.pref.GetPreferences()
x, y = data.Behavior.WindowPosX, data.Behavior.WindowPosY
width, height := data.Behavior.WindowWidth, data.Behavior.WindowHeight
var screenWidth, screenHeight int
if screens, err := runtime2.ScreenGetAll(ctx); err == nil {
for _, screen := range screens {
if screen.IsCurrent {
screenWidth, screenHeight = screen.Size.Width, screen.Size.Height
break
}
}
}
if screenWidth <= 0 || screenHeight <= 0 {
screenWidth, screenHeight = consts.DEFAULT_WINDOW_WIDTH, consts.DEFAULT_WINDOW_HEIGHT
}
if x <= 0 || x+width > screenWidth || y <= 0 || y+height > screenHeight {
// out of screen, reset to center
x, y = (screenWidth-width)/2, (screenHeight-height)/2
}
return
}
func (p *preferencesService) SaveWindowPosition(x, y int) {
if x > 0 || y > 0 {
p.UpdatePreferences(map[string]any{
"behavior.windowPosX": x,
"behavior.windowPosY": y,
})
}
}
2023-10-20 18:22:53 +08:00
func (p *preferencesService) GetScanSize() int {
data := p.pref.GetPreferences()
size := data.General.ScanSize
if size <= 0 {
size = consts.DEFAULT_SCAN_SIZE
}
return size
}
func (p *preferencesService) GetDecoder() []convutil.CmdConvert {
data := p.pref.GetPreferences()
return sliceutil.FilterMap(data.Decoder, func(i int) (convutil.CmdConvert, bool) {
//if !data.Decoder[i].Enable {
// return convutil.CmdConvert{}, false
//}
return convutil.CmdConvert{
Name: data.Decoder[i].Name,
Auto: data.Decoder[i].Auto,
DecodePath: data.Decoder[i].DecodePath,
DecodeArgs: data.Decoder[i].DecodeArgs,
EncodePath: data.Decoder[i].EncodePath,
EncodeArgs: data.Decoder[i].EncodeArgs,
}, true
})
}
type latestRelease struct {
Name string `json:"name"`
TagName string `json:"tag_name"`
Url string `json:"url"`
HtmlUrl string `json:"html_url"`
}
func (p *preferencesService) CheckForUpdate() (resp types.JSResp) {
// request latest version
res, err := http.Get("https://api.github.com/repos/tiny-craft/tiny-rdm/releases/latest")
if err != nil || res.StatusCode != http.StatusOK {
resp.Msg = "network error"
return
}
var respObj latestRelease
2023-09-17 01:15:55 +08:00
err = json.NewDecoder(res.Body).Decode(&respObj)
if err != nil {
resp.Msg = "invalid content"
return
}
// compare with current version
resp.Success = true
resp.Data = map[string]any{
"version": p.clientVersion,
"latest": respObj.TagName,
"page_url": respObj.HtmlUrl,
}
return
}