From 6a875894a40d228d9496cbc3ae3e5e158a48ac59 Mon Sep 17 00:00:00 2001 From: Abigail Pain Date: Tue, 22 Jul 2025 23:36:09 +0100 Subject: [PATCH] A number of style-based changes --- backseat/components/assets/assets.go | 15 ++ backseat/components/assets/static/main.css | 50 +++++++ .../components/assets/static/main.css.map | 1 + backseat/components/assets/static/main.scss | 56 ++++++++ .../components/recentlyListened/index.templ | 79 ++++++----- .../recentlyListened/index_templ.go | 128 ++++++++++++------ .../recentlyListened/recentlyListened.go | 7 - backseat/httpUtil/basePage.templ | 8 +- backseat/httpUtil/basePage_templ.go | 8 +- backseat/main.go | 2 + 10 files changed, 265 insertions(+), 89 deletions(-) create mode 100644 backseat/components/assets/assets.go create mode 100644 backseat/components/assets/static/main.css create mode 100644 backseat/components/assets/static/main.css.map create mode 100644 backseat/components/assets/static/main.scss diff --git a/backseat/components/assets/assets.go b/backseat/components/assets/assets.go new file mode 100644 index 0000000..6b60a39 --- /dev/null +++ b/backseat/components/assets/assets.go @@ -0,0 +1,15 @@ +package assets + +import ( + "embed" + "io/fs" + "net/http" +) + +//go:embed static/* +var staticFS embed.FS + +func New() http.Handler { + sffs, _ := fs.Sub(staticFS, "static") + return http.StripPrefix("/assets", http.FileServerFS(sffs)) +} diff --git a/backseat/components/assets/static/main.css b/backseat/components/assets/static/main.css new file mode 100644 index 0000000..5ac37cf --- /dev/null +++ b/backseat/components/assets/static/main.css @@ -0,0 +1,50 @@ +/* hello */ +html, body { + width: 100%; + min-height: 100%; + background-color: lightblue; + font-family: sans-serif; +} + +main { + max-width: 60%; /* TODO: Responsivity */ + margin: 1em auto; + background-color: white; + padding: 2em; + border-radius: 0.5em; +} + +.display-none { + display: none; +} + +ul.track-list { + list-style: none; + padding: 0; +} +ul.track-list li { + display: grid; + grid-template-columns: 1fr repeat(3, 3fr); + align-items: center; + gap: 0.5em; + padding: 0.5em; +} +ul.track-list li > div:not(.display-none):has(img) { + display: flex; + flex-direction: row; + justify-content: center; +} +ul.track-list li > div:not(.display-none):has(img) img { + height: 3em; +} +ul.track-list li:nth-of-type(odd) { + background-color: lightgray; +} +ul.track-list li:has(> input[type=checkbox]:checked) { + background-color: yellow; +} +ul.track-list li:has(> input[type=checkbox]:checked):nth-of-type(odd) { + background-color: yellowgreen; +} + +/*# sourceMappingURL=main.css.map */ diff --git a/backseat/components/assets/static/main.css.map b/backseat/components/assets/static/main.css.map new file mode 100644 index 0000000..7053847 --- /dev/null +++ b/backseat/components/assets/static/main.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["main.scss"],"names":[],"mappings":"AAAA;AAEA;EACI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;EAIA;EACA;EACA;;AAEA;EAII;EACA;EACA;;AALA;EACI;;AAOR;EACI;;AAGJ;EACI;;AACA;EACI","file":"main.css"} \ No newline at end of file diff --git a/backseat/components/assets/static/main.scss b/backseat/components/assets/static/main.scss new file mode 100644 index 0000000..9ba1816 --- /dev/null +++ b/backseat/components/assets/static/main.scss @@ -0,0 +1,56 @@ +/* hello */ + +html, body { + width: 100%; + min-height: 100%; + background-color: lightblue; + font-family: sans-serif; +} + +main { + max-width: 60%; /* TODO: Responsivity */ + margin: 1em auto; + background-color: white; + padding: 2em; + border-radius: 0.5em; +} + +.display-none { + display: none; +} + +ul.track-list { + list-style: none; + padding: 0; + + li { + display: grid; + grid-template-columns: 1fr repeat(3, 3fr); + + //display: flex; + //flex-direction: row; + align-items: center; + gap: 0.5em; + padding: 0.5em; + + > div:not(.display-none):has(img) { + img { + height: 3em; + } + display: flex; + flex-direction: row; + justify-content: center; + } + + &:nth-of-type(odd) { + background-color: lightgray; + } + + &:has(>input[type=checkbox]:checked) { + background-color: yellow; + &:nth-of-type(odd) { + background-color: yellowgreen; + } + } + } +} \ No newline at end of file diff --git a/backseat/components/recentlyListened/index.templ b/backseat/components/recentlyListened/index.templ index f37bcfe..44c2833 100644 --- a/backseat/components/recentlyListened/index.templ +++ b/backseat/components/recentlyListened/index.templ @@ -5,43 +5,52 @@ import ( "github.com/zmb3/spotify/v2" ) +func formatArtistNames(artists []spotify.SimpleArtist) string { + var res string + for i, artist := range artists { + if i != 0 { + if i == len(artists) - 1 { + res += " and " + } else { + res += ", " + } + } + res += artist.Name + } + return res +} + +func getSmallestImage(images []spotify.Image) spotify.Image { + var smallest *spotify.Image + for _, image := range images { + if smallest == nil || image.Width < smallest.Width { + smallest = &image + } + } + return *smallest +} + templ indexPage(recentlyListenedTracks []spotify.RecentlyPlayedItem) { @httpUtil.BasePage("Recently Listened"){ - - - - - - - - - - - - for _, record := range recentlyListenedTracks { - - - - - - - } - -
TrackArtistPlayed at
{ record.Track.Name } - for i, artist := range record.Track.Artists { - if i != 0 { - if i != len(record.Track.Artists) - 1 { - and - } else { - , - } - } - { artist.Name } - } - { record.PlayedAt.String() }
+ + + } } \ No newline at end of file diff --git a/backseat/components/recentlyListened/index_templ.go b/backseat/components/recentlyListened/index_templ.go index d104cf0..c208ef6 100644 --- a/backseat/components/recentlyListened/index_templ.go +++ b/backseat/components/recentlyListened/index_templ.go @@ -13,6 +13,31 @@ import ( "github.com/zmb3/spotify/v2" ) +func formatArtistNames(artists []spotify.SimpleArtist) string { + var res string + for i, artist := range artists { + if i != 0 { + if i == len(artists)-1 { + res += " and " + } else { + res += ", " + } + } + res += artist.Name + } + return res +} + +func getSmallestImage(images []spotify.Image) spotify.Image { + var smallest *spotify.Image + for _, image := range images { + if smallest == nil || image.Width < smallest.Width { + smallest = &image + } + } + return *smallest +} + func indexPage(recentlyListenedTracks []spotify.RecentlyPlayedItem) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context @@ -46,79 +71,100 @@ func indexPage(recentlyListenedTracks []spotify.RecentlyPlayedItem) templ.Compon }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\">
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(record.Track.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `backseat/components/recentlyListened/index.templ`, Line: 41, Col: 44} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(formatArtistNames(record.Track.Artists)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `backseat/components/recentlyListened/index.templ`, Line: 42, Col: 66} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(record.PlayedAt.String()) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `backseat/components/recentlyListened/index.templ`, Line: 43, Col: 51} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
TrackArtistPlayed at
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
  • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\" type=\"checkbox\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - for i, artist := range record.Track.Artists { - if i != 0 { - if i != len(record.Track.Artists)-1 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "and ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, ", ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(artist.Name) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `backseat/components/recentlyListened/index.templ`, Line: 38, Col: 47} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } + smallestImage := getSmallestImage(record.Track.Album.Images) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
    ") + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(smallestImage.URL) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `backseat/components/recentlyListened/index.templ`, Line: 40, Col: 53} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" loading=\"lazy\" alt=\"") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(record.PlayedAt.String()) + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs("album art for " + record.Track.Name) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `backseat/components/recentlyListened/index.templ`, Line: 41, Col: 54} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `backseat/components/recentlyListened/index.templ`, Line: 40, Col: 113} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/backseat/components/recentlyListened/recentlyListened.go b/backseat/components/recentlyListened/recentlyListened.go index 68ea14c..265147f 100644 --- a/backseat/components/recentlyListened/recentlyListened.go +++ b/backseat/components/recentlyListened/recentlyListened.go @@ -47,13 +47,6 @@ func (r *RecentlyListened) index(rw http.ResponseWriter, rq *http.Request) error return fmt.Errorf("get recently played tracks: %w", err) } - for _, track := range recentlyPlayed { - var artistNames []string - for _, artist := range track.Track.Artists { - artistNames = append(artistNames, artist.Name) - } - } - rw.Header().Set("Content-Type", "text/html") if err := indexPage(recentlyPlayed).Render(rq.Context(), rw); err != nil { diff --git a/backseat/httpUtil/basePage.templ b/backseat/httpUtil/basePage.templ index dfeb687..c5ff363 100644 --- a/backseat/httpUtil/basePage.templ +++ b/backseat/httpUtil/basePage.templ @@ -2,12 +2,16 @@ package httpUtil templ BasePage(title string) { - + + { title } - Backseat Music + - { children... } +
    + { children... } +
    } \ No newline at end of file diff --git a/backseat/httpUtil/basePage_templ.go b/backseat/httpUtil/basePage_templ.go index a31d07e..daf2147 100644 --- a/backseat/httpUtil/basePage_templ.go +++ b/backseat/httpUtil/basePage_templ.go @@ -29,20 +29,20 @@ func BasePage(title string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\"><title>") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `backseat/httpUtil/basePage.templ`, Line: 7, Col: 26} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `backseat/httpUtil/basePage.templ`, Line: 8, Col: 26} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " - Backseat Music") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " - Backseat Music
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -50,7 +50,7 @@ func BasePage(title string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/backseat/main.go b/backseat/main.go index f25a596..f38b7b3 100644 --- a/backseat/main.go +++ b/backseat/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "git.akpain.net/codemicro/backseat-music/backseat/components/assets" "git.akpain.net/codemicro/backseat-music/backseat/components/recentlyListened" "git.akpain.net/codemicro/backseat-music/backseat/components/spotifyAuth" "git.akpain.net/codemicro/backseat-music/backseat/config" @@ -25,6 +26,7 @@ func run() error { } mux := http.NewServeMux() + mux.Handle("/assets/", assets.New()) mux.Handle("/recentlyListened/", recentlyListened.New(dataStore)) mux.Handle("/spotify/", spotifyAuth.New(dataStore))