feat: add characters
This commit is contained in:
@@ -180,6 +180,73 @@ func (h *Handler) Frames(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// BuyFrame — POST /api/shop/buy-frame
|
||||
// Avatars — GET /api/avatars: کاتالوگِ شخصیتها + انتخابیِ کاربر.
|
||||
func (h *Handler) Avatars(w http.ResponseWriter, r *http.Request) {
|
||||
id, ok := uid(r)
|
||||
if !ok {
|
||||
httpx.Error(w, http.StatusUnauthorized, "unauthorized")
|
||||
return
|
||||
}
|
||||
avatars, err := h.svc.Avatars(r.Context(), id)
|
||||
if err != nil {
|
||||
httpx.Error(w, http.StatusInternalServerError, "server error")
|
||||
return
|
||||
}
|
||||
selected := ""
|
||||
if p, _ := h.svc.GetProfile(r.Context(), id); p != nil {
|
||||
selected = p.SelectedAvatar
|
||||
}
|
||||
httpx.JSON(w, http.StatusOK, map[string]any{
|
||||
"avatars": avatars,
|
||||
"selected": selected,
|
||||
})
|
||||
}
|
||||
|
||||
// BuyAvatar — POST /api/shop/buy-avatar
|
||||
func (h *Handler) BuyAvatar(w http.ResponseWriter, r *http.Request) {
|
||||
h.avatarAction(w, r, false)
|
||||
}
|
||||
|
||||
// SelectAvatar — POST /api/shop/select-avatar (avatar_id خالی ⇒ آواتارِ پیشفرض)
|
||||
func (h *Handler) SelectAvatar(w http.ResponseWriter, r *http.Request) {
|
||||
h.avatarAction(w, r, true)
|
||||
}
|
||||
|
||||
func (h *Handler) avatarAction(w http.ResponseWriter, r *http.Request, sel bool) {
|
||||
id, ok := uid(r)
|
||||
if !ok {
|
||||
httpx.Error(w, http.StatusUnauthorized, "unauthorized")
|
||||
return
|
||||
}
|
||||
var req struct {
|
||||
AvatarID string `json:"avatar_id"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
httpx.Error(w, http.StatusBadRequest, "invalid body")
|
||||
return
|
||||
}
|
||||
var err error
|
||||
if sel {
|
||||
err = h.svc.SelectAvatar(r.Context(), id, req.AvatarID)
|
||||
} else {
|
||||
err = h.svc.BuyAvatar(r.Context(), id, req.AvatarID)
|
||||
}
|
||||
switch {
|
||||
case err == nil:
|
||||
httpx.JSON(w, http.StatusOK, map[string]string{"message": "ok"})
|
||||
case errors.Is(err, ErrNotFound):
|
||||
httpx.Error(w, http.StatusNotFound, "avatar not found")
|
||||
case errors.Is(err, ErrAlreadyOwned):
|
||||
httpx.Error(w, http.StatusConflict, "already owned")
|
||||
case errors.Is(err, ErrNotOwned):
|
||||
httpx.Error(w, http.StatusForbidden, "avatar not owned")
|
||||
case errors.Is(err, ErrInsufficient):
|
||||
httpx.Error(w, http.StatusPaymentRequired, "insufficient coins")
|
||||
default:
|
||||
httpx.Error(w, http.StatusInternalServerError, "server error")
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) BuyFrame(w http.ResponseWriter, r *http.Request) {
|
||||
h.frameAction(w, r, false)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user