From 5630988ac2648c7a61589bc7a6bc93ba67777a50 Mon Sep 17 00:00:00 2001
From: LittleSheep <littlesheep.code@hotmail.com>
Date: Sat, 8 Mar 2025 23:14:47 +0800
Subject: [PATCH] :bug: Fix some visibility issues

---
 pkg/internal/http/api/posts_api.go | 34 +++++++++++++++++++++++-----
 pkg/internal/services/posts.go     | 36 ++++++++++++++++++------------
 2 files changed, 50 insertions(+), 20 deletions(-)

diff --git a/pkg/internal/http/api/posts_api.go b/pkg/internal/http/api/posts_api.go
index bb2c3da..809946e 100644
--- a/pkg/internal/http/api/posts_api.go
+++ b/pkg/internal/http/api/posts_api.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"strconv"
 	"strings"
+	"time"
 
 	"git.solsynth.dev/hypernet/nexus/pkg/nex/cruda"
 	"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
@@ -20,23 +21,39 @@ import (
 	"github.com/samber/lo"
 )
 
-func UniversalPostFilter(c *fiber.Ctx, tx *gorm.DB) (*gorm.DB, error) {
+type UniversalPostFilterConfig struct {
+	ShowDraft     bool
+	ShowReply     bool
+	ShowCollapsed bool
+}
+
+func UniversalPostFilter(c *fiber.Ctx, tx *gorm.DB, cfg ...UniversalPostFilterConfig) (*gorm.DB, error) {
+	var config UniversalPostFilterConfig
+	if len(cfg) > 0 {
+		config = cfg[0]
+	} else {
+		config = UniversalPostFilterConfig{}
+	}
+
 	if user, authenticated := c.Locals("user").(authm.Account); authenticated {
 		tx = services.FilterPostWithUserContext(c, tx, &user)
-		if c.QueryBool("noDraft", true) {
+		if c.QueryBool("noDraft", true) && !config.ShowDraft {
 			tx = services.FilterPostDraft(tx)
+			tx = services.FilterPostWithPublishedAt(tx, time.Now())
 		} else {
 			tx = services.FilterPostDraftWithAuthor(database.C, user.ID)
+			tx = services.FilterPostWithPublishedAt(tx, time.Now(), user.ID)
 		}
 	} else {
 		tx = services.FilterPostWithUserContext(c, tx, nil)
 		tx = services.FilterPostDraft(tx)
+		tx = services.FilterPostWithPublishedAt(tx, time.Now())
 	}
 
-	if c.QueryBool("noReply", true) {
+	if c.QueryBool("noReply", true) && !config.ShowReply {
 		tx = services.FilterPostReply(tx)
 	}
-	if c.QueryBool("noCollapse", true) {
+	if c.QueryBool("noCollapse", true) && !config.ShowCollapsed {
 		tx = tx.Where("is_collapsed = ? OR is_collapsed IS NULL", false)
 	}
 
@@ -74,7 +91,10 @@ func getPost(c *fiber.Ctx) error {
 
 	tx := database.C
 
-	if tx, err = UniversalPostFilter(c, tx); err != nil {
+	if tx, err = UniversalPostFilter(c, tx, UniversalPostFilterConfig{
+		ShowReply: true,
+		ShowDraft: true,
+	}); err != nil {
 		return err
 	}
 
@@ -120,7 +140,9 @@ func searchPost(c *fiber.Ctx) error {
 	tx = services.FilterPostWithFuzzySearch(tx, probe)
 
 	var err error
-	if tx, err = UniversalPostFilter(c, tx); err != nil {
+	if tx, err = UniversalPostFilter(c, tx, UniversalPostFilterConfig{
+		ShowReply: true,
+	}); err != nil {
 		return err
 	}
 
diff --git a/pkg/internal/services/posts.go b/pkg/internal/services/posts.go
index 8c7e9e7..80a119a 100644
--- a/pkg/internal/services/posts.go
+++ b/pkg/internal/services/posts.go
@@ -276,14 +276,30 @@ func FilterPostReply(tx *gorm.DB, replyTo ...uint) *gorm.DB {
 	}
 }
 
-func FilterPostWithPublishedAt(tx *gorm.DB, date time.Time) *gorm.DB {
+func FilterPostWithPublishedAt(tx *gorm.DB, date time.Time, uid ...uint) *gorm.DB {
+	var publishers []models.Publisher
+	if len(uid) > 0 {
+		if err := database.C.Where("account_id = ?", uid[0]).Find(&publishers).Error; err == nil {
+		}
+	}
+
 	return tx.
-		Where("(published_at >= ? OR published_at IS NULL)", date).
-		Where("(published_until < ? OR published_until IS NULL)", date)
+		Where("(published_at < ? OR published_at IS NULL)", date).
+		Where("(published_until >= ? OR published_until IS NULL)", date)
 }
 
 func FilterPostWithAuthorDraft(tx *gorm.DB, uid uint) *gorm.DB {
-	return tx.Where("publisher_id = ? AND is_draft = ?", uid, true)
+	var publishers []models.Publisher
+	if err := database.C.Where("account_id = ?", uid).Find(&publishers).Error; err != nil {
+		return FilterPostDraft(tx)
+	}
+	if len(publishers) == 0 {
+		return FilterPostDraft(tx)
+	}
+	idSet := lo.Map(publishers, func(item models.Publisher, index int) uint {
+		return item.ID
+	})
+	return tx.Where("publisher_id IN ? AND is_draft = ?", idSet, true)
 }
 
 func FilterPostDraft(tx *gorm.DB) *gorm.DB {
@@ -337,11 +353,7 @@ func PreloadGeneral(tx *gorm.DB) *gorm.DB {
 		Preload("RepostTo.Categories")
 }
 
-func GetPost(tx *gorm.DB, id uint, ignoreLimitation ...bool) (models.Post, error) {
-	if len(ignoreLimitation) == 0 || !ignoreLimitation[0] {
-		tx = FilterPostWithPublishedAt(tx, time.Now())
-	}
-
+func GetPost(tx *gorm.DB, id uint) (models.Post, error) {
 	var item models.Post
 	if err := PreloadGeneral(tx).
 		Where("id = ?", id).
@@ -352,11 +364,7 @@ func GetPost(tx *gorm.DB, id uint, ignoreLimitation ...bool) (models.Post, error
 	return item, nil
 }
 
-func GetPostByAlias(tx *gorm.DB, alias, area string, ignoreLimitation ...bool) (models.Post, error) {
-	if len(ignoreLimitation) == 0 || !ignoreLimitation[0] {
-		tx = FilterPostWithPublishedAt(tx, time.Now())
-	}
-
+func GetPostByAlias(tx *gorm.DB, alias, area string) (models.Post, error) {
 	var item models.Post
 	if err := PreloadGeneral(tx).
 		Where("alias = ?", alias).