big update: added reactions, groups, media share
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (h *apiHandler) addReaction(w http.ResponseWriter, r *http.Request) {
|
||||
userID, _ := userIDFrom(r.Context())
|
||||
convID, msgID, ok := h.parseMessagePath(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var req struct {
|
||||
Emoji string `json:"emoji"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeError(w, http.StatusBadRequest, "invalid json")
|
||||
return
|
||||
}
|
||||
if len(req.Emoji) == 0 || len(req.Emoji) > 32 {
|
||||
writeError(w, http.StatusBadRequest, "emoji must be 1-32 chars")
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.store.AddReaction(r.Context(), msgID, userID, req.Emoji); err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
}
|
||||
h.hub.PublishReactionChanged(convID, msgID, userID, req.Emoji, true)
|
||||
h.writeMessageWithReactions(w, r, convID, msgID)
|
||||
}
|
||||
|
||||
func (h *apiHandler) removeReaction(w http.ResponseWriter, r *http.Request) {
|
||||
userID, _ := userIDFrom(r.Context())
|
||||
convID, msgID, ok := h.parseMessagePath(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
emoji := r.PathValue("emoji")
|
||||
if emoji == "" {
|
||||
writeError(w, http.StatusBadRequest, "emoji is required")
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.store.RemoveReaction(r.Context(), msgID, userID, emoji); err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
}
|
||||
h.hub.PublishReactionChanged(convID, msgID, userID, emoji, false)
|
||||
h.writeMessageWithReactions(w, r, convID, msgID)
|
||||
}
|
||||
|
||||
func (h *apiHandler) parseMessagePath(w http.ResponseWriter, r *http.Request) (convID, msgID int64, ok bool) {
|
||||
userID, _ := userIDFrom(r.Context())
|
||||
convID, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
|
||||
if err != nil || convID <= 0 {
|
||||
writeError(w, http.StatusBadRequest, "invalid conversation id")
|
||||
return 0, 0, false
|
||||
}
|
||||
msgID, err = strconv.ParseInt(r.PathValue("msg_id"), 10, 64)
|
||||
if err != nil || msgID <= 0 {
|
||||
writeError(w, http.StatusBadRequest, "invalid message id")
|
||||
return 0, 0, false
|
||||
}
|
||||
if member, err := h.store.IsMember(r.Context(), convID, userID); err != nil || !member {
|
||||
writeError(w, http.StatusForbidden, "not a member")
|
||||
return 0, 0, false
|
||||
}
|
||||
belongs, err := h.store.MessageBelongsToConversation(r.Context(), convID, msgID)
|
||||
if err != nil || !belongs {
|
||||
writeError(w, http.StatusNotFound, "message not found")
|
||||
return 0, 0, false
|
||||
}
|
||||
return convID, msgID, true
|
||||
}
|
||||
|
||||
func (h *apiHandler) writeMessageWithReactions(w http.ResponseWriter, r *http.Request, convID, msgID int64) {
|
||||
msg, err := h.store.GetMessageByID(r.Context(), msgID)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
}
|
||||
msgs := []messageJSON{toMessageJSON(msg)}
|
||||
reactions, err := h.store.ReactionsForMessages(r.Context(), []int64{msgID})
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
}
|
||||
attachReactions(msgs, reactions)
|
||||
writeJSON(w, http.StatusOK, msgs[0])
|
||||
}
|
||||
Reference in New Issue
Block a user