commit 0d509722492a4d154174d578f1cf2974c9560be9
parent 76095ef63e70b7b1c2afe1cb385e773a61d16476
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Thu, 15 Jun 2023 08:32:53 -0700
click board to move to next/prev position
Diffstat:
2 files changed, 93 insertions(+), 14 deletions(-)
diff --git a/pkg/web/handlers/chess.go b/pkg/web/handlers/chess.go
@@ -246,6 +246,7 @@ func ChessGameAnalyseHandler(c echo.Context) error {
func ChessGameStatsHandler(c echo.Context) error {
key := c.Param("key")
authUser := c.Get("authUser").(*database.User)
+ csrf, _ := c.Get("csrf").(string)
g, err := interceptors.ChessInstance.GetGame(key)
if err != nil {
return c.NoContent(http.StatusOK)
@@ -265,10 +266,20 @@ func ChessGameStatsHandler(c echo.Context) error {
.graph td:hover {
background-color: #5c5c5c;
}
+.graph form {
+ height: 100%;
+ width: {{ .ColumnWidth }}px;
+ position: relative;
+ border: none;
+}
.graph .column-wrapper-wrapper {
height: 100%;
width: {{ .ColumnWidth }}px;
position: relative;
+ border: none;
+ background-color: transparent;
+ cursor: pointer;
+ padding: 0;
}
.graph .column-wrapper {
height: 50%;
@@ -287,18 +298,22 @@ func ChessGameStatsHandler(c echo.Context) error {
{{ range $idx, $el := .Stats.Scores }}
<td title="{{ $idx | fmtMove }} {{ $el.Move }} | Advantage: {{ if not $el.Mate }}{{ $el.CP | cp }}{{ else }}#{{ $el.Mate }}{{ end }}">
{{ $el.BestMove | commentHTML }}
- <a class="column-wrapper-wrapper" href="/chess/{{ $.Key }}/stats?m={{ $idx | plus }}" style="display: block;{{ if eq $.MoveIdx ($idx | plus) }} background-color: rgba(255, 255, 0, 0.2);{{ end }}">
- <div class="column-wrapper">
- {{ if ge .CP 0 }}
- <div class="column" style="height: {{ $el | renderCP "white" }}px; background-color: #eee; bottom: 0;"></div>
- {{ end }}
- </div>
- <div class="column-wrapper">
- {{ if le .CP 0 }}
- <div class="column" style="height: {{ $el | renderCP "black" }}px; background-color: #111;"></div>
- {{ end }}
- </div>
- </div>
+ <form method="post" target="iframeForm" action="/chess/{{ $.Key }}/form">
+ <input type="hidden" name="csrf" value="{{ $.CSRF }}" />
+ <input type="hidden" name="move_idx" value="{{ $idx | plus }}" />
+ <button type="submit" class="column-wrapper-wrapper" style="display: block;{{ if eq $.MoveIdx ($idx | plus) }} background-color: rgba(255, 255, 0, 0.2);{{ end }}">
+ <div class="column-wrapper" style="border-bottom: 1px solid #333; box-sizing: border-box;">
+ {{ if ge .CP 0 }}
+ <div class="column" style="height: {{ $el | renderCP "white" }}px; background-color: #eee; bottom: 0;"></div>
+ {{ end }}
+ </div>
+ <div class="column-wrapper">
+ {{ if le .CP 0 }}
+ <div class="column" style="height: {{ $el | renderCP "black" }}px; background-color: #111;"></div>
+ {{ end }}
+ </div>
+ </button>
+ </form>
</td>
{{ end }}
</tr>
@@ -328,6 +343,7 @@ func ChessGameStatsHandler(c echo.Context) error {
"Stats": stats,
"ColumnWidth": columnWidth,
"MoveIdx": moveIdx,
+ "CSRF": csrf,
}
fns := template.FuncMap{
@@ -387,7 +403,63 @@ func ChessGameFormHandler(c echo.Context) error {
isFlipped := g.IsBlack(authUser.ID)
if game.Outcome() != chess.NoOutcome {
- return c.NoContent(http.StatusOK)
+ htmlTmpl := `
+<style>
+button {
+ width: 50%;
+ background-color: transparent;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ border: none;
+}
+</style>
+<form method="post">
+ <input type="hidden" name="csrf" value="{{ .CSRF }}" />
+ <input type="hidden" name="move_idx" value="{{ .MoveIdx }}" />
+ <div style="position: fixed; top: 0; left: 0; right: 0; bottom: 0;">
+ <button name="btn_submit" value="prev_position" type="submit"></button>
+ <button name="btn_submit" value="next_position" type="submit" style="right: 0;"></button>
+ </div>
+</form>`
+
+ data := map[string]any{
+ "CSRF": csrf,
+ "MoveIdx": -1,
+ }
+
+ if c.Request().Method == http.MethodPost {
+ btnSubmit := c.Request().PostFormValue("btn_submit")
+ moveIdx, _ := strconv.Atoi(c.Request().PostFormValue("move_idx"))
+
+ var stats *interceptors.AnalyseResult
+ _ = json.Unmarshal(g.DbChessGame.Stats, &stats)
+
+ if moveIdx == -1 {
+ moveIdx = len(stats.Scores)
+ }
+ if btnSubmit == "prev_position" {
+ moveIdx -= 1
+ } else if btnSubmit == "next_position" {
+ moveIdx += 1
+ }
+ moveIdx = utils.Clamp(moveIdx, 0, len(stats.Scores))
+ var bestMove string
+ if stats != nil {
+ if len(stats.Scores) > 0 {
+ if moveIdx > 0 {
+ bestMove = stats.Scores[moveIdx-1].BestMove
+ }
+ }
+ }
+ interceptors.ChessPubSub.Pub(key+"_"+authUser.Username.String(), interceptors.ChessMove{MoveIdx: moveIdx, BestMove: bestMove})
+ data["MoveIdx"] = moveIdx
+ }
+
+ var buf bytes.Buffer
+ _ = utils.Must(template.New("").Parse(htmlTmpl)).Execute(&buf, data)
+
+ return c.HTML(http.StatusOK, buf.String())
}
if c.Request().Method == http.MethodPost {
diff --git a/pkg/web/handlers/interceptors/chess.go b/pkg/web/handlers/interceptors/chess.go
@@ -431,7 +431,14 @@ func (g *ChessGame) drawPlayerCard(moveIdx int, key string, isBlack, isSpectator
</tr>
<tr>
<td colspan="2">
- {{ if or .IsSpectator .GameOver }}
+ {{ if .GameOver }}
+ <div style="position: relative;">
+ <iframe name="iframeForm" src="/chess/{{ .Key }}/form" style="position: absolute; top: 0; left: 0; border: 0px solid red; z-index: 999; width: 100%; height: 100%;"></iframe>
+ <div style="aspect-ratio: 1/1; height: 70%;">
+ {{ .Table }}
+ </div>
+ </div>
+ {{ else if or .IsSpectator }}
{{ .Table }}
{{ else }}
<div style="position: relative;">