update checker

This commit is contained in:
Aynakeya
2023-02-21 16:21:29 -08:00
parent 6f2349e17b
commit 02cc9de11a
14 changed files with 182 additions and 10 deletions

View File

@@ -8,6 +8,18 @@
"en": "Audio Device",
"zh-CN": "音频输出设备"
},
"gui.config.basic.auto_check_update": {
"en": "Check update at startup",
"zh-CN": "自动检查更新"
},
"gui.config.basic.auto_check_update.prompt": {
"en": "Yes",
"zh-CN": "确认"
},
"gui.config.basic.check_update": {
"en": "Check Update",
"zh-CN": "检查更新"
},
"gui.config.basic.description": {
"en": "Basic Configuration",
"zh-CN": "基础设置"
@@ -39,7 +51,7 @@
"gui.config.basic.skip_when_error.prompt": {
"en": "Skip",
"zh-CN": "跳过"
},
},
"gui.config.basic.title": {
"en": "Basic",
"zh-CN": "基础设置"
@@ -256,6 +268,10 @@
"en": "Search",
"zh-CN": "搜索"
},
"gui.update.new_version": {
"en": "New Version Available",
"zh-CN": "有新版本可用"
},
"plugin.diange.admin": {
"en": "Admin",
"zh-CN": "管理员"

View File

@@ -9,8 +9,8 @@ import (
)
const (
ProgramName = "卡西米尔唱片机"
Version = "beta 0.9.7"
ProgramName = "卡西米尔唱片机"
Version uint32 = 0x000909
)
const (

View File

@@ -2,7 +2,8 @@ package config
type _GeneralConfig struct {
BaseConfig
Language string
Language string
AutoCheckUpdate bool
}
func (c *_GeneralConfig) Name() string {
@@ -10,5 +11,6 @@ func (c *_GeneralConfig) Name() string {
}
var General = &_GeneralConfig{
Language: "en",
Language: "en",
AutoCheckUpdate: true,
}

View File

@@ -0,0 +1,9 @@
package adapter
import "AynaLivePlayer/core/model"
type IApplication interface {
Version() model.VersionInfo
LatestVersion() model.VersionInfo
CheckUpdate() error
}

View File

@@ -8,6 +8,7 @@ import (
// IControlBridge is the interface for all controller and
// all system use cases.
type IControlBridge interface {
App() IApplication
LiveRooms() ILiveRoomController
PlayControl() IPlayController
Playlists() IPlaylistController

35
core/model/application.go Normal file
View File

@@ -0,0 +1,35 @@
package model
import "fmt"
type VersionInfo struct {
Version Version
Info string
}
type Version uint32
func (v Version) String() string {
return fmt.Sprintf("%d.%d.%d", (v>>16)&0xff, (v>>8)&0xff, v&0xff)
}
func (v Version) Major() uint8 {
return uint8((v >> 16) & 0xff)
}
func (v Version) Minor() uint8 {
return uint8((v >> 8) & 0xff)
}
func (v Version) Patch() uint8 {
return uint8(v & 0xff)
}
func VersionFromString(s string) Version {
var major, minor, patch uint8
_, err := fmt.Sscanf(s, "%d.%d.%d", &major, &minor, &patch)
if err != nil {
return 0
}
return Version(major)<<16 | Version(minor)<<8 | Version(patch)
}

View File

@@ -0,0 +1,17 @@
package model
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestVersion(t *testing.T) {
v := Version(0x00010203)
assert.Equal(t, "1.2.3", v.String())
v2 := VersionFromString("1.2.3")
assert.Equal(t, v, v2)
v3 := VersionFromString("1.2.4")
assert.True(t, v3 > v2)
assert.False(t, v3 < v2)
assert.Equal(t, Version(0), VersionFromString(""))
}

2
go.mod
View File

@@ -26,7 +26,7 @@ require (
)
require (
fyne.io/systray v1.10.1-0.20221115204952-d16a6177e6f1 // indirect
fyne.io/systray v1.10.1-0.20230207085535-4a244dbb9d03 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fredbi/uri v0.1.0 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect

4
go.sum
View File

@@ -40,8 +40,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
fyne.io/fyne/v2 v2.2.4 h1:izyiDUjJYAB7B/MST7M9GDs+mQ0CwDgRZTiVJZQoEe4=
fyne.io/fyne/v2 v2.2.4/go.mod h1:MBoGuHzLLSXdQOWFAwWhIhYTEMp33zqtGCReSWhaQTA=
fyne.io/systray v1.10.1-0.20220621085403-9a2652634e93/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE=
fyne.io/systray v1.10.1-0.20221115204952-d16a6177e6f1 h1:OiHw+bZAGEaSreHsA8dDkBOVJmSFzsNTOc/htpM+fOc=
fyne.io/systray v1.10.1-0.20221115204952-d16a6177e6f1/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE=
fyne.io/systray v1.10.1-0.20230207085535-4a244dbb9d03 h1:zb84y6X6lIi4Aeo8ehu6Qtu2fipBZ6Wzp41Ki/F4qdg=
fyne.io/systray v1.10.1-0.20230207085535-4a244dbb9d03/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=

View File

@@ -1,11 +1,13 @@
package gui
import (
"AynaLivePlayer/common/config"
"AynaLivePlayer/common/i18n"
"AynaLivePlayer/core/model"
"AynaLivePlayer/gui/component"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/widget"
)
@@ -79,6 +81,25 @@ func (b *bascicConfig) CreatePanel() fyne.CanvasObject {
&API.PlayControl().Config().AutoNextWhenFail,
API.PlayControl().Config().AutoNextWhenFail),
)
b.panel = container.NewVBox(randomPlaylist, outputDevice, skipPlaylist, skipWhenErr)
checkUpdateBox := container.NewHBox(
widget.NewLabel(i18n.T("gui.config.basic.auto_check_update")),
component.NewCheckOneWayBinding(
i18n.T("gui.config.basic.auto_check_update.prompt"),
&config.General.AutoCheckUpdate,
config.General.AutoCheckUpdate),
)
checkUpdateBtn := widget.NewButton(i18n.T("gui.config.basic.check_update"), func() {
err := API.App().CheckUpdate()
if err != nil {
showDialogIfError(err)
return
}
dialog.ShowCustom(
i18n.T("gui.update.new_version"),
"OK",
widget.NewRichTextFromMarkdown(API.App().LatestVersion().Info),
MainWindow)
})
b.panel = container.NewVBox(randomPlaylist, outputDevice, skipPlaylist, skipWhenErr, checkUpdateBox, checkUpdateBtn)
return b.panel
}

View File

@@ -5,11 +5,13 @@ import (
"AynaLivePlayer/common/i18n"
"AynaLivePlayer/common/util"
"AynaLivePlayer/core/adapter"
"AynaLivePlayer/core/model"
"AynaLivePlayer/resource"
"fmt"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/widget"
)
@@ -34,7 +36,7 @@ func Initialize() {
//os.Setenv("FYNE_FONT", config.GetAssetPath("msyh.ttc"))
App = app.New()
App.Settings().SetTheme(&myTheme{})
MainWindow = App.NewWindow(fmt.Sprintf("%s Ver.%s", config.ProgramName, config.Version))
MainWindow = App.NewWindow(fmt.Sprintf("%s Ver.%s", config.ProgramName, model.Version(config.Version)))
tabs := container.NewAppTabs(
container.NewTabItem(i18n.T("gui.tab.player"),
@@ -74,6 +76,9 @@ func Initialize() {
playerWindow.Hide()
//MainWindow.SetFixedSize(true)
if config.General.AutoCheckUpdate {
go checkUpdate()
}
}
func showPlayerWindow() {
@@ -94,3 +99,21 @@ func addShortCut() {
API.PlayControl().PlayNext()
})
}
func checkUpdate() {
l().Info("checking updates...")
err := API.App().CheckUpdate()
if err != nil {
l().Warnf("check update failed", err)
return
}
l().Infof("latest version: v%s", API.App().LatestVersion().Version)
if API.App().LatestVersion().Version > API.App().Version().Version {
l().Info("new update available")
dialog.ShowCustom(
i18n.T("gui.update.new_version"),
"OK",
widget.NewRichTextFromMarkdown(API.App().LatestVersion().Info),
MainWindow)
}
}

41
internal/application.go Normal file
View File

@@ -0,0 +1,41 @@
package internal
import (
"AynaLivePlayer/common/config"
"AynaLivePlayer/core/model"
"errors"
"fmt"
"github.com/go-resty/resty/v2"
"github.com/tidwall/gjson"
)
type AppBilibiliChannel struct {
latestVersion model.Version
}
func (app *AppBilibiliChannel) Version() model.VersionInfo {
return model.VersionInfo{
model.Version(config.Version), "",
}
}
func (app *AppBilibiliChannel) LatestVersion() model.VersionInfo {
return model.VersionInfo{
app.latestVersion,
fmt.Sprintf("v%s\n\n[https://play-live.bilibili.com/details/1661006726438](https://play-live.bilibili.com/details/1661006726438)", app.latestVersion),
}
}
func (app *AppBilibiliChannel) CheckUpdate() error {
uri := "https://api.live.bilibili.com/xlive/virtual-interface/v1/app/detail?app_id=1661006726438"
resp, err := resty.New().R().Get(uri)
if err != nil {
return err
}
lv := model.VersionFromString(gjson.ParseBytes(resp.Body()).Get("data.version").String())
if lv == 0 {
return errors.New("failed to get latest version")
}
app.latestVersion = lv
return nil
}

View File

@@ -5,6 +5,7 @@ import (
)
type Controller struct {
app adapter.IApplication `ini:"-"`
liveroom adapter.ILiveRoomController `ini:"-"`
player adapter.IPlayController `ini:"-"`
lyric adapter.ILyricLoader `ini:"-"`
@@ -24,6 +25,7 @@ func NewController(
provider adapter.IProviderController, plugin adapter.IPluginController,
log adapter.ILogger) adapter.IControlBridge {
cc := &Controller{
app: &AppBilibiliChannel{},
liveroom: liveroom,
player: player,
playlist: playlist,
@@ -34,6 +36,10 @@ func NewController(
return cc
}
func (c *Controller) App() adapter.IApplication {
return c.app
}
func (c *Controller) LiveRooms() adapter.ILiveRoomController {
return c.liveroom
}

View File

@@ -13,6 +13,7 @@ beta
----
Finished
- 2023.02.20 : 检查更新
- 2023.02.19 : 修复点歌机ui卡死的bug
- 2023.02.07@0.9.7: 添加播放器
- 2022.12.27@0.9.6: 闪退bug修复