chore: gitignore generated _templ.go files, track .templ sources
Generated _templ.go files are deterministic output from .templ sources, same as output.css from input.css. Remove them from version control to reduce diff noise and merge conflicts. Add build:templ and live:templ tasks to the Taskfile so generation happens as part of the build.
This commit is contained in:
75
features/snakegame/pages/game.templ
Normal file
75
features/snakegame/pages/game.templ
Normal file
@@ -0,0 +1,75 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ryanhamamura/c4/features/common/components"
|
||||
"github.com/ryanhamamura/c4/features/common/layouts"
|
||||
snakecomponents "github.com/ryanhamamura/c4/features/snakegame/components"
|
||||
"github.com/ryanhamamura/c4/snake"
|
||||
"github.com/starfederation/datastar-go/datastar"
|
||||
)
|
||||
|
||||
// keydownScript builds the inline JS for a single data-on:keydown handler
|
||||
// that dispatches WASD/arrow keys to direction POST endpoints.
|
||||
func keydownScript(gameID string) string {
|
||||
return fmt.Sprintf(
|
||||
"const k=evt.key;"+
|
||||
"if(k==='w'||k==='ArrowUp'){evt.preventDefault();%s}"+
|
||||
"else if(k==='s'||k==='ArrowDown'){evt.preventDefault();%s}"+
|
||||
"else if(k==='a'||k==='ArrowLeft'){evt.preventDefault();%s}"+
|
||||
"else if(k==='d'||k==='ArrowRight'){evt.preventDefault();%s}",
|
||||
datastar.PostSSE("/snake/%s/dir?d=0", gameID),
|
||||
datastar.PostSSE("/snake/%s/dir?d=1", gameID),
|
||||
datastar.PostSSE("/snake/%s/dir?d=2", gameID),
|
||||
datastar.PostSSE("/snake/%s/dir?d=3", gameID),
|
||||
)
|
||||
}
|
||||
|
||||
templ GamePage(sg *snake.SnakeGame, mySlot int, messages []snakecomponents.ChatMessage, gameID string) {
|
||||
@layouts.Base("Snake") {
|
||||
<main
|
||||
class="snake-wrapper flex flex-col items-center gap-4 p-4"
|
||||
data-signals={ `{"chatMsg":""}` }
|
||||
data-init={ datastar.GetSSE("/snake/%s/events", gameID) }
|
||||
data-on:keydown.throttle_100ms={ keydownScript(gameID) }
|
||||
tabindex="0"
|
||||
>
|
||||
@components.BackToLobby()
|
||||
<h1 class="text-3xl font-bold">~~~~</h1>
|
||||
@snakecomponents.PlayerList(sg, mySlot)
|
||||
@snakecomponents.StatusBanner(sg, mySlot, gameID)
|
||||
if sg.Status == snake.StatusInProgress || sg.Status == snake.StatusFinished {
|
||||
if sg.Mode == snake.ModeMultiplayer {
|
||||
<div class="snake-game-area">
|
||||
@snakecomponents.Board(sg)
|
||||
@snakecomponents.Chat(messages, gameID)
|
||||
</div>
|
||||
} else {
|
||||
@snakecomponents.Board(sg)
|
||||
}
|
||||
} else if sg.Mode == snake.ModeMultiplayer {
|
||||
@snakecomponents.Chat(messages, gameID)
|
||||
}
|
||||
if sg.Mode == snake.ModeMultiplayer && (sg.Status == snake.StatusWaitingForPlayers || sg.Status == snake.StatusCountdown) {
|
||||
@snakecomponents.InviteLink(gameID)
|
||||
}
|
||||
</main>
|
||||
}
|
||||
}
|
||||
|
||||
templ JoinPage(gameID string) {
|
||||
@layouts.Base("Snake - Join") {
|
||||
@components.GameJoinPrompt(
|
||||
fmt.Sprintf("/login?return_url=/snake/%s", gameID),
|
||||
fmt.Sprintf("/register?return_url=/snake/%s", gameID),
|
||||
fmt.Sprintf("/snake/%s", gameID),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
templ NicknamePage(gameID string) {
|
||||
@layouts.Base("Snake - Join") {
|
||||
@components.NicknamePrompt(fmt.Sprintf("/snake/%s/join", gameID))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user