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