diff --git a/go.mod b/go.mod index e42e62d..5772918 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ replace ( require ( fyne.io/fyne/v2 v2.5.0 - fyne.io/x/fyne v0.0.0-20240326131024-3ba9170cc3be github.com/AynaLivePlayer/liveroom-sdk v0.1.0 github.com/AynaLivePlayer/miaosic v0.1.5 github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b diff --git a/gui/component/entry.go b/gui/component/entry.go index affca4a..53c84b5 100644 --- a/gui/component/entry.go +++ b/gui/component/entry.go @@ -1,6 +1,7 @@ package component import ( + "AynaLivePlayer/gui/xfyne" "fyne.io/fyne/v2" "fyne.io/fyne/v2/widget" ) @@ -14,6 +15,7 @@ type Entry struct { func NewEntry() *Entry { e := &Entry{} e.ExtendBaseWidget(e) + xfyne.EntryDisableUndoRedo(&e.Entry) return e } diff --git a/gui/gui.go b/gui/gui.go index a7c61d4..7e7e568 100644 --- a/gui/gui.go +++ b/gui/gui.go @@ -82,5 +82,12 @@ func Initialize() { MainWindow.SetFixedSize(true) if config.General.ShowSystemTray { setupSysTray() + } else { + MainWindow.SetCloseIntercept( + func() { + // save twice i don;t care + _ = config.SaveToConfigFile(config.ConfigPath) + MainWindow.Close() + }) } } diff --git a/gui/gutil/resize.go b/gui/gutil/resize.go index 2568082..aae8d45 100644 --- a/gui/gutil/resize.go +++ b/gui/gutil/resize.go @@ -5,8 +5,8 @@ import ( "errors" "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" - "fyne.io/fyne/v2/storage" "github.com/AynaLivePlayer/miaosic" + "github.com/go-resty/resty/v2" "github.com/nfnt/resize" "image" "image/png" @@ -35,20 +35,15 @@ func NewImageFromPlayerPicture(picture miaosic.Picture) (*canvas.Image, error) { if img == nil { return nil, errors.New("fail to read image") } - } else { - uri, err := storage.ParseURI(picture.Url) + get, err := resty.New().R().Get(picture.Url) if err != nil { return nil, err } - if uri == nil { - return nil, errors.New("fail to fail url") - } + img = canvas.NewImageFromReader(bytes.NewReader(get.Body()), "cover") // NewImageFromURI will return an image with empty resource and file - img = canvas.NewImageFromURI(uri) - if img == nil || (img.File == "" && img.Resource == nil) { - // bug fix, return a new error to indicate fail to read an image - return nil, errors.New("fail to read image") + if img == nil { + return nil, errors.New("fail to download image") } } if img.Resource == nil { diff --git a/gui/liverooms.go b/gui/liverooms.go index 2b60801..bf583d1 100644 --- a/gui/liverooms.go +++ b/gui/liverooms.go @@ -4,6 +4,7 @@ import ( "AynaLivePlayer/core/events" "AynaLivePlayer/core/model" "AynaLivePlayer/global" + "AynaLivePlayer/gui/xfyne" "AynaLivePlayer/pkg/event" "AynaLivePlayer/pkg/i18n" "fyne.io/fyne/v2" @@ -57,8 +58,8 @@ func createRoomSelector() fyne.CanvasObject { descriptionLabel.SetText("") } }) - idEntry := widget.NewEntry() - nameEntry := widget.NewEntry() + idEntry := xfyne.EntryDisableUndoRedo(widget.NewEntry()) + nameEntry := xfyne.EntryDisableUndoRedo(widget.NewEntry()) dia := dialog.NewCustomConfirm( i18n.T("gui.room.add.title"), i18n.T("gui.room.add.confirm"), diff --git a/gui/playlists.go b/gui/playlists.go index 93dd1ab..500724d 100644 --- a/gui/playlists.go +++ b/gui/playlists.go @@ -4,6 +4,7 @@ import ( "AynaLivePlayer/core/events" "AynaLivePlayer/core/model" "AynaLivePlayer/global" + "AynaLivePlayer/gui/xfyne" "AynaLivePlayer/pkg/event" "AynaLivePlayer/pkg/i18n" "fmt" @@ -44,7 +45,7 @@ func createPlaylists() fyne.CanvasObject { }) PlaylistManager.AddBtn = widget.NewButton(i18n.T("gui.playlist.button.add"), func() { providerEntry := widget.NewSelect(PlaylistManager.providers, nil) - idEntry := widget.NewEntry() + idEntry := xfyne.EntryDisableUndoRedo(widget.NewEntry()) dia := dialog.NewCustomConfirm( i18n.T("gui.playlist.add.title"), i18n.T("gui.playlist.add.confirm"), diff --git a/gui/tray.go b/gui/tray.go index c5b95da..ca3e326 100644 --- a/gui/tray.go +++ b/gui/tray.go @@ -1,6 +1,7 @@ package gui import ( + "AynaLivePlayer/pkg/config" "AynaLivePlayer/pkg/i18n" "AynaLivePlayer/resource" "fyne.io/fyne/v2" @@ -17,6 +18,7 @@ func setupSysTray() { desk.SetSystemTrayIcon(resource.ImageIcon) } MainWindow.SetCloseIntercept(func() { + _ = config.SaveToConfigFile(config.ConfigPath) MainWindow.Hide() }) } diff --git a/gui/xfyne/patch.go b/gui/xfyne/patch.go new file mode 100644 index 0000000..5e11c48 --- /dev/null +++ b/gui/xfyne/patch.go @@ -0,0 +1,14 @@ +package xfyne + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/widget" + "reflect" +) + +func EntryDisableUndoRedo(entry *widget.Entry) *widget.Entry { + val := reflect.ValueOf(entry).Elem().FieldByName("shortcut").Addr().UnsafePointer() + (*fyne.ShortcutHandler)(val).RemoveShortcut(&fyne.ShortcutRedo{}) + (*fyne.ShortcutHandler)(val).RemoveShortcut(&fyne.ShortcutUndo{}) + return entry +} diff --git a/gui/xfyne/patch_test.go b/gui/xfyne/patch_test.go new file mode 100644 index 0000000..dc1481e --- /dev/null +++ b/gui/xfyne/patch_test.go @@ -0,0 +1,11 @@ +package xfyne + +import ( + "fyne.io/fyne/v2/widget" + "testing" +) + +func TestEntryDisableUndoRedo(t *testing.T) { + entry := widget.NewEntry() + EntryDisableUndoRedo(entry) +} diff --git a/internal/player/mpv/mpv.go b/internal/player/mpv/mpv.go index 0f41215..a125c44 100644 --- a/internal/player/mpv/mpv.go +++ b/internal/player/mpv/mpv.go @@ -176,7 +176,7 @@ func registerCmdHandler() { log.Infof("[MPV Player] Play media %s", mediaInfo.Title) mediaUrls, err := miaosic.GetMediaUrl(mediaInfo.Meta, miaosic.QualityAny) if err != nil || len(mediaUrls) == 0 { - log.Warn("[MPV PlayControl] get media url failed", err) + log.Warn("[MPV PlayControl] get media url failed ", mediaInfo.Meta.ID(), err) global.EventManager.CallA( events.PlayerPlayErrorUpdate, events.PlayerPlayErrorUpdateEvent{ diff --git a/pkg/config/config.go b/pkg/config/config.go index 18785bd..e821381 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -10,7 +10,7 @@ import ( const ( ProgramName = "卡西米尔唱片机" - Version uint32 = 0x010008 + Version uint32 = 0x010009 ) const ( diff --git a/pkg/liveroom-sdk b/pkg/liveroom-sdk index dc1612e..457e638 160000 --- a/pkg/liveroom-sdk +++ b/pkg/liveroom-sdk @@ -1 +1 @@ -Subproject commit dc1612e5c8e32244aac9b65b9190c325232fe346 +Subproject commit 457e63879a580eaf2aa1308fca5e0cac78c3d021 diff --git a/pkg/miaosic b/pkg/miaosic index fce7ebb..6ee4bed 160000 --- a/pkg/miaosic +++ b/pkg/miaosic @@ -1 +1 @@ -Subproject commit fce7ebbdd4bc35adc4cedefabdc38b27a8c8c1b5 +Subproject commit 6ee4bed0437a070c8f3b3fbe9452cd626a746665 diff --git a/plugin/diange/blacklist.go b/plugin/diange/blacklist.go index 0126712..9dd1693 100644 --- a/plugin/diange/blacklist.go +++ b/plugin/diange/blacklist.go @@ -1,6 +1,7 @@ package diange import ( + "AynaLivePlayer/gui/xfyne" "AynaLivePlayer/pkg/i18n" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" @@ -30,7 +31,7 @@ func (b *blacklist) CreatePanel() fyne.CanvasObject { return b.panel } // UI组件 - input := widget.NewEntry() + input := xfyne.EntryDisableUndoRedo(widget.NewEntry()) input.SetPlaceHolder(i18n.T("plugin.diange.blacklist.input.placeholder")) exactText := i18n.T("plugin.diange.blacklist.option.exact") diff --git a/plugin/diange/diange.go b/plugin/diange/diange.go index fc44c5d..0082d21 100644 --- a/plugin/diange/diange.go +++ b/plugin/diange/diange.go @@ -6,6 +6,7 @@ import ( "AynaLivePlayer/global" "AynaLivePlayer/gui" "AynaLivePlayer/gui/component" + "AynaLivePlayer/gui/xfyne" "AynaLivePlayer/pkg/config" "AynaLivePlayer/pkg/event" "AynaLivePlayer/pkg/i18n" @@ -345,27 +346,27 @@ func (d *Diange) CreatePanel() fyne.CanvasObject { container.NewGridWithColumns(2, container.NewBorder(nil, nil, widget.NewLabel(i18n.T("plugin.diange.medal.name")), nil, - widget.NewEntryWithData(binding.BindString(&d.MedalName))), + xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&d.MedalName)))), container.NewBorder(nil, nil, widget.NewLabel(i18n.T("plugin.diange.medal.level")), nil, - widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.MedalPermission)))), + xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.MedalPermission))))), ), ) dgQueue := container.NewBorder(nil, nil, widget.NewLabel(i18n.T("plugin.diange.queue_max")), nil, - widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.QueueMax))), + xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.QueueMax)))), ) dgUserMax := container.NewBorder(nil, nil, widget.NewLabel(i18n.T("plugin.diange.user_max")), nil, - widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserMax))), + xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserMax)))), ) dgCoolDown := container.NewBorder(nil, nil, widget.NewLabel(i18n.T("plugin.diange.cooldown")), nil, - widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserCoolDown))), + xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserCoolDown)))), ) dgShortCut := container.NewBorder(nil, nil, widget.NewLabel(i18n.T("plugin.diange.custom_cmd")), nil, - widget.NewEntryWithData(binding.BindString(&d.CustomCMD)), + xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&d.CustomCMD))), ) skipPlaylistCheck := widget.NewCheckWithData(i18n.T("plugin.diange.skip_playlist.prompt"), binding.BindBool(&d.SkipSystemPlaylist)) skipPlaylist := container.NewHBox( @@ -379,9 +380,9 @@ func (d *Diange) CreatePanel() fyne.CanvasObject { widget.NewLabel(source), widget.NewCheckWithData(i18n.T("plugin.diange.source.enable"), binding.BindBool(&cfg.Enable)), widget.NewLabel(i18n.T("plugin.diange.source.priority")), - widget.NewEntryWithData(binding.IntToString(binding.BindInt(&cfg.Priority))), + xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&cfg.Priority)))), widget.NewLabel(i18n.T("plugin.diange.source.command")), - widget.NewEntryWithData(binding.BindString(&cfg.Command)), + xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&cfg.Command))), ), ) } diff --git a/plugin/durationmgmt/durationmgmt.go b/plugin/durationmgmt/durationmgmt.go index 993cbd2..17f81ef 100644 --- a/plugin/durationmgmt/durationmgmt.go +++ b/plugin/durationmgmt/durationmgmt.go @@ -4,6 +4,7 @@ import ( "AynaLivePlayer/core/events" "AynaLivePlayer/global" "AynaLivePlayer/gui" + "AynaLivePlayer/gui/xfyne" "AynaLivePlayer/pkg/config" "AynaLivePlayer/pkg/event" "AynaLivePlayer/pkg/i18n" @@ -90,7 +91,7 @@ func (d *MaxDuration) CreatePanel() fyne.CanvasObject { if d.panel != nil { return d.panel } - maxDurationInput := widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.MaxDuration))) + maxDurationInput := xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.MaxDuration)))) skipOnPlayCheckbox := widget.NewCheckWithData(i18n.T("plugin.maxduration.enable"), binding.BindBool(&d.SkipOnPlay)) skipOnReachCheckbox := widget.NewCheckWithData(i18n.T("plugin.maxduration.enable"), binding.BindBool(&d.SkipOnReach)) d.panel = container.New( diff --git a/plugin/qiege/qiege.go b/plugin/qiege/qiege.go index fc4e067..91db3f7 100644 --- a/plugin/qiege/qiege.go +++ b/plugin/qiege/qiege.go @@ -5,6 +5,7 @@ import ( "AynaLivePlayer/global" "AynaLivePlayer/gui" "AynaLivePlayer/gui/component" + "AynaLivePlayer/gui/xfyne" "AynaLivePlayer/pkg/config" "AynaLivePlayer/pkg/event" "AynaLivePlayer/pkg/i18n" @@ -74,7 +75,7 @@ func (d *Qiege) handleMessage(event *event.Event) { if len(msgs) < 1 || msgs[0] != d.CustomCMD { return } - d.log.Infof("recieve diange command") + d.log.Infof("recieve qiege command") if d.UserPermission { if d.currentUid == message.User.Uid { global.EventManager.CallA( @@ -120,7 +121,7 @@ func (d *Qiege) CreatePanel() fyne.CanvasObject { ) qgShortCut := container.NewBorder(nil, nil, widget.NewLabel(i18n.T("plugin.qiege.custom_cmd")), nil, - widget.NewEntryWithData(binding.BindString(&d.CustomCMD)), + xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&d.CustomCMD))), ) d.panel = container.NewVBox(dgPerm, qgShortCut) return d.panel diff --git a/plugin/webinfo/webinfo.go b/plugin/webinfo/webinfo.go index b83c5c9..3d4f18a 100644 --- a/plugin/webinfo/webinfo.go +++ b/plugin/webinfo/webinfo.go @@ -7,6 +7,7 @@ import ( "AynaLivePlayer/core/model" "AynaLivePlayer/gui" "AynaLivePlayer/gui/component" + "AynaLivePlayer/gui/xfyne" "AynaLivePlayer/pkg/config" "AynaLivePlayer/pkg/event" "AynaLivePlayer/pkg/i18n" @@ -183,7 +184,7 @@ func (w *WebInfo) CreatePanel() fyne.CanvasObject { statusText.SetText(w.getServerStatusText()) serverPort := container.NewBorder(nil, nil, widget.NewLabel(i18n.T("plugin.webinfo.port")), nil, - widget.NewEntryWithData(binding.IntToString(binding.BindInt(&w.Port))), + xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&w.Port)))), ) serverUrl := widget.NewHyperlink(w.getServerUrl(), util.UrlMustParse(w.getServerUrl())) serverPreview := container.NewHBox( diff --git a/plugin/wshub/wshub.go b/plugin/wshub/wshub.go index a0cb482..889ff9f 100644 --- a/plugin/wshub/wshub.go +++ b/plugin/wshub/wshub.go @@ -5,6 +5,7 @@ import ( "AynaLivePlayer/global" "AynaLivePlayer/gui" "AynaLivePlayer/gui/component" + "AynaLivePlayer/gui/xfyne" "AynaLivePlayer/pkg/config" "AynaLivePlayer/pkg/event" "AynaLivePlayer/pkg/i18n" @@ -97,9 +98,9 @@ func (w *WsHub) CreatePanel() fyne.CanvasObject { freshStatusText() serverPort := container.NewBorder(nil, nil, widget.NewLabel(i18n.T("plugin.wshub.port")), nil, - widget.NewEntryWithData(binding.IntToString(binding.BindInt(&w.Port))), + xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&w.Port)))), ) - serverUrl := widget.NewEntry() + serverUrl := xfyne.EntryDisableUndoRedo(widget.NewEntry()) serverUrl.SetText(w.server.getWsUrl()) serverUrl.Disable() serverPreview := container.NewBorder(nil, nil, diff --git a/todo.txt b/todo.txt index 4dfe697..d9ef63c 100644 --- a/todo.txt +++ b/todo.txt @@ -12,10 +12,15 @@ - 歌词event发送全部歌词,前端处理不同版本 - 网页输出重写,使用网页版本,不绑定在点歌机内(点歌机不需要启动网页服务) - optimize local music +- 从搜索里添加的歌不能被切 +- remove tmp fix for entry undo + ---- Finished -- 2024.07.20 : fyne升级,字体修改为自动加载系统字体, 设置中课设置mpv是否现实歌曲封面 +- 2024.08.06 : 修复使用身份码连接的时候房管无法切歌的问题 +- 2024.07.25 : 或许修复配置无法正确保存的问题 +- 2024.07.20 : fyne升级,字体修改为自动加载系统字体, 设置中可设置mpv是否现实歌曲封面 - 2024.06.23@1.0.8 : 歌词字符集自动检测解码,单个点歌数上线 - 2024.06.22 : 支持多个点歌命令, kugou源 - 2024.06.21 : bilibili歌单,包括收藏夹和视频合集