+36
appview/pages/funcmap.go
+36
appview/pages/funcmap.go
···
4
4
"fmt"
5
5
"html"
6
6
"html/template"
7
+
"log"
8
+
"path/filepath"
7
9
"reflect"
8
10
"strings"
9
11
···
119
121
"list": func(args ...any) []any {
120
122
return args
121
123
},
124
+
"i": func(name string, classes ...string) template.HTML {
125
+
data, err := icon(name, classes)
126
+
if err != nil {
127
+
log.Printf("icon %s does not exist", name)
128
+
data, _ = icon("airplay", classes)
129
+
}
130
+
return template.HTML(data)
131
+
},
122
132
}
123
133
}
134
+
135
+
func icon(name string, classes []string) (template.HTML, error) {
136
+
iconPath := filepath.Join("static", "icons", name)
137
+
138
+
if filepath.Ext(name) == "" {
139
+
iconPath += ".svg"
140
+
}
141
+
142
+
data, err := Files.ReadFile(iconPath)
143
+
if err != nil {
144
+
return "", fmt.Errorf("icon %s not found: %w", name, err)
145
+
}
146
+
147
+
// Convert SVG data to string
148
+
svgStr := string(data)
149
+
150
+
svgTagEnd := strings.Index(svgStr, ">")
151
+
if svgTagEnd == -1 {
152
+
return "", fmt.Errorf("invalid SVG format for icon %s", name)
153
+
}
154
+
155
+
classTag := ` class="` + strings.Join(classes, " ") + `"`
156
+
157
+
modifiedSVG := svgStr[:svgTagEnd] + classTag + svgStr[svgTagEnd:]
158
+
return template.HTML(modifiedSVG), nil
159
+
}
+6
-6
appview/pages/pages.go
+6
-6
appview/pages/pages.go
···
25
25
"github.com/sotangled/tangled/types"
26
26
)
27
27
28
-
//go:embed templates/* static/*
29
-
var files embed.FS
28
+
//go:embed templates/* static
29
+
var Files embed.FS
30
30
31
31
type Pages struct {
32
32
t map[string]*template.Template
···
36
36
templates := make(map[string]*template.Template)
37
37
38
38
// Walk through embedded templates directory and parse all .html files
39
-
err := fs.WalkDir(files, "templates", func(path string, d fs.DirEntry, err error) error {
39
+
err := fs.WalkDir(Files, "templates", func(path string, d fs.DirEntry, err error) error {
40
40
if err != nil {
41
41
return err
42
42
}
···
49
49
if strings.HasPrefix(path, "templates/fragments/") {
50
50
tmpl, err := template.New(name).
51
51
Funcs(funcMap()).
52
-
ParseFS(files, path)
52
+
ParseFS(Files, path)
53
53
if err != nil {
54
54
return fmt.Errorf("setting up fragment: %w", err)
55
55
}
···
64
64
// Add the page template on top of the base
65
65
tmpl, err := template.New(name).
66
66
Funcs(funcMap()).
67
-
ParseFS(files, "templates/layouts/*.html", "templates/fragments/*.html", path)
67
+
ParseFS(Files, "templates/layouts/*.html", "templates/fragments/*.html", path)
68
68
if err != nil {
69
69
return fmt.Errorf("setting up template: %w", err)
70
70
}
···
577
577
}
578
578
579
579
func (p *Pages) Static() http.Handler {
580
-
sub, err := fs.Sub(files, "static")
580
+
sub, err := fs.Sub(Files, "static")
581
581
if err != nil {
582
582
log.Fatalf("no static dir found? that's crazy: %v", err)
583
583
}
appview/pages/static/.gitkeep
appview/pages/static/.gitkeep
This is a binary file and will not be displayed.
+4
-4
appview/pages/templates/fragments/diff.html
+4
-4
appview/pages/templates/fragments/diff.html
···
40
40
<a {{if $parent}}href="/{{ $repo }}/blob/{{ $parent }}/{{ .Name.Old }}"{{end}}>
41
41
{{ .Name.Old }}
42
42
</a>
43
-
<i class="w-4 h-4" data-lucide="arrow-right"></i>
43
+
{{ i "arrow-right" "w-4 h-4" }}
44
44
<a {{if $this}}href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}"{{end}}>
45
45
{{ .Name.New }}
46
46
</a>
···
53
53
54
54
{{ $iconstyle := "p-1 mx-1 hover:bg-gray-100 rounded" }}
55
55
<div id="right-side-items" class="p-2 flex items-center">
56
-
<a title="top of file" href="#file-{{ .Name.New }}" class="{{ $iconstyle }}"><i class="w-4 h-4" data-lucide="arrow-up-to-line"></i></a>
56
+
<a title="top of file" href="#file-{{ .Name.New }}" class="{{ $iconstyle }}">{{ i "arrow-up-to-line" "w-4 h-4" }}</a>
57
57
{{ if gt $idx 0 }}
58
58
{{ $prev := index $diff (sub $idx 1) }}
59
-
<a title="previous file" href="#file-{{ $prev.Name.New }}" class="{{ $iconstyle }}"><i class="w-4 h-4" data-lucide="arrow-up"></i></a>
59
+
<a title="previous file" href="#file-{{ $prev.Name.New }}" class="{{ $iconstyle }}">{{ i "arrow-up" "w-4 h-4" }}</a>
60
60
{{ end }}
61
61
62
62
{{ if lt $idx $last }}
63
63
{{ $next := index $diff (add $idx 1) }}
64
-
<a title="next file" href="#file-{{ $next.Name.New }}" class="{{ $iconstyle }}"><i class="w-4 h-4" data-lucide="arrow-down"></i></a>
64
+
<a title="next file" href="#file-{{ $next.Name.New }}" class="{{ $iconstyle }}">{{ i "arrow-down" "w-4 h-4" }}</a>
65
65
{{ end }}
66
66
</div>
67
67
+6
-6
appview/pages/templates/fragments/editRepoDescription.html
+6
-6
appview/pages/templates/fragments/editRepoDescription.html
···
1
1
{{ define "fragments/editRepoDescription" }}
2
-
<form hx-put="/{{ .RepoInfo.FullName }}/description" hx-target="this" hx-swap="outerHTML">
3
-
<input type="text" name="description" value="{{ .RepoInfo.Description }}">
4
-
<button type="submit" class="bg-green-100 text-green-700 rounded p-1 mr-1 hover:bg-green-200 font-mono uppercase text-sm">
5
-
save
2
+
<form hx-put="/{{ .RepoInfo.FullName }}/description" hx-target="this" hx-swap="outerHTML" class="flex flex-wrap gap-2">
3
+
<input type="text" class="p-1" name="description" value="{{ .RepoInfo.Description }}">
4
+
<button type="submit" class="btn p-2 flex items-center gap-2 no-underline text-sm">
5
+
save {{ i "check" "w-3 h-3" }}
6
6
</button>
7
-
<button type="button" class="bg-red-100 text-red-700 rounded p-1 hover:bg-red-200 font-mono uppercase text-sm" hx-get="/{{ .RepoInfo.FullName }}/description" >
8
-
cancel
7
+
<button type="button" class="btn p-2 flex items-center gap-2 no-underline text-sm" hx-get="/{{ .RepoInfo.FullName }}/description" >
8
+
cancel {{ i "x" "w-3 h-3" }}
9
9
</button>
10
10
</form>
11
11
{{ end }}
+3
-2
appview/pages/templates/fragments/repoDescription.html
+3
-2
appview/pages/templates/fragments/repoDescription.html
···
1
1
{{ define "fragments/repoDescription" }}
2
-
<span id="repo-description" hx-target="this" hx-swap="outerHTML">
2
+
<span id="repo-description" class="flex flex-wrap items-center gap-2" hx-target="this" hx-swap="outerHTML">
3
3
{{ if .RepoInfo.Description }}
4
4
{{ .RepoInfo.Description }}
5
5
{{ else }}
···
7
7
{{ end }}
8
8
9
9
{{ if .RepoInfo.Roles.IsOwner }}
10
-
<button class="bg-gray-200 uppercase rounded p-1 ml-1 hover:bg-gray-400 font-mono text-sm" hx-get="/{{ .RepoInfo.FullName }}/description/edit">
10
+
<button class="btn p-2 flex items-center gap-2 no-underline text-sm" hx-get="/{{ .RepoInfo.FullName }}/description/edit">
11
11
edit
12
+
{{ i "pencil" "w-3 h-3" }}
12
13
</button>
13
14
{{ end }}
14
15
</span>
+2
-7
appview/pages/templates/fragments/star.html
+2
-7
appview/pages/templates/fragments/star.html
···
15
15
>
16
16
<div class="flex gap-2 items-center">
17
17
{{ if .IsStarred }}
18
-
<span class="w-3 h-3 fill-current" data-lucide="star"></span>
18
+
{{ i "star" "w-3 h-3 fill-current" }}
19
19
{{ else }}
20
-
<span class="w-3 h-3" data-lucide="star"></span>
20
+
{{ i "star" "w-3 h-3" }}
21
21
{{ end }}
22
22
<span>
23
23
{{ .Stats.StarCount }}
24
24
</span>
25
25
</div>
26
26
</button>
27
-
<script>
28
-
document.body.addEventListener('htmx:afterRequest', function (evt) {
29
-
lucide.createIcons();
30
-
});
31
-
</script>
32
27
{{ end }}
33
28
-4
appview/pages/templates/layouts/base.html
-4
appview/pages/templates/layouts/base.html
+1
-1
appview/pages/templates/layouts/topbar.html
+1
-1
appview/pages/templates/layouts/topbar.html
+1
-1
appview/pages/templates/repo/commit.html
+1
-1
appview/pages/templates/repo/commit.html
···
37
37
<p class="flex items-center text-sm text-gray-500">
38
38
<a href="/{{ $repo }}/commit/{{ $commit.This }}" class="no-underline hover:underline text-gray-500">{{ slice $commit.This 0 8 }}</a>
39
39
{{ if $commit.Parent }}
40
-
<i class="w-3 h-3 mx-1" data-lucide="arrow-left"></i>
40
+
{{ i "arrow-left" "w-3 h-3 mx-1" }}
41
41
<a href="/{{ $repo }}/commit/{{ $commit.Parent }}" class="no-underline hover:underline text-gray-500">{{ slice $commit.Parent 0 8 }}</a>
42
42
{{ end }}
43
43
</p>
+6
-16
appview/pages/templates/repo/index.html
+6
-16
appview/pages/templates/repo/index.html
···
49
49
href="/{{ .RepoInfo.FullName }}/commits/{{ .Ref | urlquery }}"
50
50
class="ml-2 no-underline flex items-center gap-2 text-sm uppercase font-bold"
51
51
>
52
-
<i class="w-4 h-4" data-lucide="logs"></i>
52
+
{{ i "logs" "w-4 h-4" }}
53
53
{{ .TotalCommits }}
54
54
{{ if eq .TotalCommits 1 }}commit{{ else }}commits{{ end }}
55
55
</a>
···
70
70
class="{{ $linkstyle }}"
71
71
>
72
72
<div class="flex items-center gap-2">
73
-
<i
74
-
class="w-3 h-3 fill-current"
75
-
data-lucide="folder"
76
-
></i
77
-
>{{ .Name }}
73
+
{{ i "folder" "w-3 h-3 fill-current" }}
74
+
{{ .Name }}
78
75
</div>
79
76
</a>
80
77
···
95
92
class="{{ $linkstyle }}"
96
93
>
97
94
<div class="flex items-center gap-2">
98
-
<i
99
-
class="w-3 h-3"
100
-
data-lucide="file"
101
-
></i
102
-
>{{ .Name }}
95
+
{{ i "file" "w-3 h-3" }}{{ .Name }}
103
96
</div>
104
97
</a>
105
98
···
134
127
class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 rounded"
135
128
hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')"
136
129
>
137
-
<i
138
-
class="w-3 h-3"
139
-
data-lucide="ellipsis"
140
-
></i>
130
+
{{ i "ellipsis" "w-3 h-3" }}
141
131
</button>
142
132
{{ end }}
143
133
</div>
···
182
172
></div>
183
173
{{ end }}
184
174
{{ range $tagsForCommit }}
185
-
<span class="text-xs rounded bg-gray-100 font-mono px-2 mx-1/2 inline-flex items-center">
175
+
<span class="text-xs rounded bg-gray-100 text-black font-mono px-2 mx-1/2 inline-flex items-center">
186
176
{{ . }}
187
177
</span>
188
178
{{ end }}
+2
-5
appview/pages/templates/repo/issues/issue.html
+2
-5
appview/pages/templates/repo/issues/issue.html
···
19
19
<div class="inline-flex items-center gap-2">
20
20
<div id="state"
21
21
class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }} text-sm">
22
-
<i data-lucide="{{ $icon }}" class="w-4 h-4 mr-1.5 text-white" ></i>
22
+
{{ i $icon "w-4 h-4 mr-1.5 text-white" }}
23
23
<span class="text-white">{{ .State }}</span>
24
24
</div>
25
25
<span class="text-gray-500 text-sm">
···
100
100
class="mt-8"
101
101
>
102
102
<button type="submit" class="btn hover:bg-{{ $hoverColor }}-300">
103
-
<i
104
-
data-lucide="{{ $icon }}"
105
-
class="w-4 h-4 mr-2 text-{{ $hoverColor }}-400"
106
-
></i>
103
+
{{ i $icon "w-4 h-4 mr-2" }}
107
104
<span class="text-black">{{ $action }}</span>
108
105
</button>
109
106
<div id="issue-action" class="error"></div>
+2
-2
appview/pages/templates/repo/issues/issues.html
+2
-2
appview/pages/templates/repo/issues/issues.html
···
13
13
<a
14
14
href="/{{ .RepoInfo.FullName }}/issues/new"
15
15
class="btn text-sm flex items-center gap-2 no-underline hover:no-underline">
16
-
<i data-lucide="plus" class="w-5 h-5"></i>
16
+
{{ i "plus" "w-4 h-4" }}
17
17
<span>new issue</span>
18
18
</a>
19
19
</div>
···
44
44
{{ end }}
45
45
46
46
<span class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }} text-sm">
47
-
<i data-lucide="{{ $icon }}" class="w-3 h-3 mr-1.5 text-white"></i>
47
+
{{ i $icon "w-3 h-3 mr-1.5 text-white" }}
48
48
<span class="text-white">{{ $state }}</span>
49
49
</span>
50
50
+3
-6
appview/pages/templates/repo/log.html
+3
-6
appview/pages/templates/repo/log.html
···
75
75
class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 rounded"
76
76
hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')"
77
77
>
78
-
<i
79
-
class="w-3 h-3"
80
-
data-lucide="ellipsis"
81
-
></i>
78
+
{{ i "ellipsis" "w-3 h-3" }}
82
79
</button>
83
80
{{ end }}
84
81
</div>
···
138
135
hx-boost="true"
139
136
onclick="window.location.href = window.location.pathname + '?page={{ sub .Page 1 }}'"
140
137
>
141
-
<i data-lucide="chevron-left" class="w-4 h-4"></i>
138
+
{{ i "chevron-left" "w-4 h-4" }}
142
139
previous
143
140
</a>
144
141
{{ else }}
···
152
149
onclick="window.location.href = window.location.pathname + '?page={{ add .Page 1 }}'"
153
150
>
154
151
next
155
-
<i data-lucide="chevron-right" class="w-4 h-4"></i>
152
+
{{ i "chevron-right" "w-4 h-4" }}
156
153
</a>
157
154
{{ end }}
158
155
</div>
+2
-5
appview/pages/templates/repo/pulls/patch.html
+2
-5
appview/pages/templates/repo/pulls/patch.html
···
10
10
<header class="pb-2">
11
11
<div class="flex gap-3 items-center mb-3">
12
12
<a href="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/" class="flex items-center gap-2 font-medium">
13
-
<i data-lucide="arrow-left" class="w-5 h-5"></i>
13
+
{{ i "arrow-left" "w-5 h-5" }}
14
14
back
15
15
</a>
16
16
<span class="select-none before:content-['\00B7']"></span>
···
40
40
id="state"
41
41
class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }}"
42
42
>
43
-
<i
44
-
data-lucide="{{ $icon }}"
45
-
class="w-4 h-4 mr-1.5 text-white"
46
-
></i>
43
+
{{ i $icon "w-4 h-4 mr-1.5 text-white" }}
47
44
<span class="text-white">{{ .Pull.State.String }}</span>
48
45
</div>
49
46
<span class="text-gray-500 text-sm">
+24
-20
appview/pages/templates/repo/pulls/pull.html
+24
-20
appview/pages/templates/repo/pulls/pull.html
···
27
27
id="state"
28
28
class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }}"
29
29
>
30
-
<i
31
-
data-lucide="{{ $icon }}"
32
-
class="w-4 h-4 mr-1.5 text-white"
33
-
></i>
30
+
{{ i $icon "w-4 h-4 mr-1.5 text-white" }}
34
31
<span class="text-white">{{ .Pull.State.String }}</span>
35
32
</div>
36
33
<span class="text-gray-500 text-sm">
···
139
136
<div class="bg-purple-50 border border-purple-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
140
137
<div class="absolute left-8 -top-2 w-px h-2 bg-gray-300"></div>
141
138
<div class="flex items-center gap-2 text-purple-500">
142
-
<i data-lucide="git-merge" class="w-4 h-4"></i>
139
+
{{ i "git-merge" "w-4 h-4" }}
143
140
<span class="font-medium">pull request successfully merged</span
144
141
>
145
142
</div>
···
148
145
<div class="bg-red-50 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
149
146
<div class="absolute left-8 -top-2 w-px h-2 bg-gray-300"></div>
150
147
<div class="flex items-center gap-2 text-red-500">
151
-
<i data-lucide="alert-triangle" class="w-4 h-4"></i>
148
+
{{ i "triangle-alert" "w-4 h-4" }}
152
149
<span class="font-medium">merge conflicts detected</span>
153
150
<ul class="text-sm space-y-1">
154
151
{{ range .MergeCheck.Conflicts }}
155
152
{{ if .Filename }}
156
153
<li class="flex items-center">
157
-
<i
158
-
data-lucide="file-warning"
159
-
class="w-3 h-3 mr-1.5 text-red-500"
160
-
></i>
154
+
{{ i "file-warning" "w-3 h-3 mr-1.5 text-red-500" }}
161
155
<span class="font-mono">{{ slice .Filename 0 (sub (len .Filename) 2) }}</span>
162
156
</li>
163
157
{{ end }}
···
169
163
<div class="bg-green-50 border border-green-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
170
164
<div class="absolute left-8 -top-2 w-px h-2 bg-gray-300"></div>
171
165
<div class="flex items-center gap-2 text-green-500">
172
-
<i data-lucide="check-circle" class="w-4 h-4"></i>
166
+
{{ i "circle-check-big" "w-4 h-4" }}
173
167
<span class="font-medium">no conflicts, ready to merge</span>
174
168
</div>
175
169
</div>
···
191
185
<div class="absolute left-8 -top-2 w-px h-2 bg-gray-300"></div>
192
186
<div class="flex flex-wrap gap-2">
193
187
<button href="#" class="btn p-2 flex items-center gap-2 no-underline hover:no-underline">
194
-
<i data-lucide="message-square-plus" class="w-4 h-4"></i>
188
+
{{ i "message-square-plus" "w-4 h-4" }}
195
189
<span>comment</span>
196
190
</button>
197
191
{{ if and $isPushAllowed $isOpen }}
···
199
193
{{ if $isConflicted }}
200
194
{{ $disabled = "disabled" }}
201
195
{{ end }}
202
-
<button href="#" class="btn p-2 flex items-center gap-2 no-underline hover:no-underline" {{ $disabled }}>
203
-
<i data-lucide="git-merge" class="w-4 h-4"></i>
196
+
<button
197
+
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/merge"
198
+
hx-swap="none"
199
+
hx-confirm="Are you sure you want to merge this pull request?"
200
+
class="btn p-2 flex items-center gap-2" {{ $disabled }}>
201
+
{{ i "git-merge" "w-4 h-4" }}
204
202
<span>merge</span>
205
203
</button>
206
204
{{ end }}
207
205
208
206
{{ if and $isPullAuthor $isOpen }}
209
207
<button href="#" class="btn p-2 flex items-center gap-2 no-underline hover:no-underline">
210
-
<i data-lucide="rotate-ccw" class="w-4 h-4"></i>
208
+
{{ i "rotate-ccw" "w-4 h-4" }}
211
209
<span>resubmit</span>
212
210
</button>
213
211
{{ end }}
214
212
215
213
{{ if and $isPullAuthor $isPushAllowed $isOpen }}
216
-
<button href="#" class="btn p-2 flex items-center gap-2 no-underline hover:no-underline">
217
-
<i data-lucide="ban" class="w-4 h-4"></i>
214
+
<button
215
+
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/close"
216
+
hx-swap="none"
217
+
class="btn p-2 flex items-center gap-2">
218
+
{{ i "ban" "w-4 h-4" }}
218
219
<span>close</span>
219
220
</button>
220
221
{{ end }}
221
222
222
223
{{ if and $isPullAuthor $isPushAllowed $isClosed }}
223
-
<button href="#" class="btn p-2 flex items-center gap-2 no-underline hover:no-underline">
224
-
<i data-lucide="circle-dot" class="w-4 h-4"></i>
224
+
<button
225
+
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/reopen"
226
+
hx-swap="none"
227
+
class="btn p-2 flex items-center gap-2">
228
+
{{ i "circle-dot" "w-4 h-4" }}
225
229
<span>reopen</span>
226
230
</button>
227
231
{{ end }}
···
270
274
class="rounded relative bg-purple-50 border border-purple-200 p-4">
271
275
272
276
<div class="flex items-center gap-2 text-purple-500">
273
-
<i data-lucide="git-merge" class="w-4 h-4"></i>
277
+
{{ i "git-merge" "w-4 h-4" }}
274
278
<span class="font-medium"
275
279
>pull request successfully merged</span
276
280
>
+2
-5
appview/pages/templates/repo/pulls/pulls.html
+2
-5
appview/pages/templates/repo/pulls/pulls.html
···
24
24
href="/{{ .RepoInfo.FullName }}/pulls/new"
25
25
class="btn text-sm flex items-center gap-2 no-underline hover:no-underline"
26
26
>
27
-
<i data-lucide="git-pull-request" class="w-5 h-5"></i>
27
+
{{ i "git-pull-request" "w-4 h-4" }}
28
28
<span>new pull request</span>
29
29
</a>
30
30
</div>
···
57
57
<span
58
58
class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }} text-sm"
59
59
>
60
-
<i
61
-
data-lucide="{{ $icon }}"
62
-
class="w-3 h-3 mr-1.5 text-white"
63
-
></i>
60
+
{{ i $icon "w-3 h-3 mr-1.5 text-white" }}
64
61
<span class="text-white">{{ .State.String }}</span>
65
62
</span>
66
63
+2
-2
appview/pages/templates/repo/tree.html
+2
-2
appview/pages/templates/repo/tree.html
···
41
41
<div class="flex justify-between items-center">
42
42
<a href="/{{ $.BaseTreeLink }}/{{ .Name }}" class="{{ $linkstyle }}">
43
43
<div class="flex items-center gap-2">
44
-
<i class="w-3 h-3 fill-current" data-lucide="folder"></i>{{ .Name }}
44
+
{{ i "folder" "w-3 h-3 fill-current" }}{{ .Name }}
45
45
</div>
46
46
</a>
47
47
<time class="text-xs text-gray-500">{{ timeFmt .LastCommit.When }}</time>
···
56
56
<div class="flex justify-between items-center">
57
57
<a href="/{{ $.BaseBlobLink }}/{{ .Name }}" class="{{ $linkstyle }}">
58
58
<div class="flex items-center gap-2">
59
-
<i class="w-3 h-3" data-lucide="file"></i>{{ .Name }}
59
+
{{ i "file" "w-3 h-3" }}{{ .Name }}
60
60
</div>
61
61
</a>
62
62
<time class="text-xs text-gray-500">{{ timeFmt .LastCommit.When }}</time>
+6
-6
appview/pages/templates/settings.html
+6
-6
appview/pages/templates/settings.html
···
36
36
<div class="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-4">
37
37
<div class="flex flex-col gap-1">
38
38
<div class="inline-flex items-center gap-4">
39
-
<i class="w-3 h-3" data-lucide="key"></i>
39
+
{{ i "key" "w-3 h-3" }}
40
40
<p class="font-bold">{{ .Name }}</p>
41
41
</div>
42
42
<p class="text-sm text-gray-500">added {{ .Created | timeFmt }}</p>
···
48
48
class="btn text-red-500 hover:text-red-700"
49
49
title="Delete key"
50
50
hx-delete="/settings/keys?name={{urlquery .Name}}&rkey={{urlquery .Rkey}}&key={{urlquery .Key}}"
51
-
hx-confirm="Are you sure you wish to delete the key '{{ .Name }}'?">
52
-
<i class="w-5 h-5" data-lucide="trash-2"></i>
51
+
hx-confirm="Are you sure you want to delete the key '{{ .Name }}'?">
52
+
{{ i "trash-2" "w-5 h-5" }}
53
53
<span class="hidden md:inline">delete</span>
54
54
</button>
55
55
</div>
···
91
91
<div class="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-4">
92
92
<div class="flex flex-col gap-2">
93
93
<div class="inline-flex items-center gap-4">
94
-
<i class="w-3 h-3" data-lucide="mail"></i>
94
+
{{ i "mail" "w-3 h-3" }}
95
95
<p class="font-bold">{{ .Address }}</p>
96
96
<div class="inline-flex items-center gap-1">
97
97
{{ if .Verified }}
···
114
114
hx-swap="none"
115
115
href="#"
116
116
hx-vals='{"email": "{{ .Address }}"}'>
117
-
<i class="w-5 h-5" data-lucide="rotate-cw"></i>
117
+
{{ i "rotate-cw" "w-5 h-5" }}
118
118
<span class="hidden md:inline">resend</span>
119
119
</button>
120
120
{{ end }}
···
135
135
class="btn text-red-500 hover:text-red-700"
136
136
title="Delete email"
137
137
type="submit">
138
-
<i class="w-5 h-5" data-lucide="trash-2"></i>
138
+
{{ i "trash-2" "w-5 h-5" }}
139
139
<span class="hidden md:inline">delete</span>
140
140
</button>
141
141
</form>
+1
-1
appview/pages/templates/timeline.html
+1
-1
appview/pages/templates/timeline.html
···
22
22
tangled
23
23
</div>
24
24
<div class="italic text-lg">
25
-
tightly-knit social coding, <a href="/login" class="underline inline-flex gap-1 items-center">join now <i data-lucide="arrow-right" class="w-4 h-4"></i></a>
25
+
tightly-knit social coding, <a href="/login" class="underline inline-flex gap-1 items-center">join now {{ i "arrow-right" "w-4 h-4" }}</a>
26
26
<p class="pt-5 px-10 text-sm text-gray-500">Join our IRC channel: <a href="https://web.libera.chat/#tangled"><code>#tangled</code> on Libera Chat</a>.
27
27
Read an introduction to Tangled <a href="https://blog.tangled.sh/intro">here</a>.</p>
28
28
</div>
+2
-8
appview/pages/templates/user/profile.html
+2
-8
appview/pages/templates/user/profile.html
···
62
62
63
63
{{ if .RepoStats.StarCount }}
64
64
<div class="flex gap-1 items-center text-sm">
65
-
<span
66
-
class="w-3 h-3 fill-current"
67
-
data-lucide="star"
68
-
></span>
65
+
{{ i "star" "w-3 h-3 fill-current" }}
69
66
<span>{{ .RepoStats.StarCount }}</span>
70
67
</div>
71
68
{{ end }}
···
100
97
101
98
{{ if .RepoStats.StarCount }}
102
99
<div class="flex gap-1 items-center text-sm">
103
-
<span
104
-
class="w-3 h-3 fill-current"
105
-
data-lucide="star"
106
-
></span>
100
+
{{ i "star" "w-3 h-3 fill-current" }}
107
101
<span>{{ .RepoStats.StarCount }}</span>
108
102
</div>
109
103
{{ end }}
-2
appview/state/pull.go
-2
appview/state/pull.go
+6
-5
flake.lock
+6
-5
flake.lock
···
67
67
"lucide-src": {
68
68
"flake": false,
69
69
"locked": {
70
-
"narHash": "sha256-5ipNSxTlQ7627lGgsyZxk7vS1sr9RkrlR8/QMj2Zg6s=",
71
-
"type": "file",
72
-
"url": "https://unpkg.com/lucide@0.482.0"
70
+
"lastModified": 1742302029,
71
+
"narHash": "sha256-OyPVtpnC4/AAmPq84Wt1r1Gcs48d9KG+UBCtZK87e9k=",
72
+
"type": "tarball",
73
+
"url": "https://github.com/lucide-icons/lucide/releases/download/0.483.0/lucide-icons-0.483.0.zip"
73
74
},
74
75
"original": {
75
-
"type": "file",
76
-
"url": "https://unpkg.com/lucide@0.482.0"
76
+
"type": "tarball",
77
+
"url": "https://github.com/lucide-icons/lucide/releases/download/0.483.0/lucide-icons-0.483.0.zip"
77
78
}
78
79
},
79
80
"nixpkgs": {
+5
-5
flake.nix
+5
-5
flake.nix
···
12
12
flake = false;
13
13
};
14
14
lucide-src = {
15
-
url = "https://unpkg.com/lucide@0.482.0";
15
+
url = "https://github.com/lucide-icons/lucide/releases/download/0.483.0/lucide-icons-0.483.0.zip";
16
16
flake = false;
17
17
};
18
18
ia-fonts-src = {
···
71
71
src = gitignoreSource ./.;
72
72
postUnpack = ''
73
73
pushd source
74
+
mkdir -p appview/pages/static/{fonts,icons}
74
75
cp -f ${htmx-src} appview/pages/static/htmx.min.js
75
-
cp -f ${lucide-src} appview/pages/static/lucide.min.js
76
-
mkdir -p appview/pages/static/fonts
76
+
cp -rf ${lucide-src}/*.svg appview/pages/static/icons/
77
77
cp -f ${ia-fonts-src}/"iA Writer Quattro"/Static/*.ttf appview/pages/static/fonts/
78
78
cp -f ${ia-fonts-src}/"iA Writer Mono"/Static/*.ttf appview/pages/static/fonts/
79
79
${pkgs.tailwindcss}/bin/tailwindcss -i input.css -o appview/pages/static/tw.css
···
150
150
pkgs.nixos-shell
151
151
];
152
152
shellHook = ''
153
+
mkdir -p appview/pages/static/{fonts,icons}
153
154
cp -f ${htmx-src} appview/pages/static/htmx.min.js
154
-
cp -f ${lucide-src} appview/pages/static/lucide.min.js
155
-
mkdir -p appview/pages/static/fonts/
155
+
cp -rf ${lucide-src}/*.svg appview/pages/static/icons/
156
156
cp -f ${ia-fonts-src}/"iA Writer Quattro"/Static/*.ttf appview/pages/static/fonts/
157
157
cp -f ${ia-fonts-src}/"iA Writer Mono"/Static/*.ttf appview/pages/static/fonts/
158
158
'';