Files

174 lines
4.6 KiB
Go

package handlers
import (
"math/rand"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/toyffee/party-mix/internal/models"
"gorm.io/gorm"
)
const codeChars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
func generateCode() string {
b := make([]byte, 6)
for i := range b {
b[i] = codeChars[rand.Intn(len(codeChars))]
}
return string(b)
}
type createPartyReq struct {
Name string `json:"name" binding:"required"`
TelegramID int64 `json:"telegram_id"`
}
func CreateParty(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
var req createPartyReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
party := models.Party{
ID: uuid.NewString(),
Name: req.Name,
Code: generateCode(),
TelegramID: req.TelegramID,
CreatedAt: time.Now(),
}
if err := db.Create(&party).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create party"})
return
}
c.JSON(http.StatusCreated, party)
}
}
func GetParty(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
var party models.Party
err := db.Preload("Participants.Tracks").First(&party, "id = ?", c.Param("id")).Error
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "party not found"})
return
}
c.JSON(http.StatusOK, party)
}
}
func GetPartyByCode(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
var party models.Party
err := db.Preload("Participants.Tracks").First(&party, "code = ?", c.Param("code")).Error
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "party not found"})
return
}
c.JSON(http.StatusOK, party)
}
}
type addParticipantReq struct {
Name string `json:"name" binding:"required"`
Tracks []string `json:"tracks" binding:"required"`
ColorBg string `json:"color_bg"`
ColorText string `json:"color_text"`
}
func AddParticipant(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
var req addParticipantReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
participant := models.Participant{
ID: uuid.NewString(),
PartyID: c.Param("id"),
Name: req.Name,
ColorBg: req.ColorBg,
ColorText: req.ColorText,
CreatedAt: time.Now(),
}
tracks := make([]models.Track, 0, len(req.Tracks))
for i, title := range req.Tracks {
tracks = append(tracks, models.Track{
ID: uuid.NewString(),
ParticipantID: participant.ID,
Title: title,
Position: i,
CreatedAt: time.Now(),
})
}
participant.Tracks = tracks
if err := db.Create(&participant).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to add participant"})
return
}
c.JSON(http.StatusCreated, participant)
}
}
func RemoveParticipant(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
pid := c.Param("pid")
db.Where("participant_id = ?", pid).Delete(&models.Track{})
if err := db.Delete(&models.Participant{}, "id = ?", pid).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to remove participant"})
return
}
c.Status(http.StatusNoContent)
}
}
type addHistoryReq struct {
Title string `json:"title"`
Artist string `json:"artist"`
ImgURL string `json:"img_url"`
OwnerName string `json:"owner_name"`
OwnerColorBg string `json:"owner_color_bg"`
OwnerColorText string `json:"owner_color_text"`
}
func AddHistory(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
var req addHistoryReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
item := models.HistoryItem{
ID: uuid.NewString(),
PartyID: c.Param("id"),
Title: req.Title,
Artist: req.Artist,
ImgURL: req.ImgURL,
OwnerName: req.OwnerName,
OwnerColorBg: req.OwnerColorBg,
OwnerColorText: req.OwnerColorText,
PlayedAt: time.Now(),
}
db.Create(&item)
c.JSON(http.StatusCreated, item)
}
}
func GetHistory(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
var items []models.HistoryItem
db.Where("party_id = ?", c.Param("id")).Order("played_at desc").Limit(100).Find(&items)
c.JSON(http.StatusOK, items)
}
}
func ClearHistory(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
db.Where("party_id = ?", c.Param("id")).Delete(&models.HistoryItem{})
c.Status(http.StatusNoContent)
}
}