Files
Messenger/server/internal/api/search.go
T

68 lines
1.5 KiB
Go
Raw Normal View History

package api
import (
"net/http"
"strconv"
)
type searchHitJSON struct {
Message messageJSON `json:"message"`
Conversation conversationRef `json:"conversation"`
}
type conversationRef struct {
ID int64 `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
}
func (h *apiHandler) searchMessages(w http.ResponseWriter, r *http.Request) {
userID, _ := userIDFrom(r.Context())
query := r.URL.Query().Get("q")
if len(query) < 2 {
writeJSON(w, http.StatusOK, []searchHitJSON{})
return
}
limit := 50
if v := r.URL.Query().Get("limit"); v != "" {
if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 100 {
limit = n
}
}
hits, err := h.store.SearchMessages(r.Context(), userID, query, limit)
if err != nil {
writeError(w, http.StatusInternalServerError, "internal server error")
return
}
out := make([]searchHitJSON, 0, len(hits))
mediaByID := make(map[int64]mediaJSON)
for _, hit := range hits {
if hit.MediaID != nil {
if _, ok := mediaByID[*hit.MediaID]; !ok {
if m, err := h.store.GetMediaByID(r.Context(), *hit.MediaID); err == nil {
mediaByID[*hit.MediaID] = toMediaJSON(m)
}
}
}
}
for _, hit := range hits {
msg := toMessageJSON(&hit.Message)
if hit.MediaID != nil {
if md, ok := mediaByID[*hit.MediaID]; ok {
msg.Media = &md
}
}
out = append(out, searchHitJSON{
Message: msg,
Conversation: conversationRef{
ID: hit.ConversationID,
Type: hit.ConversationType,
Name: hit.ConversationName,
},
})
}
writeJSON(w, http.StatusOK, out)
}