fix: hide post
This commit is contained in:
@@ -36,7 +36,8 @@ const postSelectColumns = `
|
||||
p.reshared_from_post_id,
|
||||
ou.name AS original_author_name,
|
||||
ou.handle AS original_author_handle,
|
||||
ou.avatar_url AS original_author_avatar
|
||||
ou.avatar_url AS original_author_avatar,
|
||||
p.is_hidden
|
||||
`
|
||||
|
||||
const postSelectFrom = `
|
||||
@@ -58,6 +59,7 @@ func scanPost(row interface {
|
||||
&p.AuthorName, &p.AuthorHandle, &p.AuthorAvatarURL,
|
||||
&p.ResharedFromPostID,
|
||||
&p.OriginalAuthorName, &p.OriginalAuthorHandle, &p.OriginalAuthorAvatar,
|
||||
&p.IsHidden,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -182,16 +184,18 @@ func (r *PostRepo) ListMentioningByHandle(ctx context.Context, handle string, li
|
||||
return nil, 0, fmt.Errorf("lookup user by handle: %w", err)
|
||||
}
|
||||
|
||||
// Hidden posts are dropped from the mentions timeline too (the mentioned
|
||||
// user is not the author, so there is no owner exception here).
|
||||
var total int
|
||||
if err := r.pg.Pool.QueryRow(ctx,
|
||||
`SELECT count(*) FROM posts p JOIN post_mentions pm ON pm.post_id = p.id WHERE pm.user_id = $1`,
|
||||
`SELECT count(*) FROM posts p JOIN post_mentions pm ON pm.post_id = p.id WHERE pm.user_id = $1 AND p.is_hidden = FALSE`,
|
||||
userID,
|
||||
).Scan(&total); err != nil {
|
||||
return nil, 0, fmt.Errorf("count mentioning posts: %w", err)
|
||||
}
|
||||
q := `SELECT ` + postSelectColumns + postSelectFrom + `
|
||||
JOIN post_mentions pm ON pm.post_id = p.id
|
||||
WHERE pm.user_id = $1
|
||||
WHERE pm.user_id = $1 AND p.is_hidden = FALSE
|
||||
ORDER BY p.created_at DESC, p.id
|
||||
LIMIT $2 OFFSET $3`
|
||||
return r.collectPosts(ctx, total, q, userID, limit, offset)
|
||||
@@ -201,13 +205,30 @@ func (r *PostRepo) ListMentioningByHandle(ctx context.Context, handle string, li
|
||||
// authored or reshared. Reshares are interleaved naturally because
|
||||
// they're stored as real rows; sort by created_at gets the right order
|
||||
// without any UNION gymnastics.
|
||||
//
|
||||
// Hidden posts are excluded from this timeline for everyone, including the
|
||||
// owner — they live in the owner's separate "Hidden" list (ListHiddenByUser).
|
||||
func (r *PostRepo) ListByUser(ctx context.Context, userID string, limit, offset int) ([]model.Post, int, error) {
|
||||
total, err := r.CountByUser(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
q := `SELECT ` + postSelectColumns + postSelectFrom + `
|
||||
WHERE p.user_id = $1
|
||||
WHERE p.user_id = $1 AND p.is_hidden = FALSE
|
||||
ORDER BY p.created_at DESC, p.id
|
||||
LIMIT $2 OFFSET $3`
|
||||
return r.collectPosts(ctx, total, q, userID, limit, offset)
|
||||
}
|
||||
|
||||
// ListHiddenByUser returns the owner's hidden posts, newest first — the
|
||||
// /u/me "Hidden" tab. Owner-only (the caller enforces auth + scoping).
|
||||
func (r *PostRepo) ListHiddenByUser(ctx context.Context, userID string, limit, offset int) ([]model.Post, int, error) {
|
||||
total, err := r.CountHiddenByUser(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
q := `SELECT ` + postSelectColumns + postSelectFrom + `
|
||||
WHERE p.user_id = $1 AND p.is_hidden = TRUE
|
||||
ORDER BY p.created_at DESC, p.id
|
||||
LIMIT $2 OFFSET $3`
|
||||
return r.collectPosts(ctx, total, q, userID, limit, offset)
|
||||
@@ -239,6 +260,7 @@ func (r *PostRepo) FeedForViewer(ctx context.Context, viewerID string, limit, of
|
||||
}
|
||||
q := `SELECT ` + postSelectColumns + postSelectFrom + `
|
||||
WHERE p.user_id <> $1
|
||||
AND p.is_hidden = FALSE
|
||||
AND p.id <> ALL($4)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM user_blocks b
|
||||
@@ -339,12 +361,29 @@ func (r *PostRepo) Delete(ctx context.Context, postID, userID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetHidden flips a post's hidden flag. Owner-only: the WHERE clause scopes
|
||||
// to user_id, so a non-owner (or unknown id) affects no rows → ErrPostNotFound.
|
||||
func (r *PostRepo) SetHidden(ctx context.Context, postID, userID string, hidden bool) error {
|
||||
tag, err := r.pg.Pool.Exec(ctx,
|
||||
`UPDATE posts SET is_hidden = $3, updated_at = now() WHERE id = $1 AND user_id = $2`,
|
||||
postID, userID, hidden)
|
||||
if err != nil {
|
||||
return fmt.Errorf("set post hidden: %w", err)
|
||||
}
|
||||
if tag.RowsAffected() == 0 {
|
||||
return ErrPostNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CountByUser returns the user's total post count (authored + reshared).
|
||||
// Now just a single COUNT against posts.user_id.
|
||||
// CountByUser counts the user's visible (non-hidden) posts — matches the
|
||||
// timeline shown on their profile.
|
||||
func (r *PostRepo) CountByUser(ctx context.Context, userID string) (int, error) {
|
||||
var n int
|
||||
err := r.pg.Pool.QueryRow(ctx,
|
||||
`SELECT COUNT(*) FROM posts WHERE user_id = $1`, userID,
|
||||
`SELECT COUNT(*) FROM posts WHERE user_id = $1 AND is_hidden = FALSE`, userID,
|
||||
).Scan(&n)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("count posts: %w", err)
|
||||
@@ -352,6 +391,19 @@ func (r *PostRepo) CountByUser(ctx context.Context, userID string) (int, error)
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// CountHiddenByUser counts the owner's hidden posts (drives the "Hidden" tab's
|
||||
// visibility + badge).
|
||||
func (r *PostRepo) CountHiddenByUser(ctx context.Context, userID string) (int, error) {
|
||||
var n int
|
||||
err := r.pg.Pool.QueryRow(ctx,
|
||||
`SELECT COUNT(*) FROM posts WHERE user_id = $1 AND is_hidden = TRUE`, userID,
|
||||
).Scan(&n)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("count hidden posts: %w", err)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// PostedDates returns the set of UTC calendar days, on or after `since`,
|
||||
// on which the user created at least one post. Used by the sādhana streak
|
||||
// to detect the "posted a quote today" discipline (and to score past days
|
||||
|
||||
Reference in New Issue
Block a user