+1
appview/pages/funcmap.go
+1
appview/pages/funcmap.go
+22
-1
appview/pages/pages.go
+22
-1
appview/pages/pages.go
···
2
2
3
3
import (
4
4
"bytes"
5
+
"crypto/sha256"
5
6
"embed"
7
+
"encoding/hex"
6
8
"fmt"
7
9
"html/template"
8
10
"io"
···
730
732
731
733
func Cache(h http.Handler) http.Handler {
732
734
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
733
-
if strings.HasSuffix(r.URL.Path, ".css") {
735
+
path := strings.Split(r.URL.Path, "?")[0]
736
+
737
+
if strings.HasSuffix(path, ".css") {
734
738
// on day for css files
735
739
w.Header().Set("Cache-Control", "public, max-age=86400")
736
740
} else {
···
738
742
}
739
743
h.ServeHTTP(w, r)
740
744
})
745
+
}
746
+
747
+
func CssContentHash() string {
748
+
cssFile, err := Files.Open("static/tw.css")
749
+
if err != nil {
750
+
log.Printf("Error opening CSS file: %v", err)
751
+
return ""
752
+
}
753
+
defer cssFile.Close()
754
+
755
+
hasher := sha256.New()
756
+
if _, err := io.Copy(hasher, cssFile); err != nil {
757
+
log.Printf("Error hashing CSS file: %v", err)
758
+
return ""
759
+
}
760
+
761
+
return hex.EncodeToString(hasher.Sum(nil))[:8] // Use first 8 chars of hash
741
762
}
742
763
743
764
func (p *Pages) Error500(w io.Writer) error {
+1
-2
appview/pages/templates/layouts/base.html
+1
-2
appview/pages/templates/layouts/base.html
···
8
8
content="width=device-width, initial-scale=1.0"
9
9
/>
10
10
<script src="/static/htmx.min.js"></script>
11
-
<link href="/static/tw.css" rel="stylesheet" type="text/css" />
12
-
11
+
<link rel="stylesheet" href="/static/tw.css?{{ cssContentHash }}" type="text/css" />
13
12
<title>{{ block "title" . }}{{ end }} · tangled</title>
14
13
{{ block "extrameta" . }}{{ end }}
15
14
</head>
+10
-2
appview/pages/templates/user/login.html
+10
-2
appview/pages/templates/user/login.html
···
8
8
content="width=device-width, initial-scale=1.0"
9
9
/>
10
10
<script src="/static/htmx.min.js"></script>
11
-
<link rel="stylesheet" href="/static/tw.css" type="text/css" />
11
+
<link rel="stylesheet" href="/static/tw.css?{{ cssContentHash }}" type="text/css" />
12
12
<title>login</title>
13
13
</head>
14
14
<body class="flex items-center justify-center min-h-screen">
···
27
27
>
28
28
<div class="flex flex-col">
29
29
<label for="handle">handle</label>
30
-
<input type="text" id="handle" name="handle" required />
30
+
<input
31
+
type="text"
32
+
id="handle"
33
+
name="handle"
34
+
tabindex="1"
35
+
required
36
+
/>
31
37
<span class="text-xs text-gray-500 mt-1">
32
38
You need to use your
33
39
<a href="https://bsky.app">Bluesky</a> handle to log
···
41
47
type="password"
42
48
id="app_password"
43
49
name="app_password"
50
+
tabindex="2"
44
51
required
45
52
/>
46
53
<span class="text-xs text-gray-500 mt-1">
···
57
64
class="btn w-full my-2 mt-6"
58
65
type="submit"
59
66
id="login-button"
67
+
tabindex="3"
60
68
>
61
69
<span>login</span>
62
70
</button>
+5
-2
appview/pages/templates/user/profile.html
+5
-2
appview/pages/templates/user/profile.html
···
108
108
<img class="w-3/4 rounded-full p-2" src="{{ .AvatarUri }}" />
109
109
{{ end }}
110
110
</div>
111
-
<p class="text-xl font-bold text-center dark:text-white">
112
-
{{ truncateAt30 (didOrHandle .UserDid .UserHandle) }}
111
+
<p
112
+
title="{{ didOrHandle .UserDid .UserHandle }}"
113
+
class="text-lg font-bold text-center dark:text-white overflow-hidden text-ellipsis whitespace-nowrap max-w-full"
114
+
>
115
+
{{ didOrHandle .UserDid .UserHandle }}
113
116
</p>
114
117
<div class="text-sm text-center dark:text-gray-300">
115
118
<span>{{ .ProfileStats.Followers }} followers</span>