A community based topic aggregation platform built on atproto
1package discover 2 3import ( 4 "encoding/json" 5 "log" 6 "net/http" 7 "strconv" 8 9 "Coves/internal/core/discover" 10) 11 12// GetDiscoverHandler handles discover feed retrieval 13type GetDiscoverHandler struct { 14 service discover.Service 15} 16 17// NewGetDiscoverHandler creates a new discover handler 18func NewGetDiscoverHandler(service discover.Service) *GetDiscoverHandler { 19 return &GetDiscoverHandler{ 20 service: service, 21 } 22} 23 24// HandleGetDiscover retrieves posts from all communities (public feed) 25// GET /xrpc/social.coves.feed.getDiscover?sort=hot&limit=15&cursor=... 26// Public endpoint - no authentication required 27func (h *GetDiscoverHandler) HandleGetDiscover(w http.ResponseWriter, r *http.Request) { 28 if r.Method != http.MethodGet { 29 http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) 30 return 31 } 32 33 // Parse query parameters 34 req := h.parseRequest(r) 35 36 // Get discover feed 37 response, err := h.service.GetDiscover(r.Context(), req) 38 if err != nil { 39 handleServiceError(w, err) 40 return 41 } 42 43 // Return feed 44 w.Header().Set("Content-Type", "application/json") 45 w.WriteHeader(http.StatusOK) 46 if err := json.NewEncoder(w).Encode(response); err != nil { 47 log.Printf("ERROR: Failed to encode discover response: %v", err) 48 } 49} 50 51// parseRequest parses query parameters into GetDiscoverRequest 52func (h *GetDiscoverHandler) parseRequest(r *http.Request) discover.GetDiscoverRequest { 53 req := discover.GetDiscoverRequest{} 54 55 // Optional: sort (default: hot) 56 req.Sort = r.URL.Query().Get("sort") 57 if req.Sort == "" { 58 req.Sort = "hot" 59 } 60 61 // Optional: timeframe (default: day for top sort) 62 req.Timeframe = r.URL.Query().Get("timeframe") 63 if req.Timeframe == "" && req.Sort == "top" { 64 req.Timeframe = "day" 65 } 66 67 // Optional: limit (default: 15, max: 50) 68 req.Limit = 15 69 if limitStr := r.URL.Query().Get("limit"); limitStr != "" { 70 if limit, err := strconv.Atoi(limitStr); err == nil { 71 req.Limit = limit 72 } 73 } 74 75 // Optional: cursor 76 if cursor := r.URL.Query().Get("cursor"); cursor != "" { 77 req.Cursor = &cursor 78 } 79 80 return req 81}