+7
cmd/routes.go
+7
cmd/routes.go
···
10
10
11
11
func (app *application) routes() http.Handler {
12
12
mux := http.NewServeMux()
13
+
// Redirect /static to /static/ so it doesn't fall through to "/" handler
14
+
mux.Handle("/static/{file_name}", app.pages.Static())
15
+
//mux.HandleFunc("/static/{file_name}", func(w http.ResponseWriter, r *http.Request) {
16
+
// w.Header().Set("Content-Type", "text/html")
17
+
//
18
+
// w.Write([]byte("Static files are served from /static/"))
19
+
//})
13
20
14
21
mux.HandleFunc("/", session.WithPossibleAuth(home(app.database, app.pages), app.sessionManager))
15
22
+29
-5
pages/pages.go
+29
-5
pages/pages.go
···
1
1
package pages
2
2
3
+
// Helpers to load gohtml templates and render them
3
4
// forked and inspired from tangled's implementation
4
5
//https://tangled.org/@tangled.org/core/blob/master/appview/pages/pages.go
5
6
···
8
9
"html/template"
9
10
"io"
10
11
"io/fs"
12
+
"net/http"
11
13
"strings"
12
14
"time"
13
15
)
14
16
15
-
//go:embed templates/*
17
+
//go:embed templates/* static/*
16
18
var Files embed.FS
17
19
18
20
type Pages struct {
···
116
118
return p.parse(stack...)
117
119
}
118
120
119
-
func (p *Pages) executePlain(name string, w io.Writer, params any) error {
120
-
tpl, err := p.parse(name)
121
+
func (p *Pages) Static() http.Handler {
122
+
//if p.dev {
123
+
// return http.StripPrefix("/static/", http.FileServer(http.Dir("appview/pages/static")))
124
+
//}
125
+
126
+
sub, err := fs.Sub(Files, "static")
121
127
if err != nil {
122
-
return err
128
+
//p.logger.Error("no static dir found? that's crazy", "err", err)
129
+
panic(err)
123
130
}
131
+
return http.StripPrefix("/static/", http.FileServer(http.FS(sub)))
132
+
// Custom handler to apply Cache-Control headers for font files
133
+
//return http.FileServer(http.FS(sub))
134
+
//return http.FileServer(http.FS(sub))
135
+
}
124
136
125
-
return tpl.Execute(w, params)
137
+
func Cache(h http.Handler) http.Handler {
138
+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
139
+
path := strings.Split(r.URL.Path, "?")[0]
140
+
141
+
if strings.HasSuffix(path, ".css") {
142
+
// on day for css files
143
+
w.Header().Set("Cache-Control", "public, max-age=86400")
144
+
} else {
145
+
w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
146
+
}
147
+
h.ServeHTTP(w, r)
148
+
})
126
149
}
127
150
151
+
// Execute What loads and renders the HTML page/
128
152
func (p *Pages) Execute(name string, w io.Writer, params any) error {
129
153
tpl, err := p.parseBase(name)
130
154
if err != nil {
+32
pages/static/style.css
+32
pages/static/style.css
···
1
+
body {
2
+
font-family: Arial, sans-serif;
3
+
max-width: 800px;
4
+
margin: 0 auto;
5
+
padding: 20px;
6
+
line-height: 1.6;
7
+
}
8
+
h1 {
9
+
color: #1DB954; /* Spotify green */
10
+
}
11
+
.nav {
12
+
display: flex;
13
+
flex-wrap: wrap; /* Allow wrapping on smaller screens */
14
+
margin-bottom: 20px;
15
+
}
16
+
.nav a {
17
+
margin-right: 15px;
18
+
margin-bottom: 5px; /* Add spacing below links */
19
+
text-decoration: none;
20
+
color: #1DB954;
21
+
font-weight: bold;
22
+
}
23
+
.card {
24
+
border: 1px solid #ddd;
25
+
border-radius: 8px;
26
+
padding: 20px;
27
+
margin-bottom: 20px;
28
+
}
29
+
.service-status {
30
+
font-style: italic;
31
+
color: #555;
32
+
}
+10
pages/templates/lastFMForm.gohtml
+10
pages/templates/lastFMForm.gohtml
···
1
+
{{ define "content" }}
2
+
<h2>Link Your Last.fm Account</h2>
3
+
<p>Enter your Last.fm username to start tracking your scrobbles.</p>
4
+
<form method="post" action="/link-lastfm">
5
+
<label for="lastfm_username">Last.fm Username:</label>
6
+
<input type="text" id="lastfm_username" name="lastfm_username" value="%s" required>
7
+
<input type="submit" value="Save Username">
8
+
</form>
9
+
10
+
{{ end }}
+1
pages/templates/layouts/base.gohtml
+1
pages/templates/layouts/base.gohtml
+1
-3
service/playingnow/playingnow.go
+1
-3
service/playingnow/playingnow.go
···
86
86
Item: playView,
87
87
}
88
88
89
-
var swapRecord *string
90
89
authArgs := db.AtpSessionToAuthArgs(sess)
91
-
90
+
var swapRecord *string
92
91
swapRecord, err = p.getStatusSwapRecord(ctx, xrpcClient, sess, authArgs)
93
92
if err != nil {
94
93
return err
···
166
165
}
167
166
168
167
authArgs := db.AtpSessionToAuthArgs(sess)
169
-
170
168
var swapRecord *string
171
169
swapRecord, err = p.getStatusSwapRecord(ctx, xrpcClient, sess, authArgs)
172
170
if err != nil {