dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

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:
Mpkg/web/handlers/chess.go | 98++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Mpkg/web/handlers/interceptors/chess.go | 9++++++++-
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;">