+2
-2
handlers/routes.go
+2
-2
handlers/routes.go
···
18
18
panic(result.Error)
19
19
}
20
20
21
-
layouts.RenderDefault("", pages.Home(posts)).ServeHTTP(w, r)
21
+
layouts.RenderWithSidebar("", pages.Home(posts)).ServeHTTP(w, r)
22
22
}
23
23
24
24
func ServePostPage(w http.ResponseWriter, r *http.Request) {
···
32
32
return
33
33
}
34
34
35
-
layouts.RenderDefault(string(post.MicroformatType), pages.Post(post)).ServeHTTP(w, r)
35
+
layouts.RenderWithSidebar(string(post.MicroformatType), pages.Post(post)).ServeHTTP(w, r)
36
36
}
+21
html/components/head.templ
+21
html/components/head.templ
···
1
+
package components
2
+
3
+
import "github.com/puregarlic/space/storage"
4
+
5
+
templ Head(title string) {
6
+
<head>
7
+
if len(title) > 0 {
8
+
<title>{ title } | puregarlic dot space</title>
9
+
} else {
10
+
<title>puregarlic dot space</title>
11
+
}
12
+
<meta name="viewport" content="width=device-width, initial-scale=1"/>
13
+
<link rel="preconnect" href="https://fonts.googleapis.com"/>
14
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
15
+
<link href="https://fonts.googleapis.com/css2?family=Recursive:slnt,wght,CASL,CRSV,MONO@-15..0,300..1000,0..1,0..1,0..1&display=swap" rel="stylesheet"/>
16
+
for _, rel := range storage.GetRels() {
17
+
<link rel={ rel.Name } href={ rel.HREF }/>
18
+
}
19
+
<link rel="stylesheet" href="/static/styles.css"/>
20
+
</head>
21
+
}
+101
html/components/head_templ.go
+101
html/components/head_templ.go
···
1
+
// Code generated by templ - DO NOT EDIT.
2
+
3
+
// templ: version: v0.2.747
4
+
package components
5
+
6
+
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
+
8
+
import "github.com/a-h/templ"
9
+
import templruntime "github.com/a-h/templ/runtime"
10
+
11
+
import "github.com/puregarlic/space/storage"
12
+
13
+
func Head(title string) templ.Component {
14
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
15
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
16
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
17
+
if !templ_7745c5c3_IsBuffer {
18
+
defer func() {
19
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
20
+
if templ_7745c5c3_Err == nil {
21
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
22
+
}
23
+
}()
24
+
}
25
+
ctx = templ.InitializeContext(ctx)
26
+
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
27
+
if templ_7745c5c3_Var1 == nil {
28
+
templ_7745c5c3_Var1 = templ.NopComponent
29
+
}
30
+
ctx = templ.ClearChildren(ctx)
31
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1)
32
+
if templ_7745c5c3_Err != nil {
33
+
return templ_7745c5c3_Err
34
+
}
35
+
if len(title) > 0 {
36
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2)
37
+
if templ_7745c5c3_Err != nil {
38
+
return templ_7745c5c3_Err
39
+
}
40
+
var templ_7745c5c3_Var2 string
41
+
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title)
42
+
if templ_7745c5c3_Err != nil {
43
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/head.templ`, Line: 8, Col: 17}
44
+
}
45
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
46
+
if templ_7745c5c3_Err != nil {
47
+
return templ_7745c5c3_Err
48
+
}
49
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3)
50
+
if templ_7745c5c3_Err != nil {
51
+
return templ_7745c5c3_Err
52
+
}
53
+
} else {
54
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 4)
55
+
if templ_7745c5c3_Err != nil {
56
+
return templ_7745c5c3_Err
57
+
}
58
+
}
59
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 5)
60
+
if templ_7745c5c3_Err != nil {
61
+
return templ_7745c5c3_Err
62
+
}
63
+
for _, rel := range storage.GetRels() {
64
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 6)
65
+
if templ_7745c5c3_Err != nil {
66
+
return templ_7745c5c3_Err
67
+
}
68
+
var templ_7745c5c3_Var3 string
69
+
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(rel.Name)
70
+
if templ_7745c5c3_Err != nil {
71
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/head.templ`, Line: 17, Col: 23}
72
+
}
73
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
74
+
if templ_7745c5c3_Err != nil {
75
+
return templ_7745c5c3_Err
76
+
}
77
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 7)
78
+
if templ_7745c5c3_Err != nil {
79
+
return templ_7745c5c3_Err
80
+
}
81
+
var templ_7745c5c3_Var4 string
82
+
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(rel.HREF)
83
+
if templ_7745c5c3_Err != nil {
84
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/head.templ`, Line: 17, Col: 41}
85
+
}
86
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
87
+
if templ_7745c5c3_Err != nil {
88
+
return templ_7745c5c3_Err
89
+
}
90
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 8)
91
+
if templ_7745c5c3_Err != nil {
92
+
return templ_7745c5c3_Err
93
+
}
94
+
}
95
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 9)
96
+
if templ_7745c5c3_Err != nil {
97
+
return templ_7745c5c3_Err
98
+
}
99
+
return templ_7745c5c3_Err
100
+
})
101
+
}
+4
-6
html/components/posts/note.templ
+4
-6
html/components/posts/note.templ
···
1
1
package posts
2
2
3
-
import (
4
-
"github.com/puregarlic/space/models"
5
-
)
3
+
import "github.com/puregarlic/space/models"
6
4
7
5
templ Note(post *models.Post) {
8
-
<div class="bg-surface p-4">
9
-
{GetPostJSONProperty(post, "content")[0]}
10
-
</div>
6
+
<div class="bg-surface p-4 first:rounded-t last:rounded-b border-2 border-overlay">
7
+
{ GetPostJSONProperty(post, "content")[0] }
8
+
</div>
11
9
}
+4
-6
html/components/posts/note_templ.go
+4
-6
html/components/posts/note_templ.go
···
8
8
import "github.com/a-h/templ"
9
9
import templruntime "github.com/a-h/templ/runtime"
10
10
11
-
import (
12
-
"github.com/puregarlic/space/models"
13
-
)
11
+
import "github.com/puregarlic/space/models"
14
12
15
13
func Note(post *models.Post) templ.Component {
16
14
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
···
30
28
templ_7745c5c3_Var1 = templ.NopComponent
31
29
}
32
30
ctx = templ.ClearChildren(ctx)
33
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"bg-surface p-4\">")
31
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1)
34
32
if templ_7745c5c3_Err != nil {
35
33
return templ_7745c5c3_Err
36
34
}
37
35
var templ_7745c5c3_Var2 string
38
36
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(GetPostJSONProperty(post, "content")[0])
39
37
if templ_7745c5c3_Err != nil {
40
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/note.templ`, Line: 9, Col: 43}
38
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/note.templ`, Line: 7, Col: 43}
41
39
}
42
40
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
43
41
if templ_7745c5c3_Err != nil {
44
42
return templ_7745c5c3_Err
45
43
}
46
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
44
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2)
47
45
if templ_7745c5c3_Err != nil {
48
46
return templ_7745c5c3_Err
49
47
}
+13
-15
html/components/posts/photo.templ
+13
-15
html/components/posts/photo.templ
···
1
1
package posts
2
2
3
-
import (
4
-
"github.com/puregarlic/space/models"
5
-
)
3
+
import "github.com/puregarlic/space/models"
6
4
7
5
templ Photo(post *models.Post) {
8
-
<div class="bg-base">
9
-
for index, photo := range GetPostJSONProperty(post, "photo") {
10
-
<figure class="relative group">
11
-
<img class="w-full" src={photo} />
12
-
<figcaption
13
-
class="p-4 absolute inset-x-0 bottom-0 opacity-100 group-hover:opacity-0 bg-surface/70 backdrop-blur transition"
14
-
>
15
-
{GetPostJSONProperty(post, "content")[index]}
16
-
</figcaption>
17
-
</figure>
18
-
}
19
-
</div>
6
+
<div class="bg-base">
7
+
for index, photo := range GetPostJSONProperty(post, "photo") {
8
+
<figure class="relative group last:rounded-b">
9
+
<img class="w-full border-x-2 border-overlay group-first:rounded-t group-first:border-t-2" src={ photo }/>
10
+
<figcaption
11
+
class="p-4 bg-surface group-last:rounded-b group-last:border-b-2 group-last:border-x-2 group-last:border-overlay"
12
+
>
13
+
{ GetPostJSONProperty(post, "content")[index] }
14
+
</figcaption>
15
+
</figure>
16
+
}
17
+
</div>
20
18
}
+8
-10
html/components/posts/photo_templ.go
+8
-10
html/components/posts/photo_templ.go
···
8
8
import "github.com/a-h/templ"
9
9
import templruntime "github.com/a-h/templ/runtime"
10
10
11
-
import (
12
-
"github.com/puregarlic/space/models"
13
-
)
11
+
import "github.com/puregarlic/space/models"
14
12
15
13
func Photo(post *models.Post) templ.Component {
16
14
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
···
30
28
templ_7745c5c3_Var1 = templ.NopComponent
31
29
}
32
30
ctx = templ.ClearChildren(ctx)
33
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"bg-base\">")
31
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1)
34
32
if templ_7745c5c3_Err != nil {
35
33
return templ_7745c5c3_Err
36
34
}
37
35
for index, photo := range GetPostJSONProperty(post, "photo") {
38
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<figure class=\"relative group\"><img class=\"w-full\" src=\"")
36
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2)
39
37
if templ_7745c5c3_Err != nil {
40
38
return templ_7745c5c3_Err
41
39
}
42
40
var templ_7745c5c3_Var2 string
43
41
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(photo)
44
42
if templ_7745c5c3_Err != nil {
45
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/photo.templ`, Line: 11, Col: 35}
43
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/photo.templ`, Line: 9, Col: 106}
46
44
}
47
45
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
48
46
if templ_7745c5c3_Err != nil {
49
47
return templ_7745c5c3_Err
50
48
}
51
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><figcaption class=\"p-4 absolute inset-x-0 bottom-0 opacity-100 group-hover:opacity-0 bg-surface/70 backdrop-blur transition\">")
49
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3)
52
50
if templ_7745c5c3_Err != nil {
53
51
return templ_7745c5c3_Err
54
52
}
55
53
var templ_7745c5c3_Var3 string
56
54
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(GetPostJSONProperty(post, "content")[index])
57
55
if templ_7745c5c3_Err != nil {
58
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/photo.templ`, Line: 15, Col: 52}
56
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/photo.templ`, Line: 13, Col: 50}
59
57
}
60
58
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
61
59
if templ_7745c5c3_Err != nil {
62
60
return templ_7745c5c3_Err
63
61
}
64
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</figcaption></figure>")
62
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 4)
65
63
if templ_7745c5c3_Err != nil {
66
64
return templ_7745c5c3_Err
67
65
}
68
66
}
69
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
67
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 5)
70
68
if templ_7745c5c3_Err != nil {
71
69
return templ_7745c5c3_Err
72
70
}
+66
-50
html/components/posts/post.templ
+66
-50
html/components/posts/post.templ
···
1
1
package posts
2
2
3
3
import (
4
-
"fmt"
5
4
"encoding/json"
6
-
7
-
"github.com/puregarlic/space/models"
5
+
"fmt"
8
6
9
-
"github.com/samber/lo"
7
+
"github.com/puregarlic/space/models"
8
+
"github.com/samber/lo"
10
9
"go.hacdias.com/indielib/microformats"
11
10
)
12
11
13
12
var ImplementedPostTypes = []microformats.Type{
14
-
microformats.TypeNote,
15
-
microformats.TypePhoto,
13
+
microformats.TypeNote,
14
+
microformats.TypePhoto,
16
15
}
17
16
18
17
func GetPostJSONProperty(post *models.Post, name string) []string {
19
-
var tmp map[string]any
20
-
if err := json.Unmarshal(post.Properties, &tmp); err != nil {
21
-
panic(err)
22
-
}
18
+
var tmp map[string]any
19
+
if err := json.Unmarshal(post.Properties, &tmp); err != nil {
20
+
panic(err)
21
+
}
23
22
24
-
prop, ok := tmp[name]
25
-
if !ok {
26
-
return []string{""}
27
-
}
23
+
prop, ok := tmp[name]
24
+
if !ok {
25
+
return []string{""}
26
+
}
28
27
29
-
var out []string
30
-
for _, val := range prop.([]any) {
31
-
out = append(out, val.(string))
32
-
}
28
+
var out []string
29
+
for _, val := range prop.([]any) {
30
+
out = append(out, val.(string))
31
+
}
33
32
34
-
return out
33
+
return out
35
34
}
36
35
37
36
func formatPostTypeName(mfType microformats.Type) string {
38
-
has := lo.ContainsBy(ImplementedPostTypes, func(postType microformats.Type) bool {
39
-
return postType == mfType
40
-
})
37
+
has := lo.ContainsBy(ImplementedPostTypes, func(postType microformats.Type) bool {
38
+
return postType == mfType
39
+
})
41
40
42
-
if has {
43
-
return string(mfType)
44
-
} else {
45
-
return fmt.Sprintf("oops! (%s)", string(mfType))
46
-
}
41
+
if has {
42
+
return string(mfType)
43
+
} else {
44
+
return fmt.Sprintf("%s (oops!)", string(mfType))
45
+
}
47
46
}
48
47
49
48
templ PostFeedHeader(post *models.Post) {
50
-
<div class="px-3 py-2 bg-base text-xs text-subtle/50 group-hover:text-subtle/100 flex justify-between transition">
51
-
<p>{ formatPostTypeName(post.MicroformatType) }</p>
52
-
<a
53
-
class="hover:underline hover:text-iris flex gap-1"
54
-
target="_blank"
55
-
rel="noopener noreferrer"
56
-
href={ templ.URL("/posts/" + post.ID.String()) }
57
-
>
58
-
{ post.CreatedAt.Format("01/02/2006 at 3:04 PM") }
59
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4 -mt-px">
60
-
<path d="M6.22 8.72a.75.75 0 0 0 1.06 1.06l5.22-5.22v1.69a.75.75 0 0 0 1.5 0v-3.5a.75.75 0 0 0-.75-.75h-3.5a.75.75 0 0 0 0 1.5h1.69L6.22 8.72Z" />
61
-
<path d="M3.5 6.75c0-.69.56-1.25 1.25-1.25H7A.75.75 0 0 0 7 4H4.75A2.75 2.75 0 0 0 2 6.75v4.5A2.75 2.75 0 0 0 4.75 14h4.5A2.75 2.75 0 0 0 12 11.25V9a.75.75 0 0 0-1.5 0v2.25c0 .69-.56 1.25-1.25 1.25h-4.5c-.69 0-1.25-.56-1.25-1.25v-4.5Z" />
62
-
</svg>
63
-
</a>
64
-
</div>
49
+
<div class="px-3 py-2 bg-surface text-xs text-muted flex items-center justify-between rounded-t border-2 border-b-0 border-overlay">
50
+
<p>{ post.Timestamp() }</p>
51
+
<p class="flex gap-1.5">
52
+
{ formatPostTypeName(post.MicroformatType) }
53
+
<span class="text-muted/40">•</span>
54
+
<a
55
+
class="hover:underline hover:text-iris flex items-center gap-1 transition"
56
+
target="_blank"
57
+
rel="noopener noreferrer"
58
+
href={ templ.URL("/posts/" + post.ID.String()) }
59
+
>
60
+
open
61
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4 -mt-px">
62
+
<path d="M6.22 8.72a.75.75 0 0 0 1.06 1.06l5.22-5.22v1.69a.75.75 0 0 0 1.5 0v-3.5a.75.75 0 0 0-.75-.75h-3.5a.75.75 0 0 0 0 1.5h1.69L6.22 8.72Z"></path>
63
+
<path d="M3.5 6.75c0-.69.56-1.25 1.25-1.25H7A.75.75 0 0 0 7 4H4.75A2.75 2.75 0 0 0 2 6.75v4.5A2.75 2.75 0 0 0 4.75 14h4.5A2.75 2.75 0 0 0 12 11.25V9a.75.75 0 0 0-1.5 0v2.25c0 .69-.56 1.25-1.25 1.25h-4.5c-.69 0-1.25-.56-1.25-1.25v-4.5Z"></path>
64
+
</svg>
65
+
</a>
66
+
</p>
67
+
</div>
68
+
}
69
+
70
+
templ PostDetails(post *models.Post) {
71
+
<dl class="grid md:grid-cols-2 gap-4">
72
+
<div>
73
+
<dt class="mb-1 text-sm text-muted">Posted At</dt>
74
+
<dd class="text-subtle">{ post.Timestamp() }</dd>
75
+
</div>
76
+
<div>
77
+
<dt class="mb-1 text-sm text-muted">Post Type</dt>
78
+
<dd class="text-subtle">{ string(post.MicroformatType) }</dd>
79
+
</div>
80
+
</dl>
65
81
}
66
82
67
83
templ PostContent(post *models.Post) {
68
-
switch post.MicroformatType {
69
-
case microformats.TypePhoto:
70
-
@Photo(post)
71
-
case microformats.TypeNote:
72
-
@Note(post)
73
-
default:
74
-
@Unsupported(post)
75
-
}
84
+
switch post.MicroformatType {
85
+
case microformats.TypePhoto:
86
+
@Photo(post)
87
+
case microformats.TypeNote:
88
+
@Note(post)
89
+
default:
90
+
@Unsupported(post)
91
+
}
76
92
}
+67
-16
html/components/posts/post_templ.go
+67
-16
html/components/posts/post_templ.go
···
13
13
"fmt"
14
14
15
15
"github.com/puregarlic/space/models"
16
-
17
16
"github.com/samber/lo"
18
17
"go.hacdias.com/indielib/microformats"
19
18
)
···
50
49
if has {
51
50
return string(mfType)
52
51
} else {
53
-
return fmt.Sprintf("oops! (%s)", string(mfType))
52
+
return fmt.Sprintf("%s (oops!)", string(mfType))
54
53
}
55
54
}
56
55
···
72
71
templ_7745c5c3_Var1 = templ.NopComponent
73
72
}
74
73
ctx = templ.ClearChildren(ctx)
75
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"px-3 py-2 bg-base text-xs text-subtle/50 group-hover:text-subtle/100 flex justify-between transition\"><p>")
74
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1)
76
75
if templ_7745c5c3_Err != nil {
77
76
return templ_7745c5c3_Err
78
77
}
79
78
var templ_7745c5c3_Var2 string
80
-
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(formatPostTypeName(post.MicroformatType))
79
+
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(post.Timestamp())
81
80
if templ_7745c5c3_Err != nil {
82
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/post.templ`, Line: 51, Col: 49}
81
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/post.templ`, Line: 50, Col: 23}
83
82
}
84
83
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
85
84
if templ_7745c5c3_Err != nil {
86
85
return templ_7745c5c3_Err
87
86
}
88
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p><a class=\"hover:underline hover:text-iris flex gap-1\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"")
87
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2)
89
88
if templ_7745c5c3_Err != nil {
90
89
return templ_7745c5c3_Err
91
90
}
92
-
var templ_7745c5c3_Var3 templ.SafeURL = templ.URL("/posts/" + post.ID.String())
93
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var3)))
91
+
var templ_7745c5c3_Var3 string
92
+
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(formatPostTypeName(post.MicroformatType))
94
93
if templ_7745c5c3_Err != nil {
95
-
return templ_7745c5c3_Err
94
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/post.templ`, Line: 52, Col: 45}
96
95
}
97
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
96
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
98
97
if templ_7745c5c3_Err != nil {
99
98
return templ_7745c5c3_Err
100
99
}
101
-
var templ_7745c5c3_Var4 string
102
-
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(post.CreatedAt.Format("01/02/2006 at 3:04 PM"))
100
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3)
103
101
if templ_7745c5c3_Err != nil {
104
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/post.templ`, Line: 58, Col: 53}
102
+
return templ_7745c5c3_Err
105
103
}
106
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
104
+
var templ_7745c5c3_Var4 templ.SafeURL = templ.URL("/posts/" + post.ID.String())
105
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4)))
107
106
if templ_7745c5c3_Err != nil {
108
107
return templ_7745c5c3_Err
109
108
}
110
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 -mt-px\"><path d=\"M6.22 8.72a.75.75 0 0 0 1.06 1.06l5.22-5.22v1.69a.75.75 0 0 0 1.5 0v-3.5a.75.75 0 0 0-.75-.75h-3.5a.75.75 0 0 0 0 1.5h1.69L6.22 8.72Z\"></path> <path d=\"M3.5 6.75c0-.69.56-1.25 1.25-1.25H7A.75.75 0 0 0 7 4H4.75A2.75 2.75 0 0 0 2 6.75v4.5A2.75 2.75 0 0 0 4.75 14h4.5A2.75 2.75 0 0 0 12 11.25V9a.75.75 0 0 0-1.5 0v2.25c0 .69-.56 1.25-1.25 1.25h-4.5c-.69 0-1.25-.56-1.25-1.25v-4.5Z\"></path></svg></a></div>")
109
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 4)
111
110
if templ_7745c5c3_Err != nil {
112
111
return templ_7745c5c3_Err
113
112
}
···
115
114
})
116
115
}
117
116
118
-
func PostContent(post *models.Post) templ.Component {
117
+
func PostDetails(post *models.Post) templ.Component {
119
118
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
120
119
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
121
120
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
···
131
130
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
132
131
if templ_7745c5c3_Var5 == nil {
133
132
templ_7745c5c3_Var5 = templ.NopComponent
133
+
}
134
+
ctx = templ.ClearChildren(ctx)
135
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 5)
136
+
if templ_7745c5c3_Err != nil {
137
+
return templ_7745c5c3_Err
138
+
}
139
+
var templ_7745c5c3_Var6 string
140
+
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(post.Timestamp())
141
+
if templ_7745c5c3_Err != nil {
142
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/post.templ`, Line: 74, Col: 45}
143
+
}
144
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
145
+
if templ_7745c5c3_Err != nil {
146
+
return templ_7745c5c3_Err
147
+
}
148
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 6)
149
+
if templ_7745c5c3_Err != nil {
150
+
return templ_7745c5c3_Err
151
+
}
152
+
var templ_7745c5c3_Var7 string
153
+
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(string(post.MicroformatType))
154
+
if templ_7745c5c3_Err != nil {
155
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/post.templ`, Line: 78, Col: 57}
156
+
}
157
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
158
+
if templ_7745c5c3_Err != nil {
159
+
return templ_7745c5c3_Err
160
+
}
161
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 7)
162
+
if templ_7745c5c3_Err != nil {
163
+
return templ_7745c5c3_Err
164
+
}
165
+
return templ_7745c5c3_Err
166
+
})
167
+
}
168
+
169
+
func PostContent(post *models.Post) templ.Component {
170
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
171
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
172
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
173
+
if !templ_7745c5c3_IsBuffer {
174
+
defer func() {
175
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
176
+
if templ_7745c5c3_Err == nil {
177
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
178
+
}
179
+
}()
180
+
}
181
+
ctx = templ.InitializeContext(ctx)
182
+
templ_7745c5c3_Var8 := templ.GetChildren(ctx)
183
+
if templ_7745c5c3_Var8 == nil {
184
+
templ_7745c5c3_Var8 = templ.NopComponent
134
185
}
135
186
ctx = templ.ClearChildren(ctx)
136
187
switch post.MicroformatType {
+29
-30
html/components/posts/unsupported.templ
+29
-30
html/components/posts/unsupported.templ
···
1
1
package posts
2
2
3
3
import (
4
-
"bytes"
5
-
"encoding/json"
4
+
"bytes"
5
+
"encoding/json"
6
6
7
-
"github.com/puregarlic/space/models"
8
-
9
-
"github.com/alecthomas/chroma/v2/formatters/html"
10
-
"github.com/alecthomas/chroma/v2/styles"
11
-
"github.com/alecthomas/chroma/v2/lexers"
7
+
"github.com/alecthomas/chroma/v2/formatters/html"
8
+
"github.com/alecthomas/chroma/v2/lexers"
9
+
"github.com/alecthomas/chroma/v2/styles"
10
+
"github.com/puregarlic/space/models"
12
11
)
13
12
14
13
var style = styles.Get("rose-pine")
···
18
17
var dedupeSyntaxStyles = templ.NewOnceHandle()
19
18
20
19
func renderPostAsJSON(post *models.Post) string {
21
-
contents, err := json.MarshalIndent(post.Properties, "", " ")
22
-
if err != nil {
23
-
panic(err)
24
-
}
20
+
contents, err := json.MarshalIndent(post.Properties, "", " ")
21
+
if err != nil {
22
+
panic(err)
23
+
}
25
24
26
-
iterator, err := lexer.Tokenise(nil, string(contents))
25
+
iterator, err := lexer.Tokenise(nil, string(contents))
27
26
28
-
var buf bytes.Buffer
29
-
formatter.Format(&buf, style, iterator)
27
+
var buf bytes.Buffer
28
+
formatter.Format(&buf, style, iterator)
30
29
31
-
return buf.String()
30
+
return buf.String()
32
31
}
33
32
34
33
func generateSyntaxClassNames() string {
35
-
var buf bytes.Buffer
36
-
if err := formatter.WriteCSS(&buf, style); err != nil {
37
-
panic(err)
38
-
}
39
-
40
-
return "<style>"+buf.String()+"</style>"
34
+
var buf bytes.Buffer
35
+
if err := formatter.WriteCSS(&buf, style); err != nil {
36
+
panic(err)
37
+
}
38
+
39
+
return "<style>" + buf.String() + "</style>"
41
40
}
42
41
43
42
templ syntaxStyleTag() {
44
-
@templ.Raw(generateSyntaxClassNames())
43
+
@templ.Raw(generateSyntaxClassNames())
45
44
}
46
45
47
46
templ Unsupported(post *models.Post) {
48
-
<div
49
-
class="block p-4 bg-base overflow-x-scroll min-w-0"
50
-
>
51
-
@dedupeSyntaxStyles.Once() {
52
-
@syntaxStyleTag()
53
-
}
54
-
@templ.Raw(renderPostAsJSON(post))
55
-
</div>
47
+
<div
48
+
class="block p-4 bg-base overflow-x-scroll min-w-0 first:rounded-t last:rounded-b border-2 border-overlay"
49
+
>
50
+
@dedupeSyntaxStyles.Once() {
51
+
@syntaxStyleTag()
52
+
}
53
+
@templ.Raw(renderPostAsJSON(post))
54
+
</div>
56
55
}
+3
-4
html/components/posts/unsupported_templ.go
+3
-4
html/components/posts/unsupported_templ.go
···
12
12
"bytes"
13
13
"encoding/json"
14
14
15
-
"github.com/puregarlic/space/models"
16
-
17
15
"github.com/alecthomas/chroma/v2/formatters/html"
18
16
"github.com/alecthomas/chroma/v2/lexers"
19
17
"github.com/alecthomas/chroma/v2/styles"
18
+
"github.com/puregarlic/space/models"
20
19
)
21
20
22
21
var style = styles.Get("rose-pine")
···
92
91
templ_7745c5c3_Var2 = templ.NopComponent
93
92
}
94
93
ctx = templ.ClearChildren(ctx)
95
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"block p-4 bg-base overflow-x-scroll min-w-0\">")
94
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1)
96
95
if templ_7745c5c3_Err != nil {
97
96
return templ_7745c5c3_Err
98
97
}
···
122
121
if templ_7745c5c3_Err != nil {
123
122
return templ_7745c5c3_Err
124
123
}
125
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
124
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2)
126
125
if templ_7745c5c3_Err != nil {
127
126
return templ_7745c5c3_Err
128
127
}
+14
-29
html/layouts/default.templ
+14
-29
html/layouts/default.templ
···
1
1
package layouts
2
2
3
-
import "net/http"
4
-
import "github.com/puregarlic/space/storage"
3
+
import (
4
+
"github.com/puregarlic/space/html/components"
5
+
"net/http"
6
+
)
5
7
6
8
func RenderDefault(title string, page templ.Component) http.Handler {
7
-
rels := storage.GetRels()
8
-
document := Default(title, page, rels)
9
+
document := Default(title, page)
9
10
10
-
return templ.Handler(document)
11
+
return templ.Handler(document)
11
12
}
12
13
13
-
templ Default(title string, body templ.Component, rels []*storage.RelEntry) {
14
-
<!DOCTYPE html>
15
-
<html>
16
-
<head>
17
-
if len(title) > 0 {
18
-
<title>{title} | puregarlic dot space</title>
19
-
} else {
20
-
<title>puregarlic dot space</title>
21
-
}
22
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
23
-
<link rel="preconnect" href="https://fonts.googleapis.com" />
24
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
25
-
<link href="https://fonts.googleapis.com/css2?family=Recursive:slnt,wght,CASL,CRSV,MONO@-15..0,300..1000,0..1,0..1,0..1&display=swap" rel="stylesheet">
26
-
27
-
for _, rel := range rels {
28
-
<link rel={ rel.Name } href={ rel.HREF } />
29
-
}
30
-
31
-
<link rel="stylesheet" href="/static/styles.css" />
32
-
</head>
33
-
<body class="text-text bg-base">
34
-
@body
35
-
</body>
36
-
</html>
14
+
templ Default(title string, body templ.Component) {
15
+
<!DOCTYPE html>
16
+
<html>
17
+
@components.Head(title)
18
+
<body class="px-4 py-12 md:py-20 text-text bg-base">
19
+
@body
20
+
</body>
21
+
</html>
37
22
}
+10
-65
html/layouts/default_templ.go
+10
-65
html/layouts/default_templ.go
···
8
8
import "github.com/a-h/templ"
9
9
import templruntime "github.com/a-h/templ/runtime"
10
10
11
-
import "net/http"
12
-
import "github.com/puregarlic/space/storage"
11
+
import (
12
+
"github.com/puregarlic/space/html/components"
13
+
"net/http"
14
+
)
13
15
14
16
func RenderDefault(title string, page templ.Component) http.Handler {
15
-
rels := storage.GetRels()
16
-
document := Default(title, page, rels)
17
+
document := Default(title, page)
17
18
18
19
return templ.Handler(document)
19
20
}
20
21
21
-
func Default(title string, body templ.Component, rels []*storage.RelEntry) templ.Component {
22
+
func Default(title string, body templ.Component) templ.Component {
22
23
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
23
24
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
24
25
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
···
36
37
templ_7745c5c3_Var1 = templ.NopComponent
37
38
}
38
39
ctx = templ.ClearChildren(ctx)
39
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype html><html><head>")
40
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1)
40
41
if templ_7745c5c3_Err != nil {
41
42
return templ_7745c5c3_Err
42
43
}
43
-
if len(title) > 0 {
44
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<title>")
45
-
if templ_7745c5c3_Err != nil {
46
-
return templ_7745c5c3_Err
47
-
}
48
-
var templ_7745c5c3_Var2 string
49
-
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title)
50
-
if templ_7745c5c3_Err != nil {
51
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/layouts/default.templ`, Line: 18, Col: 21}
52
-
}
53
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
54
-
if templ_7745c5c3_Err != nil {
55
-
return templ_7745c5c3_Err
56
-
}
57
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" | puregarlic dot space</title>")
58
-
if templ_7745c5c3_Err != nil {
59
-
return templ_7745c5c3_Err
60
-
}
61
-
} else {
62
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<title>puregarlic dot space</title>")
63
-
if templ_7745c5c3_Err != nil {
64
-
return templ_7745c5c3_Err
65
-
}
66
-
}
67
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><link rel=\"preconnect\" href=\"https://fonts.googleapis.com\"><link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin><link href=\"https://fonts.googleapis.com/css2?family=Recursive:slnt,wght,CASL,CRSV,MONO@-15..0,300..1000,0..1,0..1,0..1&display=swap\" rel=\"stylesheet\">")
44
+
templ_7745c5c3_Err = components.Head(title).Render(ctx, templ_7745c5c3_Buffer)
68
45
if templ_7745c5c3_Err != nil {
69
46
return templ_7745c5c3_Err
70
47
}
71
-
for _, rel := range rels {
72
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link rel=\"")
73
-
if templ_7745c5c3_Err != nil {
74
-
return templ_7745c5c3_Err
75
-
}
76
-
var templ_7745c5c3_Var3 string
77
-
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(rel.Name)
78
-
if templ_7745c5c3_Err != nil {
79
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/layouts/default.templ`, Line: 28, Col: 28}
80
-
}
81
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
82
-
if templ_7745c5c3_Err != nil {
83
-
return templ_7745c5c3_Err
84
-
}
85
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" href=\"")
86
-
if templ_7745c5c3_Err != nil {
87
-
return templ_7745c5c3_Err
88
-
}
89
-
var templ_7745c5c3_Var4 string
90
-
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(rel.HREF)
91
-
if templ_7745c5c3_Err != nil {
92
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/layouts/default.templ`, Line: 28, Col: 46}
93
-
}
94
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
95
-
if templ_7745c5c3_Err != nil {
96
-
return templ_7745c5c3_Err
97
-
}
98
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
99
-
if templ_7745c5c3_Err != nil {
100
-
return templ_7745c5c3_Err
101
-
}
102
-
}
103
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link rel=\"stylesheet\" href=\"/static/styles.css\"></head><body class=\"text-text bg-base\">")
48
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2)
104
49
if templ_7745c5c3_Err != nil {
105
50
return templ_7745c5c3_Err
106
51
}
···
108
53
if templ_7745c5c3_Err != nil {
109
54
return templ_7745c5c3_Err
110
55
}
111
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</body></html>")
56
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3)
112
57
if templ_7745c5c3_Err != nil {
113
58
return templ_7745c5c3_Err
114
59
}
+57
-66
html/pages/auth.templ
+57
-66
html/pages/auth.templ
···
1
1
package pages
2
2
3
3
import (
4
-
"strings"
5
-
"go.hacdias.com/indielib/indieauth"
4
+
"go.hacdias.com/indielib/indieauth"
5
+
"strings"
6
6
)
7
7
8
-
templ Auth( req *indieauth.AuthenticationRequest, app *indieauth.ApplicationMetadata, nonceId string, nonce string ) {
9
-
<div class="px-4 py-12 md:py-20 mx-auto max-w-screen-sm">
10
-
<p class="text-sm font-thin italic">authorize access to</p>
11
-
<h1 class="mb-8 text-3xl font-extrabold">puregarlic dot space</h1>
12
-
13
-
<div class="pt-6 border border-highlightMed rounded bg-surface">
14
-
if app != nil {
15
-
<div class="px-6 flex gap-6 items-center">
16
-
if len(app.Logo) > 0 {
17
-
<img class="max-w-12" src={ app.Logo } />
18
-
}
19
-
20
-
<div>
21
-
<h2 class="font-bold text-lg">{ app.Name }</h2>
22
-
23
-
if len(app.Author) > 0 {
24
-
<p class="text-sm font-light">by {app.Author}</p>
25
-
}
26
-
</div>
27
-
</div>
28
-
} else {
29
-
<h2 class="px-6 font-bold text-subtle">unidentified client</h2>
30
-
}
31
-
32
-
<div class="mt-6 grid md:grid-cols-[max-content_1fr] *:border-highlightMed">
33
-
<h3 class="px-6 pt-4 pb-2 md:py-4 border-t bg-overlay md:border-r text-subtle font-bold">Client ID</h3>
34
-
<p class="px-6 pb-4 pt-1 md:py-4 md:border-t bg-overlay min-w-0 overflow-x-scroll">{ req.ClientID }</p>
35
-
36
-
<h3 class="px-6 pt-4 pb-2 md:py-4 border-t md:border-b md:border-r text-subtle font-bold">Redirect URL</h3>
37
-
<p class="px-6 pb-4 pt-1 md:py-4 md:border-y min-w-0 overflow-x-scroll">{ req.RedirectURI}</p>
38
-
39
-
<h3 class="px-6 pt-4 pb-2 md:py-4 border-t bg-overlay md:border-r text-subtle font-bold">Scopes</h3>
40
-
<ul class="px-6 pb-4 pt-1 md:py-4 bg-overlay flex flex-wrap gap-3">
41
-
for _, scope := range req.Scopes {
42
-
<li class="px-2 py-1 text-sm bg-pine rounded">{ scope }</li>
43
-
}
44
-
</ul>
45
-
</div>
46
-
</div>
47
-
48
-
<form method='post' action='/authorization/accept'>
49
-
<input type="hidden" name="response_type" value="code"/>
50
-
<input type="hidden" name="scope" value={ strings.Join(req.Scopes, " ") }/>
51
-
<input type="hidden" name="redirect_uri" value={ req.RedirectURI }/>
52
-
<input type="hidden" name="client_id" value={ req.ClientID }/>
53
-
<input type="hidden" name="state" value={ req.State }/>
54
-
<input type="hidden" name="code_challenge" value={ req.CodeChallenge }/>
55
-
<input type="hidden" name="code_challenge_method" value={ req.CodeChallengeMethod }/>
56
-
57
-
// CSRF protections
58
-
<input type="hidden" name="nonce_id" value={ nonceId }/>
59
-
<input type="hidden" name="nonce" value={ nonce }/>
60
-
61
-
<button
62
-
class="mt-8 px-3 py-2 flex items-center justify-center gap-2 bg-surface border border-highlightMed text-sm font-bold transition rounded hover:bg-foam hover:text-surface"
63
-
id="submit"
64
-
>
65
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4">
66
-
<path fill-rule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14Zm3.844-8.791a.75.75 0 0 0-1.188-.918l-3.7 4.79-1.649-1.833a.75.75 0 1 0-1.114 1.004l2.25 2.5a.75.75 0 0 0 1.15-.043l4.25-5.5Z" clip-rule="evenodd" />
67
-
</svg>
68
-
Authorize
69
-
</button>
70
-
</form>
71
-
</div>
8
+
templ Auth(req *indieauth.AuthenticationRequest, app *indieauth.ApplicationMetadata, nonceId string, nonce string) {
9
+
<main class="mx-auto max-w-screen-sm">
10
+
<p class="text-sm font-thin italic">authorize access to</p>
11
+
<h1 class="mb-8 text-3xl font-extrabold">puregarlic dot space</h1>
12
+
<div class="pt-6 border border-highlightMed rounded bg-surface">
13
+
if app != nil {
14
+
<div class="px-6 flex gap-6 items-center">
15
+
if len(app.Logo) > 0 {
16
+
<img class="max-w-12" src={ app.Logo }/>
17
+
}
18
+
<div>
19
+
<h2 class="font-bold text-lg">{ app.Name }</h2>
20
+
if len(app.Author) > 0 {
21
+
<p class="text-sm font-light">by { app.Author }</p>
22
+
}
23
+
</div>
24
+
</div>
25
+
} else {
26
+
<h2 class="px-6 font-bold text-subtle">unidentified client</h2>
27
+
}
28
+
<div class="mt-6 grid md:grid-cols-[max-content_1fr] *:border-highlightMed">
29
+
<h3 class="px-6 pt-4 pb-2 md:py-4 border-t bg-overlay md:border-r text-subtle font-bold">Client ID</h3>
30
+
<p class="px-6 pb-4 pt-1 md:py-4 md:border-t bg-overlay min-w-0 overflow-x-scroll">{ req.ClientID }</p>
31
+
<h3 class="px-6 pt-4 pb-2 md:py-4 border-t md:border-b md:border-r text-subtle font-bold">Redirect URL</h3>
32
+
<p class="px-6 pb-4 pt-1 md:py-4 md:border-y min-w-0 overflow-x-scroll">{ req.RedirectURI }</p>
33
+
<h3 class="px-6 pt-4 pb-2 md:py-4 border-t bg-overlay md:border-r text-subtle font-bold">Scopes</h3>
34
+
<ul class="px-6 pb-4 pt-1 md:py-4 bg-overlay flex flex-wrap gap-3">
35
+
for _, scope := range req.Scopes {
36
+
<li class="px-2 py-1 text-sm bg-pine rounded">{ scope }</li>
37
+
}
38
+
</ul>
39
+
</div>
40
+
</div>
41
+
<form method="post" action="/authorization/accept">
42
+
<input type="hidden" name="response_type" value="code"/>
43
+
<input type="hidden" name="scope" value={ strings.Join(req.Scopes, " ") }/>
44
+
<input type="hidden" name="redirect_uri" value={ req.RedirectURI }/>
45
+
<input type="hidden" name="client_id" value={ req.ClientID }/>
46
+
<input type="hidden" name="state" value={ req.State }/>
47
+
<input type="hidden" name="code_challenge" value={ req.CodeChallenge }/>
48
+
<input type="hidden" name="code_challenge_method" value={ req.CodeChallengeMethod }/>
49
+
// CSRF protections
50
+
<input type="hidden" name="nonce_id" value={ nonceId }/>
51
+
<input type="hidden" name="nonce" value={ nonce }/>
52
+
<button
53
+
class="mt-8 px-3 py-2 flex items-center justify-center gap-2 bg-surface border border-highlightMed text-sm font-bold transition rounded hover:bg-foam hover:text-surface"
54
+
id="submit"
55
+
>
56
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4">
57
+
<path fill-rule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14Zm3.844-8.791a.75.75 0 0 0-1.188-.918l-3.7 4.79-1.649-1.833a.75.75 0 1 0-1.114 1.004l2.25 2.5a.75.75 0 0 0 1.15-.043l4.25-5.5Z" clip-rule="evenodd"></path>
58
+
</svg>
59
+
Authorize
60
+
</button>
61
+
</form>
62
+
</main>
72
63
}
+38
-38
html/pages/auth_templ.go
+38
-38
html/pages/auth_templ.go
···
31
31
templ_7745c5c3_Var1 = templ.NopComponent
32
32
}
33
33
ctx = templ.ClearChildren(ctx)
34
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"px-4 py-12 md:py-20 mx-auto max-w-screen-sm\"><p class=\"text-sm font-thin italic\">authorize access to</p><h1 class=\"mb-8 text-3xl font-extrabold\">puregarlic dot space</h1><div class=\"pt-6 border border-highlightMed rounded bg-surface\">")
34
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1)
35
35
if templ_7745c5c3_Err != nil {
36
36
return templ_7745c5c3_Err
37
37
}
38
38
if app != nil {
39
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"px-6 flex gap-6 items-center\">")
39
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2)
40
40
if templ_7745c5c3_Err != nil {
41
41
return templ_7745c5c3_Err
42
42
}
43
43
if len(app.Logo) > 0 {
44
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<img class=\"max-w-12\" src=\"")
44
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3)
45
45
if templ_7745c5c3_Err != nil {
46
46
return templ_7745c5c3_Err
47
47
}
48
48
var templ_7745c5c3_Var2 string
49
49
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(app.Logo)
50
50
if templ_7745c5c3_Err != nil {
51
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 17, Col: 46}
51
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 16, Col: 42}
52
52
}
53
53
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
54
54
if templ_7745c5c3_Err != nil {
55
55
return templ_7745c5c3_Err
56
56
}
57
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
57
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 4)
58
58
if templ_7745c5c3_Err != nil {
59
59
return templ_7745c5c3_Err
60
60
}
61
61
}
62
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div><h2 class=\"font-bold text-lg\">")
62
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 5)
63
63
if templ_7745c5c3_Err != nil {
64
64
return templ_7745c5c3_Err
65
65
}
66
66
var templ_7745c5c3_Var3 string
67
67
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(app.Name)
68
68
if templ_7745c5c3_Err != nil {
69
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 21, Col: 49}
69
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 19, Col: 46}
70
70
}
71
71
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
72
72
if templ_7745c5c3_Err != nil {
73
73
return templ_7745c5c3_Err
74
74
}
75
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h2>")
75
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 6)
76
76
if templ_7745c5c3_Err != nil {
77
77
return templ_7745c5c3_Err
78
78
}
79
79
if len(app.Author) > 0 {
80
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-sm font-light\">by ")
80
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 7)
81
81
if templ_7745c5c3_Err != nil {
82
82
return templ_7745c5c3_Err
83
83
}
84
84
var templ_7745c5c3_Var4 string
85
85
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(app.Author)
86
86
if templ_7745c5c3_Err != nil {
87
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 24, Col: 56}
87
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 21, Col: 52}
88
88
}
89
89
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
90
90
if templ_7745c5c3_Err != nil {
91
91
return templ_7745c5c3_Err
92
92
}
93
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
93
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 8)
94
94
if templ_7745c5c3_Err != nil {
95
95
return templ_7745c5c3_Err
96
96
}
97
97
}
98
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div>")
98
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 9)
99
99
if templ_7745c5c3_Err != nil {
100
100
return templ_7745c5c3_Err
101
101
}
102
102
} else {
103
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<h2 class=\"px-6 font-bold text-subtle\">unidentified client</h2>")
103
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 10)
104
104
if templ_7745c5c3_Err != nil {
105
105
return templ_7745c5c3_Err
106
106
}
107
107
}
108
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"mt-6 grid md:grid-cols-[max-content_1fr] *:border-highlightMed\"><h3 class=\"px-6 pt-4 pb-2 md:py-4 border-t bg-overlay md:border-r text-subtle font-bold\">Client ID</h3><p class=\"px-6 pb-4 pt-1 md:py-4 md:border-t bg-overlay min-w-0 overflow-x-scroll\">")
108
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 11)
109
109
if templ_7745c5c3_Err != nil {
110
110
return templ_7745c5c3_Err
111
111
}
112
112
var templ_7745c5c3_Var5 string
113
113
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(req.ClientID)
114
114
if templ_7745c5c3_Err != nil {
115
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 34, Col: 103}
115
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 30, Col: 101}
116
116
}
117
117
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
118
118
if templ_7745c5c3_Err != nil {
119
119
return templ_7745c5c3_Err
120
120
}
121
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p><h3 class=\"px-6 pt-4 pb-2 md:py-4 border-t md:border-b md:border-r text-subtle font-bold\">Redirect URL</h3><p class=\"px-6 pb-4 pt-1 md:py-4 md:border-y min-w-0 overflow-x-scroll\">")
121
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 12)
122
122
if templ_7745c5c3_Err != nil {
123
123
return templ_7745c5c3_Err
124
124
}
125
125
var templ_7745c5c3_Var6 string
126
126
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(req.RedirectURI)
127
127
if templ_7745c5c3_Err != nil {
128
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 37, Col: 95}
128
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 32, Col: 93}
129
129
}
130
130
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
131
131
if templ_7745c5c3_Err != nil {
132
132
return templ_7745c5c3_Err
133
133
}
134
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p><h3 class=\"px-6 pt-4 pb-2 md:py-4 border-t bg-overlay md:border-r text-subtle font-bold\">Scopes</h3><ul class=\"px-6 pb-4 pt-1 md:py-4 bg-overlay flex flex-wrap gap-3\">")
134
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 13)
135
135
if templ_7745c5c3_Err != nil {
136
136
return templ_7745c5c3_Err
137
137
}
138
138
for _, scope := range req.Scopes {
139
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"px-2 py-1 text-sm bg-pine rounded\">")
139
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 14)
140
140
if templ_7745c5c3_Err != nil {
141
141
return templ_7745c5c3_Err
142
142
}
143
143
var templ_7745c5c3_Var7 string
144
144
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(scope)
145
145
if templ_7745c5c3_Err != nil {
146
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 42, Col: 63}
146
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 36, Col: 59}
147
147
}
148
148
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
149
149
if templ_7745c5c3_Err != nil {
150
150
return templ_7745c5c3_Err
151
151
}
152
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</li>")
152
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 15)
153
153
if templ_7745c5c3_Err != nil {
154
154
return templ_7745c5c3_Err
155
155
}
156
156
}
157
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</ul></div></div><form method=\"post\" action=\"/authorization/accept\"><input type=\"hidden\" name=\"response_type\" value=\"code\"> <input type=\"hidden\" name=\"scope\" value=\"")
157
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 16)
158
158
if templ_7745c5c3_Err != nil {
159
159
return templ_7745c5c3_Err
160
160
}
161
161
var templ_7745c5c3_Var8 string
162
162
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(strings.Join(req.Scopes, " "))
163
163
if templ_7745c5c3_Err != nil {
164
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 50, Col: 75}
164
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 43, Col: 74}
165
165
}
166
166
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
167
167
if templ_7745c5c3_Err != nil {
168
168
return templ_7745c5c3_Err
169
169
}
170
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"> <input type=\"hidden\" name=\"redirect_uri\" value=\"")
170
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 17)
171
171
if templ_7745c5c3_Err != nil {
172
172
return templ_7745c5c3_Err
173
173
}
174
174
var templ_7745c5c3_Var9 string
175
175
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(req.RedirectURI)
176
176
if templ_7745c5c3_Err != nil {
177
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 51, Col: 68}
177
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 44, Col: 67}
178
178
}
179
179
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
180
180
if templ_7745c5c3_Err != nil {
181
181
return templ_7745c5c3_Err
182
182
}
183
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"> <input type=\"hidden\" name=\"client_id\" value=\"")
183
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 18)
184
184
if templ_7745c5c3_Err != nil {
185
185
return templ_7745c5c3_Err
186
186
}
187
187
var templ_7745c5c3_Var10 string
188
188
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(req.ClientID)
189
189
if templ_7745c5c3_Err != nil {
190
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 52, Col: 62}
190
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 45, Col: 61}
191
191
}
192
192
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
193
193
if templ_7745c5c3_Err != nil {
194
194
return templ_7745c5c3_Err
195
195
}
196
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"> <input type=\"hidden\" name=\"state\" value=\"")
196
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 19)
197
197
if templ_7745c5c3_Err != nil {
198
198
return templ_7745c5c3_Err
199
199
}
200
200
var templ_7745c5c3_Var11 string
201
201
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(req.State)
202
202
if templ_7745c5c3_Err != nil {
203
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 53, Col: 55}
203
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 46, Col: 54}
204
204
}
205
205
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
206
206
if templ_7745c5c3_Err != nil {
207
207
return templ_7745c5c3_Err
208
208
}
209
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"> <input type=\"hidden\" name=\"code_challenge\" value=\"")
209
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 20)
210
210
if templ_7745c5c3_Err != nil {
211
211
return templ_7745c5c3_Err
212
212
}
213
213
var templ_7745c5c3_Var12 string
214
214
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(req.CodeChallenge)
215
215
if templ_7745c5c3_Err != nil {
216
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 54, Col: 72}
216
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 47, Col: 71}
217
217
}
218
218
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
219
219
if templ_7745c5c3_Err != nil {
220
220
return templ_7745c5c3_Err
221
221
}
222
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"> <input type=\"hidden\" name=\"code_challenge_method\" value=\"")
222
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 21)
223
223
if templ_7745c5c3_Err != nil {
224
224
return templ_7745c5c3_Err
225
225
}
226
226
var templ_7745c5c3_Var13 string
227
227
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(req.CodeChallengeMethod)
228
228
if templ_7745c5c3_Err != nil {
229
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 55, Col: 85}
229
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 48, Col: 84}
230
230
}
231
231
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
232
232
if templ_7745c5c3_Err != nil {
233
233
return templ_7745c5c3_Err
234
234
}
235
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><input type=\"hidden\" name=\"nonce_id\" value=\"")
235
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 22)
236
236
if templ_7745c5c3_Err != nil {
237
237
return templ_7745c5c3_Err
238
238
}
239
239
var templ_7745c5c3_Var14 string
240
240
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(nonceId)
241
241
if templ_7745c5c3_Err != nil {
242
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 58, Col: 56}
242
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 50, Col: 55}
243
243
}
244
244
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
245
245
if templ_7745c5c3_Err != nil {
246
246
return templ_7745c5c3_Err
247
247
}
248
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"> <input type=\"hidden\" name=\"nonce\" value=\"")
248
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 23)
249
249
if templ_7745c5c3_Err != nil {
250
250
return templ_7745c5c3_Err
251
251
}
252
252
var templ_7745c5c3_Var15 string
253
253
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(nonce)
254
254
if templ_7745c5c3_Err != nil {
255
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 59, Col: 51}
255
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/auth.templ`, Line: 51, Col: 50}
256
256
}
257
257
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
258
258
if templ_7745c5c3_Err != nil {
259
259
return templ_7745c5c3_Err
260
260
}
261
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"> <button class=\"mt-8 px-3 py-2 flex items-center justify-center gap-2 bg-surface border border-highlightMed text-sm font-bold transition rounded hover:bg-foam hover:text-surface\" id=\"submit\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4\"><path fill-rule=\"evenodd\" d=\"M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14Zm3.844-8.791a.75.75 0 0 0-1.188-.918l-3.7 4.79-1.649-1.833a.75.75 0 1 0-1.114 1.004l2.25 2.5a.75.75 0 0 0 1.15-.043l4.25-5.5Z\" clip-rule=\"evenodd\"></path></svg> Authorize</button></form></div>")
261
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 24)
262
262
if templ_7745c5c3_Err != nil {
263
263
return templ_7745c5c3_Err
264
264
}
+16
-30
html/pages/home.templ
+16
-30
html/pages/home.templ
···
1
1
package pages
2
2
3
3
import (
4
-
"github.com/puregarlic/space/models"
5
-
p "github.com/puregarlic/space/html/components/posts"
4
+
p "github.com/puregarlic/space/html/components/posts"
5
+
"github.com/puregarlic/space/models"
6
6
)
7
7
8
8
templ Home(posts []*models.Post) {
9
-
<div class="px-4 py-12 md:py-20 md:mx-auto md:max-w-screen-lg grid md:grid-cols-[1fr_2fr] gap-12 md:gap-16">
10
-
<aside class="min-w-0">
11
-
<div class="w-full md:sticky md:top-8">
12
-
<h1 class="font-extrabold text-xl">puregarlic dot space</h1>
13
-
<p class="font-light mt-3 text-subtle italic md:text-sm">
14
-
this space is mine, it was <a class="underline hover:text-iris" href="https://github.com/puregarlic/space">made by me</a>!
15
-
</p>
16
-
</div>
17
-
</aside>
18
-
<main class="min-w-0">
19
-
<ul class="flex flex-col gap-6 md:gap-12">
20
-
if len(posts) > 0 {
21
-
for _, post := range posts {
22
-
<li class="flex flex-col divide-y-2 divide-highlightLow group border-2 border-highlightLow">
23
-
@p.PostContent(post)
24
-
@p.PostFeedHeader(post)
25
-
</li>
26
-
}
27
-
} else {
28
-
<li class="text-muted bg-surface px-4 py-8 text-center border border-highlightLow">
29
-
intention-rich, content-poor
30
-
</li>
31
-
}
32
-
</ul>
33
-
</main>
34
-
</div>
35
-
9
+
<ul class="flex flex-col gap-6">
10
+
if len(posts) > 0 {
11
+
for _, post := range posts {
12
+
<li class="flex flex-col">
13
+
@p.PostFeedHeader(post)
14
+
@p.PostContent(post)
15
+
</li>
16
+
}
17
+
} else {
18
+
<li class="text-muted bg-surface px-4 py-8 text-center border border-overlay">
19
+
intention-rich, content-poor
20
+
</li>
21
+
}
22
+
</ul>
36
23
}
37
-
+7
-7
html/pages/home_templ.go
+7
-7
html/pages/home_templ.go
···
31
31
templ_7745c5c3_Var1 = templ.NopComponent
32
32
}
33
33
ctx = templ.ClearChildren(ctx)
34
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"px-4 py-12 md:py-20 md:mx-auto md:max-w-screen-lg grid md:grid-cols-[1fr_2fr] gap-12 md:gap-16\"><aside class=\"min-w-0\"><div class=\"w-full md:sticky md:top-8\"><h1 class=\"font-extrabold text-xl\">puregarlic dot space</h1><p class=\"font-light mt-3 text-subtle italic md:text-sm\">this space is mine, it was <a class=\"underline hover:text-iris\" href=\"https://github.com/puregarlic/space\">made by me</a>!</p></div></aside><main class=\"min-w-0\"><ul class=\"flex flex-col gap-6 md:gap-12\">")
34
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1)
35
35
if templ_7745c5c3_Err != nil {
36
36
return templ_7745c5c3_Err
37
37
}
38
38
if len(posts) > 0 {
39
39
for _, post := range posts {
40
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"flex flex-col divide-y-2 divide-highlightLow group border-2 border-highlightLow\">")
40
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2)
41
41
if templ_7745c5c3_Err != nil {
42
42
return templ_7745c5c3_Err
43
43
}
44
-
templ_7745c5c3_Err = p.PostContent(post).Render(ctx, templ_7745c5c3_Buffer)
44
+
templ_7745c5c3_Err = p.PostFeedHeader(post).Render(ctx, templ_7745c5c3_Buffer)
45
45
if templ_7745c5c3_Err != nil {
46
46
return templ_7745c5c3_Err
47
47
}
48
-
templ_7745c5c3_Err = p.PostFeedHeader(post).Render(ctx, templ_7745c5c3_Buffer)
48
+
templ_7745c5c3_Err = p.PostContent(post).Render(ctx, templ_7745c5c3_Buffer)
49
49
if templ_7745c5c3_Err != nil {
50
50
return templ_7745c5c3_Err
51
51
}
52
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</li>")
52
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3)
53
53
if templ_7745c5c3_Err != nil {
54
54
return templ_7745c5c3_Err
55
55
}
56
56
}
57
57
} else {
58
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"text-muted bg-surface px-4 py-8 text-center border border-highlightLow\">intention-rich, content-poor</li>")
58
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 4)
59
59
if templ_7745c5c3_Err != nil {
60
60
return templ_7745c5c3_Err
61
61
}
62
62
}
63
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</ul></main></div>")
63
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 5)
64
64
if templ_7745c5c3_Err != nil {
65
65
return templ_7745c5c3_Err
66
66
}
+22
-56
html/pages/post.templ
+22
-56
html/pages/post.templ
···
1
1
package pages
2
2
3
-
import "github.com/puregarlic/space/models"
4
-
import "fmt"
5
-
import "encoding/json"
6
-
import "reflect"
7
-
8
-
func printProperty(post *models.Post, name string) string {
9
-
props := make(map[string]any)
10
-
if err := json.Unmarshal(post.Properties, &props); err != nil {
11
-
panic(err)
12
-
}
13
-
14
-
if val, ok := props[name]; ok {
15
-
tp := reflect.TypeOf(val)
16
-
switch tp.Kind() {
17
-
default:
18
-
return fmt.Sprint(val)
19
-
case reflect.Slice:
20
-
str := ""
21
-
for _, v := range val.([]any) {
22
-
str = str + fmt.Sprint(v)
23
-
}
24
-
25
-
return str
26
-
}
27
-
28
-
}
29
-
30
-
return "<no name provided>"
31
-
}
32
-
33
-
func printPost(post *models.Post) string {
34
-
out, err := json.Marshal(post)
35
-
36
-
if (err != nil) {
37
-
panic (err)
38
-
}
39
-
40
-
return fmt.Sprint(string(out))
41
-
}
3
+
import (
4
+
"github.com/puregarlic/space/html/components/posts"
5
+
"github.com/puregarlic/space/models"
6
+
)
42
7
43
8
templ Post(post *models.Post) {
44
-
<!DOCTYPE html>
45
-
<html>
46
-
<head>
47
-
<title>Post | Micropub and IndieAuth Server Demo</title>
48
-
</head>
49
-
<body>
50
-
<div class={ post.Type }>
51
-
<h1 class="p-name">{ printProperty(post, "name") }</h1>
52
-
<p class="p-content">{ printProperty(post, "content") }</p>
53
-
54
-
<h3>Stored Microformats</h3>
55
-
<code>
56
-
<pre>{ printPost(post) }</pre>
57
-
</code>
58
-
</div>
59
-
</body>
60
-
</html>
9
+
<div class="flex flex-col gap-8">
10
+
<a href="/" class="text-sm text-muted flex items-center gap-1">
11
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4">
12
+
<path fill-rule="evenodd" d="M14 8a.75.75 0 0 1-.75.75H4.56l1.22 1.22a.75.75 0 1 1-1.06 1.06l-2.5-2.5a.75.75 0 0 1 0-1.06l2.5-2.5a.75.75 0 0 1 1.06 1.06L4.56 7.25h8.69A.75.75 0 0 1 14 8Z" clip-rule="evenodd"></path>
13
+
</svg>
14
+
back to home
15
+
</a>
16
+
<div>
17
+
@posts.PostContent(post)
18
+
</div>
19
+
@posts.PostDetails(post)
20
+
<div class="py-12 flex flex-col gap-1 items-center text-muted text-xs font-light">
21
+
interactions not implemented yet
22
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4">
23
+
<path fill-rule="evenodd" d="M15 8A7 7 0 1 1 1 8a7 7 0 0 1 14 0ZM6 8c.552 0 1-.672 1-1.5S6.552 5 6 5s-1 .672-1 1.5S5.448 8 6 8Zm5-1.5c0 .828-.448 1.5-1 1.5s-1-.672-1-1.5S9.448 5 10 5s1 .672 1 1.5Zm-6.005 5.805a.75.75 0 0 0 1.06 0 2.75 2.75 0 0 1 3.89 0 .75.75 0 0 0 1.06-1.06 4.25 4.25 0 0 0-6.01 0 .75.75 0 0 0 0 1.06Z" clip-rule="evenodd"></path>
24
+
</svg>
25
+
</div>
26
+
</div>
61
27
}
+9
-89
html/pages/post_templ.go
+9
-89
html/pages/post_templ.go
···
8
8
import "github.com/a-h/templ"
9
9
import templruntime "github.com/a-h/templ/runtime"
10
10
11
-
import "github.com/puregarlic/space/models"
12
-
import "fmt"
13
-
import "encoding/json"
14
-
import "reflect"
15
-
16
-
func printProperty(post *models.Post, name string) string {
17
-
props := make(map[string]any)
18
-
if err := json.Unmarshal(post.Properties, &props); err != nil {
19
-
panic(err)
20
-
}
21
-
22
-
if val, ok := props[name]; ok {
23
-
tp := reflect.TypeOf(val)
24
-
switch tp.Kind() {
25
-
default:
26
-
return fmt.Sprint(val)
27
-
case reflect.Slice:
28
-
str := ""
29
-
for _, v := range val.([]any) {
30
-
str = str + fmt.Sprint(v)
31
-
}
32
-
33
-
return str
34
-
}
35
-
36
-
}
37
-
38
-
return "<no name provided>"
39
-
}
40
-
41
-
func printPost(post *models.Post) string {
42
-
out, err := json.Marshal(post)
43
-
44
-
if err != nil {
45
-
panic(err)
46
-
}
47
-
48
-
return fmt.Sprint(string(out))
49
-
}
11
+
import (
12
+
"github.com/puregarlic/space/html/components/posts"
13
+
"github.com/puregarlic/space/models"
14
+
)
50
15
51
16
func Post(post *models.Post) templ.Component {
52
17
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
···
66
31
templ_7745c5c3_Var1 = templ.NopComponent
67
32
}
68
33
ctx = templ.ClearChildren(ctx)
69
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype html><html><head><title>Post | Micropub and IndieAuth Server Demo</title></head><body>")
70
-
if templ_7745c5c3_Err != nil {
71
-
return templ_7745c5c3_Err
72
-
}
73
-
var templ_7745c5c3_Var2 = []any{post.Type}
74
-
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
34
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1)
75
35
if templ_7745c5c3_Err != nil {
76
36
return templ_7745c5c3_Err
77
37
}
78
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
38
+
templ_7745c5c3_Err = posts.PostContent(post).Render(ctx, templ_7745c5c3_Buffer)
79
39
if templ_7745c5c3_Err != nil {
80
40
return templ_7745c5c3_Err
81
41
}
82
-
var templ_7745c5c3_Var3 string
83
-
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
84
-
if templ_7745c5c3_Err != nil {
85
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/post.templ`, Line: 1, Col: 0}
86
-
}
87
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
42
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2)
88
43
if templ_7745c5c3_Err != nil {
89
44
return templ_7745c5c3_Err
90
45
}
91
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><h1 class=\"p-name\">")
46
+
templ_7745c5c3_Err = posts.PostDetails(post).Render(ctx, templ_7745c5c3_Buffer)
92
47
if templ_7745c5c3_Err != nil {
93
48
return templ_7745c5c3_Err
94
49
}
95
-
var templ_7745c5c3_Var4 string
96
-
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(printProperty(post, "name"))
97
-
if templ_7745c5c3_Err != nil {
98
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/post.templ`, Line: 51, Col: 56}
99
-
}
100
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
101
-
if templ_7745c5c3_Err != nil {
102
-
return templ_7745c5c3_Err
103
-
}
104
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h1><p class=\"p-content\">")
105
-
if templ_7745c5c3_Err != nil {
106
-
return templ_7745c5c3_Err
107
-
}
108
-
var templ_7745c5c3_Var5 string
109
-
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(printProperty(post, "content"))
110
-
if templ_7745c5c3_Err != nil {
111
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/post.templ`, Line: 52, Col: 61}
112
-
}
113
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
114
-
if templ_7745c5c3_Err != nil {
115
-
return templ_7745c5c3_Err
116
-
}
117
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p><h3>Stored Microformats</h3><code><pre>")
118
-
if templ_7745c5c3_Err != nil {
119
-
return templ_7745c5c3_Err
120
-
}
121
-
var templ_7745c5c3_Var6 string
122
-
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(printPost(post))
123
-
if templ_7745c5c3_Err != nil {
124
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/post.templ`, Line: 56, Col: 32}
125
-
}
126
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
127
-
if templ_7745c5c3_Err != nil {
128
-
return templ_7745c5c3_Err
129
-
}
130
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</pre></code></div></body></html>")
50
+
templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3)
131
51
if templ_7745c5c3_Err != nil {
132
52
return templ_7745c5c3_Err
133
53
}