Rename module path github.com/ryanhamamura/c4 to github.com/ryanhamamura/games across go.mod, all source files, and golangci config.
78 lines
2.6 KiB
Plaintext
78 lines
2.6 KiB
Plaintext
package pages
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/ryanhamamura/games/chat"
|
|
chatcomponents "github.com/ryanhamamura/games/chat/components"
|
|
"github.com/ryanhamamura/games/features/common/components"
|
|
"github.com/ryanhamamura/games/features/common/layouts"
|
|
snakecomponents "github.com/ryanhamamura/games/features/snakegame/components"
|
|
"github.com/ryanhamamura/games/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 []chat.Message, chatCfg chatcomponents.Config, 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)
|
|
@chatcomponents.Chat(messages, chatCfg)
|
|
</div>
|
|
} else {
|
|
@snakecomponents.Board(sg)
|
|
}
|
|
} else if sg.Mode == snake.ModeMultiplayer {
|
|
@chatcomponents.Chat(messages, chatCfg)
|
|
}
|
|
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))
|
|
}
|
|
}
|