mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2025-12-06 10:22:50 +08:00
update checker
This commit is contained in:
@@ -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": "管理员"
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
ProgramName = "卡西米尔唱片机"
|
||||
Version = "beta 0.9.7"
|
||||
ProgramName = "卡西米尔唱片机"
|
||||
Version uint32 = 0x000909
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
9
core/adapter/application.go
Normal file
9
core/adapter/application.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package adapter
|
||||
|
||||
import "AynaLivePlayer/core/model"
|
||||
|
||||
type IApplication interface {
|
||||
Version() model.VersionInfo
|
||||
LatestVersion() model.VersionInfo
|
||||
CheckUpdate() error
|
||||
}
|
||||
@@ -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
35
core/model/application.go
Normal 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)
|
||||
}
|
||||
17
core/model/application_test.go
Normal file
17
core/model/application_test.go
Normal 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
2
go.mod
@@ -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
4
go.sum
@@ -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=
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
25
gui/gui.go
25
gui/gui.go
@@ -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
41
internal/application.go
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user