feat: share post to other apps

This commit is contained in:
Krispire Admin
2026-05-31 08:05:02 +05:30
parent 05b61cef09
commit 0969887008
8 changed files with 313 additions and 14 deletions
+55 -2
View File
@@ -59,9 +59,36 @@ func (h *PostHandler) Create(w http.ResponseWriter, r *http.Request) {
response.JSON(w, http.StatusCreated, p)
}
// Reshare records the caller as having reshared the post identified
// by {id}. Idempotent. Returns 204 on success; conflict for the
// "reshare your own post" case surfaces as 400 via mapSocialErr's
// fallthrough (errors.New wrapper in the service).
func (h *PostHandler) Reshare(w http.ResponseWriter, r *http.Request) {
uid := middleware.UserID(r.Context())
id := chi.URLParam(r, "id")
if err := h.svc.Reshare(r.Context(), id, uid); err != nil {
mapSocialErr(w, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
// Unreshare removes a previously recorded reshare. Idempotent.
func (h *PostHandler) Unreshare(w http.ResponseWriter, r *http.Request) {
uid := middleware.UserID(r.Context())
id := chi.URLParam(r, "id")
if err := h.svc.Unreshare(r.Context(), id, uid); err != nil {
mapSocialErr(w, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
func (h *PostHandler) Get(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
p, err := h.svc.Get(r.Context(), id)
// viewerID is "" for anonymous viewers — the service treats that as
// "no reshare hydration" so the public-cache shape is unchanged.
p, err := h.svc.Get(r.Context(), id, middleware.UserID(r.Context()))
if err != nil {
mapSocialErr(w, err)
return
@@ -420,7 +447,10 @@ func (h *ProfileHandler) Get(w http.ResponseWriter, r *http.Request) {
}
// Feed returns posts for the public feed. Same payload as ListMine but
// looked up by handle so it's reachable anonymously.
// looked up by handle so it's reachable anonymously. When an
// authenticated viewer hits this route (via OptionalAuth) each post
// carries `viewer_has_reshared` so the action footer renders the right
// button. Anonymous viewers get `false` for every post at zero cost.
func (h *ProfileHandler) Feed(w http.ResponseWriter, r *http.Request) {
handle := chi.URLParam(r, "handle")
limit, offset := parseLimitOffset(r)
@@ -429,6 +459,29 @@ func (h *ProfileHandler) Feed(w http.ResponseWriter, r *http.Request) {
mapSocialErr(w, err)
return
}
viewerID := middleware.UserID(r.Context())
if viewerID != "" && len(posts) > 0 {
ids := make([]string, 0, len(posts))
for i := range posts {
// Skip own posts — can't reshare yourself, and the swap
// already triggers on isOwner.
if posts[i].UserID != viewerID {
ids = append(ids, posts[i].ID)
}
}
if len(ids) > 0 {
states, err := h.posts.ReshareStatesFor(r.Context(), viewerID, ids)
if err != nil {
mapSocialErr(w, err)
return
}
for i := range posts {
if states[posts[i].ID] {
posts[i].ViewerHasReshared = true
}
}
}
}
response.JSONWithMeta(w, http.StatusOK, posts, paginationMeta(total, limit, offset))
}