spark-server/internal/module/moment/logic/feed.go
2026-09-18 17:51:42 +08:00

87 lines
1.9 KiB
Go

package logic
import (
"context"
"spark-server/internal/module/moment/entity"
"spark-server/internal/pkg/errs"
)
func (s *Service) Feed(ctx context.Context, viewerID, cursor int64, limit int) (*ListResult, error) {
if !s.ready() || viewerID <= 0 {
return nil, errs.ErrUnauthorized
}
limit = entity.ClampLimit(limit)
authors, err := s.feedAuthors(ctx, viewerID)
if err != nil {
return nil, err
}
picked := make([]*entity.Post, 0, limit)
for range entity.OverfetchRounds {
batch, err := s.repo.ListByAuthors(ctx, authors, cursor, entity.Overfetch)
if err != nil {
return nil, err
}
if len(batch) == 0 {
break
}
vis, err := s.visFor(ctx, viewerID, batch, false)
if err != nil {
return nil, err
}
for _, p := range batch {
cursor = p.ID
if !vis.canSee(p) {
continue
}
picked = append(picked, p)
if len(picked) >= limit {
break
}
}
if len(picked) >= limit || len(batch) < entity.Overfetch {
break
}
}
return s.listResult(ctx, viewerID, picked, false)
}
func (s *Service) feedAuthors(ctx context.Context, viewerID int64) ([]int64, error) {
ids, err := s.friends.ListFriendIDs(ctx, viewerID)
if err != nil {
return nil, err
}
hideHim, err := s.repo.HideHimIDs(ctx, viewerID)
if err != nil {
return nil, err
}
skip := idSet(hideHim)
blocked, err := s.friends.ListBlockedPeerIDs(ctx, viewerID)
if err != nil {
return nil, err
}
for _, id := range blocked {
skip[id] = true
}
out := make([]int64, 0, len(ids)+1)
out = append(out, viewerID)
for _, id := range ids {
if !skip[id] {
out = append(out, id)
}
}
return out, nil
}
func (s *Service) listResult(ctx context.Context, viewer int64, posts []*entity.Post, full bool) (*ListResult, error) {
views, err := s.attachViews(ctx, viewer, posts, full)
if err != nil {
return nil, err
}
next := int64(0)
if len(posts) > 0 {
next = posts[len(posts)-1].ID
}
return &ListResult{Items: views, NextCursor: next}, nil
}