fix: hide NSFW posts entirely when user hasn't enabled NSFW - backend filtering + Flutter safety net
This commit is contained in:
parent
b51c9ba90b
commit
25d3e213ea
|
|
@ -588,7 +588,15 @@ func (h *PostHandler) GetProfilePosts(c *gin.Context) {
|
|||
viewerID = val.(string)
|
||||
}
|
||||
|
||||
posts, err := h.postRepo.GetPostsByAuthor(c.Request.Context(), authorID, viewerID, limit, offset, onlyChains)
|
||||
// Check viewer's NSFW preference
|
||||
showNSFW := false
|
||||
if viewerID != "" {
|
||||
if settings, err := h.userRepo.GetUserSettings(c.Request.Context(), viewerID); err == nil && settings.NSFWEnabled != nil {
|
||||
showNSFW = *settings.NSFWEnabled
|
||||
}
|
||||
}
|
||||
|
||||
posts, err := h.postRepo.GetPostsByAuthor(c.Request.Context(), authorID, viewerID, limit, offset, onlyChains, showNSFW)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch profile posts", "details": err.Error()})
|
||||
return
|
||||
|
|
@ -835,7 +843,15 @@ func (h *PostHandler) GetSavedPosts(c *gin.Context) {
|
|||
limit := utils.GetQueryInt(c, "limit", 20)
|
||||
offset := utils.GetQueryInt(c, "offset", 0)
|
||||
|
||||
posts, err := h.postRepo.GetSavedPosts(c.Request.Context(), userID, limit, offset)
|
||||
// Check viewer's NSFW preference
|
||||
showNSFW := false
|
||||
if viewerID, exists := c.Get("user_id"); exists {
|
||||
if settings, err := h.userRepo.GetUserSettings(c.Request.Context(), viewerID.(string)); err == nil && settings.NSFWEnabled != nil {
|
||||
showNSFW = *settings.NSFWEnabled
|
||||
}
|
||||
}
|
||||
|
||||
posts, err := h.postRepo.GetSavedPosts(c.Request.Context(), userID, limit, offset, showNSFW)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch saved posts", "details": err.Error()})
|
||||
return
|
||||
|
|
@ -861,7 +877,15 @@ func (h *PostHandler) GetLikedPosts(c *gin.Context) {
|
|||
limit := utils.GetQueryInt(c, "limit", 20)
|
||||
offset := utils.GetQueryInt(c, "offset", 0)
|
||||
|
||||
posts, err := h.postRepo.GetLikedPosts(c.Request.Context(), userID, limit, offset)
|
||||
// Check viewer's NSFW preference
|
||||
showNSFW := false
|
||||
if viewerID, exists := c.Get("user_id"); exists {
|
||||
if settings, err := h.userRepo.GetUserSettings(c.Request.Context(), viewerID.(string)); err == nil && settings.NSFWEnabled != nil {
|
||||
showNSFW = *settings.NSFWEnabled
|
||||
}
|
||||
}
|
||||
|
||||
posts, err := h.postRepo.GetLikedPosts(c.Request.Context(), userID, limit, offset, showNSFW)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch liked posts", "details": err.Error()})
|
||||
return
|
||||
|
|
|
|||
|
|
@ -255,7 +255,13 @@ func (h *UserHandler) GetSavedPosts(c *gin.Context) {
|
|||
limit := utils.GetQueryInt(c, "limit", 20)
|
||||
offset := utils.GetQueryInt(c, "offset", 0)
|
||||
|
||||
posts, err := h.postRepo.GetSavedPosts(c.Request.Context(), targetID, limit, offset)
|
||||
// Check viewer's NSFW preference
|
||||
showNSFW := false
|
||||
if settings, err := h.repo.GetUserSettings(c.Request.Context(), currentUserID); err == nil && settings.NSFWEnabled != nil {
|
||||
showNSFW = *settings.NSFWEnabled
|
||||
}
|
||||
|
||||
posts, err := h.postRepo.GetSavedPosts(c.Request.Context(), targetID, limit, offset, showNSFW)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to fetch saved posts")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch saved posts"})
|
||||
|
|
@ -284,7 +290,13 @@ func (h *UserHandler) GetLikedPosts(c *gin.Context) {
|
|||
limit := 20
|
||||
offset := 0
|
||||
|
||||
posts, err := h.postRepo.GetLikedPosts(c.Request.Context(), userID, limit, offset)
|
||||
// Check viewer's NSFW preference
|
||||
showNSFW := false
|
||||
if settings, err := h.repo.GetUserSettings(c.Request.Context(), userID); err == nil && settings.NSFWEnabled != nil {
|
||||
showNSFW = *settings.NSFWEnabled
|
||||
}
|
||||
|
||||
posts, err := h.postRepo.GetLikedPosts(c.Request.Context(), userID, limit, offset, showNSFW)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to fetch liked posts")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch liked posts"})
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ func (r *PostRepository) GetCategories(ctx context.Context) ([]models.Category,
|
|||
return categories, nil
|
||||
}
|
||||
|
||||
func (r *PostRepository) GetPostsByAuthor(ctx context.Context, authorID string, viewerID string, limit int, offset int, onlyChains bool) ([]models.Post, error) {
|
||||
func (r *PostRepository) GetPostsByAuthor(ctx context.Context, authorID string, viewerID string, limit int, offset int, onlyChains bool, showNSFW bool) ([]models.Post, error) {
|
||||
query := `
|
||||
SELECT
|
||||
p.id, p.author_id, p.category_id, p.body,
|
||||
|
|
@ -268,10 +268,14 @@ func (r *PostRepository) GetPostsByAuthor(ctx context.Context, authorID string,
|
|||
)
|
||||
)
|
||||
AND ($5 = FALSE OR p.chain_parent_id IS NOT NULL)
|
||||
AND (
|
||||
COALESCE(p.is_nsfw, FALSE) = FALSE
|
||||
OR $6 = TRUE
|
||||
)
|
||||
ORDER BY p.created_at DESC
|
||||
LIMIT $2 OFFSET $3
|
||||
`
|
||||
rows, err := r.pool.Query(ctx, query, authorID, limit, offset, viewerID, onlyChains)
|
||||
rows, err := r.pool.Query(ctx, query, authorID, limit, offset, viewerID, onlyChains, showNSFW)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -549,7 +553,7 @@ func (r *PostRepository) GetNearbyBeacons(ctx context.Context, lat float64, long
|
|||
return beacons, nil
|
||||
}
|
||||
|
||||
func (r *PostRepository) GetSavedPosts(ctx context.Context, userID string, limit int, offset int) ([]models.Post, error) {
|
||||
func (r *PostRepository) GetSavedPosts(ctx context.Context, userID string, limit int, offset int, showNSFW bool) ([]models.Post, error) {
|
||||
query := `
|
||||
SELECT
|
||||
p.id, p.author_id, p.category_id, p.body,
|
||||
|
|
@ -569,10 +573,11 @@ func (r *PostRepository) GetSavedPosts(ctx context.Context, userID string, limit
|
|||
JOIN public.profiles pr ON p.author_id = pr.id
|
||||
LEFT JOIN public.post_metrics m ON p.id = m.post_id
|
||||
WHERE ps.user_id = $1::uuid AND p.deleted_at IS NULL
|
||||
AND (COALESCE(p.is_nsfw, FALSE) = FALSE OR $4 = TRUE)
|
||||
ORDER BY ps.created_at DESC
|
||||
LIMIT $2 OFFSET $3
|
||||
`
|
||||
rows, err := r.pool.Query(ctx, query, userID, limit, offset)
|
||||
rows, err := r.pool.Query(ctx, query, userID, limit, offset, showNSFW)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -601,7 +606,7 @@ func (r *PostRepository) GetSavedPosts(ctx context.Context, userID string, limit
|
|||
return posts, nil
|
||||
}
|
||||
|
||||
func (r *PostRepository) GetLikedPosts(ctx context.Context, userID string, limit int, offset int) ([]models.Post, error) {
|
||||
func (r *PostRepository) GetLikedPosts(ctx context.Context, userID string, limit int, offset int, showNSFW bool) ([]models.Post, error) {
|
||||
query := `
|
||||
SELECT
|
||||
p.id, p.author_id, p.category_id, p.body,
|
||||
|
|
@ -621,10 +626,11 @@ func (r *PostRepository) GetLikedPosts(ctx context.Context, userID string, limit
|
|||
JOIN public.profiles pr ON p.author_id = pr.id
|
||||
LEFT JOIN public.post_metrics m ON p.id = m.post_id
|
||||
WHERE pl.user_id = $1::uuid AND p.deleted_at IS NULL
|
||||
AND (COALESCE(p.is_nsfw, FALSE) = FALSE OR $4 = TRUE)
|
||||
ORDER BY pl.created_at DESC
|
||||
LIMIT $2 OFFSET $3
|
||||
`
|
||||
rows, err := r.pool.Query(ctx, query, userID, limit, offset)
|
||||
rows, err := r.pool.Query(ctx, query, userID, limit, offset, showNSFW)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,12 +91,18 @@ class _sojornPostCardState extends ConsumerState<sojornPostCard> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Whether to show NSFW blur overlay — respects user's blur preference
|
||||
/// Whether NSFW post should be completely hidden (not shown at all)
|
||||
bool get _shouldHideNsfw {
|
||||
if (!post.isNsfw) return false;
|
||||
final settings = ref.read(settingsProvider);
|
||||
return !(settings.user?.nsfwEnabled ?? false);
|
||||
}
|
||||
|
||||
/// Whether to show NSFW blur overlay — only applies when user HAS opted in
|
||||
bool get _shouldBlurNsfw {
|
||||
if (!post.isNsfw || _nsfwRevealed) return false;
|
||||
if (_shouldHideNsfw) return false; // Will be hidden entirely, no blur needed
|
||||
final settings = ref.read(settingsProvider);
|
||||
// Always blur if user hasn't opted into NSFW content
|
||||
if (!(settings.user?.nsfwEnabled ?? false)) return true;
|
||||
// If opted in, respect the blur toggle
|
||||
return settings.user?.nsfwBlurEnabled ?? true;
|
||||
}
|
||||
|
|
@ -114,6 +120,9 @@ class _sojornPostCardState extends ConsumerState<sojornPostCard> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Completely hide NSFW posts when user hasn't enabled NSFW
|
||||
if (_shouldHideNsfw) return const SizedBox.shrink();
|
||||
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: Container(
|
||||
|
|
|
|||
Loading…
Reference in a new issue