Compare commits

...

8 Commits

Author SHA1 Message Date
Vikeo
a96b6bc340 fix roulette card size not being the same a actual play card size 2024-06-17 14:51:30 +02:00
Vikeo
a1f8745509 bump 2024-06-09 21:40:23 +02:00
Vikeo
1dc984e7b3 fix side extra counter text rotation 2024-06-09 21:28:13 +02:00
Vikeo
df3c30da31 fix 2024-05-27 11:01:43 +02:00
Vikeo
5fff18e079 check if ios 2024-05-27 11:01:25 +02:00
Vikeo
7203f0170a hotfix 2024-05-27 10:59:09 +02:00
Vikeo
63fbceafe2 fix null state 2024-05-27 10:58:42 +02:00
Vikeo
2ec9998a2a show and hide things based on ios, add button for installing PWA 2024-05-27 10:47:59 +02:00
16 changed files with 274 additions and 238 deletions

View File

@@ -1,12 +1,12 @@
index.html,1716462527631,3daeb4b4b2f195883f1e266f94c16156ee3c60a29c3eb8c44a8dcfdbb1fa0a03
manifest.webmanifest,1716462527631,10e89b44378da695cb672bf7d801a4ade909383751f1665416f561bbe1434e5d
manifest.json,1716462527513,91ce94afb71f33a477f5d8d48c3f98bd7de422279c74f17b6500eec72003ac1a
logo192.png,1716462527512,14ac21c3975e11951c1eb7793eec18e1cc3274bfe7cf7858636d547a9a4efc1c
registerSW.js,1716462527631,8db45a5ae8765ce12ec241d6c5bd5d30eb81dd9163b2685c5e1b867a0e487018
robots.txt,1716462527513,391d14b3c2f8c9143a27a28c7399585142228d4d1bdbe2c87ac946de411fa9a2
sw.js,1716462528602,b681e1b343578a0de67032920144d05430677997580429b7e2b749f6afff69ed
workbox-3e911b1d.js,1716462528602,666146b896084273226c83dca0b93f99accb195688330d6aa5c8c570bd48a4ac
assets/index-D9CdzROR.css,1716462527631,610c77754d47a35446b00c0a50488070c943f3a05e6d57658faefd943bc3fc46
favicon.ico,1716462527511,c3d2b7ac7f6263cca7ee26f91725eb32e7539bf0564f3b31a1bfc23cc88e9739
logo512.png,1716462527512,a9ebde1252bb76a5b474130ef07a7ed744448fde84221f715f3fec849eccbcd2
assets/index-DgCoW5us.js,1716462527631,06a6d92ff20d7f9e1f5e0c4d3ad8f931d7d0636f109b5e2dbbe28abd3707bb50
index.html,1716800495173,a60a0d61bc25aa1eb4446d628875d96224860fbd767a11682a6c1db79b9403e2
manifest.webmanifest,1716800495173,10e89b44378da695cb672bf7d801a4ade909383751f1665416f561bbe1434e5d
manifest.json,1716800495051,91ce94afb71f33a477f5d8d48c3f98bd7de422279c74f17b6500eec72003ac1a
registerSW.js,1716800495173,8db45a5ae8765ce12ec241d6c5bd5d30eb81dd9163b2685c5e1b867a0e487018
robots.txt,1716800495051,391d14b3c2f8c9143a27a28c7399585142228d4d1bdbe2c87ac946de411fa9a2
sw.js,1716800496019,609c6e27a6431ece2081013efab535a218046977d97b8600a6f58ba7589373c1
logo192.png,1716800495050,14ac21c3975e11951c1eb7793eec18e1cc3274bfe7cf7858636d547a9a4efc1c
workbox-3e911b1d.js,1716800496020,666146b896084273226c83dca0b93f99accb195688330d6aa5c8c570bd48a4ac
assets/index-B0S3b36T.css,1716800495173,1eb1cb3d1dacc339354071ee052cdacc07d1c831c61e08b082518436f3463d83
favicon.ico,1716800495050,c3d2b7ac7f6263cca7ee26f91725eb32e7539bf0564f3b31a1bfc23cc88e9739
logo512.png,1716800495051,a9ebde1252bb76a5b474130ef07a7ed744448fde84221f715f3fec849eccbcd2
assets/index-2MMQ0HyH.js,1716800495173,f14516d3e15bb8fa5079d40fb7c1a7e0974d336340936bbed066d792ee1021e5

View File

@@ -1,7 +1,7 @@
{
"name": "life-trinket",
"private": true,
"version": "0.9.95",
"version": "0.9.98",
"type": "commonjs",
"engines": {
"node": ">=20",

147
pnpm-lock.yaml generated
View File

@@ -41,7 +41,7 @@ importers:
version: 11.11.4(@types/react@18.3.1)(react@18.2.0)
'@emotion/styled':
specifier: ^11.11.5
version: 11.11.5(@emotion/react@11.11.4(@types/react@18.3.1)(react@18.2.0))(@types/react@18.3.1)(react@18.2.0)
version: 11.11.5(@emotion/react@11.11.4)(@types/react@18.3.1)(react@18.2.0)
'@savvywombat/tailwindcss-grid-areas':
specifier: ^4.0.0
version: 4.0.0(tailwindcss@3.4.3)
@@ -59,13 +59,13 @@ importers:
version: 7.5.8
'@typescript-eslint/eslint-plugin':
specifier: ^7.8.0
version: 7.8.0(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)
version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/parser':
specifier: ^7.8.0
version: 7.8.0(eslint@8.57.0)(typescript@5.4.5)
'@vitejs/plugin-react-swc':
specifier: ^3.6.0
version: 3.6.0(vite@5.2.10(@types/node@20.12.2)(terser@5.30.0))
version: 3.6.0(vite@5.2.10)
autoprefixer:
specifier: ^10.4.19
version: 10.4.19(postcss@8.4.38)
@@ -80,7 +80,7 @@ importers:
version: 0.4.6(eslint@8.57.0)
firebase-tools:
specifier: ^13.7.5
version: 13.7.5(encoding@0.1.13)
version: 13.7.5
install:
specifier: ^0.13.0
version: 0.13.0
@@ -101,10 +101,10 @@ importers:
version: 5.4.5
vite:
specifier: ^5.2.10
version: 5.2.10(@types/node@20.12.2)(terser@5.30.0)
version: 5.2.10
vite-plugin-pwa:
specifier: ^0.20.0
version: 0.20.0(vite@5.2.10(@types/node@20.12.2)(terser@5.30.0))(workbox-build@7.1.0)(workbox-window@7.1.0)
version: 0.20.0(vite@5.2.10)(workbox-build@7.1.0)(workbox-window@7.1.0)
packages:
@@ -5740,10 +5740,9 @@ snapshots:
'@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0)
'@emotion/utils': 1.2.1
'@emotion/weak-memoize': 0.3.1
'@types/react': 18.3.1
hoist-non-react-statics: 3.3.2
react: 18.2.0
optionalDependencies:
'@types/react': 18.3.1
'@emotion/serialize@1.1.4':
dependencies:
@@ -5755,7 +5754,7 @@ snapshots:
'@emotion/sheet@1.2.2': {}
'@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.1)(react@18.2.0))(@types/react@18.3.1)(react@18.2.0)':
'@emotion/styled@11.11.5(@emotion/react@11.11.4)(@types/react@18.3.1)(react@18.2.0)':
dependencies:
'@babel/runtime': 7.24.1
'@emotion/babel-plugin': 11.11.0
@@ -5764,9 +5763,8 @@ snapshots:
'@emotion/serialize': 1.1.4
'@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0)
'@emotion/utils': 1.2.1
react: 18.2.0
optionalDependencies:
'@types/react': 18.3.1
react: 18.2.0
'@emotion/unitless@0.8.1': {}
@@ -6186,7 +6184,7 @@ snapshots:
'@google-cloud/promisify@2.0.4': {}
'@google-cloud/pubsub@3.7.5(encoding@0.1.13)':
'@google-cloud/pubsub@3.7.5':
dependencies:
'@google-cloud/paginator': 4.0.1
'@google-cloud/precise-date': 3.0.1
@@ -6198,8 +6196,8 @@ snapshots:
'@types/long': 4.0.2
arrify: 2.0.1
extend: 3.0.2
google-auth-library: 8.9.0(encoding@0.1.13)
google-gax: 3.6.1(encoding@0.1.13)
google-auth-library: 8.9.0
google-gax: 3.6.1
heap-js: 2.5.0
is-stream-ended: 0.1.4
lodash.snakecase: 4.1.1
@@ -6347,17 +6345,15 @@ snapshots:
'@radix-ui/react-compose-refs@1.0.1(@types/react@18.3.1)(react@18.2.0)':
dependencies:
'@babel/runtime': 7.24.1
react: 18.2.0
optionalDependencies:
'@types/react': 18.3.1
react: 18.2.0
'@radix-ui/react-slot@1.0.2(@types/react@18.3.1)(react@18.2.0)':
dependencies:
'@babel/runtime': 7.24.1
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.1)(react@18.2.0)
react: 18.2.0
optionalDependencies:
'@types/react': 18.3.1
react: 18.2.0
'@rollup/plugin-babel@5.3.1(@babel/core@7.24.5)(rollup@2.79.1)':
dependencies:
@@ -6374,7 +6370,6 @@ snapshots:
is-builtin-module: 3.2.1
is-module: 1.0.0
resolve: 1.22.8
optionalDependencies:
rollup: 2.79.1
'@rollup/plugin-replace@2.4.2(rollup@2.79.1)':
@@ -6385,11 +6380,10 @@ snapshots:
'@rollup/plugin-terser@0.4.4(rollup@2.79.1)':
dependencies:
rollup: 2.79.1
serialize-javascript: 6.0.2
smob: 1.5.0
terser: 5.30.0
optionalDependencies:
rollup: 2.79.1
'@rollup/pluginutils@3.1.0(rollup@2.79.1)':
dependencies:
@@ -6403,7 +6397,6 @@ snapshots:
'@types/estree': 1.0.5
estree-walker: 2.0.2
picomatch: 2.3.1
optionalDependencies:
rollup: 2.79.1
'@rollup/rollup-android-arm-eabi@4.13.2':
@@ -6509,9 +6502,9 @@ snapshots:
'@svgr/cli@8.1.0(typescript@5.4.5)':
dependencies:
'@svgr/core': 8.1.0(typescript@5.4.5)
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.4.5))
'@svgr/plugin-prettier': 8.1.0(@svgr/core@8.1.0(typescript@5.4.5))
'@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.4.5))(typescript@5.4.5)
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0)
'@svgr/plugin-prettier': 8.1.0(@svgr/core@8.1.0)
'@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0)(typescript@5.4.5)
camelcase: 6.3.0
chalk: 4.1.2
commander: 9.5.0
@@ -6538,7 +6531,7 @@ snapshots:
'@babel/types': 7.24.0
entities: 4.5.0
'@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.4.5))':
'@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0)':
dependencies:
'@babel/core': 7.24.3
'@svgr/babel-preset': 8.1.0(@babel/core@7.24.3)
@@ -6548,13 +6541,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@svgr/plugin-prettier@8.1.0(@svgr/core@8.1.0(typescript@5.4.5))':
'@svgr/plugin-prettier@8.1.0(@svgr/core@8.1.0)':
dependencies:
'@svgr/core': 8.1.0(typescript@5.4.5)
deepmerge: 4.3.1
prettier: 2.8.8
'@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.4.5))(typescript@5.4.5)':
'@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0)(typescript@5.4.5)':
dependencies:
'@svgr/core': 8.1.0(typescript@5.4.5)
cosmiconfig: 8.3.6(typescript@5.4.5)
@@ -6677,7 +6670,7 @@ snapshots:
'@types/trusted-types@2.0.7': {}
'@typescript-eslint/eslint-plugin@7.8.0(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)':
'@typescript-eslint/eslint-plugin@7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@5.4.5)':
dependencies:
'@eslint-community/regexpp': 4.10.0
'@typescript-eslint/parser': 7.8.0(eslint@8.57.0)(typescript@5.4.5)
@@ -6692,7 +6685,6 @@ snapshots:
natural-compare: 1.4.0
semver: 7.6.2
ts-api-utils: 1.3.0(typescript@5.4.5)
optionalDependencies:
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
@@ -6705,7 +6697,6 @@ snapshots:
'@typescript-eslint/visitor-keys': 7.8.0
debug: 4.3.4
eslint: 8.57.0
optionalDependencies:
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
@@ -6722,7 +6713,6 @@ snapshots:
debug: 4.3.4
eslint: 8.57.0
ts-api-utils: 1.3.0(typescript@5.4.5)
optionalDependencies:
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
@@ -6739,7 +6729,6 @@ snapshots:
minimatch: 9.0.4
semver: 7.6.2
ts-api-utils: 1.3.0(typescript@5.4.5)
optionalDependencies:
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
@@ -6765,10 +6754,10 @@ snapshots:
'@ungap/structured-clone@1.2.0': {}
'@vitejs/plugin-react-swc@3.6.0(vite@5.2.10(@types/node@20.12.2)(terser@5.30.0))':
'@vitejs/plugin-react-swc@3.6.0(vite@5.2.10)':
dependencies:
'@swc/core': 1.4.11
vite: 5.2.10(@types/node@20.12.2)(terser@5.30.0)
vite: 5.2.10
transitivePeerDependencies:
- '@swc/helpers'
@@ -6809,7 +6798,7 @@ snapshots:
optional: true
ajv-formats@2.1.1(ajv@8.12.0):
optionalDependencies:
dependencies:
ajv: 8.12.0
ajv@6.12.6:
@@ -7321,7 +7310,6 @@ snapshots:
js-yaml: 4.1.0
parse-json: 5.2.0
path-type: 4.0.0
optionalDependencies:
typescript: 5.4.5
crc-32@1.2.2: {}
@@ -7921,9 +7909,9 @@ snapshots:
locate-path: 6.0.0
path-exists: 4.0.0
firebase-tools@13.7.5(encoding@0.1.13):
firebase-tools@13.7.5:
dependencies:
'@google-cloud/pubsub': 3.7.5(encoding@0.1.13)
'@google-cloud/pubsub': 3.7.5
abort-controller: 3.0.0
ajv: 6.12.6
archiver: 5.3.2
@@ -7948,7 +7936,7 @@ snapshots:
fs-extra: 10.1.0
fuzzy: 0.1.3
glob: 7.2.3
google-auth-library: 7.14.1(encoding@0.1.13)
google-auth-library: 7.14.1
inquirer: 8.2.6
inquirer-autocomplete-prompt: 2.0.1(inquirer@8.2.6)
jsonwebtoken: 9.0.2
@@ -7960,7 +7948,7 @@ snapshots:
mime: 2.6.0
minimatch: 3.1.2
morgan: 1.10.0
node-fetch: 2.7.0(encoding@0.1.13)
node-fetch: 2.7.0
open: 6.4.0
ora: 5.4.1
p-limit: 3.1.0
@@ -7973,13 +7961,13 @@ snapshots:
stream-chain: 2.2.5
stream-json: 1.8.0
strip-ansi: 6.0.1
superstatic: 9.0.3(encoding@0.1.13)
superstatic: 9.0.3
tar: 6.2.1
tcp-port-used: 1.0.2
tmp: 0.2.3
triple-beam: 1.4.1
universal-analytics: 0.5.3
update-notifier-cjs: 5.1.6(encoding@0.1.13)
update-notifier-cjs: 5.1.6
uuid: 8.3.2
winston: 3.13.0
winston-transport: 4.7.0
@@ -8103,38 +8091,38 @@ snapshots:
ga-4-react@0.1.281: {}
gaxios@4.3.3(encoding@0.1.13):
gaxios@4.3.3:
dependencies:
abort-controller: 3.0.0
extend: 3.0.2
https-proxy-agent: 5.0.1
is-stream: 2.0.1
node-fetch: 2.7.0(encoding@0.1.13)
node-fetch: 2.7.0
transitivePeerDependencies:
- encoding
- supports-color
gaxios@5.1.3(encoding@0.1.13):
gaxios@5.1.3:
dependencies:
extend: 3.0.2
https-proxy-agent: 5.0.1
is-stream: 2.0.1
node-fetch: 2.7.0(encoding@0.1.13)
node-fetch: 2.7.0
transitivePeerDependencies:
- encoding
- supports-color
gcp-metadata@4.3.1(encoding@0.1.13):
gcp-metadata@4.3.1:
dependencies:
gaxios: 4.3.3(encoding@0.1.13)
gaxios: 4.3.3
json-bigint: 1.0.0
transitivePeerDependencies:
- encoding
- supports-color
gcp-metadata@5.3.0(encoding@0.1.13):
gcp-metadata@5.3.0:
dependencies:
gaxios: 5.1.3(encoding@0.1.13)
gaxios: 5.1.3
json-bigint: 1.0.0
transitivePeerDependencies:
- encoding
@@ -8233,37 +8221,37 @@ snapshots:
merge2: 1.4.1
slash: 3.0.0
google-auth-library@7.14.1(encoding@0.1.13):
google-auth-library@7.14.1:
dependencies:
arrify: 2.0.1
base64-js: 1.5.1
ecdsa-sig-formatter: 1.0.11
fast-text-encoding: 1.0.6
gaxios: 4.3.3(encoding@0.1.13)
gcp-metadata: 4.3.1(encoding@0.1.13)
gtoken: 5.3.2(encoding@0.1.13)
gaxios: 4.3.3
gcp-metadata: 4.3.1
gtoken: 5.3.2
jws: 4.0.0
lru-cache: 6.0.0
transitivePeerDependencies:
- encoding
- supports-color
google-auth-library@8.9.0(encoding@0.1.13):
google-auth-library@8.9.0:
dependencies:
arrify: 2.0.1
base64-js: 1.5.1
ecdsa-sig-formatter: 1.0.11
fast-text-encoding: 1.0.6
gaxios: 5.1.3(encoding@0.1.13)
gcp-metadata: 5.3.0(encoding@0.1.13)
gtoken: 6.1.2(encoding@0.1.13)
gaxios: 5.1.3
gcp-metadata: 5.3.0
gtoken: 6.1.2
jws: 4.0.0
lru-cache: 6.0.0
transitivePeerDependencies:
- encoding
- supports-color
google-gax@3.6.1(encoding@0.1.13):
google-gax@3.6.1:
dependencies:
'@grpc/grpc-js': 1.8.21
'@grpc/proto-loader': 0.7.12
@@ -8272,9 +8260,9 @@ snapshots:
abort-controller: 3.0.0
duplexify: 4.1.3
fast-text-encoding: 1.0.6
google-auth-library: 8.9.0(encoding@0.1.13)
google-auth-library: 8.9.0
is-stream-ended: 0.1.4
node-fetch: 2.7.0(encoding@0.1.13)
node-fetch: 2.7.0
object-hash: 3.0.0
proto3-json-serializer: 1.1.1
protobufjs: 7.2.4
@@ -8302,18 +8290,18 @@ snapshots:
graphemer@1.4.0: {}
gtoken@5.3.2(encoding@0.1.13):
gtoken@5.3.2:
dependencies:
gaxios: 4.3.3(encoding@0.1.13)
gaxios: 4.3.3
google-p12-pem: 3.1.4
jws: 4.0.0
transitivePeerDependencies:
- encoding
- supports-color
gtoken@6.1.2(encoding@0.1.13):
gtoken@6.1.2:
dependencies:
gaxios: 5.1.3(encoding@0.1.13)
gaxios: 5.1.3
google-p12-pem: 4.0.1
jws: 4.0.0
transitivePeerDependencies:
@@ -8607,9 +8595,9 @@ snapshots:
isexe@3.1.1:
optional: true
isomorphic-fetch@3.0.0(encoding@0.1.13):
isomorphic-fetch@3.0.0:
dependencies:
node-fetch: 2.7.0(encoding@0.1.13)
node-fetch: 2.7.0
whatwg-fetch: 3.6.20
transitivePeerDependencies:
- encoding
@@ -9055,11 +9043,9 @@ snapshots:
dependencies:
lodash: 4.17.21
node-fetch@2.7.0(encoding@0.1.13):
node-fetch@2.7.0:
dependencies:
whatwg-url: 5.0.0
optionalDependencies:
encoding: 0.1.13
node-forge@1.3.1: {}
@@ -9273,9 +9259,8 @@ snapshots:
postcss-load-config@4.0.2(postcss@8.4.38):
dependencies:
lilconfig: 3.1.1
yaml: 2.4.1
optionalDependencies:
postcss: 8.4.38
yaml: 2.4.1
postcss-nested@6.0.1(postcss@8.4.38):
dependencies:
@@ -9897,7 +9882,7 @@ snapshots:
pirates: 4.0.6
ts-interface-checker: 0.1.13
superstatic@9.0.3(encoding@0.1.13):
superstatic@9.0.3:
dependencies:
basic-auth-connect: 1.0.0
commander: 10.0.1
@@ -9916,7 +9901,7 @@ snapshots:
on-headers: 1.0.2
path-to-regexp: 1.8.0
router: 1.3.8
update-notifier-cjs: 5.1.6(encoding@0.1.13)
update-notifier-cjs: 5.1.6
optionalDependencies:
re2: 1.20.10
transitivePeerDependencies:
@@ -10185,7 +10170,7 @@ snapshots:
escalade: 3.1.2
picocolors: 1.0.0
update-notifier-cjs@5.1.6(encoding@0.1.13):
update-notifier-cjs@5.1.6:
dependencies:
boxen: 5.1.2
chalk: 4.1.2
@@ -10196,7 +10181,7 @@ snapshots:
is-installed-globally: 0.4.0
is-npm: 5.0.0
is-yarn-global: 0.3.0
isomorphic-fetch: 3.0.0(encoding@0.1.13)
isomorphic-fetch: 3.0.0
pupa: 2.1.1
registry-auth-token: 5.0.2
registry-url: 5.1.0
@@ -10222,26 +10207,24 @@ snapshots:
vary@1.1.2: {}
vite-plugin-pwa@0.20.0(vite@5.2.10(@types/node@20.12.2)(terser@5.30.0))(workbox-build@7.1.0)(workbox-window@7.1.0):
vite-plugin-pwa@0.20.0(vite@5.2.10)(workbox-build@7.1.0)(workbox-window@7.1.0):
dependencies:
debug: 4.3.4
fast-glob: 3.3.2
pretty-bytes: 6.1.1
vite: 5.2.10(@types/node@20.12.2)(terser@5.30.0)
vite: 5.2.10
workbox-build: 7.1.0
workbox-window: 7.1.0
transitivePeerDependencies:
- supports-color
vite@5.2.10(@types/node@20.12.2)(terser@5.30.0):
vite@5.2.10:
dependencies:
esbuild: 0.20.2
postcss: 8.4.38
rollup: 4.13.2
optionalDependencies:
'@types/node': 20.12.2
fsevents: 2.3.3
terser: 5.30.0
wcwidth@1.0.1:
dependencies:

View File

@@ -3,7 +3,7 @@ import { twc } from 'react-twc';
import { decrementTimeoutMs } from '../../Data/constants';
import { CounterType, Rotation } from '../../Types/Player';
import { OutlinedText } from '../Misc/OutlinedText';
import { MAX_TAP_MOVE_DISTANCE, RotationDivProps } from './CommanderDamage';
import { MAX_TAP_MOVE_DISTANCE } from './CommanderDamage';
const ExtraCounterContainer = twc.div`
flex
@@ -28,17 +28,14 @@ const ExtraCounterButton = twc.button`
webkit-user-select-none
`;
const IconContainer = twc.div<RotationDivProps>((props) => [
'w-auto opacity-50',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
? 'rotate-[-90deg]'
: '',
]);
const IconContainer = twc.div`
w-auto opacity-50 data-[rotation-is-side=true]:-rotate-90`;
const TextContainer = twc.div`
absolute
top-1/2
left-1/2
data-[rotation-is-side=true]:-rotate-90
`;
type ExtraCounterProps = {
@@ -115,6 +112,9 @@ const ExtraCounter = ({
const fontWeight = 'bold';
const strokeWidth = isSide ? '0.4vmax' : '0.7vmin';
const rotationIsSide =
rotation === Rotation.SideFlipped || rotation === Rotation.Side;
return (
<ExtraCounterContainer>
<ExtraCounterButton
@@ -126,8 +126,10 @@ const ExtraCounter = ({
}}
aria-label={`Player ${playerIndex} extra counter: ${type}`}
>
<IconContainer $rotation={rotation}>{Icon}</IconContainer>
<TextContainer>
<IconContainer data-rotation-is-side={rotationIsSide}>
{Icon}
</IconContainer>
<TextContainer data-rotation-is-side={rotationIsSide}>
<OutlinedText
fontSize={fontSize}
fontWeight={fontWeight}

View File

@@ -2,6 +2,7 @@ import { twc } from 'react-twc';
import { useAnalytics } from '../../Hooks/useAnalytics';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { PreStartMode } from '../../Types/Settings';
import { InstallPWAButton } from '../Misc/InstallPWAButton';
import { Separator } from '../Misc/Separator';
import { Paragraph } from '../Misc/TextComponents';
import { ToggleButton } from '../Misc/ToggleButton';
@@ -201,25 +202,25 @@ export const SettingsDialog = ({
is enabled.
</Description>
</SettingContainer>
<SettingContainer>
<ToggleContainer>
<label>
Fullscreen on start <span className="text-xs">(Android only)</span>
</label>
<ToggleButton
checked={settings.goFullscreenOnStart}
onChange={() => {
setSettings({
...settings,
goFullscreenOnStart: !settings.goFullscreenOnStart,
});
}}
/>
</ToggleContainer>
<Description>
Will enter fullscreen mode when starting a game if this is enabled.
</Description>
</SettingContainer>
{(!window.isIOS || window.isIPad) && (
<SettingContainer>
<ToggleContainer>
<label>Fullscreen on start</label>
<ToggleButton
checked={settings.goFullscreenOnStart}
onChange={() => {
setSettings({
...settings,
goFullscreenOnStart: !settings.goFullscreenOnStart,
});
}}
/>
</ToggleContainer>
<Description>
Will enter fullscreen mode when starting a game if this is enabled.
</Description>
</SettingContainer>
)}
<SettingContainer>
<ToggleContainer>
@@ -255,21 +256,45 @@ export const SettingsDialog = ({
</div>
{!isPWA && (
<>
<Separator height="1px" />
<SettingContainer>
<ToggleContainer>
<Paragraph>
<b>Tip:</b> You can{' '}
<b>add this webapp to your home page on iOS</b> or{' '}
<b>install it on Android</b> to have it act just like a normal
app!
</Paragraph>
</ToggleContainer>
<Description className="mt-1">
If you do, this app will work offline and the toolbar will be
automatically hidden.
</Description>
</SettingContainer>
{window.isIOS && (
<>
<Separator height="1px" />
<SettingContainer>
<ToggleContainer>
<Paragraph>
<b>Tip:</b> You can <b>add this webapp to your home page</b>{' '}
to have it act just like a normal app!
</Paragraph>
</ToggleContainer>
<Description className="mt-1">
If you do, this web app will work offline and the toolbar will
be automatically hidden.
</Description>
</SettingContainer>
</>
)}
{!window.isIOS && (
<>
<Separator height="1px" />
<SettingContainer>
<ToggleContainer>
<Paragraph>
<b>Tip:</b> You can <b>install this page as a PWA</b> to
have it act just like a normal app!
</Paragraph>
</ToggleContainer>
<Description className="mt-1">
If you do, this web app will work offline and the toolbar will
be automatically hidden. PWA stands for Progressive Web
Application
</Description>
</SettingContainer>
<div className="flex w-full justify-center">
<InstallPWAButton />
</div>
</>
)}
</>
)}
<Separator height="1px" />

View File

@@ -0,0 +1,45 @@
import { useEffect, useRef, useState } from 'react';
import { BeforeInstallPromptEvent } from '../../global';
import { useAnalytics } from '../../Hooks/useAnalytics';
export const InstallPWAButton = () => {
const supportsPWARef = useRef<boolean>(false);
const [promptInstall, setPromptInstall] =
useState<BeforeInstallPromptEvent | null>(null);
const analytics = useAnalytics();
const handler = (e: BeforeInstallPromptEvent) => {
e.preventDefault();
supportsPWARef.current = true;
setPromptInstall(e);
};
useEffect(() => {
window.addEventListener('beforeinstallprompt', handler);
return () => window.removeEventListener('transitionend', handler);
}, []);
if (!supportsPWARef.current) {
return null;
}
return (
<button
className="mt-1 mb-1 bg-primary-main px-3 py-1 rounded-md duration-200 ease-in-out shadow-[1px_2px_4px_0px_rgba(0,0,0,0.3)] hover:bg-primary-dark font-bold"
aria-label="Install app"
title="Install app"
onClick={(e) => {
e.preventDefault();
if (!promptInstall) {
return;
}
analytics.trackEvent('install_pwa_prompt_shown');
promptInstall.prompt();
}}
>
Install as a PWA
</button>
);
};

View File

@@ -347,30 +347,35 @@ const PlayerMenu = ({
>
<Exit size={iconSize} style={{ rotate: '180deg' }} />
</button>
<div
data-fullscreen={document.fullscreenElement ? true : false}
className="flex
{(!window.isIOS || window.isIPad) && (
<div
data-fullscreen={document.fullscreenElement ? true : false}
className="flex
data-[fullscreen=true]:bg-secondary-dark rounded-lg border border-transparent
data-[fullscreen=true]:border-primary-main"
>
<IconCheckbox
className="p-1"
name="fullscreen"
checked={document.fullscreenElement ? true : false}
icon={
<FullscreenOff
size={iconSize}
className="text-primary-main"
/>
}
checkedIcon={
<FullscreenOn size={iconSize} className="text-primary-main" />
}
onChange={toggleFullscreen}
aria-checked={document.fullscreenElement ? true : false}
aria-label="Fullscreen"
/>
</div>
>
<IconCheckbox
className="p-1"
name="fullscreen"
checked={document.fullscreenElement ? true : false}
icon={
<FullscreenOff
size={iconSize}
className="text-primary-main"
/>
}
checkedIcon={
<FullscreenOn
size={iconSize}
className="text-primary-main"
/>
}
onChange={toggleFullscreen}
aria-checked={document.fullscreenElement ? true : false}
aria-label="Fullscreen"
/>
</div>
)}
<button
data-wake-lock-active={settings.keepAwake}

View File

@@ -1,7 +1,10 @@
import { twc } from 'react-twc';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { usePlayers } from '../../Hooks/usePlayers';
import { Player as PlayerType } from '../../Types/Player';
import { PreStartMode } from '../../Types/Settings';
import LifeCounter from '../LifeCounter/LifeCounter';
import { RoulettePlayerCard } from '../PreStartGame/Games/RandomKing/RoulettePlayerCard';
import { GridLayout } from '../Views/Play';
const getGridArea = (player: PlayerType) => {
@@ -28,6 +31,8 @@ const PlayersWrapper = twc.div`w-full h-full bg-black`;
export const Players = ({ gridLayout }: { gridLayout: GridLayout }) => {
const { players } = usePlayers();
const { playing, settings, preStartCompleted } = useGlobalSettings();
return (
<PlayersWrapper>
<div className={`grid w-full h-full gap-1 box-border ${gridLayout} `}>
@@ -36,7 +41,7 @@ export const Players = ({ gridLayout }: { gridLayout: GridLayout }) => {
return (
<div
key={player.index}
className={`flex justify-center items-center align-middle ${gridArea}`}
className={`relative flex justify-center items-center align-middle ${gridArea}`}
>
<LifeCounter
player={player}
@@ -44,6 +49,15 @@ export const Players = ({ gridLayout }: { gridLayout: GridLayout }) => {
(opponent) => opponent.index !== player.index
)}
/>
{settings.preStartMode === PreStartMode.RandomKing &&
!preStartCompleted &&
!playing &&
settings.showStartingPlayer && (
<div className="absolute size-full z-20">
<RoulettePlayerCard player={player} />
</div>
)}
</div>
);
})}

View File

@@ -1,49 +0,0 @@
import { usePlayers } from '../../../../Hooks/usePlayers';
import { Player } from '../../../../Types/Player';
import { GridLayout } from '../../../Views/Play';
import { RoulettePlayerCard } from './RoulettePlayerCard';
const getGridArea = (player: Player) => {
switch (player.index) {
case 0:
return 'grid-in-player0';
case 1:
return 'grid-in-player1';
case 2:
return 'grid-in-player2';
case 3:
return 'grid-in-player3';
case 4:
return 'grid-in-player4';
case 5:
return 'grid-in-player5';
default:
throw new Error('Invalid player index');
}
};
export const RandomKingPlayers = ({
gridLayout,
}: {
gridLayout: GridLayout;
}) => {
const { players } = usePlayers();
return (
<div className="w-full h-full bg-black">
<div className={`grid w-full h-full gap-1 box-border ${gridLayout} `}>
{players.map((player) => {
const gridArea = getGridArea(player);
return (
<div
key={player.index}
className={`flex justify-center items-center align-middle ${gridArea}`}
>
<RoulettePlayerCard player={player} />
</div>
);
})}
</div>
</div>
);
};

View File

@@ -2,7 +2,7 @@ import { useEffect, useRef } from 'react';
import { useGlobalSettings } from '../../../../Hooks/useGlobalSettings';
import { usePlayers } from '../../../../Hooks/usePlayers';
export const RandomKingSelectWrapper = () => {
export const RandomKingRandomizer = () => {
const { setRandomizingPlayer } = useGlobalSettings();
const randomIntervalRef = useRef<NodeJS.Timeout | null>(null);
@@ -87,7 +87,7 @@ export const RandomKingSelectWrapper = () => {
backgroundImage: `linear-gradient(60deg, ${gradientColors})`,
}}
/>
<p className="relative z-10 text-[5vmax]">PRESS TO SELECT PLAYER</p>
<p className="relative z-10 text-[5vmax]">PRESS TO START</p>
</div>
</div>
);

View File

@@ -36,7 +36,7 @@ export const RoulettePlayerCard = ({ player }: { player: Player }) => {
: player.settings.rotation;
return (
<div className="relative flex flex-grow flex-col items-center w-full h-full overflow-hidden">
<div className="relative flex flex-grow flex-col items-center w-full h-full overflow-hidden bg-black">
<div
className="flex absolute w-full h-full justify-center items-center pointer-events-none select-none webkit-user-select-none z-10"
style={{ backgroundColor: player.color }}

View File

@@ -1,12 +1,11 @@
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { PreStartMode } from '../../Types/Settings';
import { GridLayout } from '../Views/Play';
import { FingerGame } from './Games/FingerGame';
import { RandomKingPlayers } from './Games/RandomKing/RandomKingPlayers';
import { RandomKingSelectWrapper } from './Games/RandomKing/RandomKingSelectWrapper';
import { RandomKingRandomizer } from './Games/RandomKing/RandomKingSelectWrapper';
import { Trivia } from './Games/Trivia';
export const PreStart = ({ gridLayout }: { gridLayout: GridLayout }) => {
export const PreStart = () => {
const { settings, randomizingPlayer, goToStart } = useGlobalSettings();
if (settings.preStartMode === PreStartMode.RandomKing) {
@@ -14,12 +13,7 @@ export const PreStart = ({ gridLayout }: { gridLayout: GridLayout }) => {
return null;
}
return (
<>
<RandomKingSelectWrapper />
<RandomKingPlayers gridLayout={gridLayout} />
</>
);
return <RandomKingRandomizer />;
}
if (settings.preStartMode === PreStartMode.FingerGame) {

View File

@@ -94,22 +94,14 @@ export const Play = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
if (
players.length > 1 &&
!preStartCompleted &&
settings.preStartMode !== PreStartMode.None &&
!playing &&
settings.showStartingPlayer
) {
return (
<MainWrapper>
<PreStart gridLayout={gridLayout} />
</MainWrapper>
);
}
return (
<MainWrapper>
{players.length > 1 &&
!preStartCompleted &&
settings.preStartMode !== PreStartMode.None &&
!playing &&
settings.showStartingPlayer && <PreStart />}
<Players gridLayout={gridLayout} />
</MainWrapper>
);

View File

@@ -387,7 +387,7 @@ const Start = () => {
}}
/>
</div>
{!isPWA && (
{!isPWA && window.isIOS && (
<p className="text-center text-xs text-text-primary w-11/12 mt-4">
If you're on iOS, this page works better if you{' '}
<strong>hide the toolbar</strong> or{' '}

21
src/global.d.ts vendored Normal file
View File

@@ -0,0 +1,21 @@
export {};
export interface BeforeInstallPromptEvent extends Event {
readonly platforms: string[];
readonly userChoice: Promise<{
outcome: 'accepted' | 'dismissed';
platform: string;
}>;
prompt(): Promise<void>;
}
declare global {
interface Window {
isIOS: boolean;
isIPad: boolean;
}
interface WindowEventMap {
beforeinstallprompt: BeforeInstallPromptEvent;
transitionend: BeforeInstallPromptEvent;
}
}

View File

@@ -3,6 +3,10 @@ import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import './index.css';
window.isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
window.isIPad = /iPad/.test(navigator.userAgent);
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);