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) }