Feat: add backlog
This commit is contained in:
17
components/actionhistory.html
Normal file
17
components/actionhistory.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{{define "actionhistory"}}
|
||||||
|
<div class="overflow-y-auto max-h-96 border-2 border-gray-300 p-4 rounded-lg space-y-2">
|
||||||
|
Backlog:
|
||||||
|
{{range .}}
|
||||||
|
<div class="flex items-center justify-between p-2 rounded">
|
||||||
|
<span class="font-mono text-sm">
|
||||||
|
<span class="text-{{.ActorColor}}-600">{{.Actor}}:</span>
|
||||||
|
<span class="text-gray-600">{{.Action}}:</span>
|
||||||
|
<span class="text-{{.WordColor}}-500 font-medium">{{.Word}}</span>
|
||||||
|
{{if .Number}}
|
||||||
|
<span class="text-gray-400">- {{.Number}}</span>
|
||||||
|
{{end}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
@ -1,53 +0,0 @@
|
|||||||
{{define "cluepopup"}}
|
|
||||||
<div hx-sse="swap:newClue" hx-swap="none"
|
|
||||||
_="on htmx:sseMessage(mimeclue_{{.ID}})
|
|
||||||
-- Update content
|
|
||||||
set match to event.detail.match(/(.*?)(\d+)$/)
|
|
||||||
if match
|
|
||||||
set clue to match[1]
|
|
||||||
set number to match[2]
|
|
||||||
else
|
|
||||||
set clue to 'Invalid clue'
|
|
||||||
set number to '0'
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Cancel any previous timeout
|
|
||||||
if window.clueTimeout then clearTimeout(window.clueTimeout)
|
|
||||||
|
|
||||||
-- Show with animation
|
|
||||||
remove .hidden from #clueModal
|
|
||||||
remove .opacity-0.-translate-y-4 from #clueModal div
|
|
||||||
add .opacity-100.translate-y-0 to #clueModal div
|
|
||||||
|
|
||||||
-- Auto-hide after 3 seconds
|
|
||||||
set window.clueTimeout to setTimeout(() =>
|
|
||||||
trigger closeModal
|
|
||||||
end, 3000)
|
|
||||||
|
|
||||||
on closeModal
|
|
||||||
-- Hide with animation
|
|
||||||
add .opacity-0.-translate-y-4 to #clueModal div
|
|
||||||
wait 300ms
|
|
||||||
add .hidden to #clueModal">
|
|
||||||
<div id="clueModal"
|
|
||||||
class="hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full transition-opacity duration-300 ease-in-out">
|
|
||||||
<div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white
|
|
||||||
transform transition-all duration-300 ease-out
|
|
||||||
opacity-0 -translate-y-4">
|
|
||||||
<div class="mt-3 text-center">
|
|
||||||
<h3 class="text-lg leading-6 font-medium text-gray-900">New Clue Received! 🔍</h3>
|
|
||||||
<div class="mt-2 px-7 py-3">
|
|
||||||
<p class="text-sm text-gray-500">Clue: <span id="modalClue" class="font-medium"></span></p>
|
|
||||||
<p class="text-sm text-gray-500">Number: <span id="modalNumber" class="font-medium"></span></p>
|
|
||||||
</div>
|
|
||||||
<div class="items-center px-4 py-3">
|
|
||||||
<button _="on click trigger closeModal"
|
|
||||||
class="px-4 py-2 bg-green-500 text-white rounded-md hover:bg-green-700 transition-colors">
|
|
||||||
OK
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
@ -45,10 +45,8 @@
|
|||||||
{{template "mimeclue"}}
|
{{template "mimeclue"}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div hx-get="/actionhistory" hx-trigger="sse:backlog_{{.Room.ID}}">
|
||||||
{{if .Room.MimeDone}}
|
{{template "actionhistory" .Room.ActionHistory}}
|
||||||
{{template "cluepop"}}
|
|
||||||
{{end}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -66,6 +66,14 @@ func HandleShowColor(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
fi.Room.RevealSpecificWord(word)
|
fi.Room.RevealSpecificWord(word)
|
||||||
fi.Room.UpdateCounter()
|
fi.Room.UpdateCounter()
|
||||||
|
action := models.Action{
|
||||||
|
Actor: fi.State.Username,
|
||||||
|
ActorColor: string(fi.State.Team),
|
||||||
|
WordColor: color,
|
||||||
|
Action: "guessed",
|
||||||
|
Word: word,
|
||||||
|
}
|
||||||
|
fi.Room.ActionHistory = append(fi.Room.ActionHistory, action)
|
||||||
// if opened card is of color of opp team, change turn
|
// if opened card is of color of opp team, change turn
|
||||||
switch color {
|
switch color {
|
||||||
case "black":
|
case "black":
|
||||||
@ -83,3 +91,17 @@ func HandleShowColor(w http.ResponseWriter, r *http.Request) {
|
|||||||
notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "")
|
notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "")
|
||||||
tmpl.ExecuteTemplate(w, "cardword", cardword)
|
tmpl.ExecuteTemplate(w, "cardword", cardword)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HandleActionHistory(w http.ResponseWriter, r *http.Request) {
|
||||||
|
fi, err := getFullInfoByCtx(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
abortWithError(w, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tmpl, err := template.ParseGlob("components/*.html")
|
||||||
|
if err != nil {
|
||||||
|
abortWithError(w, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tmpl.ExecuteTemplate(w, "actionhistory", fi.Room.ActionHistory)
|
||||||
|
}
|
||||||
|
@ -253,16 +253,19 @@ func HandleGiveClue(w http.ResponseWriter, r *http.Request) {
|
|||||||
abortWithError(w, err.Error())
|
abortWithError(w, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
action := models.Action{
|
||||||
|
Actor: fi.State.Username,
|
||||||
|
ActorColor: string(fi.State.Team),
|
||||||
|
WordColor: string(fi.State.Team),
|
||||||
|
Action: "gave clue",
|
||||||
|
Word: clue,
|
||||||
|
Number: num,
|
||||||
|
}
|
||||||
|
fi.Room.ActionHistory = append(fi.Room.ActionHistory, action)
|
||||||
fi.Room.MimeDone = true
|
fi.Room.MimeDone = true
|
||||||
notify(models.NotifyMimePrefix+fi.Room.ID, clue+num)
|
notify(models.NotifyBacklogPrefix+fi.Room.ID, clue+num)
|
||||||
if err := saveFullInfo(fi); err != nil {
|
if err := saveFullInfo(fi); err != nil {
|
||||||
abortWithError(w, err.Error())
|
abortWithError(w, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// tmpl, err := template.ParseGlob("components/*.html")
|
|
||||||
// if err != nil {
|
|
||||||
// abortWithError(w, err.Error())
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// tmpl.ExecuteTemplate(w, "room", fi)
|
|
||||||
}
|
}
|
||||||
|
1
main.go
1
main.go
@ -31,6 +31,7 @@ func ListenToRequests(port string) error {
|
|||||||
mux.HandleFunc("GET /room-join", handlers.HandleJoinRoom)
|
mux.HandleFunc("GET /room-join", handlers.HandleJoinRoom)
|
||||||
mux.HandleFunc("POST /give-clue", handlers.HandleGiveClue)
|
mux.HandleFunc("POST /give-clue", handlers.HandleGiveClue)
|
||||||
//elements
|
//elements
|
||||||
|
mux.HandleFunc("GET /actionhistory", handlers.HandleActionHistory)
|
||||||
mux.HandleFunc("GET /room/createform", handlers.HandleShowCreateForm)
|
mux.HandleFunc("GET /room/createform", handlers.HandleShowCreateForm)
|
||||||
mux.HandleFunc("GET /room/hideform", handlers.HandleHideCreateForm)
|
mux.HandleFunc("GET /room/hideform", handlers.HandleHideCreateForm)
|
||||||
mux.HandleFunc("GET /word/show-color", handlers.HandleShowColor)
|
mux.HandleFunc("GET /word/show-color", handlers.HandleShowColor)
|
||||||
|
@ -9,5 +9,5 @@ var (
|
|||||||
CacheStatePrefix = "state-"
|
CacheStatePrefix = "state-"
|
||||||
// sse
|
// sse
|
||||||
NotifyRoomUpdatePrefix = "roomupdate_"
|
NotifyRoomUpdatePrefix = "roomupdate_"
|
||||||
NotifyMimePrefix = "mimeclue_"
|
NotifyBacklogPrefix = "backlog_"
|
||||||
)
|
)
|
||||||
|
@ -37,24 +37,34 @@ type Team struct {
|
|||||||
Color string
|
Color string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Action struct {
|
||||||
|
Actor string
|
||||||
|
ActorColor string
|
||||||
|
Action string // clue | guess
|
||||||
|
Word string
|
||||||
|
WordColor string
|
||||||
|
Number string // for clue
|
||||||
|
}
|
||||||
|
|
||||||
type Room struct {
|
type Room struct {
|
||||||
ID string `json:"id" db:"id"`
|
ID string `json:"id" db:"id"`
|
||||||
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||||
// RoomName string `json:"room_name"`
|
// RoomName string `json:"room_name"`
|
||||||
RoomPass string `json:"room_pass"`
|
RoomPass string `json:"room_pass"`
|
||||||
RoomLink string
|
RoomLink string
|
||||||
CreatorName string `json:"creator_name"`
|
CreatorName string `json:"creator_name"`
|
||||||
PlayerList []string `json:"player_list"`
|
PlayerList []string `json:"player_list"`
|
||||||
TeamTurn string
|
ActionHistory []Action
|
||||||
RedTeam Team
|
TeamTurn string
|
||||||
BlueTeam Team
|
RedTeam Team
|
||||||
Cards []WordCard
|
BlueTeam Team
|
||||||
Result uint8 // 0 for unknown; 1 is win for red; 2 if for blue;
|
Cards []WordCard
|
||||||
BlueCounter uint8
|
Result uint8 // 0 for unknown; 1 is win for red; 2 if for blue;
|
||||||
RedCounter uint8
|
BlueCounter uint8
|
||||||
RedTurn bool // false is blue turn
|
RedCounter uint8
|
||||||
MimeDone bool
|
RedTurn bool // false is blue turn
|
||||||
IsPublic bool
|
MimeDone bool
|
||||||
|
IsPublic bool
|
||||||
// GameSettings *GameSettings `json:"settings"`
|
// GameSettings *GameSettings `json:"settings"`
|
||||||
IsRunning bool `json:"is_running"`
|
IsRunning bool `json:"is_running"`
|
||||||
Language string `json:"language" example:"en" form:"language"`
|
Language string `json:"language" example:"en" form:"language"`
|
||||||
|
Reference in New Issue
Block a user