make artist and album hyperlinks in tracklist; refactor navigation to the controller package
This commit is contained in:
+4
-4
@@ -5,7 +5,7 @@ import (
|
|||||||
"image"
|
"image"
|
||||||
"supersonic/backend"
|
"supersonic/backend"
|
||||||
"supersonic/player"
|
"supersonic/player"
|
||||||
"supersonic/ui/browsing"
|
"supersonic/ui/controller"
|
||||||
"supersonic/ui/layouts"
|
"supersonic/ui/layouts"
|
||||||
"supersonic/ui/widgets"
|
"supersonic/ui/widgets"
|
||||||
"time"
|
"time"
|
||||||
@@ -30,7 +30,7 @@ type BottomPanel struct {
|
|||||||
|
|
||||||
var _ fyne.Widget = (*BottomPanel)(nil)
|
var _ fyne.Widget = (*BottomPanel)(nil)
|
||||||
|
|
||||||
func NewBottomPanel(p *player.Player, nav func(browsing.Route)) *BottomPanel {
|
func NewBottomPanel(p *player.Player, nav func(controller.Route)) *BottomPanel {
|
||||||
bp := &BottomPanel{}
|
bp := &BottomPanel{}
|
||||||
bp.ExtendBaseWidget(bp)
|
bp.ExtendBaseWidget(bp)
|
||||||
p.OnPaused(func() {
|
p.OnPaused(func() {
|
||||||
@@ -45,10 +45,10 @@ func NewBottomPanel(p *player.Player, nav func(browsing.Route)) *BottomPanel {
|
|||||||
|
|
||||||
bp.NowPlaying = widgets.NewNowPlayingCard()
|
bp.NowPlaying = widgets.NewNowPlayingCard()
|
||||||
bp.NowPlaying.OnAlbumNameTapped(func() {
|
bp.NowPlaying.OnAlbumNameTapped(func() {
|
||||||
nav(browsing.AlbumRoute(bp.playbackManager.NowPlaying().AlbumID))
|
nav(controller.AlbumRoute(bp.playbackManager.NowPlaying().AlbumID))
|
||||||
})
|
})
|
||||||
bp.NowPlaying.OnArtistNameTapped(func() {
|
bp.NowPlaying.OnArtistNameTapped(func() {
|
||||||
nav(browsing.ArtistRoute(bp.playbackManager.NowPlaying().ArtistID))
|
nav(controller.ArtistRoute(bp.playbackManager.NowPlaying().ArtistID))
|
||||||
})
|
})
|
||||||
bp.Controls = widgets.NewPlayerControls()
|
bp.Controls = widgets.NewPlayerControls()
|
||||||
bp.Controls.OnPlayPause(func() {
|
bp.Controls.OnPlayPause(func() {
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ type albumPageState struct {
|
|||||||
im *backend.ImageManager
|
im *backend.ImageManager
|
||||||
sm *backend.ServerManager
|
sm *backend.ServerManager
|
||||||
contr controller.Controller
|
contr controller.Controller
|
||||||
nav func(Route)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAlbumPage(
|
func NewAlbumPage(
|
||||||
@@ -49,7 +48,6 @@ func NewAlbumPage(
|
|||||||
lm *backend.LibraryManager,
|
lm *backend.LibraryManager,
|
||||||
im *backend.ImageManager,
|
im *backend.ImageManager,
|
||||||
contr controller.Controller,
|
contr controller.Controller,
|
||||||
nav func(Route),
|
|
||||||
) *AlbumPage {
|
) *AlbumPage {
|
||||||
a := &AlbumPage{
|
a := &AlbumPage{
|
||||||
albumPageState: albumPageState{
|
albumPageState: albumPageState{
|
||||||
@@ -59,7 +57,6 @@ func NewAlbumPage(
|
|||||||
pm: pm,
|
pm: pm,
|
||||||
lm: lm,
|
lm: lm,
|
||||||
im: im,
|
im: im,
|
||||||
nav: nav,
|
|
||||||
contr: contr,
|
contr: contr,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -90,8 +87,8 @@ func (a *AlbumPage) Save() SavedPage {
|
|||||||
return &s
|
return &s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AlbumPage) Route() Route {
|
func (a *AlbumPage) Route() controller.Route {
|
||||||
return AlbumRoute(a.albumID)
|
return controller.AlbumRoute(a.albumID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AlbumPage) OnSongChange(song *subsonic.Child, lastScrobbledIfAny *subsonic.Child) {
|
func (a *AlbumPage) OnSongChange(song *subsonic.Child, lastScrobbledIfAny *subsonic.Child) {
|
||||||
@@ -166,11 +163,11 @@ func NewAlbumPageHeader(page *AlbumPage) *AlbumPageHeader {
|
|||||||
}
|
}
|
||||||
a.artistLabel = widgets.NewCustomHyperlink()
|
a.artistLabel = widgets.NewCustomHyperlink()
|
||||||
a.artistLabel.OnTapped = func() {
|
a.artistLabel.OnTapped = func() {
|
||||||
page.nav(ArtistRoute(a.artistID))
|
page.contr.NavigateTo(controller.ArtistRoute(a.artistID))
|
||||||
}
|
}
|
||||||
a.genreLabel = widgets.NewCustomHyperlink()
|
a.genreLabel = widgets.NewCustomHyperlink()
|
||||||
a.genreLabel.OnTapped = func() {
|
a.genreLabel.OnTapped = func() {
|
||||||
page.nav(GenreRoute(a.genre))
|
page.contr.NavigateTo(controller.GenreRoute(a.genre))
|
||||||
}
|
}
|
||||||
a.miscLabel = widget.NewLabel("")
|
a.miscLabel = widget.NewLabel("")
|
||||||
playButton := widget.NewButtonWithIcon("Play", theme.MediaPlayIcon(), func() {
|
playButton := widget.NewButtonWithIcon("Play", theme.MediaPlayIcon(), func() {
|
||||||
@@ -249,5 +246,5 @@ func formatMiscLabelStr(a *subsonic.AlbumID3) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *albumPageState) Restore() Page {
|
func (s *albumPageState) Restore() Page {
|
||||||
return NewAlbumPage(s.albumID, s.cfg, s.sm, s.pm, s.lm, s.im, s.contr, s.nav)
|
return NewAlbumPage(s.albumID, s.cfg, s.sm, s.pm, s.lm, s.im, s.contr)
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-10
@@ -2,6 +2,7 @@ package browsing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"supersonic/backend"
|
"supersonic/backend"
|
||||||
|
"supersonic/ui/controller"
|
||||||
"supersonic/ui/widgets"
|
"supersonic/ui/widgets"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
@@ -17,10 +18,10 @@ type AlbumsPage struct {
|
|||||||
widget.BaseWidget
|
widget.BaseWidget
|
||||||
|
|
||||||
title string
|
title string
|
||||||
|
contr controller.Controller
|
||||||
pm *backend.PlaybackManager
|
pm *backend.PlaybackManager
|
||||||
im *backend.ImageManager
|
im *backend.ImageManager
|
||||||
lm *backend.LibraryManager
|
lm *backend.LibraryManager
|
||||||
nav func(Route)
|
|
||||||
grid *widgets.AlbumGrid
|
grid *widgets.AlbumGrid
|
||||||
searchGrid *widgets.AlbumGrid
|
searchGrid *widgets.AlbumGrid
|
||||||
searcher *widgets.Searcher
|
searcher *widgets.Searcher
|
||||||
@@ -51,13 +52,13 @@ func (s *selectWidget) MinSize() fyne.Size {
|
|||||||
return fyne.NewSize(170, s.height)
|
return fyne.NewSize(170, s.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAlbumsPage(title string, sortOrder string, pm *backend.PlaybackManager, lm *backend.LibraryManager, im *backend.ImageManager, nav func(Route)) *AlbumsPage {
|
func NewAlbumsPage(title string, sortOrder string, contr controller.Controller, pm *backend.PlaybackManager, lm *backend.LibraryManager, im *backend.ImageManager) *AlbumsPage {
|
||||||
a := &AlbumsPage{
|
a := &AlbumsPage{
|
||||||
title: title,
|
title: title,
|
||||||
|
contr: contr,
|
||||||
pm: pm,
|
pm: pm,
|
||||||
lm: lm,
|
lm: lm,
|
||||||
im: im,
|
im: im,
|
||||||
nav: nav,
|
|
||||||
}
|
}
|
||||||
a.ExtendBaseWidget(a)
|
a.ExtendBaseWidget(a)
|
||||||
|
|
||||||
@@ -99,10 +100,10 @@ func (a *AlbumsPage) createContainer(searchgrid bool) {
|
|||||||
func restoreAlbumsPage(saved *savedAlbumsPage) *AlbumsPage {
|
func restoreAlbumsPage(saved *savedAlbumsPage) *AlbumsPage {
|
||||||
a := &AlbumsPage{
|
a := &AlbumsPage{
|
||||||
title: saved.title,
|
title: saved.title,
|
||||||
|
contr: saved.contr,
|
||||||
pm: saved.pm,
|
pm: saved.pm,
|
||||||
lm: saved.lm,
|
lm: saved.lm,
|
||||||
im: saved.im,
|
im: saved.im,
|
||||||
nav: saved.nav,
|
|
||||||
}
|
}
|
||||||
a.ExtendBaseWidget(a)
|
a.ExtendBaseWidget(a)
|
||||||
|
|
||||||
@@ -138,8 +139,8 @@ func (a *AlbumsPage) OnSearched(query string) {
|
|||||||
a.doSearch(query)
|
a.doSearch(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AlbumsPage) Route() Route {
|
func (a *AlbumsPage) Route() controller.Route {
|
||||||
return AlbumsRoute(backend.AlbumSortOrder(a.sortOrder.Selected))
|
return controller.AlbumsRoute(backend.AlbumSortOrder(a.sortOrder.Selected))
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Searchable = (*AlbumsPage)(nil)
|
var _ Searchable = (*AlbumsPage)(nil)
|
||||||
@@ -160,10 +161,10 @@ func (a *AlbumsPage) Reload() {
|
|||||||
func (a *AlbumsPage) Save() SavedPage {
|
func (a *AlbumsPage) Save() SavedPage {
|
||||||
sa := &savedAlbumsPage{
|
sa := &savedAlbumsPage{
|
||||||
title: a.title,
|
title: a.title,
|
||||||
|
contr: a.contr,
|
||||||
pm: a.pm,
|
pm: a.pm,
|
||||||
lm: a.lm,
|
lm: a.lm,
|
||||||
im: a.im,
|
im: a.im,
|
||||||
nav: a.nav,
|
|
||||||
searchText: a.searchText,
|
searchText: a.searchText,
|
||||||
sortOrder: a.sortOrder.Selected,
|
sortOrder: a.sortOrder.Selected,
|
||||||
gridState: a.grid.SaveToState(),
|
gridState: a.grid.SaveToState(),
|
||||||
@@ -192,11 +193,11 @@ func (a *AlbumsPage) onPlayAlbum(albumID string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *AlbumsPage) onShowArtistPage(artistID string) {
|
func (a *AlbumsPage) onShowArtistPage(artistID string) {
|
||||||
a.nav(ArtistRoute(artistID))
|
a.contr.NavigateTo(controller.ArtistRoute(artistID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AlbumsPage) onShowAlbumPage(albumID string) {
|
func (a *AlbumsPage) onShowAlbumPage(albumID string) {
|
||||||
a.nav(AlbumRoute(albumID))
|
a.contr.NavigateTo(controller.AlbumRoute(albumID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AlbumsPage) onSortOrderChanged(order string) {
|
func (a *AlbumsPage) onSortOrderChanged(order string) {
|
||||||
@@ -215,10 +216,10 @@ func (a *AlbumsPage) CreateRenderer() fyne.WidgetRenderer {
|
|||||||
type savedAlbumsPage struct {
|
type savedAlbumsPage struct {
|
||||||
title string
|
title string
|
||||||
searchText string
|
searchText string
|
||||||
|
contr controller.Controller
|
||||||
pm *backend.PlaybackManager
|
pm *backend.PlaybackManager
|
||||||
lm *backend.LibraryManager
|
lm *backend.LibraryManager
|
||||||
im *backend.ImageManager
|
im *backend.ImageManager
|
||||||
nav func(Route)
|
|
||||||
sortOrder string
|
sortOrder string
|
||||||
gridState widgets.AlbumGridState
|
gridState widgets.AlbumGridState
|
||||||
searchGridState widgets.AlbumGridState
|
searchGridState widgets.AlbumGridState
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ type artistPageState struct {
|
|||||||
artistID string
|
artistID string
|
||||||
sm *backend.ServerManager
|
sm *backend.ServerManager
|
||||||
im *backend.ImageManager
|
im *backend.ImageManager
|
||||||
nav func(Route)
|
|
||||||
contr controller.Controller
|
contr controller.Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,16 +40,15 @@ type ArtistPage struct {
|
|||||||
OnPlayAlbum func(string, int)
|
OnPlayAlbum func(string, int)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewArtistPage(artistID string, sm *backend.ServerManager, im *backend.ImageManager, contr controller.Controller, nav func(Route)) *ArtistPage {
|
func NewArtistPage(artistID string, sm *backend.ServerManager, im *backend.ImageManager, contr controller.Controller) *ArtistPage {
|
||||||
a := &ArtistPage{artistPageState: artistPageState{
|
a := &ArtistPage{artistPageState: artistPageState{
|
||||||
artistID: artistID,
|
artistID: artistID,
|
||||||
sm: sm,
|
sm: sm,
|
||||||
im: im,
|
im: im,
|
||||||
nav: nav,
|
|
||||||
contr: contr,
|
contr: contr,
|
||||||
}}
|
}}
|
||||||
a.ExtendBaseWidget(a)
|
a.ExtendBaseWidget(a)
|
||||||
a.header = NewArtistPageHeader(a, nav)
|
a.header = NewArtistPageHeader(a)
|
||||||
a.container = container.NewBorder(
|
a.container = container.NewBorder(
|
||||||
container.New(&layouts.MaxPadLayout{PadLeft: 15, PadRight: 15, PadTop: 15, PadBottom: 10}, a.header),
|
container.New(&layouts.MaxPadLayout{PadLeft: 15, PadRight: 15, PadTop: 15, PadBottom: 10}, a.header),
|
||||||
nil, nil, nil, layout.NewSpacer())
|
nil, nil, nil, layout.NewSpacer())
|
||||||
@@ -58,8 +56,8 @@ func NewArtistPage(artistID string, sm *backend.ServerManager, im *backend.Image
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ArtistPage) Route() Route {
|
func (a *ArtistPage) Route() controller.Route {
|
||||||
return ArtistRoute(a.artistID)
|
return controller.ArtistRoute(a.artistID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ArtistPage) SetPlayAlbumCallback(cb func(string, int)) {
|
func (a *ArtistPage) SetPlayAlbumCallback(cb func(string, int)) {
|
||||||
@@ -82,7 +80,7 @@ func (a *ArtistPage) onPlayAlbum(albumID string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *ArtistPage) onShowAlbumPage(albumID string) {
|
func (a *ArtistPage) onShowAlbumPage(albumID string) {
|
||||||
a.nav(AlbumRoute(albumID))
|
a.contr.NavigateTo(controller.AlbumRoute(albumID))
|
||||||
}
|
}
|
||||||
|
|
||||||
// should be called asynchronously
|
// should be called asynchronously
|
||||||
@@ -111,13 +109,12 @@ func (a *ArtistPage) CreateRenderer() fyne.WidgetRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *artistPageState) Restore() Page {
|
func (s *artistPageState) Restore() Page {
|
||||||
return NewArtistPage(s.artistID, s.sm, s.im, s.contr, s.nav)
|
return NewArtistPage(s.artistID, s.sm, s.im, s.contr)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArtistPageHeader struct {
|
type ArtistPageHeader struct {
|
||||||
widget.BaseWidget
|
widget.BaseWidget
|
||||||
|
|
||||||
nav func(Route)
|
|
||||||
artistID string
|
artistID string
|
||||||
artistPage *ArtistPage
|
artistPage *ArtistPage
|
||||||
artistImage *widgets.ImagePlaceholder
|
artistImage *widgets.ImagePlaceholder
|
||||||
@@ -128,9 +125,8 @@ type ArtistPageHeader struct {
|
|||||||
container *fyne.Container
|
container *fyne.Container
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewArtistPageHeader(page *ArtistPage, nav func(Route)) *ArtistPageHeader {
|
func NewArtistPageHeader(page *ArtistPage) *ArtistPageHeader {
|
||||||
a := &ArtistPageHeader{
|
a := &ArtistPageHeader{
|
||||||
nav: nav,
|
|
||||||
artistPage: page,
|
artistPage: page,
|
||||||
titleDisp: widget.NewRichTextWithText(""),
|
titleDisp: widget.NewRichTextWithText(""),
|
||||||
biographyDisp: widget.NewRichTextWithText("Artist biography not available."),
|
biographyDisp: widget.NewRichTextWithText("Artist biography not available."),
|
||||||
@@ -181,7 +177,7 @@ func (a *ArtistPageHeader) UpdateInfo(info *subsonic.ArtistInfo2) {
|
|||||||
h.NoTruncate = true
|
h.NoTruncate = true
|
||||||
h.SetText(art.Name)
|
h.SetText(art.Name)
|
||||||
h.OnTapped = func(id string) func() {
|
h.OnTapped = func(id string) func() {
|
||||||
return func() { a.nav(ArtistRoute(id)) }
|
return func() { a.artistPage.contr.NavigateTo(controller.ArtistRoute(id)) }
|
||||||
}(art.ID)
|
}(art.ID)
|
||||||
a.similarArtists.Add(h)
|
a.similarArtists.Add(h)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package browsing
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"supersonic/backend"
|
"supersonic/backend"
|
||||||
|
"supersonic/ui/controller"
|
||||||
"supersonic/ui/layouts"
|
"supersonic/ui/layouts"
|
||||||
"supersonic/ui/widgets"
|
"supersonic/ui/widgets"
|
||||||
"time"
|
"time"
|
||||||
@@ -20,22 +21,22 @@ type ArtistsGenresPage struct {
|
|||||||
widget.BaseWidget
|
widget.BaseWidget
|
||||||
|
|
||||||
isGenresPage bool
|
isGenresPage bool
|
||||||
|
contr controller.Controller
|
||||||
sm *backend.ServerManager
|
sm *backend.ServerManager
|
||||||
nav func(Route)
|
|
||||||
titleDisp *widget.RichText
|
titleDisp *widget.RichText
|
||||||
container *fyne.Container
|
container *fyne.Container
|
||||||
list *widgets.ArtistGenrePlaylist
|
list *widgets.ArtistGenrePlaylist
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewArtistsGenresPage(isGenresPage bool, sm *backend.ServerManager, nav func(Route)) *ArtistsGenresPage {
|
func NewArtistsGenresPage(isGenresPage bool, contr controller.Controller, sm *backend.ServerManager) *ArtistsGenresPage {
|
||||||
title := "Artists"
|
title := "Artists"
|
||||||
if isGenresPage {
|
if isGenresPage {
|
||||||
title = "Genres"
|
title = "Genres"
|
||||||
}
|
}
|
||||||
a := &ArtistsGenresPage{
|
a := &ArtistsGenresPage{
|
||||||
isGenresPage: isGenresPage,
|
isGenresPage: isGenresPage,
|
||||||
|
contr: contr,
|
||||||
sm: sm,
|
sm: sm,
|
||||||
nav: nav,
|
|
||||||
titleDisp: widget.NewRichTextWithText(title),
|
titleDisp: widget.NewRichTextWithText(title),
|
||||||
}
|
}
|
||||||
a.ExtendBaseWidget(a)
|
a.ExtendBaseWidget(a)
|
||||||
@@ -45,9 +46,9 @@ func NewArtistsGenresPage(isGenresPage bool, sm *backend.ServerManager, nav func
|
|||||||
a.list.ShowTrackCount = isGenresPage
|
a.list.ShowTrackCount = isGenresPage
|
||||||
a.list.OnNavTo = func(id string) {
|
a.list.OnNavTo = func(id string) {
|
||||||
if a.isGenresPage {
|
if a.isGenresPage {
|
||||||
nav(GenreRoute(id))
|
a.contr.NavigateTo(controller.GenreRoute(id))
|
||||||
} else {
|
} else {
|
||||||
nav(ArtistRoute(id))
|
a.contr.NavigateTo(controller.ArtistRoute(id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a.buildContainer()
|
a.buildContainer()
|
||||||
@@ -73,11 +74,11 @@ func (a *ArtistsGenresPage) load() {
|
|||||||
a.Refresh()
|
a.Refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ArtistsGenresPage) Route() Route {
|
func (a *ArtistsGenresPage) Route() controller.Route {
|
||||||
if a.isGenresPage {
|
if a.isGenresPage {
|
||||||
return GenresRoute()
|
return controller.GenresRoute()
|
||||||
}
|
}
|
||||||
return ArtistsRoute()
|
return controller.ArtistsRoute()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ArtistsGenresPage) Reload() {
|
func (a *ArtistsGenresPage) Reload() {
|
||||||
@@ -87,19 +88,19 @@ func (a *ArtistsGenresPage) Reload() {
|
|||||||
func (a *ArtistsGenresPage) Save() SavedPage {
|
func (a *ArtistsGenresPage) Save() SavedPage {
|
||||||
return &savedArtistsGenresPage{
|
return &savedArtistsGenresPage{
|
||||||
isGenresPage: a.isGenresPage,
|
isGenresPage: a.isGenresPage,
|
||||||
|
contr: a.contr,
|
||||||
sm: a.sm,
|
sm: a.sm,
|
||||||
nav: a.nav,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type savedArtistsGenresPage struct {
|
type savedArtistsGenresPage struct {
|
||||||
isGenresPage bool
|
isGenresPage bool
|
||||||
|
contr controller.Controller
|
||||||
sm *backend.ServerManager
|
sm *backend.ServerManager
|
||||||
nav func(Route)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *savedArtistsGenresPage) Restore() Page {
|
func (s *savedArtistsGenresPage) Restore() Page {
|
||||||
return NewArtistsGenresPage(s.isGenresPage, s.sm, s.nav)
|
return NewArtistsGenresPage(s.isGenresPage, s.contr, s.sm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ArtistsGenresPage) buildArtistListModel(artists *subsonic.ArtistsID3) []widgets.ArtistGenrePlaylistItemModel {
|
func (a *ArtistsGenresPage) buildArtistListModel(artists *subsonic.ArtistsID3) []widgets.ArtistGenrePlaylistItemModel {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package browsing
|
|||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"supersonic/backend"
|
"supersonic/backend"
|
||||||
|
"supersonic/ui/controller"
|
||||||
"supersonic/ui/layouts"
|
"supersonic/ui/layouts"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
@@ -19,7 +20,7 @@ type Page interface {
|
|||||||
|
|
||||||
Save() SavedPage
|
Save() SavedPage
|
||||||
Reload()
|
Reload()
|
||||||
Route() Route
|
Route() controller.Route
|
||||||
}
|
}
|
||||||
|
|
||||||
type SavedPage interface {
|
type SavedPage interface {
|
||||||
@@ -216,7 +217,7 @@ var _ Page = (*blankPage)(nil)
|
|||||||
|
|
||||||
func (p *blankPage) Reload() {}
|
func (p *blankPage) Reload() {}
|
||||||
|
|
||||||
func (p *blankPage) Route() Route { return Route{Page: Blank} }
|
func (p *blankPage) Route() controller.Route { return controller.Route{Page: controller.Blank} }
|
||||||
|
|
||||||
func (p *blankPage) Save() SavedPage { return p }
|
func (p *blankPage) Save() SavedPage { return p }
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ type FavoritesPage struct {
|
|||||||
im *backend.ImageManager
|
im *backend.ImageManager
|
||||||
sm *backend.ServerManager
|
sm *backend.ServerManager
|
||||||
lm *backend.LibraryManager
|
lm *backend.LibraryManager
|
||||||
nav func(Route)
|
|
||||||
|
|
||||||
searchText string
|
searchText string
|
||||||
nowPlayingID string
|
nowPlayingID string
|
||||||
@@ -42,7 +41,7 @@ type FavoritesPage struct {
|
|||||||
container *fyne.Container
|
container *fyne.Container
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFavoritesPage(cfg *backend.FavoritesPageConfig, contr controller.Controller, sm *backend.ServerManager, pm *backend.PlaybackManager, lm *backend.LibraryManager, im *backend.ImageManager, nav func(Route)) *FavoritesPage {
|
func NewFavoritesPage(cfg *backend.FavoritesPageConfig, contr controller.Controller, sm *backend.ServerManager, pm *backend.PlaybackManager, lm *backend.LibraryManager, im *backend.ImageManager) *FavoritesPage {
|
||||||
a := &FavoritesPage{
|
a := &FavoritesPage{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
contr: contr,
|
contr: contr,
|
||||||
@@ -50,7 +49,6 @@ func NewFavoritesPage(cfg *backend.FavoritesPageConfig, contr controller.Control
|
|||||||
lm: lm,
|
lm: lm,
|
||||||
sm: sm,
|
sm: sm,
|
||||||
im: im,
|
im: im,
|
||||||
nav: nav,
|
|
||||||
}
|
}
|
||||||
a.ExtendBaseWidget(a)
|
a.ExtendBaseWidget(a)
|
||||||
a.createHeader(0, "")
|
a.createHeader(0, "")
|
||||||
@@ -106,7 +104,6 @@ func restoreFavoritesPage(saved *savedFavoritesPage) *FavoritesPage {
|
|||||||
lm: saved.lm,
|
lm: saved.lm,
|
||||||
sm: saved.sm,
|
sm: saved.sm,
|
||||||
im: saved.im,
|
im: saved.im,
|
||||||
nav: saved.nav,
|
|
||||||
}
|
}
|
||||||
a.ExtendBaseWidget(a)
|
a.ExtendBaseWidget(a)
|
||||||
a.createHeader(saved.activeToggleBtn, saved.searchText)
|
a.createHeader(saved.activeToggleBtn, saved.searchText)
|
||||||
@@ -126,8 +123,8 @@ func restoreFavoritesPage(saved *savedFavoritesPage) *FavoritesPage {
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FavoritesPage) Route() Route {
|
func (a *FavoritesPage) Route() controller.Route {
|
||||||
return FavoritesRoute()
|
return controller.FavoritesRoute()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FavoritesPage) Reload() {
|
func (a *FavoritesPage) Reload() {
|
||||||
@@ -179,7 +176,6 @@ func (a *FavoritesPage) Save() SavedPage {
|
|||||||
sm: a.sm,
|
sm: a.sm,
|
||||||
im: a.im,
|
im: a.im,
|
||||||
lm: a.lm,
|
lm: a.lm,
|
||||||
nav: a.nav,
|
|
||||||
searchText: a.searchText,
|
searchText: a.searchText,
|
||||||
gridState: a.grid.SaveToState(),
|
gridState: a.grid.SaveToState(),
|
||||||
activeToggleBtn: a.toggleBtns.ActivatedButtonIndex(),
|
activeToggleBtn: a.toggleBtns.ActivatedButtonIndex(),
|
||||||
@@ -266,7 +262,7 @@ func (a *FavoritesPage) onShowFavoriteArtists() {
|
|||||||
artistList := widgets.NewArtistGenrePlaylist(model)
|
artistList := widgets.NewArtistGenrePlaylist(model)
|
||||||
artistList.ShowAlbumCount = true
|
artistList.ShowAlbumCount = true
|
||||||
artistList.OnNavTo = func(artistID string) {
|
artistList.OnNavTo = func(artistID string) {
|
||||||
a.nav(ArtistRoute(artistID))
|
a.contr.NavigateTo(controller.ArtistRoute(artistID))
|
||||||
}
|
}
|
||||||
a.artistListCtr = container.New(
|
a.artistListCtr = container.New(
|
||||||
&layouts.MaxPadLayout{PadLeft: 15, PadRight: 15, PadTop: 5, PadBottom: 15},
|
&layouts.MaxPadLayout{PadLeft: 15, PadRight: 15, PadTop: 5, PadBottom: 15},
|
||||||
@@ -330,11 +326,11 @@ func (a *FavoritesPage) onPlayAlbum(albumID string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *FavoritesPage) onShowAlbumPage(albumID string) {
|
func (a *FavoritesPage) onShowAlbumPage(albumID string) {
|
||||||
a.nav(AlbumRoute(albumID))
|
a.contr.NavigateTo(controller.AlbumRoute(albumID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FavoritesPage) onShowArtistPage(artistID string) {
|
func (a *FavoritesPage) onShowArtistPage(artistID string) {
|
||||||
a.nav(ArtistRoute(artistID))
|
a.contr.NavigateTo(controller.ArtistRoute(artistID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FavoritesPage) CreateRenderer() fyne.WidgetRenderer {
|
func (a *FavoritesPage) CreateRenderer() fyne.WidgetRenderer {
|
||||||
@@ -353,7 +349,6 @@ type savedFavoritesPage struct {
|
|||||||
searchGridState widgets.AlbumGridState
|
searchGridState widgets.AlbumGridState
|
||||||
searchText string
|
searchText string
|
||||||
activeToggleBtn int
|
activeToggleBtn int
|
||||||
nav func(Route)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *savedFavoritesPage) Restore() Page {
|
func (s *savedFavoritesPage) Restore() Page {
|
||||||
|
|||||||
+11
-10
@@ -2,6 +2,7 @@ package browsing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"supersonic/backend"
|
"supersonic/backend"
|
||||||
|
"supersonic/ui/controller"
|
||||||
"supersonic/ui/widgets"
|
"supersonic/ui/widgets"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
@@ -17,10 +18,10 @@ type GenrePage struct {
|
|||||||
widget.BaseWidget
|
widget.BaseWidget
|
||||||
|
|
||||||
genre string
|
genre string
|
||||||
|
contr controller.Controller
|
||||||
im *backend.ImageManager
|
im *backend.ImageManager
|
||||||
pm *backend.PlaybackManager
|
pm *backend.PlaybackManager
|
||||||
lm *backend.LibraryManager
|
lm *backend.LibraryManager
|
||||||
nav func(Route)
|
|
||||||
grid *widgets.AlbumGrid
|
grid *widgets.AlbumGrid
|
||||||
searchGrid *widgets.AlbumGrid
|
searchGrid *widgets.AlbumGrid
|
||||||
searcher *widgets.Searcher
|
searcher *widgets.Searcher
|
||||||
@@ -32,13 +33,13 @@ type GenrePage struct {
|
|||||||
container *fyne.Container
|
container *fyne.Container
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGenrePage(genre string, pm *backend.PlaybackManager, lm *backend.LibraryManager, im *backend.ImageManager, nav func(Route)) *GenrePage {
|
func NewGenrePage(genre string, contr controller.Controller, pm *backend.PlaybackManager, lm *backend.LibraryManager, im *backend.ImageManager) *GenrePage {
|
||||||
g := &GenrePage{
|
g := &GenrePage{
|
||||||
genre: genre,
|
genre: genre,
|
||||||
|
contr: contr,
|
||||||
pm: pm,
|
pm: pm,
|
||||||
lm: lm,
|
lm: lm,
|
||||||
im: im,
|
im: im,
|
||||||
nav: nav,
|
|
||||||
}
|
}
|
||||||
g.ExtendBaseWidget(g)
|
g.ExtendBaseWidget(g)
|
||||||
|
|
||||||
@@ -76,10 +77,10 @@ func (g *GenrePage) createContainer(searchGrid bool) {
|
|||||||
func restoreGenrePage(saved *savedGenrePage) *GenrePage {
|
func restoreGenrePage(saved *savedGenrePage) *GenrePage {
|
||||||
g := &GenrePage{
|
g := &GenrePage{
|
||||||
genre: saved.genre,
|
genre: saved.genre,
|
||||||
|
contr: saved.contr,
|
||||||
pm: saved.pm,
|
pm: saved.pm,
|
||||||
lm: saved.lm,
|
lm: saved.lm,
|
||||||
im: saved.im,
|
im: saved.im,
|
||||||
nav: saved.nav,
|
|
||||||
}
|
}
|
||||||
g.ExtendBaseWidget(g)
|
g.ExtendBaseWidget(g)
|
||||||
|
|
||||||
@@ -103,8 +104,8 @@ func (g *GenrePage) CreateRenderer() fyne.WidgetRenderer {
|
|||||||
return widget.NewSimpleRenderer(g.container)
|
return widget.NewSimpleRenderer(g.container)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *GenrePage) Route() Route {
|
func (a *GenrePage) Route() controller.Route {
|
||||||
return GenreRoute(a.genre)
|
return controller.GenreRoute(a.genre)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *GenrePage) SetPlayAlbumCallback(cb func(string, int)) {
|
func (a *GenrePage) SetPlayAlbumCallback(cb func(string, int)) {
|
||||||
@@ -124,10 +125,10 @@ func (g *GenrePage) Save() SavedPage {
|
|||||||
sg := &savedGenrePage{
|
sg := &savedGenrePage{
|
||||||
genre: g.genre,
|
genre: g.genre,
|
||||||
searchText: g.searchText,
|
searchText: g.searchText,
|
||||||
|
contr: g.contr,
|
||||||
pm: g.pm,
|
pm: g.pm,
|
||||||
lm: g.lm,
|
lm: g.lm,
|
||||||
im: g.im,
|
im: g.im,
|
||||||
nav: g.nav,
|
|
||||||
gridState: g.grid.SaveToState(),
|
gridState: g.grid.SaveToState(),
|
||||||
}
|
}
|
||||||
if g.searchGrid != nil {
|
if g.searchGrid != nil {
|
||||||
@@ -147,11 +148,11 @@ func (a *GenrePage) onPlayAlbum(albumID string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *GenrePage) onShowArtistPage(artistID string) {
|
func (a *GenrePage) onShowArtistPage(artistID string) {
|
||||||
a.nav(ArtistRoute(artistID))
|
a.contr.NavigateTo(controller.ArtistRoute(artistID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *GenrePage) onShowAlbumPage(albumID string) {
|
func (a *GenrePage) onShowAlbumPage(albumID string) {
|
||||||
a.nav(AlbumRoute(albumID))
|
a.contr.NavigateTo(controller.AlbumRoute(albumID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GenrePage) OnSearched(query string) {
|
func (g *GenrePage) OnSearched(query string) {
|
||||||
@@ -186,10 +187,10 @@ func (g *GenrePage) doSearch(query string) {
|
|||||||
type savedGenrePage struct {
|
type savedGenrePage struct {
|
||||||
genre string
|
genre string
|
||||||
searchText string
|
searchText string
|
||||||
|
contr controller.Controller
|
||||||
pm *backend.PlaybackManager
|
pm *backend.PlaybackManager
|
||||||
lm *backend.LibraryManager
|
lm *backend.LibraryManager
|
||||||
im *backend.ImageManager
|
im *backend.ImageManager
|
||||||
nav func(Route)
|
|
||||||
gridState widgets.AlbumGridState
|
gridState widgets.AlbumGridState
|
||||||
searchGridState widgets.AlbumGridState
|
searchGridState widgets.AlbumGridState
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ type nowPlayingPageState struct {
|
|||||||
conf *backend.NowPlayingPageConfig
|
conf *backend.NowPlayingPageConfig
|
||||||
sm *backend.ServerManager
|
sm *backend.ServerManager
|
||||||
pm *backend.PlaybackManager
|
pm *backend.PlaybackManager
|
||||||
nav func(Route)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNowPlayingPage(
|
func NewNowPlayingPage(
|
||||||
@@ -37,9 +36,8 @@ func NewNowPlayingPage(
|
|||||||
conf *backend.NowPlayingPageConfig,
|
conf *backend.NowPlayingPageConfig,
|
||||||
sm *backend.ServerManager,
|
sm *backend.ServerManager,
|
||||||
pm *backend.PlaybackManager,
|
pm *backend.PlaybackManager,
|
||||||
nav func(Route),
|
|
||||||
) *NowPlayingPage {
|
) *NowPlayingPage {
|
||||||
a := &NowPlayingPage{nowPlayingPageState: nowPlayingPageState{contr: contr, conf: conf, sm: sm, pm: pm, nav: nav}}
|
a := &NowPlayingPage{nowPlayingPageState: nowPlayingPageState{contr: contr, conf: conf, sm: sm, pm: pm}}
|
||||||
a.ExtendBaseWidget(a)
|
a.ExtendBaseWidget(a)
|
||||||
a.tracklist = widgets.NewTracklist(nil)
|
a.tracklist = widgets.NewTracklist(nil)
|
||||||
a.tracklist.SetVisibleColumns(conf.TracklistColumns)
|
a.tracklist.SetVisibleColumns(conf.TracklistColumns)
|
||||||
@@ -69,8 +67,8 @@ func (a *NowPlayingPage) Save() SavedPage {
|
|||||||
return &nps
|
return &nps
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *NowPlayingPage) Route() Route {
|
func (a *NowPlayingPage) Route() controller.Route {
|
||||||
return NowPlayingRoute()
|
return controller.NowPlayingRoute()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *NowPlayingPage) Tapped(*fyne.PointEvent) {
|
func (a *NowPlayingPage) Tapped(*fyne.PointEvent) {
|
||||||
@@ -113,5 +111,5 @@ func (a *NowPlayingPage) load() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *nowPlayingPageState) Restore() Page {
|
func (s *nowPlayingPageState) Restore() Page {
|
||||||
return NewNowPlayingPage(s.contr, s.conf, s.sm, s.pm, s.nav)
|
return NewNowPlayingPage(s.contr, s.conf, s.sm, s.pm)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ type playlistPageState struct {
|
|||||||
sm *backend.ServerManager
|
sm *backend.ServerManager
|
||||||
pm *backend.PlaybackManager
|
pm *backend.PlaybackManager
|
||||||
im *backend.ImageManager
|
im *backend.ImageManager
|
||||||
nav func(Route)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlaylistPage(
|
func NewPlaylistPage(
|
||||||
@@ -46,7 +45,6 @@ func NewPlaylistPage(
|
|||||||
sm *backend.ServerManager,
|
sm *backend.ServerManager,
|
||||||
pm *backend.PlaybackManager,
|
pm *backend.PlaybackManager,
|
||||||
im *backend.ImageManager,
|
im *backend.ImageManager,
|
||||||
nav func(Route),
|
|
||||||
) *PlaylistPage {
|
) *PlaylistPage {
|
||||||
a := &PlaylistPage{playlistPageState: playlistPageState{playlistID: playlistID, conf: conf, contr: contr, sm: sm, pm: pm, im: im}}
|
a := &PlaylistPage{playlistPageState: playlistPageState{playlistID: playlistID, conf: conf, contr: contr, sm: sm, pm: pm, im: im}}
|
||||||
a.ExtendBaseWidget(a)
|
a.ExtendBaseWidget(a)
|
||||||
@@ -77,8 +75,8 @@ func (a *PlaylistPage) Save() SavedPage {
|
|||||||
return &p
|
return &p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *PlaylistPage) Route() Route {
|
func (a *PlaylistPage) Route() controller.Route {
|
||||||
return PlaylistRoute(a.playlistID)
|
return controller.PlaylistRoute(a.playlistID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *PlaylistPage) OnSongChange(song *subsonic.Child, lastScrobbledIfAny *subsonic.Child) {
|
func (a *PlaylistPage) OnSongChange(song *subsonic.Child, lastScrobbledIfAny *subsonic.Child) {
|
||||||
@@ -211,5 +209,5 @@ func (a *PlaylistPageHeader) formatPlaylistTrackTimeStr(p *subsonic.Playlist) st
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *playlistPageState) Restore() Page {
|
func (s *playlistPageState) Restore() Page {
|
||||||
return NewPlaylistPage(s.playlistID, s.conf, s.contr, s.sm, s.pm, s.im, s.nav)
|
return NewPlaylistPage(s.playlistID, s.conf, s.contr, s.sm, s.pm, s.im)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
"supersonic/backend"
|
"supersonic/backend"
|
||||||
|
"supersonic/ui/controller"
|
||||||
"supersonic/ui/layouts"
|
"supersonic/ui/layouts"
|
||||||
"supersonic/ui/widgets"
|
"supersonic/ui/widgets"
|
||||||
|
|
||||||
@@ -17,24 +18,24 @@ import (
|
|||||||
type PlaylistsPage struct {
|
type PlaylistsPage struct {
|
||||||
widget.BaseWidget
|
widget.BaseWidget
|
||||||
|
|
||||||
|
contr controller.Controller
|
||||||
sm *backend.ServerManager
|
sm *backend.ServerManager
|
||||||
nav func(Route)
|
|
||||||
titleDisp *widget.RichText
|
titleDisp *widget.RichText
|
||||||
container *fyne.Container
|
container *fyne.Container
|
||||||
list *PlaylistList
|
list *PlaylistList
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlaylistsPage(sm *backend.ServerManager, nav func(Route)) *PlaylistsPage {
|
func NewPlaylistsPage(contr controller.Controller, sm *backend.ServerManager) *PlaylistsPage {
|
||||||
a := &PlaylistsPage{
|
a := &PlaylistsPage{
|
||||||
sm: sm,
|
sm: sm,
|
||||||
nav: nav,
|
contr: contr,
|
||||||
titleDisp: widget.NewRichTextWithText("Playlists"),
|
titleDisp: widget.NewRichTextWithText("Playlists"),
|
||||||
}
|
}
|
||||||
a.ExtendBaseWidget(a)
|
a.ExtendBaseWidget(a)
|
||||||
a.titleDisp.Segments[0].(*widget.TextSegment).Style.SizeName = theme.SizeNameHeadingText
|
a.titleDisp.Segments[0].(*widget.TextSegment).Style.SizeName = theme.SizeNameHeadingText
|
||||||
a.list = NewPlaylistList()
|
a.list = NewPlaylistList()
|
||||||
a.list.OnNavTo = func(id string) {
|
a.list.OnNavTo = func(id string) {
|
||||||
nav(PlaylistRoute(id))
|
a.contr.NavigateTo(controller.PlaylistRoute(id))
|
||||||
}
|
}
|
||||||
a.buildContainer()
|
a.buildContainer()
|
||||||
go a.loadAsync()
|
go a.loadAsync()
|
||||||
@@ -50,8 +51,8 @@ func (a *PlaylistsPage) loadAsync() {
|
|||||||
a.list.Refresh()
|
a.list.Refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *PlaylistsPage) Route() Route {
|
func (a *PlaylistsPage) Route() controller.Route {
|
||||||
return PlaylistsRoute()
|
return controller.PlaylistsRoute()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *PlaylistsPage) Reload() {
|
func (a *PlaylistsPage) Reload() {
|
||||||
@@ -60,18 +61,18 @@ func (a *PlaylistsPage) Reload() {
|
|||||||
|
|
||||||
func (a *PlaylistsPage) Save() SavedPage {
|
func (a *PlaylistsPage) Save() SavedPage {
|
||||||
return &savedPlaylistsPage{
|
return &savedPlaylistsPage{
|
||||||
sm: a.sm,
|
contr: a.contr,
|
||||||
nav: a.nav,
|
sm: a.sm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type savedPlaylistsPage struct {
|
type savedPlaylistsPage struct {
|
||||||
sm *backend.ServerManager
|
contr controller.Controller
|
||||||
nav func(Route)
|
sm *backend.ServerManager
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *savedPlaylistsPage) Restore() Page {
|
func (s *savedPlaylistsPage) Restore() Page {
|
||||||
return NewPlaylistsPage(s.sm, s.nav)
|
return NewPlaylistsPage(s.contr, s.sm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *PlaylistsPage) buildContainer() {
|
func (a *PlaylistsPage) buildContainer() {
|
||||||
|
|||||||
+24
-84
@@ -5,77 +5,17 @@ import (
|
|||||||
"supersonic/ui/controller"
|
"supersonic/ui/controller"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PageName int
|
|
||||||
|
|
||||||
const (
|
|
||||||
Blank PageName = iota
|
|
||||||
Album
|
|
||||||
Albums
|
|
||||||
Artist
|
|
||||||
Artists
|
|
||||||
Genre
|
|
||||||
Genres
|
|
||||||
Favorites
|
|
||||||
NowPlaying
|
|
||||||
Playlist
|
|
||||||
Playlists
|
|
||||||
)
|
|
||||||
|
|
||||||
type Route struct {
|
|
||||||
Page PageName
|
|
||||||
Arg string
|
|
||||||
}
|
|
||||||
|
|
||||||
func AlbumsRoute(sortOrder backend.AlbumSortOrder) Route {
|
|
||||||
return Route{Page: Albums, Arg: string(sortOrder)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ArtistRoute(artistID string) Route {
|
|
||||||
return Route{Page: Artist, Arg: artistID}
|
|
||||||
}
|
|
||||||
|
|
||||||
func AlbumRoute(albumID string) Route {
|
|
||||||
return Route{Page: Album, Arg: albumID}
|
|
||||||
}
|
|
||||||
|
|
||||||
func FavoritesRoute() Route {
|
|
||||||
return Route{Page: Favorites}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenreRoute(genre string) Route {
|
|
||||||
return Route{Page: Genre, Arg: genre}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenresRoute() Route {
|
|
||||||
return Route{Page: Genres}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PlaylistRoute(id string) Route {
|
|
||||||
return Route{Page: Playlist, Arg: id}
|
|
||||||
}
|
|
||||||
func PlaylistsRoute() Route {
|
|
||||||
return Route{Page: Playlists}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ArtistsRoute() Route {
|
|
||||||
return Route{Page: Artists}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NowPlayingRoute() Route {
|
|
||||||
return Route{Page: NowPlaying}
|
|
||||||
}
|
|
||||||
|
|
||||||
type NavigationHandler interface {
|
type NavigationHandler interface {
|
||||||
SetPage(Page)
|
SetPage(Page)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Router struct {
|
type Router struct {
|
||||||
App *backend.App
|
App *backend.App
|
||||||
Controller controller.Controller
|
Controller *controller.Controller
|
||||||
Nav NavigationHandler
|
Nav NavigationHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRouter(app *backend.App, controller controller.Controller, nav NavigationHandler) Router {
|
func NewRouter(app *backend.App, controller *controller.Controller, nav NavigationHandler) Router {
|
||||||
r := Router{
|
r := Router{
|
||||||
App: app,
|
App: app,
|
||||||
Controller: controller,
|
Controller: controller,
|
||||||
@@ -84,32 +24,32 @@ func NewRouter(app *backend.App, controller controller.Controller, nav Navigatio
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Router) CreatePage(rte Route) Page {
|
func (r Router) CreatePage(rte controller.Route) Page {
|
||||||
switch rte.Page {
|
switch rte.Page {
|
||||||
case Album:
|
case controller.Album:
|
||||||
return NewAlbumPage(rte.Arg, &r.App.Config.AlbumPage, r.App.ServerManager, r.App.PlaybackManager, r.App.LibraryManager, r.App.ImageManager, r.Controller, r.OpenRoute)
|
return NewAlbumPage(rte.Arg, &r.App.Config.AlbumPage, r.App.ServerManager, r.App.PlaybackManager, r.App.LibraryManager, r.App.ImageManager, *r.Controller)
|
||||||
case Albums:
|
case controller.Albums:
|
||||||
return NewAlbumsPage("Albums", rte.Arg, r.App.PlaybackManager, r.App.LibraryManager, r.App.ImageManager, r.OpenRoute)
|
return NewAlbumsPage("Albums", rte.Arg, *r.Controller, r.App.PlaybackManager, r.App.LibraryManager, r.App.ImageManager)
|
||||||
case Artist:
|
case controller.Artist:
|
||||||
return NewArtistPage(rte.Arg, r.App.ServerManager, r.App.ImageManager, r.Controller, r.OpenRoute)
|
return NewArtistPage(rte.Arg, r.App.ServerManager, r.App.ImageManager, *r.Controller)
|
||||||
case Artists:
|
case controller.Artists:
|
||||||
return NewArtistsGenresPage(false, r.App.ServerManager, r.OpenRoute)
|
return NewArtistsGenresPage(false, *r.Controller, r.App.ServerManager)
|
||||||
case Favorites:
|
case controller.Favorites:
|
||||||
return NewFavoritesPage(&r.App.Config.FavoritesPage, r.Controller, r.App.ServerManager, r.App.PlaybackManager, r.App.LibraryManager, r.App.ImageManager, r.OpenRoute)
|
return NewFavoritesPage(&r.App.Config.FavoritesPage, *r.Controller, r.App.ServerManager, r.App.PlaybackManager, r.App.LibraryManager, r.App.ImageManager)
|
||||||
case Genre:
|
case controller.Genre:
|
||||||
return NewGenrePage(rte.Arg, r.App.PlaybackManager, r.App.LibraryManager, r.App.ImageManager, r.OpenRoute)
|
return NewGenrePage(rte.Arg, *r.Controller, r.App.PlaybackManager, r.App.LibraryManager, r.App.ImageManager)
|
||||||
case Genres:
|
case controller.Genres:
|
||||||
return NewArtistsGenresPage(true, r.App.ServerManager, r.OpenRoute)
|
return NewArtistsGenresPage(true, *r.Controller, r.App.ServerManager)
|
||||||
case NowPlaying:
|
case controller.NowPlaying:
|
||||||
return NewNowPlayingPage(r.Controller, &r.App.Config.NowPlayingPage, r.App.ServerManager, r.App.PlaybackManager, r.OpenRoute)
|
return NewNowPlayingPage(*r.Controller, &r.App.Config.NowPlayingPage, r.App.ServerManager, r.App.PlaybackManager)
|
||||||
case Playlist:
|
case controller.Playlist:
|
||||||
return NewPlaylistPage(rte.Arg, &r.App.Config.PlaylistPage, r.Controller, r.App.ServerManager, r.App.PlaybackManager, r.App.ImageManager, r.OpenRoute)
|
return NewPlaylistPage(rte.Arg, &r.App.Config.PlaylistPage, *r.Controller, r.App.ServerManager, r.App.PlaybackManager, r.App.ImageManager)
|
||||||
case Playlists:
|
case controller.Playlists:
|
||||||
return NewPlaylistsPage(r.App.ServerManager, r.OpenRoute)
|
return NewPlaylistsPage(*r.Controller, r.App.ServerManager)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Router) OpenRoute(rte Route) {
|
func (r Router) NavigateTo(rte controller.Route) {
|
||||||
r.Nav.SetPage(r.CreatePage(rte))
|
r.Nav.SetPage(r.CreatePage(rte))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,16 @@ import (
|
|||||||
"github.com/dweymouth/go-subsonic/subsonic"
|
"github.com/dweymouth/go-subsonic/subsonic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type NavigationHandler func(Route)
|
||||||
|
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
MainWindow fyne.Window
|
MainWindow fyne.Window
|
||||||
App *backend.App
|
App *backend.App
|
||||||
|
NavHandler NavigationHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Controller) NavigateTo(route Route) {
|
||||||
|
m.NavHandler(route)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Controller) ShowPopUpImage(img image.Image) {
|
func (m Controller) ShowPopUpImage(img image.Image) {
|
||||||
@@ -66,6 +73,12 @@ func (m Controller) ConnectTracklistActions(tracklist *widgets.Tracklist) {
|
|||||||
m.App.PlaybackManager.OnTrackFavoriteStatusChanged(id, fav)
|
m.App.PlaybackManager.OnTrackFavoriteStatusChanged(id, fav)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tracklist.OnShowAlbumPage = func(albumID string) {
|
||||||
|
m.NavigateTo(AlbumRoute(albumID))
|
||||||
|
}
|
||||||
|
tracklist.OnShowArtistPage = func(artistID string) {
|
||||||
|
m.NavigateTo(ArtistRoute(artistID))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Controller) PromptForFirstServer() {
|
func (m Controller) PromptForFirstServer() {
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import "supersonic/backend"
|
||||||
|
|
||||||
|
type PageName int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Blank PageName = iota
|
||||||
|
Album
|
||||||
|
Albums
|
||||||
|
Artist
|
||||||
|
Artists
|
||||||
|
Genre
|
||||||
|
Genres
|
||||||
|
Favorites
|
||||||
|
NowPlaying
|
||||||
|
Playlist
|
||||||
|
Playlists
|
||||||
|
)
|
||||||
|
|
||||||
|
type Route struct {
|
||||||
|
Page PageName
|
||||||
|
Arg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func AlbumsRoute(sortOrder backend.AlbumSortOrder) Route {
|
||||||
|
return Route{Page: Albums, Arg: string(sortOrder)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ArtistRoute(artistID string) Route {
|
||||||
|
return Route{Page: Artist, Arg: artistID}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AlbumRoute(albumID string) Route {
|
||||||
|
return Route{Page: Album, Arg: albumID}
|
||||||
|
}
|
||||||
|
|
||||||
|
func FavoritesRoute() Route {
|
||||||
|
return Route{Page: Favorites}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenreRoute(genre string) Route {
|
||||||
|
return Route{Page: Genre, Arg: genre}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenresRoute() Route {
|
||||||
|
return Route{Page: Genres}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PlaylistRoute(id string) Route {
|
||||||
|
return Route{Page: Playlist, Arg: id}
|
||||||
|
}
|
||||||
|
func PlaylistsRoute() Route {
|
||||||
|
return Route{Page: Playlists}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ArtistsRoute() Route {
|
||||||
|
return Route{Page: Artists}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NowPlayingRoute() Route {
|
||||||
|
return Route{Page: NowPlaying}
|
||||||
|
}
|
||||||
+12
-11
@@ -35,7 +35,7 @@ type MainWindow struct {
|
|||||||
|
|
||||||
App *backend.App
|
App *backend.App
|
||||||
Router browsing.Router
|
Router browsing.Router
|
||||||
Controller controller.Controller
|
Controller *controller.Controller
|
||||||
BrowsingPane *browsing.BrowsingPane
|
BrowsingPane *browsing.BrowsingPane
|
||||||
BottomPanel *BottomPanel
|
BottomPanel *BottomPanel
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ type MainWindow struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
HomePage = browsing.AlbumsRoute(backend.AlbumSortRecentlyAdded)
|
HomePage = controller.AlbumsRoute(backend.AlbumSortRecentlyAdded)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewMainWindow(fyneApp fyne.App, appName string, app *backend.App, size fyne.Size) MainWindow {
|
func NewMainWindow(fyneApp fyne.App, appName string, app *backend.App, size fyne.Size) MainWindow {
|
||||||
@@ -53,12 +53,13 @@ func NewMainWindow(fyneApp fyne.App, appName string, app *backend.App, size fyne
|
|||||||
BrowsingPane: browsing.NewBrowsingPane(app),
|
BrowsingPane: browsing.NewBrowsingPane(app),
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Controller = controller.Controller{
|
m.Controller = &controller.Controller{
|
||||||
MainWindow: m.Window,
|
MainWindow: m.Window,
|
||||||
App: app,
|
App: app,
|
||||||
}
|
}
|
||||||
m.Router = browsing.NewRouter(app, m.Controller, m.BrowsingPane)
|
m.Router = browsing.NewRouter(app, m.Controller, m.BrowsingPane)
|
||||||
m.BottomPanel = NewBottomPanel(app.Player, m.Router.OpenRoute)
|
m.Controller.NavHandler = m.Router.NavigateTo
|
||||||
|
m.BottomPanel = NewBottomPanel(app.Player, m.Router.NavigateTo)
|
||||||
m.BottomPanel.SetPlaybackManager(app.PlaybackManager)
|
m.BottomPanel.SetPlaybackManager(app.PlaybackManager)
|
||||||
m.BottomPanel.ImageManager = app.ImageManager
|
m.BottomPanel.ImageManager = app.ImageManager
|
||||||
m.container = container.NewBorder(nil, m.BottomPanel, nil, nil, m.BrowsingPane)
|
m.container = container.NewBorder(nil, m.BottomPanel, nil, nil, m.BrowsingPane)
|
||||||
@@ -73,7 +74,7 @@ func NewMainWindow(fyneApp fyne.App, appName string, app *backend.App, size fyne
|
|||||||
})
|
})
|
||||||
app.ServerManager.OnServerConnected(func() {
|
app.ServerManager.OnServerConnected(func() {
|
||||||
m.BrowsingPane.EnableNavigationButtons()
|
m.BrowsingPane.EnableNavigationButtons()
|
||||||
m.Router.OpenRoute(HomePage)
|
m.Router.NavigateTo(HomePage)
|
||||||
})
|
})
|
||||||
app.ServerManager.OnLogout(func() {
|
app.ServerManager.OnLogout(func() {
|
||||||
m.BrowsingPane.DisableNavigationButtons()
|
m.BrowsingPane.DisableNavigationButtons()
|
||||||
@@ -89,22 +90,22 @@ func NewMainWindow(fyneApp fyne.App, appName string, app *backend.App, size fyne
|
|||||||
|
|
||||||
func (m *MainWindow) addNavigationButtons() {
|
func (m *MainWindow) addNavigationButtons() {
|
||||||
m.BrowsingPane.AddNavigationButton(res.ResHeadphonesInvertPng, func() {
|
m.BrowsingPane.AddNavigationButton(res.ResHeadphonesInvertPng, func() {
|
||||||
m.Router.OpenRoute(browsing.NowPlayingRoute())
|
m.Router.NavigateTo(controller.NowPlayingRoute())
|
||||||
})
|
})
|
||||||
m.BrowsingPane.AddNavigationButton(res.ResHeartFilledInvertPng, func() {
|
m.BrowsingPane.AddNavigationButton(res.ResHeartFilledInvertPng, func() {
|
||||||
m.Router.OpenRoute(browsing.FavoritesRoute())
|
m.Router.NavigateTo(controller.FavoritesRoute())
|
||||||
})
|
})
|
||||||
m.BrowsingPane.AddNavigationButton(res.ResDiscInvertPng, func() {
|
m.BrowsingPane.AddNavigationButton(res.ResDiscInvertPng, func() {
|
||||||
m.Router.OpenRoute(browsing.AlbumsRoute(backend.AlbumSortRecentlyAdded))
|
m.Router.NavigateTo(controller.AlbumsRoute(backend.AlbumSortRecentlyAdded))
|
||||||
})
|
})
|
||||||
m.BrowsingPane.AddNavigationButton(res.ResPeopleInvertPng, func() {
|
m.BrowsingPane.AddNavigationButton(res.ResPeopleInvertPng, func() {
|
||||||
m.Router.OpenRoute(browsing.ArtistsRoute())
|
m.Router.NavigateTo(controller.ArtistsRoute())
|
||||||
})
|
})
|
||||||
m.BrowsingPane.AddNavigationButton(res.ResTheatermasksInvertPng, func() {
|
m.BrowsingPane.AddNavigationButton(res.ResTheatermasksInvertPng, func() {
|
||||||
m.Router.OpenRoute(browsing.GenresRoute())
|
m.Router.NavigateTo(controller.GenresRoute())
|
||||||
})
|
})
|
||||||
m.BrowsingPane.AddNavigationButton(res.ResPlaylistInvertPng, func() {
|
m.BrowsingPane.AddNavigationButton(res.ResPlaylistInvertPng, func() {
|
||||||
m.Router.OpenRoute(browsing.PlaylistsRoute())
|
m.Router.NavigateTo(controller.PlaylistsRoute())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-10
@@ -46,6 +46,9 @@ type Tracklist struct {
|
|||||||
OnAddToPlaylist func(trackIDs []string)
|
OnAddToPlaylist func(trackIDs []string)
|
||||||
OnSetFavorite func(trackIDs []string, fav bool)
|
OnSetFavorite func(trackIDs []string, fav bool)
|
||||||
|
|
||||||
|
OnShowArtistPage func(artistID string)
|
||||||
|
OnShowAlbumPage func(albumID string)
|
||||||
|
|
||||||
visibleColumns []bool
|
visibleColumns []bool
|
||||||
|
|
||||||
selectionMgr util.ListSelectionManager
|
selectionMgr util.ListSelectionManager
|
||||||
@@ -253,6 +256,18 @@ func (t *Tracklist) onSetFavorite(trackID string, fav bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Tracklist) onArtistTapped(artistID string) {
|
||||||
|
if t.OnShowArtistPage != nil {
|
||||||
|
t.OnShowArtistPage(artistID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tracklist) onAlbumTapped(albumID string) {
|
||||||
|
if t.OnShowAlbumPage != nil {
|
||||||
|
t.OnShowAlbumPage(albumID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Tracklist) selectedTracks() []*subsonic.Child {
|
func (t *Tracklist) selectedTracks() []*subsonic.Child {
|
||||||
sel := t.selectionMgr.GetSelection()
|
sel := t.selectionMgr.GetSelection()
|
||||||
tracks := make([]*subsonic.Child, 0, len(sel))
|
tracks := make([]*subsonic.Child, 0, len(sel))
|
||||||
@@ -328,6 +343,8 @@ type TrackRow struct {
|
|||||||
trackIdx int
|
trackIdx int
|
||||||
trackNum int
|
trackNum int
|
||||||
trackID string
|
trackID string
|
||||||
|
artistID string
|
||||||
|
albumID string
|
||||||
isPlaying bool
|
isPlaying bool
|
||||||
isFavorite bool
|
isFavorite bool
|
||||||
playCount int64
|
playCount int64
|
||||||
@@ -335,8 +352,8 @@ type TrackRow struct {
|
|||||||
|
|
||||||
num *widget.RichText
|
num *widget.RichText
|
||||||
name *widget.RichText
|
name *widget.RichText
|
||||||
artist *widget.RichText
|
artist *CustomHyperlink
|
||||||
album *widget.RichText
|
album *CustomHyperlink
|
||||||
dur *widget.RichText
|
dur *widget.RichText
|
||||||
year *widget.RichText
|
year *widget.RichText
|
||||||
favorite *fyne.Container
|
favorite *fyne.Container
|
||||||
@@ -359,10 +376,10 @@ func NewTrackRow(tracklist *Tracklist, playingIcon fyne.CanvasObject) *TrackRow
|
|||||||
t.num.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignTrailing
|
t.num.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignTrailing
|
||||||
t.name = widget.NewRichTextWithText("")
|
t.name = widget.NewRichTextWithText("")
|
||||||
t.name.Wrapping = fyne.TextTruncate
|
t.name.Wrapping = fyne.TextTruncate
|
||||||
t.artist = widget.NewRichTextWithText("")
|
t.artist = NewCustomHyperlink()
|
||||||
t.artist.Wrapping = fyne.TextTruncate
|
t.artist.OnTapped = func() { tracklist.onArtistTapped(t.artistID) }
|
||||||
t.album = widget.NewRichTextWithText("")
|
t.album = NewCustomHyperlink()
|
||||||
t.album.Wrapping = fyne.TextTruncate
|
t.album.OnTapped = func() { tracklist.onAlbumTapped(t.albumID) }
|
||||||
t.dur = widget.NewRichTextWithText("")
|
t.dur = widget.NewRichTextWithText("")
|
||||||
t.dur.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignTrailing
|
t.dur.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignTrailing
|
||||||
t.year = widget.NewRichTextWithText("")
|
t.year = widget.NewRichTextWithText("")
|
||||||
@@ -388,10 +405,12 @@ func (t *TrackRow) Update(tr *subsonic.Child, isPlaying bool, rowNum int) {
|
|||||||
// a new track (*subsonic.Child)
|
// a new track (*subsonic.Child)
|
||||||
if tr.ID != t.trackID {
|
if tr.ID != t.trackID {
|
||||||
t.trackID = tr.ID
|
t.trackID = tr.ID
|
||||||
|
t.artistID = tr.ArtistID
|
||||||
|
t.albumID = tr.AlbumID
|
||||||
|
|
||||||
t.name.Segments[0].(*widget.TextSegment).Text = tr.Title
|
t.name.Segments[0].(*widget.TextSegment).Text = tr.Title
|
||||||
t.artist.Segments[0].(*widget.TextSegment).Text = tr.Artist
|
t.artist.SetText(tr.Artist)
|
||||||
t.album.Segments[0].(*widget.TextSegment).Text = tr.Album
|
t.album.SetText(tr.Album)
|
||||||
t.dur.Segments[0].(*widget.TextSegment).Text = util.SecondsToTimeString(float64(tr.Duration))
|
t.dur.Segments[0].(*widget.TextSegment).Text = util.SecondsToTimeString(float64(tr.Duration))
|
||||||
t.year.Segments[0].(*widget.TextSegment).Text = strconv.Itoa(tr.Year)
|
t.year.Segments[0].(*widget.TextSegment).Text = strconv.Itoa(tr.Year)
|
||||||
t.plays.Segments[0].(*widget.TextSegment).Text = strconv.Itoa(int(tr.PlayCount))
|
t.plays.Segments[0].(*widget.TextSegment).Text = strconv.Itoa(int(tr.PlayCount))
|
||||||
@@ -418,8 +437,6 @@ func (t *TrackRow) Update(tr *subsonic.Child, isPlaying bool, rowNum int) {
|
|||||||
if isPlaying != t.isPlaying {
|
if isPlaying != t.isPlaying {
|
||||||
t.isPlaying = isPlaying
|
t.isPlaying = isPlaying
|
||||||
t.name.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying
|
t.name.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying
|
||||||
t.artist.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying
|
|
||||||
t.album.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying
|
|
||||||
t.dur.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying
|
t.dur.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying
|
||||||
t.year.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying
|
t.year.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying
|
||||||
t.plays.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying
|
t.plays.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying
|
||||||
|
|||||||
Reference in New Issue
Block a user