Merge pull request #25 from dweymouth/develop
Reduce memory and CPU use
This commit is contained in:
@@ -44,4 +44,4 @@ require (
|
||||
honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect
|
||||
)
|
||||
|
||||
replace fyne.io/fyne/v2 v2.2.4 => github.com/dweymouth/fyne/v2 v2.2.5-0.20221227225053-ae75dfbeb567
|
||||
replace fyne.io/fyne/v2 v2.2.4 => github.com/dweymouth/fyne/v2 v2.2.5-0.20230110171955-98071d7f072f
|
||||
|
||||
@@ -72,8 +72,8 @@ github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7h
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dweymouth/fyne/v2 v2.2.5-0.20221227225053-ae75dfbeb567 h1:JEBJ5YN74ryKQNW1TgH0GjHkVpgmHMb1oYuz8ZShjY8=
|
||||
github.com/dweymouth/fyne/v2 v2.2.5-0.20221227225053-ae75dfbeb567/go.mod h1:MBoGuHzLLSXdQOWFAwWhIhYTEMp33zqtGCReSWhaQTA=
|
||||
github.com/dweymouth/fyne/v2 v2.2.5-0.20230110171955-98071d7f072f h1:Tgz5Tx14yQLkKl4JH5eGWnUpq9J8+cbLTuj8lfzgqG0=
|
||||
github.com/dweymouth/fyne/v2 v2.2.5-0.20230110171955-98071d7f072f/go.mod h1:MBoGuHzLLSXdQOWFAwWhIhYTEMp33zqtGCReSWhaQTA=
|
||||
github.com/dweymouth/go-subsonic v0.0.0-20221214005741-bd8048fa1863 h1:bOWMpFJ9zY839T1EngQ5nxVCiMlatPtpGkg/yHK6szg=
|
||||
github.com/dweymouth/go-subsonic v0.0.0-20221214005741-bd8048fa1863/go.mod h1:fUez6NFiEJiQTZizZ1BThZr5GJXAbigzGYjEPNm4tdI=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
|
||||
@@ -52,6 +52,15 @@ func (a *AlbumPage) SetPlayAlbumCallback(cb func(string, int)) {
|
||||
a.OnPlayAlbum = cb
|
||||
}
|
||||
|
||||
func (a *AlbumPage) Save() SavedPage {
|
||||
return &savedAlbumPage{
|
||||
albumID: a.albumID,
|
||||
lm: a.lm,
|
||||
im: a.im,
|
||||
nav: a.nav,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlbumPage) Route() Route {
|
||||
return AlbumRoute(a.albumID)
|
||||
}
|
||||
@@ -175,3 +184,14 @@ func (a *AlbumPageHeader) Update(album *subsonic.AlbumID3, im *backend.ImageMana
|
||||
func formatMiscLabelStr(a *subsonic.AlbumID3) string {
|
||||
return fmt.Sprintf("%d · %d tracks · %s", a.Year, a.SongCount, util.SecondsToTimeString(float64(a.Duration)))
|
||||
}
|
||||
|
||||
type savedAlbumPage struct {
|
||||
albumID string
|
||||
lm *backend.LibraryManager
|
||||
im *backend.ImageManager
|
||||
nav func(Route)
|
||||
}
|
||||
|
||||
func (s *savedAlbumPage) Restore() Page {
|
||||
return NewAlbumPage(s.albumID, s.lm, s.im, s.nav)
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ var _ fyne.Widget = (*AlbumsPage)(nil)
|
||||
type AlbumsPage struct {
|
||||
widget.BaseWidget
|
||||
|
||||
title string
|
||||
im *backend.ImageManager
|
||||
lm *backend.LibraryManager
|
||||
nav func(Route)
|
||||
@@ -52,9 +53,10 @@ func (s *selectWidget) MinSize() fyne.Size {
|
||||
|
||||
func NewAlbumsPage(title string, sortOrder string, lm *backend.LibraryManager, im *backend.ImageManager, nav func(Route)) *AlbumsPage {
|
||||
a := &AlbumsPage{
|
||||
lm: lm,
|
||||
im: im,
|
||||
nav: nav,
|
||||
title: title,
|
||||
lm: lm,
|
||||
im: im,
|
||||
nav: nav,
|
||||
}
|
||||
a.ExtendBaseWidget(a)
|
||||
|
||||
@@ -65,7 +67,6 @@ func NewAlbumsPage(title string, sortOrder string, lm *backend.LibraryManager, i
|
||||
a.sortOrder = NewSelect(backend.AlbumSortOrders, nil)
|
||||
a.sortOrder.Selected = sortOrder
|
||||
a.sortOrder.OnChanged = a.onSortOrderChanged
|
||||
sortVbox := container.NewVBox(layout.NewSpacer(), a.sortOrder, layout.NewSpacer())
|
||||
iter := lm.AlbumsIter(backend.AlbumSortOrder(a.sortOrder.Selected))
|
||||
a.grid = widgets.NewAlbumGrid(iter, im, false /*showYear*/)
|
||||
a.grid.OnPlayAlbum = a.onPlayAlbum
|
||||
@@ -73,7 +74,14 @@ func NewAlbumsPage(title string, sortOrder string, lm *backend.LibraryManager, i
|
||||
a.grid.OnShowAlbumPage = a.onShowAlbumPage
|
||||
a.searcher = widgets.NewSearcher()
|
||||
a.searcher.OnSearched = a.OnSearched
|
||||
a.createContainer()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *AlbumsPage) createContainer() {
|
||||
searchVbox := container.NewVBox(layout.NewSpacer(), a.searcher.Entry, layout.NewSpacer())
|
||||
sortVbox := container.NewVBox(layout.NewSpacer(), a.sortOrder, layout.NewSpacer())
|
||||
a.container = container.NewBorder(
|
||||
container.NewHBox(widgets.NewHSpace(9), a.titleDisp, sortVbox, layout.NewSpacer(), searchVbox, widgets.NewHSpace(15)),
|
||||
nil,
|
||||
@@ -81,6 +89,29 @@ func NewAlbumsPage(title string, sortOrder string, lm *backend.LibraryManager, i
|
||||
nil,
|
||||
a.grid,
|
||||
)
|
||||
}
|
||||
|
||||
func restoreAlbumsPage(saved *savedAlbumsPage) *AlbumsPage {
|
||||
a := &AlbumsPage{
|
||||
title: saved.title,
|
||||
lm: saved.lm,
|
||||
im: saved.im,
|
||||
nav: saved.nav,
|
||||
}
|
||||
a.ExtendBaseWidget(a)
|
||||
|
||||
a.titleDisp = widget.NewRichTextWithText(a.title)
|
||||
a.titleDisp.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{
|
||||
SizeName: theme.SizeNameHeadingText,
|
||||
}
|
||||
a.sortOrder = NewSelect(backend.AlbumSortOrders, nil)
|
||||
a.sortOrder.Selected = saved.sortOrder
|
||||
a.sortOrder.OnChanged = a.onSortOrderChanged
|
||||
a.grid = widgets.NewAlbumGridFromState(saved.gridState)
|
||||
a.searcher = widgets.NewSearcher()
|
||||
a.searcher.OnSearched = a.OnSearched
|
||||
a.createContainer()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -114,6 +145,17 @@ func (a *AlbumsPage) Reload() {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlbumsPage) Save() SavedPage {
|
||||
return &savedAlbumsPage{
|
||||
title: a.title,
|
||||
lm: a.lm,
|
||||
im: a.im,
|
||||
nav: a.nav,
|
||||
sortOrder: a.sortOrder.Selected,
|
||||
gridState: a.grid.SaveToState(),
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlbumsPage) doSearch(query string) {
|
||||
if a.searchGrid == nil {
|
||||
a.searchGrid = widgets.NewAlbumGrid(a.lm.SearchIter(query), a.im, false /*showYear*/)
|
||||
@@ -153,3 +195,16 @@ func (a *AlbumsPage) CreateRenderer() fyne.WidgetRenderer {
|
||||
a.ExtendBaseWidget(a)
|
||||
return widget.NewSimpleRenderer(a.container)
|
||||
}
|
||||
|
||||
type savedAlbumsPage struct {
|
||||
title string
|
||||
lm *backend.LibraryManager
|
||||
im *backend.ImageManager
|
||||
nav func(Route)
|
||||
sortOrder string
|
||||
gridState widgets.AlbumGridState
|
||||
}
|
||||
|
||||
func (s *savedAlbumsPage) Restore() Page {
|
||||
return restoreAlbumsPage(s)
|
||||
}
|
||||
|
||||
@@ -57,6 +57,15 @@ func (a *ArtistPage) Reload() {
|
||||
a.loadAsync()
|
||||
}
|
||||
|
||||
func (a *ArtistPage) Save() SavedPage {
|
||||
return &savedArtistPage{
|
||||
artistID: a.artistID,
|
||||
sm: a.sm,
|
||||
im: a.im,
|
||||
nav: a.nav,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *ArtistPage) onPlayAlbum(albumID string) {
|
||||
if a.OnPlayAlbum != nil {
|
||||
a.OnPlayAlbum(albumID, 0)
|
||||
@@ -88,3 +97,14 @@ func (a *ArtistPage) CreateRenderer() fyne.WidgetRenderer {
|
||||
a.ExtendBaseWidget(a)
|
||||
return widget.NewSimpleRenderer(a.container)
|
||||
}
|
||||
|
||||
type savedArtistPage struct {
|
||||
artistID string
|
||||
sm *backend.ServerManager
|
||||
im *backend.ImageManager
|
||||
nav func(Route)
|
||||
}
|
||||
|
||||
func (s *savedArtistPage) Restore() Page {
|
||||
return NewArtistPage(s.artistID, s.sm, s.im, s.nav)
|
||||
}
|
||||
|
||||
+29
-12
@@ -16,10 +16,15 @@ import (
|
||||
type Page interface {
|
||||
fyne.CanvasObject
|
||||
|
||||
Save() SavedPage
|
||||
Reload()
|
||||
Route() Route
|
||||
}
|
||||
|
||||
type SavedPage interface {
|
||||
Restore() Page
|
||||
}
|
||||
|
||||
type CanPlayAlbum interface {
|
||||
SetPlayAlbumCallback(func(albumID string, startingTrack int))
|
||||
}
|
||||
@@ -42,7 +47,7 @@ type BrowsingPane struct {
|
||||
forward *widget.Button
|
||||
back *widget.Button
|
||||
reload *widget.Button
|
||||
history []Page
|
||||
history []SavedPage
|
||||
historyIdx int
|
||||
|
||||
pageContainer *fyne.Container
|
||||
@@ -67,8 +72,9 @@ func NewBrowsingPane(app *backend.App) *BrowsingPane {
|
||||
}
|
||||
|
||||
func (b *BrowsingPane) SetPage(p Page) {
|
||||
if b.doSetPage(p) {
|
||||
b.addPageToHistory(p)
|
||||
oldPage := b.curPage
|
||||
if b.doSetPage(p) && oldPage != nil {
|
||||
b.addPageToHistory(oldPage, true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,9 +105,19 @@ func (b *BrowsingPane) onSongChange(song *subsonic.Child) {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BrowsingPane) addPageToHistory(p Page) {
|
||||
b.history = b.history[:b.historyIdx]
|
||||
b.history = append(b.history, p)
|
||||
func (b *BrowsingPane) addPageToHistory(p Page, truncate bool) {
|
||||
if truncate {
|
||||
// allow garbage collection of pages that will be removed from the history
|
||||
for i := b.historyIdx; i < len(b.history); i++ {
|
||||
b.history[i] = nil
|
||||
}
|
||||
b.history = b.history[:b.historyIdx]
|
||||
}
|
||||
if b.historyIdx < len(b.history) {
|
||||
b.history[b.historyIdx] = p.Save()
|
||||
} else {
|
||||
b.history = append(b.history, p.Save())
|
||||
}
|
||||
b.historyIdx++
|
||||
}
|
||||
|
||||
@@ -112,16 +128,17 @@ func (b *BrowsingPane) goHome() {
|
||||
}
|
||||
|
||||
func (b *BrowsingPane) GoBack() {
|
||||
if b.historyIdx > 1 {
|
||||
b.historyIdx -= 1
|
||||
b.doSetPage(b.history[b.historyIdx-1])
|
||||
if b.historyIdx > 0 {
|
||||
b.addPageToHistory(b.curPage, false)
|
||||
b.historyIdx -= 2
|
||||
b.doSetPage(b.history[b.historyIdx].Restore())
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BrowsingPane) GoForward() {
|
||||
if b.historyIdx < len(b.history) {
|
||||
b.historyIdx++
|
||||
b.doSetPage(b.history[b.historyIdx-1])
|
||||
if b.historyIdx < len(b.history)-1 {
|
||||
b.addPageToHistory(b.curPage, false)
|
||||
b.doSetPage(b.history[b.historyIdx].Restore())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,12 @@ func NewGenrePage(genre string, lm *backend.LibraryManager, im *backend.ImageMan
|
||||
g.grid.OnShowAlbumPage = g.onShowAlbumPage
|
||||
g.searcher = widgets.NewSearcher()
|
||||
g.searcher.OnSearched = g.OnSearched
|
||||
g.createContainer()
|
||||
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *GenrePage) createContainer() {
|
||||
searchVbox := container.NewVBox(layout.NewSpacer(), g.searcher.Entry, layout.NewSpacer())
|
||||
g.container = container.NewBorder(
|
||||
container.NewHBox(widgets.NewHSpace(9), g.titleDisp, layout.NewSpacer(), searchVbox, widgets.NewHSpace(15)),
|
||||
@@ -59,6 +65,26 @@ func NewGenrePage(genre string, lm *backend.LibraryManager, im *backend.ImageMan
|
||||
nil,
|
||||
g.grid,
|
||||
)
|
||||
}
|
||||
|
||||
func restoreGenrePage(saved *savedGenrePage) *GenrePage {
|
||||
g := &GenrePage{
|
||||
genre: saved.genre,
|
||||
lm: saved.lm,
|
||||
im: saved.im,
|
||||
nav: saved.nav,
|
||||
}
|
||||
g.ExtendBaseWidget(g)
|
||||
|
||||
g.titleDisp = widget.NewRichTextWithText(g.genre)
|
||||
g.titleDisp.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{
|
||||
SizeName: theme.SizeNameHeadingText,
|
||||
}
|
||||
g.grid = widgets.NewAlbumGridFromState(saved.gridState)
|
||||
g.searcher = widgets.NewSearcher()
|
||||
g.searcher.OnSearched = g.OnSearched
|
||||
g.createContainer()
|
||||
|
||||
return g
|
||||
}
|
||||
|
||||
@@ -83,6 +109,16 @@ func (g *GenrePage) Reload() {
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GenrePage) Save() SavedPage {
|
||||
return &savedGenrePage{
|
||||
genre: g.genre,
|
||||
lm: g.lm,
|
||||
im: g.im,
|
||||
nav: g.nav,
|
||||
gridState: g.grid.SaveToState(),
|
||||
}
|
||||
}
|
||||
|
||||
func (a *GenrePage) onPlayAlbum(albumID string) {
|
||||
if a.OnPlayAlbum != nil {
|
||||
a.OnPlayAlbum(albumID, 0)
|
||||
@@ -125,3 +161,15 @@ func (g *GenrePage) doSearch(query string) {
|
||||
g.container.Objects[0] = g.searchGrid
|
||||
g.Refresh()
|
||||
}
|
||||
|
||||
type savedGenrePage struct {
|
||||
genre string
|
||||
lm *backend.LibraryManager
|
||||
im *backend.ImageManager
|
||||
nav func(Route)
|
||||
gridState widgets.AlbumGridState
|
||||
}
|
||||
|
||||
func (s *savedGenrePage) Restore() Page {
|
||||
return restoreGenrePage(s)
|
||||
}
|
||||
|
||||
+33
-7
@@ -22,7 +22,12 @@ type AlbumIterator interface {
|
||||
type AlbumGrid struct {
|
||||
widget.BaseWidget
|
||||
|
||||
grid *widget.GridWrapList
|
||||
AlbumGridState
|
||||
|
||||
grid *widget.GridWrapList
|
||||
}
|
||||
|
||||
type AlbumGridState struct {
|
||||
albums []*subsonic.AlbumID3
|
||||
iter AlbumIterator
|
||||
fetching bool
|
||||
@@ -33,16 +38,20 @@ type AlbumGrid struct {
|
||||
OnPlayAlbum func(string)
|
||||
OnShowAlbumPage func(string)
|
||||
OnShowArtistPage func(string)
|
||||
|
||||
scrollPos float32
|
||||
}
|
||||
|
||||
var _ fyne.Widget = (*AlbumGrid)(nil)
|
||||
|
||||
func NewFixedAlbumGrid(albums []*subsonic.AlbumID3, fetch ImageFetcher, showYear bool) *AlbumGrid {
|
||||
ag := &AlbumGrid{
|
||||
albums: albums,
|
||||
done: true,
|
||||
imageFetcher: fetch,
|
||||
showYear: showYear,
|
||||
AlbumGridState: AlbumGridState{
|
||||
albums: albums,
|
||||
done: true,
|
||||
imageFetcher: fetch,
|
||||
showYear: showYear,
|
||||
},
|
||||
}
|
||||
ag.ExtendBaseWidget(ag)
|
||||
ag.createGridWrapList()
|
||||
@@ -51,8 +60,10 @@ func NewFixedAlbumGrid(albums []*subsonic.AlbumID3, fetch ImageFetcher, showYear
|
||||
|
||||
func NewAlbumGrid(iter AlbumIterator, fetch ImageFetcher, showYear bool) *AlbumGrid {
|
||||
ag := &AlbumGrid{
|
||||
iter: iter,
|
||||
imageFetcher: fetch,
|
||||
AlbumGridState: AlbumGridState{
|
||||
iter: iter,
|
||||
imageFetcher: fetch,
|
||||
},
|
||||
}
|
||||
ag.ExtendBaseWidget(ag)
|
||||
|
||||
@@ -63,6 +74,21 @@ func NewAlbumGrid(iter AlbumIterator, fetch ImageFetcher, showYear bool) *AlbumG
|
||||
return ag
|
||||
}
|
||||
|
||||
func (ag *AlbumGrid) SaveToState() AlbumGridState {
|
||||
s := ag.AlbumGridState
|
||||
s.scrollPos = ag.grid.GetScrollOffset()
|
||||
return s
|
||||
}
|
||||
|
||||
func NewAlbumGridFromState(state AlbumGridState) *AlbumGrid {
|
||||
ag := &AlbumGrid{AlbumGridState: state}
|
||||
ag.ExtendBaseWidget(ag)
|
||||
ag.createGridWrapList()
|
||||
ag.Refresh() // needed to initialize the widget
|
||||
ag.grid.ScrollToOffset(state.scrollPos)
|
||||
return ag
|
||||
}
|
||||
|
||||
func (ag *AlbumGrid) Clear() {
|
||||
ag.albums = nil
|
||||
ag.done = true
|
||||
|
||||
Reference in New Issue
Block a user