An experimental IndieWeb site built in Go.

add note, photo, and default unsupported formatting components

+604 -97
+11
html/components/posts/note.templ
··· 1 + package posts 2 + 3 + import ( 4 + "github.com/puregarlic/space/models" 5 + ) 6 + 7 + templ Note(post *models.Post) { 8 + <div class="bg-surface p-4"> 9 + {GetPostJSONProperty(post, "content")[0]} 10 + </div> 11 + }
+52
html/components/posts/note_templ.go
··· 1 + // Code generated by templ - DO NOT EDIT. 2 + 3 + // templ: version: v0.2.747 4 + package posts 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 ( 12 + "github.com/puregarlic/space/models" 13 + ) 14 + 15 + func Note(post *models.Post) templ.Component { 16 + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 17 + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context 18 + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) 19 + if !templ_7745c5c3_IsBuffer { 20 + defer func() { 21 + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) 22 + if templ_7745c5c3_Err == nil { 23 + templ_7745c5c3_Err = templ_7745c5c3_BufErr 24 + } 25 + }() 26 + } 27 + ctx = templ.InitializeContext(ctx) 28 + templ_7745c5c3_Var1 := templ.GetChildren(ctx) 29 + if templ_7745c5c3_Var1 == nil { 30 + templ_7745c5c3_Var1 = templ.NopComponent 31 + } 32 + ctx = templ.ClearChildren(ctx) 33 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"bg-surface p-4\">") 34 + if templ_7745c5c3_Err != nil { 35 + return templ_7745c5c3_Err 36 + } 37 + var templ_7745c5c3_Var2 string 38 + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(GetPostJSONProperty(post, "content")[0]) 39 + if templ_7745c5c3_Err != nil { 40 + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/note.templ`, Line: 9, Col: 43} 41 + } 42 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) 43 + if templ_7745c5c3_Err != nil { 44 + return templ_7745c5c3_Err 45 + } 46 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>") 47 + if templ_7745c5c3_Err != nil { 48 + return templ_7745c5c3_Err 49 + } 50 + return templ_7745c5c3_Err 51 + }) 52 + }
+20
html/components/posts/photo.templ
··· 1 + package posts 2 + 3 + import ( 4 + "github.com/puregarlic/space/models" 5 + ) 6 + 7 + 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> 20 + }
+75
html/components/posts/photo_templ.go
··· 1 + // Code generated by templ - DO NOT EDIT. 2 + 3 + // templ: version: v0.2.747 4 + package posts 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 ( 12 + "github.com/puregarlic/space/models" 13 + ) 14 + 15 + func Photo(post *models.Post) templ.Component { 16 + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 17 + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context 18 + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) 19 + if !templ_7745c5c3_IsBuffer { 20 + defer func() { 21 + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) 22 + if templ_7745c5c3_Err == nil { 23 + templ_7745c5c3_Err = templ_7745c5c3_BufErr 24 + } 25 + }() 26 + } 27 + ctx = templ.InitializeContext(ctx) 28 + templ_7745c5c3_Var1 := templ.GetChildren(ctx) 29 + if templ_7745c5c3_Var1 == nil { 30 + templ_7745c5c3_Var1 = templ.NopComponent 31 + } 32 + ctx = templ.ClearChildren(ctx) 33 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"bg-base\">") 34 + if templ_7745c5c3_Err != nil { 35 + return templ_7745c5c3_Err 36 + } 37 + for index, photo := range GetPostJSONProperty(post, "photo") { 38 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<figure class=\"relative group\"><img class=\"w-full\" src=\"") 39 + if templ_7745c5c3_Err != nil { 40 + return templ_7745c5c3_Err 41 + } 42 + var templ_7745c5c3_Var2 string 43 + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(photo) 44 + if templ_7745c5c3_Err != nil { 45 + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/photo.templ`, Line: 11, Col: 35} 46 + } 47 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) 48 + if templ_7745c5c3_Err != nil { 49 + return templ_7745c5c3_Err 50 + } 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\">") 52 + if templ_7745c5c3_Err != nil { 53 + return templ_7745c5c3_Err 54 + } 55 + var templ_7745c5c3_Var3 string 56 + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(GetPostJSONProperty(post, "content")[index]) 57 + if templ_7745c5c3_Err != nil { 58 + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/photo.templ`, Line: 15, Col: 52} 59 + } 60 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) 61 + if templ_7745c5c3_Err != nil { 62 + return templ_7745c5c3_Err 63 + } 64 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</figcaption></figure>") 65 + if templ_7745c5c3_Err != nil { 66 + return templ_7745c5c3_Err 67 + } 68 + } 69 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>") 70 + if templ_7745c5c3_Err != nil { 71 + return templ_7745c5c3_Err 72 + } 73 + return templ_7745c5c3_Err 74 + }) 75 + }
+76
html/components/posts/post.templ
··· 1 + package posts 2 + 3 + import ( 4 + "fmt" 5 + "encoding/json" 6 + 7 + "github.com/puregarlic/space/models" 8 + 9 + "github.com/samber/lo" 10 + "go.hacdias.com/indielib/microformats" 11 + ) 12 + 13 + var ImplementedPostTypes = []microformats.Type{ 14 + microformats.TypeNote, 15 + microformats.TypePhoto, 16 + } 17 + 18 + 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 + } 23 + 24 + prop, ok := tmp[name] 25 + if !ok { 26 + return []string{""} 27 + } 28 + 29 + var out []string 30 + for _, val := range prop.([]any) { 31 + out = append(out, val.(string)) 32 + } 33 + 34 + return out 35 + } 36 + 37 + func formatPostTypeName(mfType microformats.Type) string { 38 + has := lo.ContainsBy(ImplementedPostTypes, func(postType microformats.Type) bool { 39 + return postType == mfType 40 + }) 41 + 42 + if has { 43 + return string(mfType) 44 + } else { 45 + return fmt.Sprintf("oops! (%s)", string(mfType)) 46 + } 47 + } 48 + 49 + 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> 65 + } 66 + 67 + 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 + } 76 + }
+155
html/components/posts/post_templ.go
··· 1 + // Code generated by templ - DO NOT EDIT. 2 + 3 + // templ: version: v0.2.747 4 + package posts 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 ( 12 + "encoding/json" 13 + "fmt" 14 + 15 + "github.com/puregarlic/space/models" 16 + 17 + "github.com/samber/lo" 18 + "go.hacdias.com/indielib/microformats" 19 + ) 20 + 21 + var ImplementedPostTypes = []microformats.Type{ 22 + microformats.TypeNote, 23 + microformats.TypePhoto, 24 + } 25 + 26 + func GetPostJSONProperty(post *models.Post, name string) []string { 27 + var tmp map[string]any 28 + if err := json.Unmarshal(post.Properties, &tmp); err != nil { 29 + panic(err) 30 + } 31 + 32 + prop, ok := tmp[name] 33 + if !ok { 34 + return []string{""} 35 + } 36 + 37 + var out []string 38 + for _, val := range prop.([]any) { 39 + out = append(out, val.(string)) 40 + } 41 + 42 + return out 43 + } 44 + 45 + func formatPostTypeName(mfType microformats.Type) string { 46 + has := lo.ContainsBy(ImplementedPostTypes, func(postType microformats.Type) bool { 47 + return postType == mfType 48 + }) 49 + 50 + if has { 51 + return string(mfType) 52 + } else { 53 + return fmt.Sprintf("oops! (%s)", string(mfType)) 54 + } 55 + } 56 + 57 + func PostFeedHeader(post *models.Post) templ.Component { 58 + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 59 + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context 60 + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) 61 + if !templ_7745c5c3_IsBuffer { 62 + defer func() { 63 + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) 64 + if templ_7745c5c3_Err == nil { 65 + templ_7745c5c3_Err = templ_7745c5c3_BufErr 66 + } 67 + }() 68 + } 69 + ctx = templ.InitializeContext(ctx) 70 + templ_7745c5c3_Var1 := templ.GetChildren(ctx) 71 + if templ_7745c5c3_Var1 == nil { 72 + templ_7745c5c3_Var1 = templ.NopComponent 73 + } 74 + 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>") 76 + if templ_7745c5c3_Err != nil { 77 + return templ_7745c5c3_Err 78 + } 79 + var templ_7745c5c3_Var2 string 80 + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(formatPostTypeName(post.MicroformatType)) 81 + if templ_7745c5c3_Err != nil { 82 + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/post.templ`, Line: 51, Col: 49} 83 + } 84 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) 85 + if templ_7745c5c3_Err != nil { 86 + return templ_7745c5c3_Err 87 + } 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=\"") 89 + if templ_7745c5c3_Err != nil { 90 + return templ_7745c5c3_Err 91 + } 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))) 94 + if templ_7745c5c3_Err != nil { 95 + return templ_7745c5c3_Err 96 + } 97 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">") 98 + if templ_7745c5c3_Err != nil { 99 + return templ_7745c5c3_Err 100 + } 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")) 103 + if templ_7745c5c3_Err != nil { 104 + return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/components/posts/post.templ`, Line: 58, Col: 53} 105 + } 106 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) 107 + if templ_7745c5c3_Err != nil { 108 + return templ_7745c5c3_Err 109 + } 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>") 111 + if templ_7745c5c3_Err != nil { 112 + return templ_7745c5c3_Err 113 + } 114 + return templ_7745c5c3_Err 115 + }) 116 + } 117 + 118 + func PostContent(post *models.Post) templ.Component { 119 + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 120 + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context 121 + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) 122 + if !templ_7745c5c3_IsBuffer { 123 + defer func() { 124 + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) 125 + if templ_7745c5c3_Err == nil { 126 + templ_7745c5c3_Err = templ_7745c5c3_BufErr 127 + } 128 + }() 129 + } 130 + ctx = templ.InitializeContext(ctx) 131 + templ_7745c5c3_Var5 := templ.GetChildren(ctx) 132 + if templ_7745c5c3_Var5 == nil { 133 + templ_7745c5c3_Var5 = templ.NopComponent 134 + } 135 + ctx = templ.ClearChildren(ctx) 136 + switch post.MicroformatType { 137 + case microformats.TypePhoto: 138 + templ_7745c5c3_Err = Photo(post).Render(ctx, templ_7745c5c3_Buffer) 139 + if templ_7745c5c3_Err != nil { 140 + return templ_7745c5c3_Err 141 + } 142 + case microformats.TypeNote: 143 + templ_7745c5c3_Err = Note(post).Render(ctx, templ_7745c5c3_Buffer) 144 + if templ_7745c5c3_Err != nil { 145 + return templ_7745c5c3_Err 146 + } 147 + default: 148 + templ_7745c5c3_Err = Unsupported(post).Render(ctx, templ_7745c5c3_Buffer) 149 + if templ_7745c5c3_Err != nil { 150 + return templ_7745c5c3_Err 151 + } 152 + } 153 + return templ_7745c5c3_Err 154 + }) 155 + }
+56
html/components/posts/unsupported.templ
··· 1 + package posts 2 + 3 + import ( 4 + "bytes" 5 + "encoding/json" 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" 12 + ) 13 + 14 + var style = styles.Get("rose-pine") 15 + var lexer = lexers.Get("json") 16 + var formatter = html.New(html.TabWidth(2), html.WithClasses(true)) 17 + 18 + var dedupeSyntaxStyles = templ.NewOnceHandle() 19 + 20 + func renderPostAsJSON(post *models.Post) string { 21 + contents, err := json.MarshalIndent(post.Properties, "", " ") 22 + if err != nil { 23 + panic(err) 24 + } 25 + 26 + iterator, err := lexer.Tokenise(nil, string(contents)) 27 + 28 + var buf bytes.Buffer 29 + formatter.Format(&buf, style, iterator) 30 + 31 + return buf.String() 32 + } 33 + 34 + 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>" 41 + } 42 + 43 + templ syntaxStyleTag() { 44 + @templ.Raw(generateSyntaxClassNames()) 45 + } 46 + 47 + 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> 56 + }
+131
html/components/posts/unsupported_templ.go
··· 1 + // Code generated by templ - DO NOT EDIT. 2 + 3 + // templ: version: v0.2.747 4 + package posts 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 ( 12 + "bytes" 13 + "encoding/json" 14 + 15 + "github.com/puregarlic/space/models" 16 + 17 + "github.com/alecthomas/chroma/v2/formatters/html" 18 + "github.com/alecthomas/chroma/v2/lexers" 19 + "github.com/alecthomas/chroma/v2/styles" 20 + ) 21 + 22 + var style = styles.Get("rose-pine") 23 + var lexer = lexers.Get("json") 24 + var formatter = html.New(html.TabWidth(2), html.WithClasses(true)) 25 + 26 + var dedupeSyntaxStyles = templ.NewOnceHandle() 27 + 28 + func renderPostAsJSON(post *models.Post) string { 29 + contents, err := json.MarshalIndent(post.Properties, "", " ") 30 + if err != nil { 31 + panic(err) 32 + } 33 + 34 + iterator, err := lexer.Tokenise(nil, string(contents)) 35 + 36 + var buf bytes.Buffer 37 + formatter.Format(&buf, style, iterator) 38 + 39 + return buf.String() 40 + } 41 + 42 + func generateSyntaxClassNames() string { 43 + var buf bytes.Buffer 44 + if err := formatter.WriteCSS(&buf, style); err != nil { 45 + panic(err) 46 + } 47 + 48 + return "<style>" + buf.String() + "</style>" 49 + } 50 + 51 + func syntaxStyleTag() templ.Component { 52 + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 53 + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context 54 + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) 55 + if !templ_7745c5c3_IsBuffer { 56 + defer func() { 57 + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) 58 + if templ_7745c5c3_Err == nil { 59 + templ_7745c5c3_Err = templ_7745c5c3_BufErr 60 + } 61 + }() 62 + } 63 + ctx = templ.InitializeContext(ctx) 64 + templ_7745c5c3_Var1 := templ.GetChildren(ctx) 65 + if templ_7745c5c3_Var1 == nil { 66 + templ_7745c5c3_Var1 = templ.NopComponent 67 + } 68 + ctx = templ.ClearChildren(ctx) 69 + templ_7745c5c3_Err = templ.Raw(generateSyntaxClassNames()).Render(ctx, templ_7745c5c3_Buffer) 70 + if templ_7745c5c3_Err != nil { 71 + return templ_7745c5c3_Err 72 + } 73 + return templ_7745c5c3_Err 74 + }) 75 + } 76 + 77 + func Unsupported(post *models.Post) templ.Component { 78 + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 79 + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context 80 + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) 81 + if !templ_7745c5c3_IsBuffer { 82 + defer func() { 83 + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) 84 + if templ_7745c5c3_Err == nil { 85 + templ_7745c5c3_Err = templ_7745c5c3_BufErr 86 + } 87 + }() 88 + } 89 + ctx = templ.InitializeContext(ctx) 90 + templ_7745c5c3_Var2 := templ.GetChildren(ctx) 91 + if templ_7745c5c3_Var2 == nil { 92 + templ_7745c5c3_Var2 = templ.NopComponent 93 + } 94 + 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\">") 96 + if templ_7745c5c3_Err != nil { 97 + return templ_7745c5c3_Err 98 + } 99 + templ_7745c5c3_Var3 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 100 + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context 101 + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) 102 + if !templ_7745c5c3_IsBuffer { 103 + defer func() { 104 + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) 105 + if templ_7745c5c3_Err == nil { 106 + templ_7745c5c3_Err = templ_7745c5c3_BufErr 107 + } 108 + }() 109 + } 110 + ctx = templ.InitializeContext(ctx) 111 + templ_7745c5c3_Err = syntaxStyleTag().Render(ctx, templ_7745c5c3_Buffer) 112 + if templ_7745c5c3_Err != nil { 113 + return templ_7745c5c3_Err 114 + } 115 + return templ_7745c5c3_Err 116 + }) 117 + templ_7745c5c3_Err = dedupeSyntaxStyles.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer) 118 + if templ_7745c5c3_Err != nil { 119 + return templ_7745c5c3_Err 120 + } 121 + templ_7745c5c3_Err = templ.Raw(renderPostAsJSON(post)).Render(ctx, templ_7745c5c3_Buffer) 122 + if templ_7745c5c3_Err != nil { 123 + return templ_7745c5c3_Err 124 + } 125 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>") 126 + if templ_7745c5c3_Err != nil { 127 + return templ_7745c5c3_Err 128 + } 129 + return templ_7745c5c3_Err 130 + }) 131 + }
+1 -1
html/layouts/default.templ
··· 26 26 27 27 <link rel="stylesheet" href="/static/styles.css" /> 28 28 </head> 29 - <body class="text-text bg-surface"> 29 + <body class="text-text bg-base"> 30 30 @body 31 31 </body> 32 32 </html>
+1 -1
html/layouts/default_templ.go
··· 72 72 return templ_7745c5c3_Err 73 73 } 74 74 } 75 - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link rel=\"stylesheet\" href=\"/static/styles.css\"></head><body class=\"text-text bg-surface\">") 75 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link rel=\"stylesheet\" href=\"/static/styles.css\"></head><body class=\"text-text bg-base\">") 76 76 if templ_7745c5c3_Err != nil { 77 77 return templ_7745c5c3_Err 78 78 }
+19 -45
html/pages/home.templ
··· 1 1 package pages 2 2 3 3 import ( 4 - "encoding/json" 5 - "bytes" 6 - 7 4 "github.com/puregarlic/space/models" 8 - "github.com/alecthomas/chroma/v2/formatters/html" 9 - "github.com/alecthomas/chroma/v2/styles" 10 - "github.com/alecthomas/chroma/v2/lexers" 5 + p "github.com/puregarlic/space/html/components/posts" 11 6 ) 12 7 13 - func formatUnknownPost(post *models.Post) string { 14 - style := styles.Get("rose-pine") 15 - lexer := lexers.Get("json") 16 - formatter := html.New( 17 - html.TabWidth(2), 18 - ) 19 - 20 - contents, err := json.MarshalIndent(post.Properties, "", " ") 21 - if err != nil { 22 - panic(err) 23 - } 24 - 25 - iterator, err := lexer.Tokenise(nil, string(contents)) 26 - 27 - var buf bytes.Buffer 28 - formatter.Format(&buf, style, iterator) 29 - 30 - return buf.String() 31 - } 32 - 33 8 templ Home(posts []*models.Post) { 34 - <div class="px-4 py-8 md:py-20 md:mx-auto md:max-w-screen-lg grid md:grid-cols-[1fr_2fr] gap-12 md:gap-16"> 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"> 35 10 <aside class="min-w-0"> 36 - <h1 class="font-extrabold">puregarlic dot space</h1> 37 - <p class="font-light mt-3 text-sm text-subtle">this space is mine, it was <a class="underline" href="https://github.com/puregarlic/space">made by me</a>!</p> 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> 38 17 </aside> 39 18 <main class="min-w-0"> 40 - <ul class="flex flex-col gap-6"> 41 - if len(posts) > 0 { 42 - for _, post := range posts { 43 - <li> 44 - <div class="mb-1 flex items-center justify-between text-muted text-xs"> 45 - <p>{ post.CreatedAt.Format("01/02/2006 at 3:04 PM") }</p> 46 - <p>oops, unimplemented!</p> 47 - </div> 48 - <a href={ templ.URL("/posts/" + post.ID.String()) } class="block p-4 bg-base overflow-x-scroll min-w-0"> 49 - @templ.Raw(formatUnknownPost(post)) 50 - </a> 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 51 30 </li> 52 31 } 53 - } else { 54 - <li class="text-highlightLow italic font-light bg-base p-4 text-center"> 55 - intention rich, content poor 56 - </li> 57 - } 58 32 </ul> 59 33 </main> 60 34 </div>
+7 -50
html/pages/home_templ.go
··· 9 9 import templruntime "github.com/a-h/templ/runtime" 10 10 11 11 import ( 12 - "bytes" 13 - "encoding/json" 14 - 15 - "github.com/alecthomas/chroma/v2/formatters/html" 16 - "github.com/alecthomas/chroma/v2/lexers" 17 - "github.com/alecthomas/chroma/v2/styles" 12 + p "github.com/puregarlic/space/html/components/posts" 18 13 "github.com/puregarlic/space/models" 19 14 ) 20 15 21 - func formatUnknownPost(post *models.Post) string { 22 - style := styles.Get("rose-pine") 23 - lexer := lexers.Get("json") 24 - formatter := html.New( 25 - html.TabWidth(2), 26 - ) 27 - 28 - contents, err := json.MarshalIndent(post.Properties, "", " ") 29 - if err != nil { 30 - panic(err) 31 - } 32 - 33 - iterator, err := lexer.Tokenise(nil, string(contents)) 34 - 35 - var buf bytes.Buffer 36 - formatter.Format(&buf, style, iterator) 37 - 38 - return buf.String() 39 - } 40 - 41 16 func Home(posts []*models.Post) templ.Component { 42 17 return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 43 18 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context ··· 56 31 templ_7745c5c3_Var1 = templ.NopComponent 57 32 } 58 33 ctx = templ.ClearChildren(ctx) 59 - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"px-4 py-8 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\"><h1 class=\"font-extrabold\">puregarlic dot space</h1><p class=\"font-light mt-3 text-sm text-subtle\">this space is mine, it was <a class=\"underline\" href=\"https://github.com/puregarlic/space\">made by me</a>!</p></aside><main class=\"min-w-0\"><ul class=\"flex flex-col gap-6\">") 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\">") 60 35 if templ_7745c5c3_Err != nil { 61 36 return templ_7745c5c3_Err 62 37 } 63 38 if len(posts) > 0 { 64 39 for _, post := range posts { 65 - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li><div class=\"mb-1 flex items-center justify-between text-muted text-xs\"><p>") 66 - if templ_7745c5c3_Err != nil { 67 - return templ_7745c5c3_Err 68 - } 69 - var templ_7745c5c3_Var2 string 70 - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(post.CreatedAt.Format("01/02/2006 at 3:04 PM")) 71 - if templ_7745c5c3_Err != nil { 72 - return templ.Error{Err: templ_7745c5c3_Err, FileName: `html/pages/home.templ`, Line: 45, Col: 64} 73 - } 74 - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) 75 - if templ_7745c5c3_Err != nil { 76 - return templ_7745c5c3_Err 77 - } 78 - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p><p>oops, unimplemented!</p></div><a href=\"") 40 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"flex flex-col divide-y-2 divide-highlightLow group border-2 border-highlightLow\">") 79 41 if templ_7745c5c3_Err != nil { 80 42 return templ_7745c5c3_Err 81 43 } 82 - var templ_7745c5c3_Var3 templ.SafeURL = templ.URL("/posts/" + post.ID.String()) 83 - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var3))) 84 - if templ_7745c5c3_Err != nil { 85 - return templ_7745c5c3_Err 86 - } 87 - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"block p-4 bg-base overflow-x-scroll min-w-0\">") 44 + templ_7745c5c3_Err = p.PostContent(post).Render(ctx, templ_7745c5c3_Buffer) 88 45 if templ_7745c5c3_Err != nil { 89 46 return templ_7745c5c3_Err 90 47 } 91 - templ_7745c5c3_Err = templ.Raw(formatUnknownPost(post)).Render(ctx, templ_7745c5c3_Buffer) 48 + templ_7745c5c3_Err = p.PostFeedHeader(post).Render(ctx, templ_7745c5c3_Buffer) 92 49 if templ_7745c5c3_Err != nil { 93 50 return templ_7745c5c3_Err 94 51 } 95 - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></li>") 52 + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</li>") 96 53 if templ_7745c5c3_Err != nil { 97 54 return templ_7745c5c3_Err 98 55 } 99 56 } 100 57 } else { 101 - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"text-highlightLow italic font-light bg-base p-4 text-center\">intention rich, content poor</li>") 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>") 102 59 if templ_7745c5c3_Err != nil { 103 60 return templ_7745c5c3_Err 104 61 }