2023-07-11 18:06:44 +08:00
|
|
|
package services
|
|
|
|
|
|
|
|
import (
|
2023-08-26 02:40:30 +08:00
|
|
|
"encoding/json"
|
2023-07-12 11:48:08 +08:00
|
|
|
"github.com/adrg/sysfont"
|
2023-08-26 02:40:30 +08:00
|
|
|
"net/http"
|
2023-07-12 11:48:08 +08:00
|
|
|
"sort"
|
|
|
|
"strings"
|
2023-07-11 18:06:44 +08:00
|
|
|
"sync"
|
2023-09-28 21:45:44 +08:00
|
|
|
"tinyrdm/backend/consts"
|
2023-07-11 18:06:44 +08:00
|
|
|
storage2 "tinyrdm/backend/storage"
|
|
|
|
"tinyrdm/backend/types"
|
2023-07-12 11:48:08 +08:00
|
|
|
"tinyrdm/backend/utils/coll"
|
2023-07-11 18:06:44 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type preferencesService struct {
|
2023-08-26 02:40:30 +08:00
|
|
|
pref *storage2.PreferencesStorage
|
|
|
|
clientVersion string
|
2023-07-11 18:06:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
var preferences *preferencesService
|
|
|
|
var oncePreferences sync.Once
|
|
|
|
|
|
|
|
func Preferences() *preferencesService {
|
|
|
|
if preferences == nil {
|
|
|
|
oncePreferences.Do(func() {
|
|
|
|
preferences = &preferencesService{
|
2023-08-26 02:40:30 +08:00
|
|
|
pref: storage2.NewPreferences(),
|
|
|
|
clientVersion: "",
|
2023-07-11 18:06:44 +08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return preferences
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *preferencesService) GetPreferences() (resp types.JSResp) {
|
|
|
|
resp.Data = p.pref.GetPreferences()
|
|
|
|
resp.Success = true
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-10-04 22:21:35 +08:00
|
|
|
func (p *preferencesService) SetPreferences(pf types.Preferences) (resp types.JSResp) {
|
|
|
|
err := p.pref.SetPreferences(&pf)
|
2023-07-11 18:06:44 +08:00
|
|
|
if err != nil {
|
|
|
|
resp.Msg = err.Error()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
resp.Success = true
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-10-04 22:21:35 +08:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-07-11 18:06:44 +08:00
|
|
|
func (p *preferencesService) RestorePreferences() (resp types.JSResp) {
|
|
|
|
defaultPref := p.pref.RestoreDefault()
|
|
|
|
resp.Data = map[string]any{
|
|
|
|
"pref": defaultPref,
|
|
|
|
}
|
|
|
|
resp.Success = true
|
|
|
|
return
|
|
|
|
}
|
2023-07-12 11:48:08 +08:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2023-08-26 02:40:30 +08:00
|
|
|
|
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-08-26 02:40:30 +08:00
|
|
|
}
|
|
|
|
|
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
|
2023-10-15 04:02:09 +08:00
|
|
|
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-10-15 04:02:09 +08:00
|
|
|
})
|
|
|
|
}
|
2023-09-28 21:45:44 +08:00
|
|
|
}
|
|
|
|
|
2023-11-24 11:49:59 +08:00
|
|
|
func (p *preferencesService) GetWindowSize() (width, height int, maximised bool) {
|
2023-09-28 21:45:44 +08:00
|
|
|
data := p.pref.GetPreferences()
|
2023-11-24 11:49:59 +08:00
|
|
|
width, height, maximised = data.Behavior.WindowWidth, data.Behavior.WindowHeight, data.Behavior.WindowMaximised
|
2023-10-04 22:21:35 +08:00
|
|
|
if width <= 0 {
|
|
|
|
width = consts.DEFAULT_WINDOW_WIDTH
|
2023-09-28 21:45:44 +08:00
|
|
|
}
|
2023-10-04 22:21:35 +08:00
|
|
|
if height <= 0 {
|
|
|
|
height = consts.DEFAULT_WINDOW_HEIGHT
|
2023-09-28 21:45:44 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-08-26 02:40:30 +08:00
|
|
|
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)
|
2023-08-26 02:40:30 +08:00
|
|
|
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
|
|
|
|
}
|