From 49612ba9a9cbc0c1ec2a85dd607728b68ee1fb41 Mon Sep 17 00:00:00 2001 From: johndoknjas Date: Tue, 21 Jan 2025 04:02:42 -0800 Subject: [PATCH 01/10] Only close a dialog if it is connected in the first place. --- ui/common/src/dialog.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/common/src/dialog.ts b/ui/common/src/dialog.ts index c82e6dede364e..b7c2cb454db29 100644 --- a/ui/common/src/dialog.ts +++ b/ui/common/src/dialog.ts @@ -245,7 +245,7 @@ class DialogWrapper implements Dialog { const justThen = Date.now(); const cancelOnInterval = (e: PointerEvent) => { - if (Date.now() - justThen < 200) return; + if (Date.now() - justThen < 200 || !dialog.isConnected) return; const r = dialog.getBoundingClientRect(); if (e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom) this.close('cancel'); From 460a390f64b23572924ef582b4e400df44b3ee61 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 21 Jan 2025 18:27:03 +0100 Subject: [PATCH 02/10] code tweak --- modules/relay/src/main/RelayFetch.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/relay/src/main/RelayFetch.scala b/modules/relay/src/main/RelayFetch.scala index a2782b901773b..c3b85eb992f42 100644 --- a/modules/relay/src/main/RelayFetch.scala +++ b/modules/relay/src/main/RelayFetch.scala @@ -166,11 +166,10 @@ final private class RelayFetch( ) private def reportBroadcastFailure(r: RelayRound.WithTour): Unit = - if r.round.sync.log.alwaysFails then + if r.round.sync.log.alwaysFails && r.tour.official && r.round.shouldHaveStarted then r.round.sync.log.events.lastOption .filterNot(_.isTimeout) .flatMap(_.error) - .ifTrue(r.tour.official && r.round.shouldHaveStarted) .filterNot(_.contains("Cannot parse move")) .filterNot(_.contains("Cannot parse pgn")) .filterNot(_.contains("Found an empty PGN")) From 4993e1c77376643c60f1545f28f40559477306d2 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 21 Jan 2025 18:27:10 +0100 Subject: [PATCH 03/10] report image upload errors --- app/controllers/Main.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/Main.scala b/app/controllers/Main.scala index db702e8c60c1d..bfdff3890b9bd 100644 --- a/app/controllers/Main.scala +++ b/app/controllers/Main.scala @@ -144,5 +144,7 @@ final class Main( env.memo.picfitApi.bodyImage .upload(rel, image) .map(url => JsonOk(Json.obj("imageUrl" -> url))) + .recover: + case e: Exception => JsonBadRequest(jsonError(e.getMessage)) case None => JsonBadRequest(jsonError("Image content only")) } From f3187e7a465e12ade6fd6dac05ab1c45644abdda Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 21 Jan 2025 19:01:16 +0100 Subject: [PATCH 04/10] add vukovicMate puzzle theme - closes #16792 --- modules/coreI18n/src/main/key.scala | 2 ++ modules/puzzle/src/main/PuzzleTheme.scala | 2 ++ public/images/puzzle-themes/vukovicMate.svg | 1 + translation/source/puzzleTheme.xml | 2 ++ 4 files changed, 7 insertions(+) create mode 100644 public/images/puzzle-themes/vukovicMate.svg diff --git a/modules/coreI18n/src/main/key.scala b/modules/coreI18n/src/main/key.scala index 54709bfa51958..8606a864ab997 100644 --- a/modules/coreI18n/src/main/key.scala +++ b/modules/coreI18n/src/main/key.scala @@ -1278,6 +1278,8 @@ object I18nKey: val `intermezzoDescription`: I18nKey = "puzzleTheme:intermezzoDescription" val `killBoxMate`: I18nKey = "puzzleTheme:killBoxMate" val `killBoxMateDescription`: I18nKey = "puzzleTheme:killBoxMateDescription" + val `vukovicMate`: I18nKey = "puzzleTheme:vukovicMate" + val `vukovicMateDescription`: I18nKey = "puzzleTheme:vukovicMateDescription" val `knightEndgame`: I18nKey = "puzzleTheme:knightEndgame" val `knightEndgameDescription`: I18nKey = "puzzleTheme:knightEndgameDescription" val `long`: I18nKey = "puzzleTheme:long" diff --git a/modules/puzzle/src/main/PuzzleTheme.scala b/modules/puzzle/src/main/PuzzleTheme.scala index 8dacb99dc2d7f..c5582232b24c5 100644 --- a/modules/puzzle/src/main/PuzzleTheme.scala +++ b/modules/puzzle/src/main/PuzzleTheme.scala @@ -50,6 +50,7 @@ object PuzzleTheme: val intermezzo = PuzzleTheme(i.intermezzo, i.intermezzoDescription) val kingsideAttack = PuzzleTheme(i.kingsideAttack, i.kingsideAttackDescription) val killBoxMate = PuzzleTheme(i.killBoxMate, i.killBoxMateDescription) + val vukovicMate = PuzzleTheme(i.vukovicMate, i.vukovicMateDescription) val knightEndgame = PuzzleTheme(i.knightEndgame, i.knightEndgameDescription) val long = PuzzleTheme(i.long, i.longDescription) val master = PuzzleTheme(i.master, i.masterDescription) @@ -141,6 +142,7 @@ object PuzzleTheme: dovetailMate, hookMate, killBoxMate, + vukovicMate, smotheredMate ), I18nKey.puzzle.specialMoves -> List( diff --git a/public/images/puzzle-themes/vukovicMate.svg b/public/images/puzzle-themes/vukovicMate.svg new file mode 100644 index 0000000000000..e18eabaabdbb4 --- /dev/null +++ b/public/images/puzzle-themes/vukovicMate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/translation/source/puzzleTheme.xml b/translation/source/puzzleTheme.xml index dfaa121997ba2..5ad8952a72744 100644 --- a/translation/source/puzzleTheme.xml +++ b/translation/source/puzzleTheme.xml @@ -59,6 +59,8 @@ Instead of playing the expected move, first interpose another move posing an immediate threat that the opponent must answer. Also known as "Zwischenzug" or "In between". Kill box mate A rook is next to the enemy king and supported by a queen that also blocks the king's escape squares. The rook and the queen catch the enemy king in a 3 by 3 "kill box". + Vukovic mate + A rook and knight team up to mate the king. The rook delivers mate while supported by a third piece, and the knight is used to block the king's escape squares. Knight endgame An endgame with only knights and pawns. Long puzzle From 627c653d0478ac02496b5484802d2088a6fa661a Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Thu, 16 Jan 2025 23:30:29 +0100 Subject: [PATCH 05/10] didn't actually cause any bug --- modules/core/src/main/game/Game.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/core/src/main/game/Game.scala b/modules/core/src/main/game/Game.scala index 7dcb833233177..345722c7b2c6d 100644 --- a/modules/core/src/main/game/Game.scala +++ b/modules/core/src/main/game/Game.scala @@ -258,8 +258,7 @@ case class Game( yield w -> b def averageUsersRating: Option[IntRating] = players.flatMap(_.rating) match - // case a :: b :: Nil => Some((a + b).map(_ / 2)) - case a :: b :: Nil => Some((a + b)) + case a :: b :: Nil => Some((a + b).map(_ / 2)) case a :: Nil => Some((a + IntRating(1500)).map(_ / 2)) case _ => None From 88a865fd06f237ca4726f640d361e63002807827 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 21 Jan 2025 19:09:18 +0100 Subject: [PATCH 06/10] script to add a theme to puzzle ids --- bin/mongodb/puzzle-add-theme.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 bin/mongodb/puzzle-add-theme.js diff --git a/bin/mongodb/puzzle-add-theme.js b/bin/mongodb/puzzle-add-theme.js new file mode 100644 index 0000000000000..8f00de8b1e53f --- /dev/null +++ b/bin/mongodb/puzzle-add-theme.js @@ -0,0 +1,8 @@ +puzzleDb = connect(`mongodb://localhost:27317/puzzler`); +ids = ''.split(' '); +ids.forEach(id => { + puzzleDb.puzzle2_round.updateOne({ _id: 'lichess:' + id }, { + $push: { t: '+vukovicMate' } + }); +}); +puzzleDb.puzzle2_puzzle.updateMany({ _id: { $in: ids } }, { $set: { dirty: true } }); From c47478f1b513e95328a452178e42140d26d786b1 Mon Sep 17 00:00:00 2001 From: Jonathan Gamble <101470903+schlawg@users.noreply.github.com> Date: Tue, 21 Jan 2025 12:28:58 -0600 Subject: [PATCH 07/10] normal weight on broadcast/study player clock --- ui/analyse/css/study/_player.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/analyse/css/study/_player.scss b/ui/analyse/css/study/_player.scss index b475b4041fc7a..a8ea747c218df 100644 --- a/ui/analyse/css/study/_player.scss +++ b/ui/analyse/css/study/_player.scss @@ -63,13 +63,13 @@ $player-height: 1.6rem; .analyse__clock { @extend %roboto, %flex-center-nowrap; - - height: 100%; - font-size: 1.2em; @include padding-direction(0, 0.8em, 0, 0.6em); + height: 100%; border-radius: 0 4px 0 0; box-shadow: none; + font-size: 1.2em; + font-weight: normal; } &-bot .analyse__clock { From b19cbaae6b4b63565f15a4f59720bf922f78c56d Mon Sep 17 00:00:00 2001 From: Jonathan Gamble <101470903+schlawg@users.noreply.github.com> Date: Tue, 21 Jan 2025 15:04:17 -0600 Subject: [PATCH 08/10] don't leak common.ts snabDialog wrappers --- ui/analyse/src/explorer/explorerConfig.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ui/analyse/src/explorer/explorerConfig.ts b/ui/analyse/src/explorer/explorerConfig.ts index 72935df2c22e3..9ae234b6e4080 100644 --- a/ui/analyse/src/explorer/explorerConfig.ts +++ b/ui/analyse/src/explorer/explorerConfig.ts @@ -1,7 +1,7 @@ import { h, VNode } from 'snabbdom'; import { myUserId, type Prop, prop } from 'common'; import * as licon from 'common/licon'; -import { snabDialog } from 'common/dialog'; +import { type Dialog, snabDialog } from 'common/dialog'; import { bind, dataIcon, iconTag, onInsert } from 'common/snabbdom'; import { storedProp, storedJsonProp, type StoredProp, storedStringProp } from 'common/storage'; import { ExplorerDb, ExplorerSpeed, ExplorerMode } from './interfaces'; @@ -46,6 +46,7 @@ export class ExplorerConfigCtrl { allDbs: ExplorerDb[] = ['lichess', 'player']; myName?: string; participants: (string | undefined)[]; + modal?: Dialog; constructor( readonly root: AnalyseCtrl, @@ -100,7 +101,6 @@ export class ExplorerConfigCtrl { } this.data.db('player'); this.data.playerName.value(name); - this.data.playerName.open(false); }; removePlayer = (name?: string) => { @@ -313,9 +313,10 @@ const monthSection = (ctrl: ExplorerConfigCtrl) => ]); const playerModal = (ctrl: ExplorerConfigCtrl) => { + let dlg: Dialog; const onSelect = (name: string | undefined) => { ctrl.selectPlayer(name); - ctrl.root.redraw(); + dlg.close(); }; const nameToOptionalColor = (name: string | undefined) => { if (!name) { @@ -333,6 +334,7 @@ const playerModal = (ctrl: ExplorerConfigCtrl) => { ctrl.data.playerName.open(false); ctrl.root.redraw(); }, + onInsert: dialog => (dlg = dialog).show(), modal: true, vnodes: [ h('h2', 'Personal opening explorer'), From 93ac2a67420da7c7a7269df822d26b1f9d760de0 Mon Sep 17 00:00:00 2001 From: Jonathan Gamble <101470903+schlawg@users.noreply.github.com> Date: Tue, 21 Jan 2025 15:07:00 -0600 Subject: [PATCH 09/10] remove unused class member --- ui/analyse/src/explorer/explorerConfig.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/analyse/src/explorer/explorerConfig.ts b/ui/analyse/src/explorer/explorerConfig.ts index 9ae234b6e4080..f78cae3ae25b9 100644 --- a/ui/analyse/src/explorer/explorerConfig.ts +++ b/ui/analyse/src/explorer/explorerConfig.ts @@ -46,7 +46,6 @@ export class ExplorerConfigCtrl { allDbs: ExplorerDb[] = ['lichess', 'player']; myName?: string; participants: (string | undefined)[]; - modal?: Dialog; constructor( readonly root: AnalyseCtrl, From cf0cae6f05aa7ac498cbbbaea59d82ab2423ddcb Mon Sep 17 00:00:00 2001 From: Jonathan Gamble <101470903+schlawg@users.noreply.github.com> Date: Tue, 21 Jan 2025 15:19:05 -0600 Subject: [PATCH 10/10] prettier --- bin/mongodb/puzzle-add-theme.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bin/mongodb/puzzle-add-theme.js b/bin/mongodb/puzzle-add-theme.js index 8f00de8b1e53f..4d87241fcb3c3 100644 --- a/bin/mongodb/puzzle-add-theme.js +++ b/bin/mongodb/puzzle-add-theme.js @@ -1,8 +1,11 @@ puzzleDb = connect(`mongodb://localhost:27317/puzzler`); ids = ''.split(' '); ids.forEach(id => { - puzzleDb.puzzle2_round.updateOne({ _id: 'lichess:' + id }, { - $push: { t: '+vukovicMate' } - }); + puzzleDb.puzzle2_round.updateOne( + { _id: 'lichess:' + id }, + { + $push: { t: '+vukovicMate' }, + }, + ); }); puzzleDb.puzzle2_puzzle.updateMany({ _id: { $in: ids } }, { $set: { dirty: true } });