diff --git a/controller/blog.go b/controller/blog.go index 3e367d5..5b309b2 100644 --- a/controller/blog.go +++ b/controller/blog.go @@ -26,6 +26,7 @@ func GetBlogPost(db *sqlx.DB, id string) (*model.BlogPost, error) { if strings.Contains(err.Error(), "no rows") { return nil, nil } return nil, err } + defer rows.Close() blueskyActor := sql.NullString{} blueskyRecord := sql.NullString{} @@ -84,6 +85,7 @@ func GetBlogPosts(db *sqlx.DB, onlyVisible bool, limit int, offset int) ([]*mode if err != nil { return nil, err } + defer rows.Close() for rows.Next() { blog := model.BlogPost{} diff --git a/controller/bluesky.go b/controller/bluesky.go index bb8ac90..754de4f 100644 --- a/controller/bluesky.go +++ b/controller/bluesky.go @@ -11,7 +11,7 @@ import ( const BSKY_API_BASE = "https://public.api.bsky.app" -func FetchThreadViewPost(actorID string, recordID string) (*model.ThreadViewPost, error) { +func FetchThreadViewPost(app *model.AppState, actorID string, recordID string) (*model.ThreadViewPost, error) { uri := fmt.Sprintf("at://%s/app.bsky.feed.post/%s", actorID, recordID) req, err := http.NewRequest( @@ -24,7 +24,7 @@ func FetchThreadViewPost(actorID string, recordID string) (*model.ThreadViewPost req.URL.RawQuery = url.Values{ "uri": { uri }, }.Encode() - req.Header.Set("User-Agent", "ari melody [https://arimelody.me]") + req.Header.Set("User-Agent", fmt.Sprintf("ari melody [%s]", app.Config.BaseUrl)) req.Header.Set("Accept", "application/json") client := &http.Client{} diff --git a/controller/release.go b/controller/release.go index ab25db4..ebaa5f4 100644 --- a/controller/release.go +++ b/controller/release.go @@ -339,6 +339,7 @@ func GetReleaseCredits(db *sqlx.DB, releaseID string) ([]*model.Credit, error) { if err != nil { return nil, err } + defer rows.Close() var credits []*model.Credit for rows.Next() { diff --git a/model/blog.go b/model/blog.go index 512d5e5..802e25b 100644 --- a/model/blog.go +++ b/model/blog.go @@ -51,7 +51,11 @@ func (b *BlogPost) GetMonth() string { } func (b *BlogPost) PrintDate() string { - return b.PublishDate.Format("2 January 2006, 15:04") + return b.PublishDate.Format("02 January 2006, 15:04") +} + +func (b *BlogPost) PrintShortDate() string { + return b.PublishDate.Format("2 Jan 2006") } func (b *BlogPost) TextPublishDate() string { diff --git a/public/style/blogpost.css b/public/style/blogpost.css index 24569ce..0be0739 100644 --- a/public/style/blogpost.css +++ b/public/style/blogpost.css @@ -6,7 +6,7 @@ } main { - width: min(calc(100% - 4rem), 1200px); + width: min(calc(100% - 4rem), 800px); margin: 0 auto 1rem auto; } @@ -70,24 +70,26 @@ main { margin: 0; } -article#blog p:hover, +#blog p:hover, .comment p:hover { background: inherit; } -article#blog { +#blog { font-size: 22px; } -article#blog h1 { +#blog h1 { margin-bottom: 0; font-size: 1.8em; } +#blog h2::before { content: "## " } +#blog h3::before { content: "### " } .blog-author { margin: .2em 0; } -article#blog .blog-author img { +#blog .blog-author img { width: 1.3em; height: 1.3em; display: inline-block; @@ -104,11 +106,11 @@ article#blog .blog-author img { opacity: .75; } -article#blog { +#blog { font-family: 'Lora', serif; } -article#blog header { +#blog header { position: relative; width: auto; font-family: 'Monaspace Argon', monospace; @@ -117,20 +119,20 @@ article#blog header { z-index: 0; } -article#blog p { - line-height: 1.5em; +#blog p { + line-height: 1.25em; } -article#blog p.no-content { +#blog p.no-content { font-style: italic; opacity: .66; } -article#blog sub { +#blog sub { opacity: .75; } -article#blog pre { +#blog pre { max-height: 15em; padding: .5em; font-size: .9em; @@ -140,7 +142,7 @@ article#blog pre { background: var(--background-alt); } -article#blog p code { +#blog p code { padding: .2em .3em; font-size: .9em; border: 1px solid #8884; @@ -148,20 +150,30 @@ article#blog p code { background: var(--background-alt); } -article#blog blockquote { +#blog blockquote { margin: 1em 0; padding: 0 0 0 1em; border-left: .2em solid #8888; } -article#blog img { +#blog img { max-height: 50%; max-width: 100%; display: block; } -article#blog i.end-mark { +#blog figure { + margin: 1em 0; + padding: 0 1em; +} + +#blog figure.quote { + border-left: 4px solid color-mix(in srgb, var(--on-background), transparent 75%); + color: color-mix(in srgb, var(--on-background), transparent 25%); +} + +#blog i.end-mark { width: 1.2em; height: 1.2em; margin-top: -.2em; @@ -236,7 +248,7 @@ article#blog i.end-mark { } .comment-callout { - margin: 0 0 0 1em; + margin: 0 0 0 .5em; } .comment-callout:hover { background: none; diff --git a/templates/html/blog.html b/templates/html/blog.html index c6a2579..fca9913 100644 --- a/templates/html/blog.html +++ b/templates/html/blog.html @@ -34,7 +34,7 @@
{{.Description}}
diff --git a/templates/html/blogpost.html b/templates/html/blogpost.html index a4adad6..9e7a7ac 100644 --- a/templates/html/blogpost.html +++ b/templates/html/blogpost.html @@ -85,7 +85,7 @@posted {{.PrintDate}}
+Published {{.PrintDate}}
join the conversation on diff --git a/view/blog.go b/view/blog.go index 1679572..80929f5 100644 --- a/view/blog.go +++ b/view/blog.go @@ -141,11 +141,17 @@ func ServeBlogPost(app *model.AppState, blogPostID string) http.Handler { var blueskyURL string var blueskyPost *model.ThreadViewPost if blog.Bluesky != nil { - blueskyPost, err = controller.FetchThreadViewPost(blog.Bluesky.ActorDID, blog.Bluesky.RecordID) + blueskyPost, err = controller.FetchThreadViewPost(app, blog.Bluesky.ActorDID, blog.Bluesky.RecordID) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to fetch blog post Bluesky thread: %v\n", err) } else { - comments = append(comments, blueskyPost.Replies...) + replies := []*model.ThreadViewPost{} + for _, reply := range blueskyPost.Replies { + if reply.Post.Author.DID != blog.Bluesky.ActorDID { + replies = append(replies, reply) + } + } + comments = append(comments, replies...) likeCount += blueskyPost.Post.LikeCount boostCount += blueskyPost.Post.RepostCount blueskyURL = fmt.Sprintf("https://bsky.app/profile/%s/post/%s", blueskyPost.Post.Author.Handle, blog.Bluesky.RecordID)