migrate to eventbus, add support to macos

This commit is contained in:
aynakeya
2025-10-02 21:57:22 +08:00
parent a81eb4a131
commit 918e2e81b3
49 changed files with 251 additions and 236 deletions

View File

@@ -13,6 +13,7 @@ import (
"flag"
"os"
"os/signal"
"path/filepath"
"time"
)
@@ -45,8 +46,18 @@ func setupGlobal() {
global.Logger.SetLogLevel(Log.Level)
}
func main() {
func init() {
flag.Parse()
// if not dev, set working directory to executable directory
if !*dev {
exePath, _ := os.Executable()
exePath, _ = filepath.EvalSymlinks(exePath)
exeDir := filepath.Dir(exePath)
_ = os.Chdir(exeDir)
}
}
func main() {
config.LoadFromFile(config.ConfigPath)
config.LoadConfig(Log)
i18n.LoadLanguage(config.General.Language)

View File

@@ -556,37 +556,37 @@
"en": "Obs browser output",
"zh-CN": "OBS网页输出: "
},
"plugin.yinliang.title": {
"en": "Volume Control",
"zh-CN": "音量控制"
"plugin.yinliang.admin_permission": {
"en": "Admin only",
"zh-CN": "仅房管可操作"
},
"plugin.yinliang.description": {
"en": "Control volume via danmaku",
"zh-CN": "通过弹幕控制音量"
},
"plugin.yinliang.admin_permission": {
"en": "Admin only",
"zh-CN": "仅房管可操作"
},
"plugin.yinliang.enabled": {
"en": "Enabled volume control",
"zh-CN": "启用弹幕音量控制"
},
"plugin.yinliang.volume_up_cmd": {
"en": "Volume increase command",
"zh-CN": "音量增加命令"
"plugin.yinliang.max_volume": {
"en": "Maximum volume (%)",
"zh-CN": "最大音量限制 (%)"
},
"plugin.yinliang.title": {
"en": "Volume Control",
"zh-CN": "音量控制"
},
"plugin.yinliang.volume_down_cmd": {
"en": "Volume decrease command",
"en": "Volume decrease command",
"zh-CN": "音量减少命令"
},
"plugin.yinliang.volume_step": {
"en": "Adjustment step (%)",
"zh-CN": "每次音量调整 (%)"
},
"plugin.yinliang.max_volume": {
"en": "Maximum volume (%)",
"zh-CN": "最大音量限制 (%)"
"plugin.yinliang.volume_up_cmd": {
"en": "Volume increase command",
"zh-CN": "音量增加命令"
}
}
}

View File

@@ -5,16 +5,6 @@ import (
liveroomsdk "github.com/AynaLivePlayer/liveroom-sdk"
)
//const (
// LiveRoomStatusChange string = "liveclient.status.change"
// LiveRoomMessageReceive string = "liveclient.message.receive"
//)
//
//type StatusChangeEvent struct {
// Connected bool
// Client adapter.LiveClient
//}
const LiveRoomAddCmd = "cmd.liveroom.add"
type LiveRoomAddCmdEvent struct {

View File

@@ -22,8 +22,8 @@ var EventsMapping = map[string]any{
PlayerToggleCmd: PlayerToggleCmdEvent{},
PlayerSetPauseCmd: PlayerSetPauseCmdEvent{},
PlayerPlayNextCmd: PlayerPlayNextCmdEvent{},
PlayerLyricRequestCmd: PlayerLyricRequestCmdEvent{},
PlayerLyricReload: PlayerLyricReloadEvent{},
CmdGetCurrentLyric: CmdGetCurrentLyricData{},
UpdateCurrentLyric: UpdateCurrentLyricData{},
PlayerLyricPosUpdate: PlayerLyricPosUpdateEvent{},
PlayerPlayingUpdate: PlayerPlayingUpdateEvent{},
PlayerPropertyPauseUpdate: PlayerPropertyPauseUpdateEvent{},

View File

@@ -2,14 +2,14 @@ package events
import "github.com/AynaLivePlayer/miaosic"
const PlayerLyricRequestCmd = "cmd.player.lyric.request"
const CmdGetCurrentLyric = "cmd.player.lyric.request"
type PlayerLyricRequestCmdEvent struct {
type CmdGetCurrentLyricData struct {
}
const PlayerLyricReload = "update.player.lyric.reload"
const UpdateCurrentLyric = "update.player.lyric.reload"
type PlayerLyricReloadEvent struct {
type UpdateCurrentLyricData struct {
Lyrics miaosic.Lyrics
}

View File

@@ -1,7 +1,6 @@
package component
import (
"AynaLivePlayer/gui/xfyne"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/widget"
)
@@ -15,7 +14,6 @@ type Entry struct {
func NewEntry() *Entry {
e := &Entry{}
e.ExtendBaseWidget(e)
xfyne.EntryDisableUndoRedo(&e.Entry)
return e
}

View File

@@ -38,12 +38,12 @@ func (b *bascicConfig) CreatePanel() fyne.CanvasObject {
mode = model.PlaylistModeRandom
}
logger.Infof("Set player playlist mode to %d", mode)
_ = global.EventBus.Publish(events.PlaylistModeChangeCmd(model.PlaylistIDPlayer),
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistModeChangeCmd(model.PlaylistIDPlayer),
events.PlaylistModeChangeCmdEvent{
Mode: mode,
})
})
global.EventBus.Subscribe("", events.PlaylistModeChangeUpdate(model.PlaylistIDPlayer),
global.EventBus.Subscribe(eventChannel, events.PlaylistModeChangeUpdate(model.PlaylistIDPlayer),
"gui.config.basic.random_playlist.player",
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
data := event.Data.(events.PlaylistModeChangeUpdateEvent)
@@ -56,13 +56,13 @@ func (b *bascicConfig) CreatePanel() fyne.CanvasObject {
if b {
mode = model.PlaylistModeRandom
}
_ = global.EventBus.Publish(events.PlaylistModeChangeCmd(model.PlaylistIDSystem),
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistModeChangeCmd(model.PlaylistIDSystem),
events.PlaylistModeChangeCmdEvent{
Mode: mode,
})
})
global.EventBus.Subscribe("", events.PlaylistModeChangeUpdate(model.PlaylistIDSystem),
global.EventBus.Subscribe(eventChannel, events.PlaylistModeChangeUpdate(model.PlaylistIDSystem),
"gui.config.basic.random_playlist.system",
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
data := event.Data.(events.PlaylistModeChangeUpdateEvent)
@@ -80,11 +80,11 @@ func (b *bascicConfig) CreatePanel() fyne.CanvasObject {
if !ok {
return
}
_ = global.EventBus.Publish(events.PlayerSetAudioDeviceCmd, events.PlayerSetAudioDeviceCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerSetAudioDeviceCmd, events.PlayerSetAudioDeviceCmdEvent{
Device: name,
})
})
global.EventBus.Subscribe("",
global.EventBus.Subscribe(eventChannel,
events.PlayerAudioDeviceUpdate,
"gui.config.basic.audio_device.update",
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
@@ -123,7 +123,7 @@ func (b *bascicConfig) CreatePanel() fyne.CanvasObject {
config.General.AutoCheckUpdate),
)
checkUpdateBtn := widget.NewButton(i18n.T("gui.config.basic.check_update"), func() {
_ = global.EventBus.Publish(events.CheckUpdateCmd, events.CheckUpdateCmdEvent{})
_ = global.EventBus.PublishToChannel(eventChannel, events.CheckUpdateCmd, events.CheckUpdateCmdEvent{})
})
useSysPlaylistBtn := container.NewHBox(
widget.NewLabel(i18n.T("gui.config.basic.use_system_playlist")),

5
gui/consts.go Normal file
View File

@@ -0,0 +1,5 @@
package gui
const (
eventChannel = "gui"
)

View File

@@ -72,7 +72,7 @@ func Initialize() {
// setupPlayerWindow()
// register error
global.EventBus.Subscribe("",
global.EventBus.Subscribe(eventChannel,
events.ErrorUpdate, "gui.show_error", gutil.ThreadSafeHandler(func(e *eventbus.Event) {
err := e.Data.(events.ErrorUpdateEvent).Error
logger.Warnf("gui received error event: %v, %v", err, err == nil)

View File

@@ -1,6 +1,6 @@
//go:build darwin || windows || linux
package xfyne
package gutil
import (
"fyne.io/fyne/v2"

View File

@@ -1,7 +1,10 @@
//go:build darwin
// +build darwin
package xfyne
package gutil
import (
"fyne.io/fyne/v2"
)
func GetWindowHandle(window fyne.Window) uintptr {
glfwWindow := getGlfwWindow(window)

View File

@@ -1,7 +1,6 @@
//go:build linux
// +build linux
package xfyne
package gutil
import (
"fyne.io/fyne/v2"

View File

@@ -1,7 +1,6 @@
//go:build !darwin && !windows && !linux
// +build !darwin,!windows,!linux
package xfyne
package gutil
import "fyne.io/fyne/v2"

View File

@@ -1,7 +1,6 @@
//go:build windows
// +build windows
package xfyne
package gutil
import (
"fyne.io/fyne/v2"

View File

@@ -7,7 +7,7 @@ import (
)
func registerHandlers() {
global.EventBus.Subscribe("", events.GUISetPlayerWindowOpenCmd, "gui.player.videoplayer.handleopen", func(event *eventbus.Event) {
global.EventBus.Subscribe(eventChannel, events.GUISetPlayerWindowOpenCmd, "gui.player.videoplayer.handleopen", func(event *eventbus.Event) {
data := event.Data.(events.GUISetPlayerWindowOpenCmdEvent)
if data.SetOpen {
playerWindow.Close()

View File

@@ -50,12 +50,12 @@ func createHistoryList() fyne.CanvasObject {
btns := object.(*fyne.Container).Objects[2].(*fyne.Container).Objects
m.User = model.SystemUser
btns[0].(*widget.Button).OnTapped = func() {
_ = global.EventBus.Publish(events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
Media: m,
})
}
btns[1].(*widget.Button).OnTapped = func() {
_ = global.EventBus.Publish(events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
Media: m,
Position: -1,
})
@@ -75,7 +75,7 @@ func createHistoryList() fyne.CanvasObject {
}
func registerHistoryHandler() {
global.EventBus.Subscribe("",
global.EventBus.Subscribe(eventChannel,
events.PlaylistDetailUpdate(model.PlaylistIDHistory),
"gui.history.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
History.mux.Lock()

View File

@@ -5,7 +5,6 @@ import (
"AynaLivePlayer/core/model"
"AynaLivePlayer/global"
"AynaLivePlayer/gui/gutil"
"AynaLivePlayer/gui/xfyne"
"AynaLivePlayer/pkg/eventbus"
"AynaLivePlayer/pkg/i18n"
"fyne.io/fyne/v2"
@@ -59,8 +58,8 @@ func createRoomSelector() fyne.CanvasObject {
descriptionLabel.SetText("")
}
})
idEntry := xfyne.EntryDisableUndoRedo(widget.NewEntry())
nameEntry := xfyne.EntryDisableUndoRedo(widget.NewEntry())
idEntry := widget.NewEntry()
nameEntry := widget.NewEntry()
dia := dialog.NewCustomConfirm(
i18n.T("gui.room.add.title"),
i18n.T("gui.room.add.confirm"),
@@ -80,7 +79,7 @@ func createRoomSelector() fyne.CanvasObject {
func(b bool) {
if b && len(clientNameEntry.Selected) > 0 && len(idEntry.Text) > 0 {
logger.Infof("Add room %s %s", clientNameEntry.Selected, idEntry.Text)
_ = global.EventBus.Publish(
_ = global.EventBus.PublishToChannel(eventChannel,
events.LiveRoomAddCmd,
events.LiveRoomAddCmdEvent{
Title: nameEntry.Text,
@@ -98,7 +97,7 @@ func createRoomSelector() fyne.CanvasObject {
if len(RoomTab.rooms) == 0 {
return
}
_ = global.EventBus.Publish(
_ = global.EventBus.PublishToChannel(eventChannel,
events.LiveRoomRemoveCmd,
events.LiveRoomRemoveCmdEvent{
Identifier: RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier(),
@@ -133,14 +132,14 @@ func createRoomSelector() fyne.CanvasObject {
}
func registerRoomHandlers() {
global.EventBus.Subscribe("",
global.EventBus.Subscribe(eventChannel,
events.LiveRoomProviderUpdate,
"gui.liveroom.provider_update",
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
RoomTab.providers = event.Data.(events.LiveRoomProviderUpdateEvent).Providers
RoomTab.Rooms.Refresh()
}))
global.EventBus.Subscribe("",
global.EventBus.Subscribe(eventChannel,
events.LiveRoomRoomsUpdate,
"gui.liveroom.rooms_update",
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
@@ -152,7 +151,7 @@ func registerRoomHandlers() {
RoomTab.Rooms.Refresh()
RoomTab.lock.Unlock()
}))
global.EventBus.Subscribe("",
global.EventBus.Subscribe(eventChannel,
events.LiveRoomStatusUpdate,
"gui.liveroom.room_status_update",
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
@@ -194,7 +193,7 @@ func createRoomController() fyne.CanvasObject {
}
RoomTab.ConnectBtn.Disable()
logger.Infof("Connect to room %s", RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier())
_ = global.EventBus.Publish(
_ = global.EventBus.PublishToChannel(eventChannel,
events.LiveRoomOperationCmd,
events.LiveRoomOperationCmdEvent{
Identifier: RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier(),
@@ -207,14 +206,14 @@ func createRoomController() fyne.CanvasObject {
}
RoomTab.DisConnectBtn.Disable()
logger.Infof("Disconnect from room %s", RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier())
_ = global.EventBus.Publish(
_ = global.EventBus.PublishToChannel(eventChannel,
events.LiveRoomOperationCmd,
events.LiveRoomOperationCmdEvent{
Identifier: RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier(),
SetConnect: false,
})
})
global.EventBus.Subscribe("",
global.EventBus.Subscribe(eventChannel,
events.LiveRoomOperationFinish,
"gui.liveroom.operation_finish",
gutil.ThreadSafeHandler(func(event *eventbus.Event) {
@@ -229,7 +228,7 @@ func createRoomController() fyne.CanvasObject {
return
}
logger.Infof("Change room %s autoconnect to %v", RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier(), b)
_ = global.EventBus.Publish(
_ = global.EventBus.PublishToChannel(eventChannel,
events.LiveRoomConfigChangeCmd,
events.LiveRoomConfigChangeCmdEvent{
Identifier: RoomTab.rooms[RoomTab.Index].LiveRoom.Identifier(),

View File

@@ -45,16 +45,16 @@ var PlayController = &PlayControllerContainer{}
func registerPlayControllerHandler() {
PlayController.ButtonPrev.OnTapped = func() {
_ = global.EventBus.Publish(events.PlayerSeekCmd, events.PlayerSeekCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerSeekCmd, events.PlayerSeekCmdEvent{
Position: 0,
Absolute: true,
})
}
PlayController.ButtonSwitch.OnTapped = func() {
_ = global.EventBus.Publish(events.PlayerToggleCmd, events.PlayerToggleCmdEvent{})
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerToggleCmd, events.PlayerToggleCmdEvent{})
}
PlayController.ButtonNext.OnTapped = func() {
_ = global.EventBus.Publish(events.PlayerPlayNextCmd, events.PlayerPlayNextCmdEvent{})
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerPlayNextCmd, events.PlayerPlayNextCmdEvent{})
}
PlayController.ButtonLrc.OnTapped = func() {
@@ -68,7 +68,7 @@ func registerPlayControllerHandler() {
showPlayerWindow()
}
global.EventBus.Subscribe("", events.PlayerPropertyPauseUpdate, "gui.player.controller.paused", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyPauseUpdate, "gui.player.controller.paused", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
if event.Data.(events.PlayerPropertyPauseUpdateEvent).Paused {
PlayController.ButtonSwitch.Icon = theme.MediaPlayIcon()
} else {
@@ -77,7 +77,7 @@ func registerPlayControllerHandler() {
PlayController.ButtonSwitch.Refresh()
}))
global.EventBus.Subscribe("", events.PlayerPropertyPercentPosUpdate, "gui.player.controller.percent_pos", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyPercentPosUpdate, "gui.player.controller.percent_pos", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
if PlayController.Progress.Dragging {
return
}
@@ -85,7 +85,7 @@ func registerPlayControllerHandler() {
PlayController.Progress.Refresh()
}))
global.EventBus.Subscribe("", events.PlayerPropertyStateUpdate, "gui.player.controller.idle_active", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyStateUpdate, "gui.player.controller.idle_active", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
state := event.Data.(events.PlayerPropertyStateUpdateEvent).State
if state == model.PlayerStateIdle || state == model.PlayerStateLoading {
PlayController.Progress.Value = 0
@@ -101,33 +101,33 @@ func registerPlayControllerHandler() {
PlayController.Progress.Max = 0
PlayController.Progress.OnDragEnd = func(f float64) {
_ = global.EventBus.Publish(events.PlayerSeekCmd, events.PlayerSeekCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerSeekCmd, events.PlayerSeekCmdEvent{
Position: f / 10,
Absolute: false,
})
}
global.EventBus.Subscribe("", events.PlayerPropertyTimePosUpdate, "gui.player.controller.time_pos", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyTimePosUpdate, "gui.player.controller.time_pos", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
PlayController.CurrentTime.SetText(util.FormatTime(int(event.Data.(events.PlayerPropertyTimePosUpdateEvent).TimePos)))
}))
global.EventBus.Subscribe("", events.PlayerPropertyDurationUpdate, "gui.player.controller.duration", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyDurationUpdate, "gui.player.controller.duration", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
PlayController.TotalTime.SetText(util.FormatTime(int(event.Data.(events.PlayerPropertyDurationUpdateEvent).Duration)))
}))
global.EventBus.Subscribe("", events.PlayerPropertyVolumeUpdate, "gui.player.controller.volume", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
global.EventBus.Subscribe(eventChannel, events.PlayerPropertyVolumeUpdate, "gui.player.controller.volume", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
PlayController.Volume.Value = event.Data.(events.PlayerPropertyVolumeUpdateEvent).Volume
PlayController.Volume.Refresh()
}))
PlayController.Volume.OnChanged = func(f float64) {
_ = global.EventBus.Publish(events.PlayerVolumeChangeCmd, events.PlayerVolumeChangeCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerVolumeChangeCmd, events.PlayerVolumeChangeCmdEvent{
Volume: f,
})
}
// todo: double check cover loading for new thread model
global.EventBus.Subscribe("", events.PlayerPlayingUpdate, "gui.player.updateinfo", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
global.EventBus.Subscribe(eventChannel, events.PlayerPlayingUpdate, "gui.player.updateinfo", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
if event.Data.(events.PlayerPlayingUpdateEvent).Removed {
PlayController.Progress.Value = 0
PlayController.Progress.Max = 0
@@ -227,7 +227,7 @@ func createPlayControllerV2() fyne.CanvasObject {
PlayController.Progress)
PlayController.Title = widget.NewLabel("Title")
PlayController.Title.Wrapping = fyne.TextTruncate
PlayController.Title.Truncation = fyne.TextTruncateClip
PlayController.Artist = widget.NewLabel("Artist")
PlayController.Username = widget.NewLabel("Username")

View File

@@ -42,7 +42,7 @@ func createLyricWindow() fyne.Window {
w.CenterOnScreen()
// register handlers
global.EventBus.Subscribe("",
global.EventBus.Subscribe(eventChannel,
events.PlayerLyricPosUpdate, "player.lyric.current_lyric", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
e := event.Data.(events.PlayerLyricPosUpdateEvent)
logger.Debug("lyric update", e)
@@ -69,16 +69,16 @@ func createLyricWindow() fyne.Window {
fullLrc.Refresh()
}))
global.EventBus.Subscribe("", events.PlayerLyricReload, "player.lyric.current_lyric", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
e := event.Data.(events.PlayerLyricReloadEvent)
global.EventBus.Subscribe(eventChannel, events.UpdateCurrentLyric, "player.lyric.current_lyric", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
e := event.Data.(events.UpdateCurrentLyricData)
fullLrc.Objects = createLyricObj(&e.Lyrics)
lrcWindow.Refresh()
}))
_ = global.EventBus.Publish(events.PlayerLyricRequestCmd, events.PlayerLyricRequestCmdEvent{})
_ = global.EventBus.PublishToChannel(eventChannel, events.CmdGetCurrentLyric, events.CmdGetCurrentLyricData{})
w.SetOnClosed(func() {
global.EventBus.Unsubscribe(events.PlayerLyricReload, "player.lyric.current_lyric")
global.EventBus.Unsubscribe(events.UpdateCurrentLyric, "player.lyric.current_lyric")
PlayController.LrcWindowOpen = false
})
return w

View File

@@ -28,12 +28,12 @@ func (b *playlistOperationButton) Tapped(e *fyne.PointEvent) {
func newPlaylistOperationButton() *playlistOperationButton {
b := &playlistOperationButton{Index: 0}
deleteItem := fyne.NewMenuItem(i18n.T("gui.player.playlist.op.delete"), func() {
_ = global.EventBus.Publish(events.PlaylistDeleteCmd(model.PlaylistIDPlayer), events.PlaylistDeleteCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistDeleteCmd(model.PlaylistIDPlayer), events.PlaylistDeleteCmdEvent{
Index: b.Index,
})
})
topItem := fyne.NewMenuItem(i18n.T("gui.player.playlist.op.top"), func() {
_ = global.EventBus.Publish(events.PlaylistMoveCmd(model.PlaylistIDPlayer), events.PlaylistMoveCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistMoveCmd(model.PlaylistIDPlayer), events.PlaylistMoveCmdEvent{
From: b.Index,
To: 0,
})
@@ -75,7 +75,7 @@ func createPlaylist() fyne.CanvasObject {
object.(*fyne.Container).Objects[1].(*widget.Label).SetText(fmt.Sprintf("%d", id))
object.(*fyne.Container).Objects[2].(*playlistOperationButton).Index = id
})
global.EventBus.Subscribe("", events.PlaylistDetailUpdate(model.PlaylistIDPlayer), "gui.player.playlist.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
global.EventBus.Subscribe(eventChannel, events.PlaylistDetailUpdate(model.PlaylistIDPlayer), "gui.player.playlist.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
UserPlaylist.mux.Lock()
UserPlaylist.Medias = event.Data.(events.PlaylistDetailUpdateEvent).Medias
UserPlaylist.List.Refresh()

View File

@@ -3,7 +3,7 @@ package gui
import (
"AynaLivePlayer/core/events"
"AynaLivePlayer/global"
"AynaLivePlayer/gui/xfyne"
"AynaLivePlayer/gui/gutil"
"fyne.io/fyne/v2"
)
@@ -22,10 +22,10 @@ func showPlayerWindow() {
}
playerWindow.Show()
if playerWindowHandle == 0 {
playerWindowHandle = xfyne.GetWindowHandle(playerWindow)
playerWindowHandle = gutil.GetWindowHandle(playerWindow)
logger.Infof("video output window handle: %d", playerWindowHandle)
if playerWindowHandle != 0 {
_ = global.EventBus.Publish(events.PlayerVideoPlayerSetWindowHandleCmd,
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerVideoPlayerSetWindowHandleCmd,
events.PlayerVideoPlayerSetWindowHandleCmdEvent{Handle: playerWindowHandle})
}
}

View File

@@ -5,7 +5,7 @@ import (
"AynaLivePlayer/core/model"
"AynaLivePlayer/global"
"AynaLivePlayer/gui/gutil"
"AynaLivePlayer/gui/xfyne"
"AynaLivePlayer/pkg/eventbus"
"AynaLivePlayer/pkg/i18n"
"fmt"
@@ -46,7 +46,7 @@ func createPlaylists() fyne.CanvasObject {
})
PlaylistManager.AddBtn = widget.NewButton(i18n.T("gui.playlist.button.add"), func() {
providerEntry := widget.NewSelect(PlaylistManager.providers, nil)
idEntry := xfyne.EntryDisableUndoRedo(widget.NewEntry())
idEntry := widget.NewEntry()
dia := dialog.NewCustomConfirm(
i18n.T("gui.playlist.add.title"),
i18n.T("gui.playlist.add.confirm"),
@@ -64,7 +64,7 @@ func createPlaylists() fyne.CanvasObject {
func(b bool) {
if b && len(providerEntry.Selected) > 0 && len(idEntry.Text) > 0 {
logger.Infof("add playlists %s %s", providerEntry.Selected, idEntry.Text)
_ = global.EventBus.Publish(
_ = global.EventBus.PublishToChannel(eventChannel,
events.PlaylistManagerAddPlaylistCmd,
events.PlaylistManagerAddPlaylistCmdEvent{
Provider: providerEntry.Selected,
@@ -82,7 +82,7 @@ func createPlaylists() fyne.CanvasObject {
return
}
logger.Infof("remove playlists %s", PlaylistManager.currentPlaylists[PlaylistManager.Index].Meta.ID())
_ = global.EventBus.Publish(
_ = global.EventBus.PublishToChannel(eventChannel,
events.PlaylistManagerRemovePlaylistCmd,
events.PlaylistManagerRemovePlaylistCmdEvent{
PlaylistID: PlaylistManager.currentPlaylists[PlaylistManager.Index].Meta.ID(),
@@ -93,18 +93,18 @@ func createPlaylists() fyne.CanvasObject {
return
}
PlaylistManager.Index = id
_ = global.EventBus.Publish(events.PlaylistManagerGetCurrentCmd, events.PlaylistManagerGetCurrentCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistManagerGetCurrentCmd, events.PlaylistManagerGetCurrentCmdEvent{
PlaylistID: PlaylistManager.currentPlaylists[id].Meta.ID(),
})
}
global.EventBus.Subscribe("", events.MediaProviderUpdate,
global.EventBus.Subscribe(eventChannel, events.MediaProviderUpdate,
"gui.playlists.provider.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
providers := event.Data.(events.MediaProviderUpdateEvent)
s := make([]string, len(providers.Providers))
copy(s, providers.Providers)
PlaylistManager.providers = s
}))
global.EventBus.Subscribe("", events.PlaylistManagerInfoUpdate,
global.EventBus.Subscribe(eventChannel, events.PlaylistManagerInfoUpdate,
"gui.playlists.info.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
data := event.Data.(events.PlaylistManagerInfoUpdateEvent)
prevLen := len(PlaylistManager.currentPlaylists)
@@ -115,7 +115,7 @@ func createPlaylists() fyne.CanvasObject {
PlaylistManager.Playlists.Select(0)
}
}))
global.EventBus.Subscribe("", events.PlaylistManagerSystemUpdate,
global.EventBus.Subscribe(eventChannel, events.PlaylistManagerSystemUpdate,
"gui.playlists.system.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
data := event.Data.(events.PlaylistManagerSystemUpdateEvent)
PlaylistManager.CurrentSystemPlaylist.SetText(i18n.T("gui.playlist.current") + data.Info.DisplayName())
@@ -137,7 +137,7 @@ func createPlaylistMedias() fyne.CanvasObject {
if PlaylistManager.Index >= len(PlaylistManager.currentPlaylists) {
return
}
_ = global.EventBus.Publish(events.PlaylistManagerRefreshCurrentCmd, events.PlaylistManagerRefreshCurrentCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistManagerRefreshCurrentCmd, events.PlaylistManagerRefreshCurrentCmdEvent{
PlaylistID: PlaylistManager.currentPlaylists[PlaylistManager.Index].Meta.ID(),
})
})
@@ -148,7 +148,7 @@ func createPlaylistMedias() fyne.CanvasObject {
return
}
logger.Infof("set playlist %s as system", PlaylistManager.currentPlaylists[PlaylistManager.Index].Meta.ID())
_ = global.EventBus.Publish(events.PlaylistManagerSetSystemCmd, events.PlaylistManagerSetSystemCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistManagerSetSystemCmd, events.PlaylistManagerSetSystemCmdEvent{
PlaylistID: PlaylistManager.currentPlaylists[PlaylistManager.Index].Meta.ID(),
})
})
@@ -179,18 +179,18 @@ func createPlaylistMedias() fyne.CanvasObject {
btns := object.(*fyne.Container).Objects[2].(*fyne.Container).Objects
m.User = model.SystemUser
btns[0].(*widget.Button).OnTapped = func() {
_ = global.EventBus.Publish(events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
Media: m,
})
}
btns[1].(*widget.Button).OnTapped = func() {
_ = global.EventBus.Publish(events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
Media: m,
Position: -1,
})
}
})
global.EventBus.Subscribe("", events.PlaylistManagerCurrentUpdate,
global.EventBus.Subscribe(eventChannel, events.PlaylistManagerCurrentUpdate,
"gui.playlists.current.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
logger.Infof("receive current playlist update, try to refresh playlist medias")
data := event.Data.(events.PlaylistManagerCurrentUpdateEvent)

View File

@@ -35,13 +35,13 @@ func createSearchBar() fyne.CanvasObject {
SearchResult.Items = make([]model.Media, 0)
SearchResult.List.Refresh()
SearchResult.mux.Unlock()
_ = global.EventBus.Publish(events.SearchCmd, events.SearchCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.SearchCmd, events.SearchCmdEvent{
Keyword: keyword,
Provider: pr,
})
})
global.EventBus.Subscribe("", events.MediaProviderUpdate,
global.EventBus.Subscribe(eventChannel, events.MediaProviderUpdate,
"gui.search.provider.update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
providers := event.Data.(events.MediaProviderUpdateEvent)
s := make([]string, len(providers.Providers))

View File

@@ -51,18 +51,18 @@ func createSearchList() fyne.CanvasObject {
object.(*fyne.Container).Objects[1].(*widget.Label).SetText(fmt.Sprintf("%d", id))
btns := object.(*fyne.Container).Objects[2].(*fyne.Container).Objects
btns[0].(*widget.Button).OnTapped = func() {
_ = global.EventBus.Publish(events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlayerPlayCmd, events.PlayerPlayCmdEvent{
Media: SearchResult.Items[id],
})
}
btns[1].(*widget.Button).OnTapped = func() {
_ = global.EventBus.Publish(events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
_ = global.EventBus.PublishToChannel(eventChannel, events.PlaylistInsertCmd(model.PlaylistIDPlayer), events.PlaylistInsertCmdEvent{
Media: SearchResult.Items[id],
Position: -1,
})
}
})
global.EventBus.Subscribe("", events.SearchResultUpdate, "gui.search.update_result", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
global.EventBus.Subscribe(eventChannel, events.SearchResultUpdate, "gui.search.update_result", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
items := event.Data.(events.SearchResultUpdateEvent).Medias
SearchResult.Items = items
SearchResult.mux.Lock()

View File

@@ -11,7 +11,7 @@ import (
)
func checkUpdate() {
global.EventBus.Subscribe("",
global.EventBus.Subscribe(eventChannel,
events.CheckUpdateResultUpdate, "gui.updater.check_update", gutil.ThreadSafeHandler(func(event *eventbus.Event) {
data := event.Data.(events.CheckUpdateResultUpdateEvent)
msg := data.Info.Version.String() + "\n\n\n" + data.Info.Info

View File

@@ -1,14 +0,0 @@
package xfyne
import (
"fyne.io/fyne/v2/widget"
)
func EntryDisableUndoRedo(entry *widget.Entry) *widget.Entry {
// do nothing because the bug has been fixed in fyne@v2.5.1
return entry
//val := reflect.ValueOf(entry).Elem().FieldByName("shortcut").Addr().UnsafePointer()
//(*fyne.ShortcutHandler)(val).RemoveShortcut(&fyne.ShortcutRedo{})
//(*fyne.ShortcutHandler)(val).RemoveShortcut(&fyne.ShortcutUndo{})
//return entry
}

View File

@@ -1,11 +0,0 @@
package xfyne
import (
"fyne.io/fyne/v2/widget"
"testing"
)
func TestEntryDisableUndoRedo(t *testing.T) {
entry := widget.NewEntry()
EntryDisableUndoRedo(entry)
}

View File

@@ -10,8 +10,6 @@ import (
)
func Initialize() {
handleSearch()
createLyricLoader()
handlePlayNext()
}

View File

@@ -0,0 +1,5 @@
# player
**player implementation**
for now, just use mpv, vlc not fully supported yet.

46
internal/source/base.go Normal file
View File

@@ -0,0 +1,46 @@
package source
import (
"AynaLivePlayer/core/events"
"AynaLivePlayer/global"
"AynaLivePlayer/pkg/config"
"AynaLivePlayer/pkg/logger"
"github.com/AynaLivePlayer/miaosic"
)
type _sourceConfig struct {
LocalSourcePath string
QQChannel string
}
func (_ _sourceConfig) Name() string {
return "Source"
}
func (_ _sourceConfig) OnLoad() {
}
func (_ _sourceConfig) OnSave() {
}
var sourceCfg = &_sourceConfig{
LocalSourcePath: "./music",
QQChannel: "qq",
}
var log logger.ILogger = nil
func Initialize() {
config.LoadConfig(sourceCfg)
log = global.Logger.WithPrefix("MediaProvider")
loadMediaProvider()
handleSearch()
createLyricLoader()
_ = global.EventBus.Publish(
events.MediaProviderUpdate, events.MediaProviderUpdateEvent{
Providers: miaosic.ListAvailableProviders(),
})
}

View File

@@ -4,6 +4,7 @@ import (
"github.com/AynaLivePlayer/miaosic"
)
// dummySource is placeholder source for bypassing copyright requirement
type dummySource struct{}
func (d *dummySource) GetName() string {

View File

@@ -1,4 +1,4 @@
package controller
package source
import (
"AynaLivePlayer/core/events"
@@ -16,8 +16,8 @@ type lyricLoader struct {
var lyricManager = &lyricLoader{}
func createLyricLoader() {
log := global.Logger.WithPrefix("LyricLoader")
global.EventBus.Subscribe("", events.PlayerPlayingUpdate, "internal.lyric.update", func(event *eventbus.Event) {
var err error
err = global.EventBus.Subscribe("", events.PlayerPlayingUpdate, "internal.lyric.update", func(event *eventbus.Event) {
data := event.Data.(events.PlayerPlayingUpdateEvent)
if data.Removed {
log.Debugf("current media removed, clear lyric")
@@ -32,11 +32,14 @@ func createLyricLoader() {
lyricManager.Lyric = miaosic.ParseLyrics("", "")
log.Errorf("failed to get lyric for %s (%s): %s", data.Media.Info.Title, data.Media.Info.Meta.ID(), err)
}
_ = global.EventBus.Publish(events.PlayerLyricReload, events.PlayerLyricReloadEvent{
_ = global.EventBus.Publish(events.UpdateCurrentLyric, events.UpdateCurrentLyricData{
Lyrics: lyricManager.Lyric,
})
})
global.EventBus.Subscribe("", events.PlayerPropertyTimePosUpdate, "internal.lyric.update_current", func(event *eventbus.Event) {
if err != nil {
log.ErrorW("Subscribe player playing update event failed", "error", err)
}
err = global.EventBus.Subscribe("", events.PlayerPropertyTimePosUpdate, "internal.lyric.update_current", func(event *eventbus.Event) {
time := event.Data.(events.PlayerPropertyTimePosUpdateEvent).TimePos
idx := lyricManager.Lyric.FindIndex(time)
if idx == lyricManager.prevIndex {
@@ -53,9 +56,15 @@ func createLyricLoader() {
})
return
})
global.EventBus.Subscribe("", events.PlayerLyricRequestCmd, "internal.lyric.request", func(event *eventbus.Event) {
_ = global.EventBus.Publish(events.PlayerLyricReload, events.PlayerLyricReloadEvent{
if err != nil {
log.ErrorW("Subscribe player time position update event failed", "error", err)
}
err = global.EventBus.Subscribe("", events.CmdGetCurrentLyric, "internal.lyric.request", func(event *eventbus.Event) {
_ = global.EventBus.Reply(event, events.UpdateCurrentLyric, events.UpdateCurrentLyricData{
Lyrics: lyricManager.Lyric,
})
})
if err != nil {
log.ErrorW("Subscribe player lyric request command event failed", "error", err)
}
}

View File

@@ -3,35 +3,9 @@
package source
import (
"AynaLivePlayer/core/events"
"AynaLivePlayer/global"
"AynaLivePlayer/pkg/config"
"github.com/AynaLivePlayer/miaosic"
)
type _sourceConfig struct {
LocalSourcePath string
}
func (_ _sourceConfig) Name() string {
return "Source"
}
func (_ _sourceConfig) OnLoad() {
}
func (_ _sourceConfig) OnSave() {
}
var sourceCfg = &_sourceConfig{
LocalSourcePath: "./music",
}
func Initialize() {
config.LoadConfig(sourceCfg)
func loadMediaProvider() {
miaosic.RegisterProvider(&dummySource{})
_ = global.EventBus.Publish(
events.MediaProviderUpdate, events.MediaProviderUpdateEvent{
Providers: miaosic.ListAvailableProviders(),
})
}

View File

@@ -1,4 +1,4 @@
package controller
package source
import (
"AynaLivePlayer/core/events"
@@ -9,9 +9,8 @@ import (
)
func handleSearch() {
log := global.Logger.WithPrefix("Search")
global.EventBus.Subscribe("",
events.SearchCmd, "internal.controller.search.handleSearchCmd", func(event *eventbus.Event) {
err := global.EventBus.Subscribe("",
events.SearchCmd, "internal.media_provider.search_handler", func(event *eventbus.Event) {
data := event.Data.(events.SearchCmdEvent)
log.Infof("Search %s using %s", data.Keyword, data.Provider)
searchResult, err := miaosic.SearchByProvider(data.Provider, data.Keyword, 1, 10)
@@ -26,9 +25,13 @@ func handleSearch() {
User: model.SystemUser,
}
}
_ = global.EventBus.Publish(
events.SearchResultUpdate, events.SearchResultUpdateEvent{
_ = global.EventBus.Reply(
event, events.SearchResultUpdate,
events.SearchResultUpdateEvent{
Medias: medias,
})
})
if err != nil {
log.ErrorW("Subscribe search event failed", "error", err)
}
}

View File

@@ -3,9 +3,6 @@
package source
import (
"AynaLivePlayer/core/events"
"AynaLivePlayer/global"
"AynaLivePlayer/pkg/config"
"github.com/AynaLivePlayer/miaosic"
_ "github.com/AynaLivePlayer/miaosic/providers/bilivideo"
"github.com/AynaLivePlayer/miaosic/providers/kugou"
@@ -15,28 +12,7 @@ import (
"github.com/AynaLivePlayer/miaosic/providers/qq"
)
type _sourceConfig struct {
LocalSourcePath string
QQChannel string
}
func (_ _sourceConfig) Name() string {
return "Source"
}
func (_ _sourceConfig) OnLoad() {
}
func (_ _sourceConfig) OnSave() {
}
var sourceCfg = &_sourceConfig{
LocalSourcePath: "./music",
QQChannel: "qq",
}
func Initialize() {
config.LoadConfig(sourceCfg)
func loadMediaProvider() {
kugou.UseInstrumental()
miaosic.RegisterProvider(local.NewLocal(sourceCfg.LocalSourcePath))
if sourceCfg.QQChannel == "wechat" {
@@ -44,9 +20,4 @@ func Initialize() {
} else {
qq.UseQQLogin()
}
_ = global.EventBus.Publish(
events.MediaProviderUpdate, events.MediaProviderUpdateEvent{
Providers: miaosic.ListAvailableProviders(),
})
}

View File

@@ -0,0 +1,9 @@
package sysmediacontrol
func InitSystemMediaControl() {
// stub
}
func Destroy() {
// stub
}

View File

@@ -26,7 +26,7 @@ type Subscriber interface {
// SubscribeAny is Subscribe with empty channel. this function will subscribe to event from any channel
SubscribeAny(eventId string, handlerName string, fn HandlerFunc) error
// SubscribeOnce will run handler once, and delete handler internally
SubscribeOnce(eventId string, handlerName string, fn HandlerFunc) error
SubscribeOnce(channel string, eventId string, handlerName string, fn HandlerFunc) error
// Unsubscribe just remove handler for the bus
Unsubscribe(eventId string, handlerName string) error
}
@@ -34,6 +34,8 @@ type Subscriber interface {
type Publisher interface {
// Publish basically a wrapper to PublishEvent
Publish(eventId string, data interface{}) error
// PublishToChannel publish event to a specific channel, basically another wrapper to PublishEvent
PublishToChannel(channel string, eventId string, data interface{}) error
// PublishEvent publish an event
PublishEvent(event *Event) error
}
@@ -41,6 +43,7 @@ type Publisher interface {
// Caller is special usage of a Publisher
type Caller interface {
Call(pubEvtId string, data interface{}, subEvtId string) (*Event, error)
Reply(req *Event, eventId string, data interface{}) error
}
type Controller interface {

View File

@@ -191,7 +191,7 @@ func (b *bus) SubscribeAny(eventId, handlerName string, fn HandlerFunc) error {
return nil
}
func (b *bus) SubscribeOnce(eventId, handlerName string, fn HandlerFunc) error {
func (b *bus) SubscribeOnce(channel, eventId, handlerName string, fn HandlerFunc) error {
if eventId == "" || handlerName == "" || fn == nil {
return errors.New("invalid SubscribeOnce args")
}
@@ -202,7 +202,7 @@ func (b *bus) SubscribeOnce(eventId, handlerName string, fn HandlerFunc) error {
m = make(map[string]handlerRec)
b.handlers[eventId] = m
}
m[handlerName] = handlerRec{name: handlerName, fn: fn, once: true}
m[handlerName] = handlerRec{channel: channel, name: handlerName, fn: fn, once: true}
return nil
}
@@ -225,6 +225,10 @@ func (b *bus) Publish(eventId string, data interface{}) error {
return b.PublishEvent(&Event{Id: eventId, Data: data})
}
func (b *bus) PublishToChannel(channel string, eventId string, data interface{}) error {
return b.PublishEvent(&Event{Id: eventId, Channel: channel, Data: data})
}
func (b *bus) PublishEvent(ev *Event) error {
if ev == nil || ev.Id == "" {
return errors.New("invalid PublishEvent args")
@@ -327,6 +331,15 @@ func (b *bus) Call(eventId string, data interface{}, subEvtId string) (*Event, e
}
}
func (b *bus) Reply(req *Event, eventId string, data interface{}) error {
return b.PublishEvent(&Event{
Id: eventId,
Channel: req.Channel,
EchoId: req.EchoId,
Data: data,
})
}
func (b *bus) nextEchoId() string {
x := b.idCtr.Add(1)
return fmt.Sprintf("echo-%d-%d", time.Now().UnixNano(), x)

View File

@@ -11,7 +11,7 @@ func main() {
a := app.New()
w := a.NewWindow("SysTray")
icon, _ := fyne.LoadResourceFromPath("./assets/icon.jpg")
icon, _ := fyne.LoadResourceFromPath("./assets/icon2.jpg")
//icon, _ := fyne.LoadResourceFromPath("./assets/icon.png")
if desk, ok := a.(desktop.App); ok {

View File

@@ -1,7 +1,6 @@
package diange
import (
"AynaLivePlayer/gui/xfyne"
"AynaLivePlayer/pkg/i18n"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
@@ -31,7 +30,7 @@ func (b *blacklist) CreatePanel() fyne.CanvasObject {
return b.panel
}
// UI组件
input := xfyne.EntryDisableUndoRedo(widget.NewEntry())
input := widget.NewEntry()
input.SetPlaceHolder(i18n.T("plugin.diange.blacklist.input.placeholder"))
exactText := i18n.T("plugin.diange.blacklist.option.exact")

View File

@@ -6,7 +6,7 @@ import (
"AynaLivePlayer/global"
"AynaLivePlayer/gui"
"AynaLivePlayer/gui/component"
"AynaLivePlayer/gui/xfyne"
"AynaLivePlayer/pkg/config"
"AynaLivePlayer/pkg/eventbus"
"AynaLivePlayer/pkg/i18n"
@@ -382,27 +382,27 @@ func (d *Diange) CreatePanel() fyne.CanvasObject {
container.NewGridWithColumns(2,
container.NewBorder(nil, nil,
widget.NewLabel(i18n.T("plugin.diange.medal.name")), nil,
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&d.MedalName)))),
widget.NewEntryWithData(binding.BindString(&d.MedalName))),
container.NewBorder(nil, nil,
widget.NewLabel(i18n.T("plugin.diange.medal.level")), nil,
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.MedalPermission))))),
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.MedalPermission)))),
),
)
dgQueue := container.NewBorder(nil, nil,
widget.NewLabel(i18n.T("plugin.diange.queue_max")), nil,
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.QueueMax)))),
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.QueueMax))),
)
dgUserMax := container.NewBorder(nil, nil,
widget.NewLabel(i18n.T("plugin.diange.user_max")), nil,
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserMax)))),
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserMax))),
)
dgCoolDown := container.NewBorder(nil, nil,
widget.NewLabel(i18n.T("plugin.diange.cooldown")), nil,
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserCoolDown)))),
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.UserCoolDown))),
)
dgShortCut := container.NewBorder(nil, nil,
widget.NewLabel(i18n.T("plugin.diange.custom_cmd")), nil,
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&d.CustomCMD))),
widget.NewEntryWithData(binding.BindString(&d.CustomCMD)),
)
skipPlaylistCheck := widget.NewCheckWithData(i18n.T("plugin.diange.skip_playlist.prompt"), binding.BindBool(&d.SkipSystemPlaylist))
skipPlaylist := container.NewHBox(
@@ -420,9 +420,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")),
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&cfg.Priority)))),
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&cfg.Priority))),
widget.NewLabel(i18n.T("plugin.diange.source.command")),
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&cfg.Command))),
widget.NewEntryWithData(binding.BindString(&cfg.Command)),
),
)
}

View File

@@ -4,7 +4,7 @@ import (
"AynaLivePlayer/core/events"
"AynaLivePlayer/global"
"AynaLivePlayer/gui"
"AynaLivePlayer/gui/xfyne"
"AynaLivePlayer/pkg/config"
"AynaLivePlayer/pkg/eventbus"
"AynaLivePlayer/pkg/i18n"
@@ -91,7 +91,7 @@ func (d *MaxDuration) CreatePanel() fyne.CanvasObject {
if d.panel != nil {
return d.panel
}
maxDurationInput := xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&d.MaxDuration))))
maxDurationInput := 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(

View File

@@ -5,7 +5,7 @@ import (
"AynaLivePlayer/global"
"AynaLivePlayer/gui"
"AynaLivePlayer/gui/component"
"AynaLivePlayer/gui/xfyne"
"AynaLivePlayer/pkg/config"
"AynaLivePlayer/pkg/eventbus"
"AynaLivePlayer/pkg/i18n"
@@ -121,7 +121,7 @@ func (d *Qiege) CreatePanel() fyne.CanvasObject {
)
qgShortCut := container.NewBorder(nil, nil,
widget.NewLabel(i18n.T("plugin.qiege.custom_cmd")), nil,
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&d.CustomCMD))),
widget.NewEntryWithData(binding.BindString(&d.CustomCMD)),
)
d.panel = container.NewVBox(dgPerm, qgShortCut)
return d.panel

5
plugin/wshub/consts.go Normal file
View File

@@ -0,0 +1,5 @@
package wshub
const (
eventChannel = "wshub"
)

View File

@@ -49,7 +49,7 @@ func (c *wsClient) start() {
return
}
if globalEnableWsHubControl {
_ = global.EventBus.Publish(data.EventID, actualEventData)
_ = global.EventBus.PublishToChannel(eventChannel, data.EventID, actualEventData)
}
}
}

View File

@@ -5,7 +5,7 @@ import (
"AynaLivePlayer/global"
"AynaLivePlayer/gui"
"AynaLivePlayer/gui/component"
"AynaLivePlayer/gui/xfyne"
"AynaLivePlayer/pkg/config"
"AynaLivePlayer/pkg/eventbus"
"AynaLivePlayer/pkg/i18n"
@@ -104,9 +104,9 @@ func (w *WsHub) CreatePanel() fyne.CanvasObject {
freshStatusText()
serverPort := container.NewBorder(nil, nil,
widget.NewLabel(i18n.T("plugin.wshub.port")), nil,
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.IntToString(binding.BindInt(&w.Port)))),
widget.NewEntryWithData(binding.IntToString(binding.BindInt(&w.Port))),
)
serverUrl := xfyne.EntryDisableUndoRedo(widget.NewEntry())
serverUrl := widget.NewEntry()
serverUrl.SetText(w.server.getWsUrl())
serverUrl.Disable()
serverPreview := container.NewBorder(nil, nil,
@@ -175,7 +175,7 @@ func (w *WsHub) registerEvents() {
for eid, _ := range events.EventsMapping {
eventCache = append(eventCache, &EventData{})
currentIdx := i
global.EventBus.Subscribe("", eid,
global.EventBus.Subscribe(eventChannel, eid,
"plugin.wshub.event."+string(eid),
func(e *eventbus.Event) {
ed := EventData{

View File

@@ -5,7 +5,7 @@ import (
"AynaLivePlayer/global"
"AynaLivePlayer/gui"
"AynaLivePlayer/gui/component"
"AynaLivePlayer/gui/xfyne"
"AynaLivePlayer/pkg/config"
"AynaLivePlayer/pkg/eventbus"
"AynaLivePlayer/pkg/i18n"
@@ -147,9 +147,9 @@ func (y *Yinliang) CreatePanel() fyne.CanvasObject {
cmdConfig := container.NewGridWithColumns(2,
widget.NewLabel(i18n.T("plugin.yinliang.volume_up_cmd")),
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&y.VolumeUpCMD))),
widget.NewEntryWithData(binding.BindString(&y.VolumeUpCMD)),
widget.NewLabel(i18n.T("plugin.yinliang.volume_down_cmd")),
xfyne.EntryDisableUndoRedo(widget.NewEntryWithData(binding.BindString(&y.VolumeDownCMD))),
widget.NewEntryWithData(binding.BindString(&y.VolumeDownCMD)),
)
stepEntry := widget.NewEntryWithData(binding.FloatToStringWithFormat(binding.BindFloat(&y.VolumeStep), "%.1f"))
@@ -182,9 +182,9 @@ func (y *Yinliang) CreatePanel() fyne.CanvasObject {
volumeControlConfig := container.NewGridWithColumns(2,
widget.NewLabel(i18n.T("plugin.yinliang.volume_step")),
xfyne.EntryDisableUndoRedo(stepEntry),
stepEntry,
widget.NewLabel(i18n.T("plugin.yinliang.max_volume")),
xfyne.EntryDisableUndoRedo(maxVolEntry),
maxVolEntry,
)
y.panel = container.NewVBox(

View File

@@ -16,6 +16,7 @@
----
Finished
- 2024.09.30 : qq音乐微信登陆
- 2024.08.07 : 修复由于无法获取到连接的歌曲导致的播放的歌曲和展示的信息不匹配的问题/修复qq登陆刷新logic
- 2024.07.30 : 由于相关法律法规问题,删除了第三方歌源
- 2024.07.24 : 修复网易云修复wshub大小写问题