···
1
+
package communityFeed
4
+
"Coves/internal/core/communityFeeds"
11
+
// GetCommunityHandler handles community feed retrieval
12
+
type GetCommunityHandler struct {
13
+
service communityFeeds.Service
16
+
// NewGetCommunityHandler creates a new community feed handler
17
+
func NewGetCommunityHandler(service communityFeeds.Service) *GetCommunityHandler {
18
+
return &GetCommunityHandler{
23
+
// HandleGetCommunity retrieves posts from a community with sorting
24
+
// GET /xrpc/social.coves.communityFeed.getCommunity?community={did_or_handle}&sort=hot&limit=15&cursor=...
25
+
func (h *GetCommunityHandler) HandleGetCommunity(w http.ResponseWriter, r *http.Request) {
26
+
if r.Method != http.MethodGet {
27
+
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
31
+
// Parse query parameters
32
+
req, err := h.parseRequest(r)
34
+
writeError(w, http.StatusBadRequest, "InvalidRequest", err.Error())
38
+
// Alpha: No viewer context needed for basic community sorting
39
+
// TODO(feed-generator): Extract viewer DID when implementing viewer-specific state
40
+
// (blocks, upvotes, saves) in feed generator skeleton
42
+
// Get community feed
43
+
response, err := h.service.GetCommunityFeed(r.Context(), req)
45
+
handleServiceError(w, err)
50
+
w.Header().Set("Content-Type", "application/json")
51
+
w.WriteHeader(http.StatusOK)
52
+
if err := json.NewEncoder(w).Encode(response); err != nil {
53
+
// Log encoding errors but don't return error response (headers already sent)
54
+
log.Printf("ERROR: Failed to encode feed response: %v", err)
58
+
// parseRequest parses query parameters into GetCommunityFeedRequest
59
+
func (h *GetCommunityHandler) parseRequest(r *http.Request) (communityFeeds.GetCommunityFeedRequest, error) {
60
+
req := communityFeeds.GetCommunityFeedRequest{}
62
+
// Required: community
63
+
req.Community = r.URL.Query().Get("community")
65
+
// Optional: sort (default: hot)
66
+
req.Sort = r.URL.Query().Get("sort")
71
+
// Optional: timeframe (default: day for top sort)
72
+
req.Timeframe = r.URL.Query().Get("timeframe")
73
+
if req.Timeframe == "" && req.Sort == "top" {
74
+
req.Timeframe = "day"
77
+
// Optional: limit (default: 15, max: 50)
79
+
if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
80
+
if limit, err := strconv.Atoi(limitStr); err == nil {
86
+
if cursor := r.URL.Query().Get("cursor"); cursor != "" {
87
+
req.Cursor = &cursor