package logic import ( "context" "spark-server/internal/module/square/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) picked := make([]*entity.Post, 0, limit) scan := cursor for range entity.OverfetchRounds { batch, err := s.repo.ListPublicFeed(ctx, scan, entity.Overfetch) if err != nil { return nil, err } if len(batch) == 0 { break } vis, err := s.visFor(ctx, viewerID, batch) if err != nil { return nil, err } for _, p := range batch { scan = 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, limit, false) } func (s *Service) listResult(ctx context.Context, viewer int64, posts []*entity.Post, limit int, 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 } hasMore := len(posts) >= limit && limit > 0 return &ListResult{Items: views, NextCursor: next, HasMore: hasMore}, nil }