blog style improvements; fix connection pool drain

This commit is contained in:
ari melody 2025-11-08 18:42:02 +00:00
parent 0a75216aaf
commit 1d98a6fdca
Signed by: ari
GPG key ID: CF99829C92678188
8 changed files with 51 additions and 24 deletions

View file

@ -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{}

View file

@ -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{}

View file

@ -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() {

View file

@ -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 {

View file

@ -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;

View file

@ -34,7 +34,7 @@
<h3 class="blog-title"><a href="/blog/{{.ID}}">{{.Title}}</a></h3>
<p class="blog-meta">
<span class="blog-author"><img src="/img/favicon.png" alt="" width="32" height="32"/> {{.Author.DisplayName}}</span>
<span class="blog-date">&bull; {{.PrintDate}}</span>
<span class="blog-date">&bull; {{.PrintShortDate}}</span>
</p>
{{if ne .Description ""}}
<p class="blog-description">{{.Description}}</p>

View file

@ -85,7 +85,7 @@
<header>
<h1 class="typeout"># {{.Title}}</h1>
<p class="blog-author">by <a href="/blog?author={{.Author.DisplayName}}">{{.Author.DisplayName}} <img src="/img/favicon.png" alt="" aria-hidden="true" width="32" height="32"/></a></p>
<p class="blog-date">posted {{.PrintDate}}</p>
<p class="blog-date">Published {{.PrintDate}}</p>
</header>
<hr>
@ -110,6 +110,7 @@
</div>
{{.Likes}}
</a>
<!--
<a href="{{.BlueskyURL}}" class="button boosts" aria-label="{{.Boosts}} boosts">
<div class="dark-only">
<img src="/img/blog/boost-dark.svg" alt="" width="32" height="32">
@ -119,6 +120,7 @@
</div>
{{.Boosts}}
</a>
-->
<p class="comment-callout">
join the conversation on

View file

@ -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)