94 lines
2.7 KiB
Go
94 lines
2.7 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"messenger/internal/store"
|
|
)
|
|
|
|
func (h *apiHandler) searchUsers(w http.ResponseWriter, r *http.Request) {
|
|
query := r.URL.Query().Get("q")
|
|
users, err := h.store.SearchUsers(r.Context(), query, 20)
|
|
if err != nil {
|
|
writeError(w, http.StatusInternalServerError, "internal server error")
|
|
return
|
|
}
|
|
out := make([]userJSON, 0, len(users))
|
|
for i := range users {
|
|
out = append(out, toUserJSON(&users[i]))
|
|
}
|
|
writeJSON(w, http.StatusOK, out)
|
|
}
|
|
|
|
type contactJSON struct {
|
|
User userJSON `json:"user"`
|
|
AddedAt string `json:"added_at"`
|
|
}
|
|
|
|
func (h *apiHandler) listContacts(w http.ResponseWriter, r *http.Request) {
|
|
userID, _ := userIDFrom(r.Context())
|
|
contacts, err := h.store.ListContacts(r.Context(), userID)
|
|
if err != nil {
|
|
writeError(w, http.StatusInternalServerError, "internal server error")
|
|
return
|
|
}
|
|
out := make([]contactJSON, 0, len(contacts))
|
|
for _, c := range contacts {
|
|
u, err := h.store.GetUserByID(r.Context(), c.ContactID)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
out = append(out, contactJSON{User: toUserJSON(u), AddedAt: c.CreatedAt.Format("2006-01-02T15:04:05Z07:00")})
|
|
}
|
|
writeJSON(w, http.StatusOK, out)
|
|
}
|
|
|
|
func (h *apiHandler) addContact(w http.ResponseWriter, r *http.Request) {
|
|
userID, _ := userIDFrom(r.Context())
|
|
var req struct {
|
|
UserID int64 `json:"user_id"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.UserID <= 0 {
|
|
writeError(w, http.StatusBadRequest, "invalid user_id")
|
|
return
|
|
}
|
|
if req.UserID == userID {
|
|
writeError(w, http.StatusBadRequest, "cannot add yourself")
|
|
return
|
|
}
|
|
if _, err := h.store.GetUserByID(r.Context(), req.UserID); err != nil {
|
|
if errors.Is(err, store.ErrNotFound) {
|
|
writeError(w, http.StatusNotFound, "user not found")
|
|
return
|
|
}
|
|
writeError(w, http.StatusInternalServerError, "internal server error")
|
|
return
|
|
}
|
|
if err := h.store.AddContact(r.Context(), userID, req.UserID); err != nil {
|
|
if errors.Is(err, store.ErrDuplicate) {
|
|
writeJSON(w, http.StatusOK, map[string]string{"status": "already a contact"})
|
|
return
|
|
}
|
|
writeError(w, http.StatusInternalServerError, "internal server error")
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusCreated, map[string]string{"status": "ok"})
|
|
}
|
|
|
|
func (h *apiHandler) removeContact(w http.ResponseWriter, r *http.Request) {
|
|
userID, _ := userIDFrom(r.Context())
|
|
contactID, err := strconv.ParseInt(r.PathValue("user_id"), 10, 64)
|
|
if err != nil || contactID <= 0 {
|
|
writeError(w, http.StatusBadRequest, "invalid user_id")
|
|
return
|
|
}
|
|
if err := h.store.RemoveContact(r.Context(), userID, contactID); err != nil {
|
|
writeError(w, http.StatusInternalServerError, "internal server error")
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, map[string]string{"status": "ok"})
|
|
}
|