feat: Display list of remote users who liked a post
This change implements the ability to display a list of remote users who have liked a post on an individual entry page (collection post). Key changes include: - Added a `RemoteLikers []*RemoteUser` field to the `PublicPost` struct in `posts.go`. - Implemented a new database function `getRemoteLikersForPost(postID string)` in `database.go` to fetch likers by joining `remote_likes` and `remoteusers` tables. - Modified the `GetPost` function in `database.go` to call `getRemoteLikersForPost` and populate the `RemoteLikers` field. - Updated the `templates/collection-post.tmpl` template to iterate over `RemoteLikers` and display each user's handle as a link to their profile.
This commit is contained in:
parent
db66a885fb
commit
90dbc05bd3
3 changed files with 79 additions and 0 deletions
64
database.go
64
database.go
|
@ -1132,6 +1132,19 @@ func (db *datastore) GetEditablePost(id, editToken string) (*PublicPost, error)
|
||||||
res.Owner = &PublicUser{Username: ownerName.String}
|
res.Owner = &PublicUser{Username: ownerName.String}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get remote likers for the post
|
||||||
|
likers, err := db.getRemoteLikersForPost(p.ID)
|
||||||
|
if err != nil {
|
||||||
|
// Log the error but don't block returning the post
|
||||||
|
// getRemoteLikersForPost is expected to return an empty slice on sql.ErrNoRows
|
||||||
|
log.Error("GetPost: Failed to get remote likers for post %s: %v", p.ID, err)
|
||||||
|
// If likers is nil due to an unexpected error, ensure it's an empty slice
|
||||||
|
if likers == nil {
|
||||||
|
likers = []*RemoteUser{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.RemoteLikers = likers
|
||||||
|
|
||||||
return &res, nil
|
return &res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1462,6 +1475,57 @@ func (db *datastore) GetPostsTagged(cfg *config.Config, c *Collection, tag strin
|
||||||
return &posts, nil
|
return &posts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getRemoteLikersForPost retrieves a list of remote users who liked a specific post.
|
||||||
|
func (db *datastore) getRemoteLikersForPost(postID string) ([]*RemoteUser, error) {
|
||||||
|
rows, err := db.Query(`
|
||||||
|
SELECT ru.id, ru.actor_id, ru.url, ru.handle, ru.created, ru.inbox, ru.shared_inbox
|
||||||
|
FROM remoteusers ru
|
||||||
|
JOIN remote_likes rl ON ru.id = rl.remote_user_id
|
||||||
|
WHERE rl.post_id = ?
|
||||||
|
ORDER BY rl.created DESC
|
||||||
|
`, postID)
|
||||||
|
if err != nil {
|
||||||
|
// sql.ErrNoRows is not an error in this case, just means no likers.
|
||||||
|
// It's handled by the loop below which won't execute.
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var likers []*RemoteUser
|
||||||
|
for rows.Next() {
|
||||||
|
var u RemoteUser
|
||||||
|
var handle sql.NullString
|
||||||
|
var created sql.NullTime
|
||||||
|
var url sql.NullString
|
||||||
|
var inbox sql.NullString
|
||||||
|
var sharedInbox sql.NullString
|
||||||
|
|
||||||
|
err := rows.Scan(&u.ID, &u.ActorID, &url, &handle, &created, &inbox, &sharedInbox)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u.URL = url.String
|
||||||
|
u.Handle = handle.String
|
||||||
|
if created.Valid {
|
||||||
|
u.Created = created.Time
|
||||||
|
}
|
||||||
|
u.Inbox = inbox.String
|
||||||
|
u.SharedInbox = sharedInbox.String
|
||||||
|
likers = append(likers, &u)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If likers slice is still nil (e.g. no rows found), initialize it to an empty slice.
|
||||||
|
if likers == nil {
|
||||||
|
likers = []*RemoteUser{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return likers, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (db *datastore) GetCollLangTotalPosts(collID int64, lang string) (uint64, error) {
|
func (db *datastore) GetCollLangTotalPosts(collID int64, lang string) (uint64, error) {
|
||||||
var articles uint64
|
var articles uint64
|
||||||
err := db.QueryRow("SELECT COUNT(*) FROM posts WHERE collection_id = ? AND language = ? AND created <= "+db.now(), collID, lang).Scan(&articles)
|
err := db.QueryRow("SELECT COUNT(*) FROM posts WHERE collection_id = ? AND language = ? AND created <= "+db.now(), collID, lang).Scan(&articles)
|
||||||
|
|
1
posts.go
1
posts.go
|
@ -135,6 +135,7 @@ type (
|
||||||
DisplayDate string `json:"-"`
|
DisplayDate string `json:"-"`
|
||||||
Views int64 `json:"views"`
|
Views int64 `json:"views"`
|
||||||
Likes int64 `json:"likes"`
|
Likes int64 `json:"likes"`
|
||||||
|
RemoteLikers []*RemoteUser `json:"remote_likers,omitempty"` // New field
|
||||||
Owner *PublicUser `json:"-"`
|
Owner *PublicUser `json:"-"`
|
||||||
IsOwner bool `json:"-"`
|
IsOwner bool `json:"-"`
|
||||||
URL string `json:"url,omitempty"`
|
URL string `json:"url,omitempty"`
|
||||||
|
|
|
@ -56,6 +56,20 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
{{ if and .IsOwner .IsFound }}<span class="views" dir="ltr"><strong>{{largeNumFmt .Views}}</strong> {{pluralize "view" "views" .Views}}</span>
|
{{ if and .IsOwner .IsFound }}<span class="views" dir="ltr"><strong>{{largeNumFmt .Views}}</strong> {{pluralize "view" "views" .Views}}</span>
|
||||||
{{if .Likes}}<span class="views" dir="ltr"><strong>{{largeNumFmt .Likes}}</strong> {{pluralize "like" "likes" .Likes}}</span>{{end}}
|
{{if .Likes}}<span class="views" dir="ltr"><strong>{{largeNumFmt .Likes}}</strong> {{pluralize "like" "likes" .Likes}}</span>{{end}}
|
||||||
|
|
||||||
|
{{/* New section for Remote Likers */}}
|
||||||
|
{{if .RemoteLikers}}
|
||||||
|
<div class="remote-likers views" dir="ltr"> {{/* Borrowing "views" class for similar styling */}}
|
||||||
|
<p style="margin-top: 5px; margin-bottom: 2px; font-size: 0.9em;">Liked by:</p>
|
||||||
|
<ul style="list-style-type: none; padding-left: 0; margin-top: 0;">
|
||||||
|
{{range .RemoteLikers}}
|
||||||
|
<li style="display: inline-block; margin-right: 5px;">
|
||||||
|
<a href="{{.URL}}" target="_blank" rel="noopener noreferrer" title="{{.ActorID}}">{{.EstimatedHandle}}</a>
|
||||||
|
</li>
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
<a href="/{{if not .SingleUser}}{{.Collection.Alias}}/{{end}}{{.Slug.String}}/edit" dir="{{.Direction}}">Edit</a>
|
<a href="/{{if not .SingleUser}}{{.Collection.Alias}}/{{end}}{{.Slug.String}}/edit" dir="{{.Direction}}">Edit</a>
|
||||||
{{if .IsPinned}}<a class="xtra-feature unpin" href="/{{.Collection.Alias}}/{{.Slug.String}}/unpin" dir="{{.Direction}}" onclick="unpinPost(event, '{{.ID}}')">Unpin</a>{{end}}
|
{{if .IsPinned}}<a class="xtra-feature unpin" href="/{{.Collection.Alias}}/{{.Slug.String}}/unpin" dir="{{.Direction}}" onclick="unpinPost(event, '{{.ID}}')">Unpin</a>{{end}}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
Loading…
Add table
Reference in a new issue