| 1 | import type { Prefs } from '../game/prefs'; |
| 2 | import { enterFullscreen, exitFullscreen, fullscreenSupported, useFullscreen } from './fullscreen'; |
| 3 | |
| 4 | interface Props { |
| 5 | prefs: Prefs; |
| 6 | onPrefs: (p: Prefs) => void; |
| 7 | /** Icon only, for the cramped row of controls in the middle of the table. */ |
| 8 | compact?: boolean; |
| 9 | } |
| 10 | |
| 11 | /* Corner brackets rather than a glyph: this has to read on whatever font a |
| 12 | phone happens to have, and the symbols for it are thin on the ground. */ |
| 13 | const Corners = ({ out }: { out: boolean }) => ( |
| 14 | <svg |
| 15 | className="fs-icon" |
| 16 | viewBox="0 0 20 20" |
| 17 | width="15" |
| 18 | height="15" |
| 19 | aria-hidden |
| 20 | fill="none" |
| 21 | stroke="currentColor" |
| 22 | strokeWidth="2" |
| 23 | strokeLinecap="round" |
| 24 | strokeLinejoin="round" |
| 25 | > |
| 26 | {out ? ( |
| 27 | <path d="M2 7V2h5M13 2h5v5M18 13v5h-5M7 18H2v-5" /> |
| 28 | ) : ( |
| 29 | <path d="M7 2v5H2M18 7h-5V2M13 18v-5h5M2 13h5v5" /> |
| 30 | )} |
| 31 | </svg> |
| 32 | ); |
| 33 | |
| 34 | /** |
| 35 | * Takes the screen and gives it back — and remembers which the player wanted. |
| 36 | * The browser drops fullscreen on every reload, and this game is built to be |
| 37 | * put down and resumed, so without that memory you would be reaching for this |
| 38 | * button every single time. |
| 39 | */ |
| 40 | export function FullscreenToggle({ prefs, onPrefs, compact }: Props) { |
| 41 | const active = useFullscreen(); |
| 42 | if (!fullscreenSupported()) return null; |
| 43 | |
| 44 | return ( |
| 45 | <button |
| 46 | className={`btn ghost pill fs-toggle ${compact ? 'compact' : ''} ${active ? 'on' : ''}`} |
| 47 | aria-pressed={active} |
| 48 | onClick={() => { |
| 49 | // Made here, inside the click: the same call from an effect is refused. |
| 50 | if (active) exitFullscreen(); |
| 51 | else enterFullscreen(); |
| 52 | onPrefs({ ...prefs, fullscreen: !active }); |
| 53 | }} |
| 54 | > |
| 55 | <Corners out={!active} /> |
| 56 | {!compact && <span>{active ? '離開全螢幕 Exit full screen' : '全螢幕 Full screen'}</span>} |
| 57 | </button> |
| 58 | ); |
| 59 | } |