mirror of
https://github.com/AynaLivePlayer/AynaLivePlayer.git
synced 2026-04-01 16:55:16 +08:00
1
go.mod
1
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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
}
|
||||
|
||||
14
gui/xfyne/patch.go
Normal file
14
gui/xfyne/patch.go
Normal file
@@ -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
|
||||
}
|
||||
11
gui/xfyne/patch_test.go
Normal file
11
gui/xfyne/patch_test.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package xfyne
|
||||
|
||||
import (
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEntryDisableUndoRedo(t *testing.T) {
|
||||
entry := widget.NewEntry()
|
||||
EntryDisableUndoRedo(entry)
|
||||
}
|
||||
@@ -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{
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
const (
|
||||
ProgramName = "卡西米尔唱片机"
|
||||
Version uint32 = 0x010008
|
||||
Version uint32 = 0x010009
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
Submodule pkg/liveroom-sdk updated: dc1612e5c8...457e63879a
Submodule pkg/miaosic updated: fce7ebbdd4...6ee4bed043
@@ -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")
|
||||
|
||||
@@ -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))),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
7
todo.txt
7
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歌单,包括收藏夹和视频合集
|
||||
|
||||
Reference in New Issue
Block a user