fix: hide post

This commit is contained in:
Krispire Admin
2026-06-14 19:51:57 +05:30
parent 93e92c610c
commit 438258ade0
8 changed files with 176 additions and 8 deletions
+2 -2
View File
@@ -207,7 +207,7 @@ func (r *CollectionRepo) CollectionsContaining(ctx context.Context, postID, user
func (r *CollectionRepo) PostsIn(ctx context.Context, collectionID string) ([]model.Post, error) {
rows, err := r.pg.Pool.Query(ctx, `
SELECT p.id, p.user_id, p.caption, p.source_url, COALESCE(p.source_title, ''),
p.created_at, p.updated_at, u.name, u.handle, u.avatar_url
p.created_at, p.updated_at, u.name, u.handle, u.avatar_url, p.is_hidden
FROM collection_items ci
JOIN posts p ON p.id = ci.post_id
JOIN users u ON u.id = p.user_id
@@ -227,7 +227,7 @@ func (r *CollectionRepo) PostsIn(ctx context.Context, collectionID string) ([]mo
if err := rows.Scan(
&p.ID, &p.UserID, &p.Caption, &p.SourceURL, &p.SourceTitle,
&p.CreatedAt, &p.UpdatedAt,
&p.AuthorName, &p.AuthorHandle, &p.AuthorAvatarURL,
&p.AuthorName, &p.AuthorHandle, &p.AuthorAvatarURL, &p.IsHidden,
); err != nil {
return nil, fmt.Errorf("scan post: %w", err)
}
+57 -5
View File
@@ -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