diff --git a/css/chess.css b/css/chess.css index caf229c..a3496fc 100644 --- a/css/chess.css +++ b/css/chess.css @@ -2,92 +2,315 @@ box-sizing: border-box; } +html, body, #page { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + overflow: hidden; + background: white; +} + body { font-family: 'Roboto', sans-serif; padding: 0; margin: 0; } -#page { +body > #page { + position: fixed; + top: 0; + left: 0; width: 100%; - height: 100vh; - display: flex; - flex-flow: column nowrap; -} - -h1 { - font-family: 'Vollkorn', serif; - font-size: 2em; - line-height: 1.4em; - height: 1.4em; - margin-top: 8px; - margin-left: 8px; - margin-bottom: 0; -} - -a.plain-link { - font-family: inherit; - font-size: inherit; - font-weight: inherit; - line-height: inherit; - color: inherit; - background-color: inherit; - text-decoration: inherit; -} - -.media-button-svg { - width: 12pt; - height: 12pt; -} - -button:disabled .silhouette { - fill: #c0c0c0; -} - -#content { display: flex; flex-flow: row nowrap; } -#cb_outer2 { - flex: 1 1 auto; - width: 100%; - max-width: calc(100vh - (8px + 2.8em + 8px)); - margin-left: 8px; +#page.horizontal-layout #board_ui { + border-left: 1px solid black; } -#cb_outer { +#board_ui { + display: flex; + flex-flow: column nowrap; + justify-content: stretch; + align-items: center; width: 100%; - max-width: calc(100vw - (8px + 24px)); + height: 100%; +} + +#header { + display: flex; + flex-flow: row nowrap; + flex: 0 0 auto; + width: 100%; + height: 2.5rem; + font-size: 2rem; + line-height: 2.4rem; + margin: 0; + background-image: linear-gradient(#FFFFF0, #F5DEB3); + border-bottom: 1px solid black; + align-items: center; +} + +#header > h1 { + font-family: 'Vollkorn', serif; + width: 100%; + text-align: center; + font-size: 1.2rem; + line-height: 2.4rem; + margin: 0; + padding: 0; + padding-top: 0.1rem; + height: 2.5rem; +} + +#header > button { + width: 4rem; + height: 2.5rem; + border: none; + background: none; + padding: 0; + margin: 0; +} + +#header > button:active { + background-image: linear-gradient(#F5DEB3, #FFFFF0); +} + +input.image-checkbox { + display: inline-block; + -webkit-appearance: none; + appearance: none; + padding: 0; + margin: 0; +} + +input.image-checkbox:checked { + color: #00f; +} + +input.image-checkbox:focus { + outline: blue solid medium; + outline: -webkit-focus-ring-color solid medium; + outline-offset: 3px; +} + +#header > .checkbox-container { + display: flex; + flex-flow: column nowrap; + justify-content: center; + align-items: center; + width: 4rem; + height: 2.5rem; + border: none; + background: none; +} + +button#settings, button#cb_choose_game { + border-right: 1px solid #DCC8A1; +} + +#header > .checkbox-container, button#help { + border-left: 1px solid #DCC8A1; } #cb_container { - position: relative; width: 100%; - padding-top: 100%; + flex: 1 1 auto; + position: relative; } -#cb_inner { - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; +#page.horizontal-layout #cb_container { + flex: 0 0.5 auto; } #cb_board { - position: relative; - width: 100%; - height: 100%; + position: absolute; border-collapse: collapse; border-style: hidden; - padding-top: 100%; box-shadow: 0 0 0 1px black, 2px 2px 4px #00000080; border-radius: 6pt; overflow: hidden; background-color: #FAEED2; } +#cb_status { + display: flex; + position: relative; + flex-flow: column nowrap; + width: 100%; + padding-top: 0.25rem; + padding-left: 0.25rem; + padding-right: 0.25rem; + padding-bottom: 0.5rem; +} + +#page.horizontal-layout #cb_status { + flex: 1 1 auto; +} + +#cb_status::after { + content: ''; + display: block; + position: absolute; + width: 100%; + height: 1.5em; + left: 0; + bottom: 0.5rem; + background: linear-gradient(rgba(255,255,255,0), white); + pointer-events: none; +} + +#cb_message { + height: 1.2em; + margin-bottom: 0.1rem; +} + +#cb_explain_check { + color: red; + height: 2.4em; + margin-bottom: 0.1em; +} + +#cb_scrollable { + flex: 0 0 auto; + overflow: auto; + height: 4.8em; + padding-bottom: 1.2em; +} + +#page.horizontal-layout #cb_scrollable { + flex: 1 1 auto; +} + +#cb_history { + color: black; +} + +#cb_history_future { + color: grey; +} + +#cb_names { + position: relative; + display: flex; + flex-flow: row nowrap; + white-space: nowrap; + justify-content: stretch; + align-items: flex-end; + font-size: 1.5rem; + width: 100%; + height: 3rem; + padding-left: 2rem; + padding-right: 2rem; +} + +#cb_names_text { + display: flex; + flex-flow: row nowrap; + white-space: nowrap; + justify-content: stretch; + align-items: baseline; + width: 100%; +} + +#cb_names::before { + content: ''; + display: block; + background-image: url(../svg/pacosako-theme.svg#light_king_left); + background-size: contain; + background-repeat: no-repeat; + position: absolute; + bottom: 0; + left: 0.5rem; + width: 3rem; + height: 3rem; + z-index: -1; +} + +#cb_names::after { + content: ''; + display: block; + background-image: url(../svg/pacosako-theme.svg#dark_king_right); + background-size: contain; + background-repeat: no-repeat; + position: absolute; + bottom: 0; + right: 0.5rem; + width: 3rem; + height: 3rem; + z-index: -1; +} + +#cb_names .cb-names-vs { + padding-left: 0.25em; + padding-right: 0.25em; +} + +#cb_names input { + flex: 1 1 auto; + width: 4em; + background-color: inherit; + border: none; + margin: 2px; + font-size: 1.5rem; +} + +#cb_names input:focus { + outline: 1px solid blue; + outline-offset: 2px; +} + +#cb_dark_name { + text-align: right; +} + +#cb_navigate { + display: flex; + flex-flow: row nowrap; + align-items: stretch; + justify-content: stretch; + border-top: 1px solid black; + background-image: linear-gradient(#FFFFF0, #F5DEB3); + white-space: nowrap; + width: 100%; + flex: 0 1 auto; + font-size: 1.25rem; +} + +#cb_navigate .nav-spacer { + flex: 1 1 auto; + min-width: 1rem; + width: 100%; + background: none; + background-color: #DCC8A140; +} + +#cb_navigate button { + padding: 0; + margin: 0; + border: none; + width: 2rem; + min-width: 2rem; + min-height: 2rem; + background: none; + font-size: inherit; +} + +#cb_navigate button:active { + background-image: linear-gradient(#F5DEB3, #FFFFF0); +} + +#cb_navigate > .nav-spacer, #cb_navigate > button { + border-left: 1px solid #DCC8A1; +} + +#cb_navigate > .nav-spacer:first-child, #cb_navigate > button:first-child { + border-left: none; +} + #cb_board tr { position: relative; } @@ -97,163 +320,14 @@ button:disabled .silhouette { position: relative; } -#cb_light_name, #cb_dark_name { - width: 8em; -} - -#cb_control_container { - display: flex; - flex-flow: column nowrap; - flex: 0 1000 auto; - margin-left: 1em; - width: 100%; - min-width: 24em; - max-height: calc(100vh - (8px + 2.8em)); - padding-right: calc(3.25em + 10px); -} - -#cb_control_form { - flex: 0 1 auto; - display: flex; - flex-flow: column nowrap; - margin-right: auto; - border-radius: 6pt; - padding: 1.125em; - background-color: #FFFFF0; - box-shadow: 0 0 0 1px black, 2px 2px 4px #00000080; -} - -#cb_controls, #cb_theme, #cb_names, #cb_navigate { - white-space: nowrap; -} - -#cb_theme, #cb_names, #cb_navigate { - margin-top: 1.125em; -} - -#cb_names input { - background-color: inherit; - border: none; - border-bottom: 1px solid black; - margin: 2px; -} - -#cb_names input:focus { - outline: 1px solid blue; - outline-offset: 2px; -} - -#cb_scrollable { - flex: 1 1000 auto; - padding-bottom: 0.5em; - overflow: auto; -} - -#cb_message { - margin-top: 0.5em; - margin-bottom: 1em; -} - -#cb_theme { - display: flex; - flex-flow: row nowrap; - align-items: baseline; -} - -.cb-spacer { - flex: 1 1 auto; -} - -#cb_choose_game { - margin-left: 0.2em; -} - -#cb_theme label { - flex: 0 0 auto; - padding-right: 0.2em; -} - -#cb_undo { - margin-left: auto; - margin-right: 0.1em; -} - -#cb_redo { - margin-left: 0.1em; - margin-right: auto; -} - -#cb_resign { - margin-left: 0.1em; - margin-right: 0; -} - -#cb_navigate { - display: flex; - flex-flow: row nowrap; - justify-items: center; - justify-content: center; - padding-left: 1em; -} - -#cb_navigate button { - margin-left: 0.1em; - margin-right: 0.1em; -} - -#cb_navigate button:first-child { - margin-left: 0; -} - -#cb_navigate button:last-child { - margin-right: 0; -} - -#cb_history { - max-width: 7.5in; - margin-bottom: 0.5em; -} - -#cb_history_future { - color: grey; -} - -#cb_explain_check { - color: red; - margin-top: 0.5em; -} - -.cb-hbox { - display: flex; - flex-flow: row nowrap; - align-items: center; -} - -.cb-vbox { - display: flex; - flex-flow: column nowrap; - align-items: center; -} - -.cb-align-start { - align-items: start; -} - -.cb-align-stretch { - align-items: stretch; -} - .cb-square { position: relative; - width: calc((100% - 16pt) / 8); - height: calc((100% - 16pt) / 8); border: 1px solid black; padding: 0; } .cb-horiz-label { position: relative; - width: calc((100% - 16pt) / 8); height: 8pt; border: 1px solid black; padding: 0; @@ -261,7 +335,7 @@ button:disabled .silhouette { .cb-horiz-label div { position: absolute; - top: calc(50% - (1em / 2)); + top: calc(50% - 3pt); left: 0; bottom: 0; right: 0; @@ -273,7 +347,6 @@ button:disabled .silhouette { .cb-vert-label { position: relative; width: 8pt; - height: calc((100% - 16pt) / 8); border: 1px solid black; padding: 0; } @@ -393,13 +466,25 @@ button:disabled .silhouette { z-index: 1; } -.badges { - position: fixed; - bottom: 5px; - right: 5px; +.jBox-title h2 { margin: 0; +} + +.rules { + display: block; + max-width: 80vw; +} + +.badges { + position: static; + bottom: auto; + right: auto; + margin-top: 0; + margin-bottom: 0; + margin-left: auto; + margin-right: 5px; display: flex; - flex-flow: column nowrap; + flex-flow: row nowrap; justify-content: flex-end; align-items: center; } @@ -409,16 +494,21 @@ button:disabled .silhouette { } .badge img { - width: 3em; - height: 3em; - opacity: 0.5; + width: 3rem; + height: 3rem; margin: 0; } -.badge.game-link-badge img { - width: 1.8em; - height: 1.8em; - margin: 0.6em; +#cb_theme { + display: flex; + flex-flow: row nowrap; + align-items: baseline; + margin-top: 1rem; +} + +#cb_theme label { + flex: 0 0 auto; + padding-right: 0.2rem; } .game-tiles { @@ -612,61 +702,30 @@ button:disabled .silhouette { } } -@media only screen and (max-aspect-ratio: 3/2) { - #content { - flex-flow: column nowrap; - } +.cb-dk-piece.cb-king { content: url(../svg/pacosako-theme.svg#dark_king_right); } +.cb-dk-piece.cb-queen { content: url(../svg/pacosako-theme.svg#dark_queen_right); } +.cb-dk-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#dark_bishop_right); } +.cb-dk-piece.cb-knight { content: url(../svg/pacosako-theme.svg#dark_knight_right); } +.cb-dk-piece.cb-rook { content: url(../svg/pacosako-theme.svg#dark_rook_right); } +.cb-dk-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#dark_pawn_right); } +.cb-lt-piece.cb-king { content: url(../svg/pacosako-theme.svg#light_king_left); } +.cb-lt-piece.cb-queen { content: url(../svg/pacosako-theme.svg#light_queen_left); } +.cb-lt-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#light_bishop_left); } +.cb-lt-piece.cb-knight { content: url(../svg/pacosako-theme.svg#light_knight_left); } +.cb-lt-piece.cb-rook { content: url(../svg/pacosako-theme.svg#light_rook_left); } +.cb-lt-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#light_pawn_left); } - #cb_outer2 { - width: auto; - } - - #cb_control_container { - margin-top: 1em; - margin-left: 8px; - max-height: none; - overflow: visible; - width: 100%; - max-width: calc(100vw - (8px + 24px)); - padding-right: 0; - } - - .badges { - position: static; - bottom: auto; - right: auto; - margin-left: auto; - margin-right: 5px; - display: flex; - flex-flow: row nowrap; - justify-content: flex-end; - } -} - -.cb-dk-piece.cb-king { content: url(../svg/traditional-theme.svg#dark_king_right); } -.cb-dk-piece.cb-queen { content: url(../svg/traditional-theme.svg#dark_queen_right); } -.cb-dk-piece.cb-bishop { content: url(../svg/traditional-theme.svg#dark_bishop_right); } -.cb-dk-piece.cb-knight { content: url(../svg/traditional-theme.svg#dark_knight_right); } -.cb-dk-piece.cb-rook { content: url(../svg/traditional-theme.svg#dark_rook_right); } -.cb-dk-piece.cb-pawn { content: url(../svg/traditional-theme.svg#dark_pawn_right); } -.cb-lt-piece.cb-king { content: url(../svg/traditional-theme.svg#light_king_left); } -.cb-lt-piece.cb-queen { content: url(../svg/traditional-theme.svg#light_queen_left); } -.cb-lt-piece.cb-bishop { content: url(../svg/traditional-theme.svg#light_bishop_left); } -.cb-lt-piece.cb-knight { content: url(../svg/traditional-theme.svg#light_knight_left); } -.cb-lt-piece.cb-rook { content: url(../svg/traditional-theme.svg#light_rook_left); } -.cb-lt-piece.cb-pawn { content: url(../svg/traditional-theme.svg#light_pawn_left); } - -.cb-reversed .cb-dk-piece.cb-king { content: url(../svg/traditional-theme.svg#dark_king_left); } -.cb-reversed .cb-dk-piece.cb-queen { content: url(../svg/traditional-theme.svg#dark_queen_left); } -.cb-reversed .cb-dk-piece.cb-bishop { content: url(../svg/traditional-theme.svg#dark_bishop_left); } -.cb-reversed .cb-dk-piece.cb-knight { content: url(../svg/traditional-theme.svg#dark_knight_left); } -.cb-reversed .cb-dk-piece.cb-rook { content: url(../svg/traditional-theme.svg#dark_rook_left); } -.cb-reversed .cb-dk-piece.cb-pawn { content: url(../svg/traditional-theme.svg#dark_pawn_left); } -.cb-reversed .cb-lt-piece.cb-king { content: url(../svg/traditional-theme.svg#light_king_right); } -.cb-reversed .cb-lt-piece.cb-queen { content: url(../svg/traditional-theme.svg#light_queen_right); } -.cb-reversed .cb-lt-piece.cb-bishop { content: url(../svg/traditional-theme.svg#light_bishop_right); } -.cb-reversed .cb-lt-piece.cb-knight { content: url(../svg/traditional-theme.svg#light_knight_right); } -.cb-reversed .cb-lt-piece.cb-rook { content: url(../svg/traditional-theme.svg#light_rook_right); } -.cb-reversed .cb-lt-piece.cb-pawn { content: url(../svg/traditional-theme.svg#light_pawn_right); } +.cb-reversed .cb-dk-piece.cb-king { content: url(../svg/pacosako-theme.svg#dark_king_left); } +.cb-reversed .cb-dk-piece.cb-queen { content: url(../svg/pacosako-theme.svg#dark_queen_left); } +.cb-reversed .cb-dk-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#dark_bishop_left); } +.cb-reversed .cb-dk-piece.cb-knight { content: url(../svg/pacosako-theme.svg#dark_knight_left); } +.cb-reversed .cb-dk-piece.cb-rook { content: url(../svg/pacosako-theme.svg#dark_rook_left); } +.cb-reversed .cb-dk-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#dark_pawn_left); } +.cb-reversed .cb-lt-piece.cb-king { content: url(../svg/pacosako-theme.svg#light_king_right); } +.cb-reversed .cb-lt-piece.cb-queen { content: url(../svg/pacosako-theme.svg#light_queen_right); } +.cb-reversed .cb-lt-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#light_bishop_right); } +.cb-reversed .cb-lt-piece.cb-knight { content: url(../svg/pacosako-theme.svg#light_knight_right); } +.cb-reversed .cb-lt-piece.cb-rook { content: url(../svg/pacosako-theme.svg#light_rook_right); } +.cb-reversed .cb-lt-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#light_pawn_right); } /* vim: set expandtab sw=3 ts=8: */ diff --git a/css/theme/traditional.css b/css/theme/traditional.css new file mode 100644 index 0000000..41740f9 --- /dev/null +++ b/css/theme/traditional.css @@ -0,0 +1,25 @@ +.cb-theme-traditional .cb-dk-piece.cb-king { content: url(../../svg/traditional-theme.svg#dark_king_right); } +.cb-theme-traditional .cb-dk-piece.cb-queen { content: url(../../svg/traditional-theme.svg#dark_queen_right); } +.cb-theme-traditional .cb-dk-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#dark_bishop_right); } +.cb-theme-traditional .cb-dk-piece.cb-knight { content: url(../../svg/traditional-theme.svg#dark_knight_right); } +.cb-theme-traditional .cb-dk-piece.cb-rook { content: url(../../svg/traditional-theme.svg#dark_rook_right); } +.cb-theme-traditional .cb-dk-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#dark_pawn_right); } +.cb-theme-traditional .cb-lt-piece.cb-king { content: url(../../svg/traditional-theme.svg#light_king_left); } +.cb-theme-traditional .cb-lt-piece.cb-queen { content: url(../../svg/traditional-theme.svg#light_queen_left); } +.cb-theme-traditional .cb-lt-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#light_bishop_left); } +.cb-theme-traditional .cb-lt-piece.cb-knight { content: url(../../svg/traditional-theme.svg#light_knight_left); } +.cb-theme-traditional .cb-lt-piece.cb-rook { content: url(../../svg/traditional-theme.svg#light_rook_left); } +.cb-theme-traditional .cb-lt-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#light_pawn_left); } + +.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-king { content: url(../../svg/traditional-theme.svg#dark_king_left); } +.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-queen { content: url(../../svg/traditional-theme.svg#dark_queen_left); } +.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#dark_bishop_left); } +.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-knight { content: url(../../svg/traditional-theme.svg#dark_knight_left); } +.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-rook { content: url(../../svg/traditional-theme.svg#dark_rook_left); } +.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#dark_pawn_left); } +.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-king { content: url(../../svg/traditional-theme.svg#light_king_right); } +.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-queen { content: url(../../svg/traditional-theme.svg#light_queen_right); } +.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#light_bishop_right); } +.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-knight { content: url(../../svg/traditional-theme.svg#light_knight_right); } +.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-rook { content: url(../../svg/traditional-theme.svg#light_rook_right); } +.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#light_pawn_right); } diff --git a/index.html b/index.html index 7c24457..13db667 100644 --- a/index.html +++ b/index.html @@ -14,246 +14,208 @@
-

Paco Ŝako

- -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
A
B
C
D
E
F
G
H
8
8
7
7
6
6
5
5
4
4
3
3
2
2
1
1
A
B
C
D
E
F
G
H
-
-
-
+
+ -
-
-
-
-
-
-
-
-
-
-
-
- - - -
-
- - - - - - -
-
-
-
-
- - -
- -
-
- - vs. -
-
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
-
-
- Rule Reference -

The basic movement for each piece is the same as traditional chess.

-

Pieces are never removed from the board. Instead, the capturing piece shares the square with the captured piece, and the two pieces become a joined pair.

-

When either piece moves from a square containing two pieces, the other piece moves with it. - Each player can only move a joined pair according to the rules for their own piece. Joined pieces cannot capture other pieces.

-

A free (non-joined) piece may move into a square occupied by pieces of both colors. - When it does, the other piece of the same color becomes a free piece and must move to a new location following the normal movement rules. - This process may be repeated multiple times in the same turn.

-

Ŝako (checkmate) occurs when an opposing piece joins with the king. - Important: The king is not permitted to join with (capture) other pieces.

-

Due to joined movement, it is possible for a pawn to be moved backward to, or past, its starting row. - Pawns may move forward two spaces from either of the first two rows on their own side of the board.

-

When a pawn is captured en passant while joined with another piece, the captured pawn moves back one square to become joined with the capturing pawn - and the joined piece from the capturing side moves to a new location from its original position as with any other capture.

-

Pawns are promoted when they reach the final row on the opposite side of the board, even if they were moved there by the other player as part of a joined pair.

-
-
+
+
+ + vs. + +
+
+
+ + + + + + + + + + + +
+
+
+ + + diff --git a/index.js b/index.js index 825d114..43b26e6 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,7 @@ import './css/chess.css'; import './css/theme/pacosako.css'; +import '@fortawesome/fontawesome-free/css/fontawesome.css'; +import '@fortawesome/fontawesome-free/css/solid.css'; + import './js/pacosako_ui.js'; diff --git a/js/pacosako_ui.js b/js/pacosako_ui.js index 32962be..ffb5888 100644 --- a/js/pacosako_ui.js +++ b/js/pacosako_ui.js @@ -20,6 +20,9 @@ import 'jbox/dist/jBox.all.css'; import {Workbox, messageSW} from 'workbox-window'; +import {ResizeSensor, ElementQueries} from 'css-element-queries'; +ElementQueries.listen(); + /* "Waterdrop" by Porphyr (freesound.org/people/Porphyr) / CC BY 3.0 (creativecommons.org/licenses/by/3.0) */ import Waterdrop from '../mp3/191678__porphyr__waterdrop.mp3'; @@ -604,6 +607,16 @@ $(function (){ updateQueue.add(gameId, meta, $('#cb_board').data('modified')); } + function setNotifyChecked(doNotify) { + const cbNotify = $('#cb_notify'); + cbNotify.prop('checked', doNotify); + if (doNotify) { + cbNotify.removeClass('fa-bell-slash').addClass('fa-bell'); + } else { + cbNotify.removeClass('fa-bell').addClass('fa-bell-slash'); + } + } + function switchGameId(newId, force) { const boardElem = $('#cb_board'); const gameId = boardElem.data('gameId'); @@ -656,7 +669,7 @@ $(function (){ const notifyList = $('#cb_notify').data('gameList'); const doNotify = notifyList.includes('*') || notifyList.includes(newId); - $('#cb_notify').prop('checked', doNotify); + setNotifyChecked(doNotify); if (doNotify) { requestNotify(); } @@ -666,9 +679,6 @@ $(function (){ $('#cb_reverse').prop('checked', doReverse); arrangeBoard(doReverse); - $('#jitsi_link').attr('href', 'https://meet.jit.si/PacoSaco_' + newId); - $('#game_link').attr('href', location.href); - /* Ensure that the selected game is in the list (for new games). */ if ($('#game_tile_' + newId).length < 1) { updateSelectGameMeta({}, newId); @@ -685,7 +695,7 @@ $(function (){ } function disableNotify(){ - $('#cb_notify')[0].checked = false; + setNotifyChecked(false); $('#cb_notify').attr('disabled', true); } @@ -838,7 +848,7 @@ $(function (){ const gameId = $('#cb_board').data('gameId'); if (value === 'on') { gameList = ['*'] - } else if (value === 'off') { + } else if (value === null || value === 'off') { gameList = []; } else { try { @@ -869,6 +879,7 @@ $(function (){ debug('from localStorage', { key, value }); if (key === LS_KEY_NOTIFY) { updatePerGameFlag(key, value, '#cb_notify', (enabled) => { + setNotifyChecked(enabled); if (enabled) { requestNotify(); } @@ -882,11 +893,14 @@ $(function (){ arrangeBoard(enabled); }); } else if (key === LS_KEY_THEME) { + if (value === null) { + value = 'pacosako'; + } const cb_theme = $('#cb_select_theme'); if (value !== cb_theme.val()) { cb_theme.val(value); if (!cb_theme.val()) { - value = 'traditional'; + value = 'pacosako'; cb_theme.val(value); } applyTheme(value); @@ -900,9 +914,7 @@ $(function (){ for (const key of [LS_KEY_NOTIFY, LS_KEY_SOUND, LS_KEY_REVERSE, LS_KEY_THEME]) { const value = window.localStorage.getItem(key); - if (value !== null) { - fromStorage(key, value); - } + fromStorage(key, value); } } @@ -940,6 +952,7 @@ $(function (){ $('#cb_notify').on('change', function(){ perGameFlagChanged(LS_KEY_NOTIFY, this); + setNotifyChecked(this.checked); if (this.checked) { requestNotify(); } @@ -1056,6 +1069,36 @@ $(function (){ } }); + let helpBox = null; + $('#help').on('click', function() { + helpBox = helpBox || new jBox('Modal', { + title: '

Rule Reference

', + content: $('#rules_content'), + blockScroll: false, + blockScrollAdjust: false, + isolateScroll: false, + footer: `
`, + closeButton: 'title', + onCreated() { + $('.badges').appendTo('#help_badges'); + }, + }); + helpBox.open(); + }); + + let settingBox = null; + $('#settings').on('click', function() { + settingBox = settingBox || new jBox('Modal', { + title: '

Settings

', + content: $('#settings_content'), + blockScroll: false, + blockScrollAdjust: false, + isolateScroll: false, + closeButton: 'title', + }); + settingBox.open(); + }); + $('#cb_light_name, #cb_dark_name').on('input', function() { putMeta(); }); let gameSelectContent = $(`
`).appendTo('body'); @@ -1304,6 +1347,55 @@ $(function (){ switchGameId(randomId()); } + function adjustBoardSize() { + let container = $('#cb_container'); + let outerWidth = container.width(); + let outerHeight = container.height(); + let size = ((outerWidth < outerHeight) ? outerWidth : outerHeight) - 24; + $('#cb_board').css({ + width: size + 'px', + height: size + 'px', + top: ((outerHeight - size) / 2) + 'px', + left: ((outerWidth - size) / 2) + 'px', + visibility: '', + }); + } + + new ResizeSensor($('#cb_container'), adjustBoardSize); + adjustBoardSize(); + + (function() { + const body = $('body').first(); + let horizontal = false; + + function updateLayout() { + const oldHorizontal = horizontal; + horizontal = body.width() >= (1.5 * body.height()); + if (horizontal !== oldHorizontal) { + if (horizontal) { + $('#cb_container').prependTo('#page'); + $('#header').appendTo('#board_ui'); + $('#cb_status').appendTo('#board_ui'); + $('#cb_names').appendTo('#board_ui'); + $('#cb_navigate').appendTo('#board_ui'); + $('#board_ui').appendTo('#page'); + $('#page').removeClass('vertical-layout').addClass('horizontal-layout'); + } else { + $('#header').appendTo('#board_ui'); + $('#cb_container').appendTo('#board_ui'); + $('#cb_status').appendTo('#board_ui'); + $('#cb_names').appendTo('#board_ui'); + $('#cb_navigate').appendTo('#board_ui'); + $('#board_ui').appendTo('#page'); + $('#page').removeClass('horizontal-layout').addClass('vertical-layout'); + } + } + } + + new ResizeSensor(body, updateLayout); + updateLayout(); + })(); + /* Low-level commands to be run from the JS console */ window.Admin = { getGameId() { return $('#cb_board').data('gameId'); }, @@ -1320,25 +1412,6 @@ $(function (){ $, }; - /* - * Safari uses the container's *height* instead of its *width* as - * required by W3C standards for relative margin/padding values. - * This breaks the CSS that should be ensuring a 1:1 aspect ratio. - */ - function fixSafariPadding() { - let squares = $('#cb_board .cb-square'); - for (let square of squares) { - square = $(square); - const width = square.width(); - square.css('height', width + 'px'); - } - } - - if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) { - $(window).on('resize', fixSafariPadding); - fixSafariPadding(); - } - (function() { const match = location.href.match('^https://jessemcdonald.info/~nybble/paco_sako/(.*)'); if (match) { diff --git a/package-lock.json b/package-lock.json index 3307501..0b08ff1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1044,6 +1044,12 @@ } } }, + "@fortawesome/fontawesome-free": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.13.0.tgz", + "integrity": "sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg==", + "dev": true + }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", @@ -3410,6 +3416,12 @@ } } }, + "css-element-queries": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/css-element-queries/-/css-element-queries-1.2.3.tgz", + "integrity": "sha512-QK9uovYmKTsV2GXWQiMOByVNrLn2qz6m3P7vWpOR4IdD6I3iXoDw5qtgJEN3Xq7gIbdHVKvzHjdAtcl+4Arc4Q==", + "dev": true + }, "css-loader": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.1.tgz", diff --git a/package.json b/package.json index b74e53d..89e06fc 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,10 @@ "url": "https://jessemcdonald.info/gogs/nybble/paco_sako.git" }, "devDependencies": { + "@fortawesome/fontawesome-free": "^5.13.0", "clean-webpack-plugin": "^3.0.0", "copy-webpack-plugin": "^5.1.1", + "css-element-queries": "^1.2.3", "deep-equal": "git+https://jessemcdonald.info/gogs/nybble/node-deep-equal", "extract-loader": "^5.0.1", "html-webpack-plugin": "^4.3.0", diff --git a/svg/external-link-alt-solid.svg b/svg/external-link-alt-solid.svg deleted file mode 100644 index 190df50..0000000 --- a/svg/external-link-alt-solid.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/svg/jitsi-logo-blue.svg b/svg/jitsi-logo-blue.svg deleted file mode 100644 index 2ff2159..0000000 --- a/svg/jitsi-logo-blue.svg +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/webpack.config.js b/webpack.config.js index 9651d5f..f7e7db9 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -23,7 +23,7 @@ module.exports = { loaders: [MiniCssExtractPlugin.loader, "css-loader"] }, { - test: { and: [ /\.(jpe?g|png|gif|svg)$/i, /jquery-ui/i ] }, + test: { and: [ /\.(jpe?g|png|gif|svg|ttf|eot|woff2?)$/i, /jquery-ui/i ] }, loader: "file-loader", options: { name: '[name].[contenthash].[ext]', @@ -31,7 +31,7 @@ module.exports = { } }, { - test: { and: [ /\.(jpe?g|png|gif|mp3|wav)$/i, { not: [ /jquery-ui/i ] } ] }, + test: { and: [ /\.(jpe?g|png|gif|mp3|wav|ttf|eot|woff2?)$/i, { not: [ /jquery-ui/i ] } ] }, loader: "file-loader", options: { name: '[path][name].[contenthash].[ext]', @@ -93,7 +93,7 @@ module.exports = { ]), new InjectManifest({ swSrc: './sw.js', - dontCacheBustURLsMatching: /\.[0-9a-f]{16,}\.(css|js|svg|png|jpg|wav)$/, + dontCacheBustURLsMatching: /\.[0-9a-f]{16,}\.\w{2,4}$/, exclude: [ /(^|[/\\])\.htaccess$/ ], }), ],