Merge pull request #25 from dweymouth/develop

Reduce memory and CPU use
This commit is contained in:
Drew Weymouth
2023-01-10 18:58:43 -08:00
committed by GitHub
8 changed files with 212 additions and 26 deletions
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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=
+20
View File
@@ -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)
}
+59 -4
View File
@@ -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)
}
+20
View File
@@ -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
View File
@@ -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())
}
}
+48
View File
@@ -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
View File
@@ -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