+7
cmd/routes.go
+7
cmd/routes.go
···
10
11
func (app *application) routes() http.Handler {
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
+
//})
20
21
mux.HandleFunc("/", session.WithPossibleAuth(home(app.database, app.pages), app.sessionManager))
22
+29
-5
pages/pages.go
+29
-5
pages/pages.go
···
1
package pages
2
3
// forked and inspired from tangled's implementation
4
//https://tangled.org/@tangled.org/core/blob/master/appview/pages/pages.go
5
···
8
"html/template"
9
"io"
10
"io/fs"
11
"strings"
12
"time"
13
)
14
15
-
//go:embed templates/*
16
var Files embed.FS
17
18
type Pages struct {
···
116
return p.parse(stack...)
117
}
118
119
-
func (p *Pages) executePlain(name string, w io.Writer, params any) error {
120
-
tpl, err := p.parse(name)
121
if err != nil {
122
-
return err
123
}
124
125
-
return tpl.Execute(w, params)
126
}
127
128
func (p *Pages) Execute(name string, w io.Writer, params any) error {
129
tpl, err := p.parseBase(name)
130
if err != nil {
···
1
package pages
2
3
+
// Helpers to load gohtml templates and render them
4
// forked and inspired from tangled's implementation
5
//https://tangled.org/@tangled.org/core/blob/master/appview/pages/pages.go
6
···
9
"html/template"
10
"io"
11
"io/fs"
12
+
"net/http"
13
"strings"
14
"time"
15
)
16
17
+
//go:embed templates/* static/*
18
var Files embed.FS
19
20
type Pages struct {
···
118
return p.parse(stack...)
119
}
120
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")
127
if err != nil {
128
+
//p.logger.Error("no static dir found? that's crazy", "err", err)
129
+
panic(err)
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
+
}
136
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
+
})
149
}
150
151
+
// Execute What loads and renders the HTML page/
152
func (p *Pages) Execute(name string, w io.Writer, params any) error {
153
tpl, err := p.parseBase(name)
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
Item: playView,
87
}
88
89
-
var swapRecord *string
90
authArgs := db.AtpSessionToAuthArgs(sess)
91
-
92
swapRecord, err = p.getStatusSwapRecord(ctx, xrpcClient, sess, authArgs)
93
if err != nil {
94
return err
···
166
}
167
168
authArgs := db.AtpSessionToAuthArgs(sess)
169
-
170
var swapRecord *string
171
swapRecord, err = p.getStatusSwapRecord(ctx, xrpcClient, sess, authArgs)
172
if err != nil {
···
86
Item: playView,
87
}
88
89
authArgs := db.AtpSessionToAuthArgs(sess)
90
+
var swapRecord *string
91
swapRecord, err = p.getStatusSwapRecord(ctx, xrpcClient, sess, authArgs)
92
if err != nil {
93
return err
···
165
}
166
167
authArgs := db.AtpSessionToAuthArgs(sess)
168
var swapRecord *string
169
swapRecord, err = p.getStatusSwapRecord(ctx, xrpcClient, sess, authArgs)
170
if err != nil {