forked from external-repos/LifeTrinket
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3770d13beb | ||
|
|
13733242a2 | ||
|
|
81f3891b20 |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "life-trinket",
|
||||
"private": true,
|
||||
"version": "0.5.51",
|
||||
"version": "0.5.52",
|
||||
"type": "commonjs",
|
||||
"engines": {
|
||||
"node": ">=18",
|
||||
@@ -43,8 +43,9 @@
|
||||
"install": "^0.13.0",
|
||||
"postcss": "^8.4.32",
|
||||
"prettier": "2.8.8",
|
||||
"tailwindcss": "^3.4.0",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.4.5"
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.0.12",
|
||||
"vite-plugin-pwa": "^0.17.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { twc } from 'react-twc';
|
||||
import { Separator } from './Separator';
|
||||
import { Paragraph } from './TextComponents';
|
||||
|
||||
export const ModalWrapper = twc.div`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[80vw] h-[85vh] bg-background-default p-4 overflow-scroll rounded-2xl border-none text-text-primary`;
|
||||
export const ModalWrapper = twc.div`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 h-[85vh] bg-background-default p-4 overflow-scroll rounded-2xl border-none text-text-primary w-[95vw] max-w-[548px]`;
|
||||
|
||||
type InfoModalProps = {
|
||||
isOpen: boolean;
|
||||
@@ -12,63 +12,77 @@ type InfoModalProps = {
|
||||
|
||||
export const InfoModal = ({ isOpen, closeModal }: InfoModalProps) => {
|
||||
return (
|
||||
<Modal open={isOpen} onClose={closeModal}>
|
||||
<ModalWrapper>
|
||||
<div>
|
||||
<h2 className="text-2xl text-center mb-4">📋 Usage Guide</h2>
|
||||
<Separator height="1px" />
|
||||
<Paragraph className="my-4">
|
||||
There are some controls that you might not know about, so here's a
|
||||
short list of them.
|
||||
</Paragraph>
|
||||
<h3 className="text-lg font-bold mb-2">Life counter</h3>
|
||||
<ul className="list-disc ml-6 mb-4">
|
||||
<li>
|
||||
<strong>Tap</strong> on a player's + or - button to add or
|
||||
subtract <strong>1 life</strong>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Long press</strong> on a player's + or - button to add or
|
||||
subtract <strong>10 life</strong>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3 className="text-lg font-bold mb-2">
|
||||
Commander damage and other counters
|
||||
</h3>
|
||||
<ul className="list-disc ml-6 mb-4">
|
||||
<li>
|
||||
<strong>Tap</strong> on the counter to add{' '}
|
||||
<strong>1 counter</strong>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Long press</strong> on the counter to subtract{' '}
|
||||
<strong>1 counter</strong>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3 className="text-lg font-bold mb-2">Other</h3>
|
||||
<Paragraph className="mb-4">
|
||||
When a player is <strong>at or below 0 life</strong>, has taken{' '}
|
||||
<strong>21 or more Commander Damage</strong> or has{' '}
|
||||
<strong>10 or more poison counters</strong>, a button with a skull
|
||||
will appear on that player's card. Tapping it will dim the player's
|
||||
card.
|
||||
</Paragraph>
|
||||
</div>
|
||||
<div className="text-center mt-4">
|
||||
Visit my
|
||||
<a
|
||||
href="https://github.com/Vikeo/LifeTrinket"
|
||||
target="_blank"
|
||||
className="text-text-secondary underline"
|
||||
<Modal
|
||||
open={isOpen}
|
||||
onClose={closeModal}
|
||||
style={{ display: 'flex', justifyContent: 'center' }}
|
||||
>
|
||||
<>
|
||||
<div className="flex relative w-full max-w-[548px]">
|
||||
<button
|
||||
onClick={closeModal}
|
||||
className="flex absolute top-10 right-0 z-10 w-10 h-10 text-common-white bg-primary-main items-center justify-center rounded-full border-solid border-primary-dark border-2"
|
||||
>
|
||||
{' '}
|
||||
GitHub{' '}
|
||||
</a>
|
||||
for more info about this web app.
|
||||
X
|
||||
</button>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
<ModalWrapper>
|
||||
<div>
|
||||
<h2 className="text-2xl text-center mb-4">📋 Usage Guide</h2>
|
||||
<Separator height="1px" />
|
||||
<Paragraph className="my-4">
|
||||
There are some controls that you might not know about, so here's a
|
||||
short list of them.
|
||||
</Paragraph>
|
||||
<h3 className="text-lg font-bold mb-2">Life counter</h3>
|
||||
<ul className="list-disc ml-6 mb-4">
|
||||
<li>
|
||||
<strong>Tap</strong> on a player's + or - button to add or
|
||||
subtract <strong>1 life</strong>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Long press</strong> on a player's + or - button to add
|
||||
or subtract <strong>10 life</strong>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3 className="text-lg font-bold mb-2">
|
||||
Commander damage and other counters
|
||||
</h3>
|
||||
<ul className="list-disc ml-6 mb-4">
|
||||
<li>
|
||||
<strong>Tap</strong> on the counter to add{' '}
|
||||
<strong>1 counter</strong>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Long press</strong> on the counter to subtract{' '}
|
||||
<strong>1 counter</strong>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3 className="text-lg font-bold mb-2">Other</h3>
|
||||
<Paragraph className="mb-4">
|
||||
When a player is <strong>at or below 0 life</strong>, has taken{' '}
|
||||
<strong>21 or more Commander Damage</strong> or has{' '}
|
||||
<strong>10 or more poison counters</strong>, a button with a skull
|
||||
will appear on that player's card. Tapping it will dim the
|
||||
player's card.
|
||||
</Paragraph>
|
||||
</div>
|
||||
<div className="text-center mt-4">
|
||||
Visit my
|
||||
<a
|
||||
href="https://github.com/Vikeo/LifeTrinket"
|
||||
target="_blank"
|
||||
className="text-text-secondary underline"
|
||||
>
|
||||
{' '}
|
||||
GitHub{' '}
|
||||
</a>
|
||||
for more info about this web app.
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
</>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -67,116 +67,129 @@ export const SettingsModal = ({ isOpen, closeModal }: SettingsModalProps) => {
|
||||
|
||||
return (
|
||||
<Modal open={isOpen} onClose={closeModal}>
|
||||
<ModalWrapper>
|
||||
<Container>
|
||||
<h2 className="text-center text-2xl mb-2">⚙️ Settings ⚙️</h2>
|
||||
<Separator height="1px" />
|
||||
<SettingContainer>
|
||||
<ToggleContainer>
|
||||
<FormLabel>Show Start Player</FormLabel>
|
||||
<Switch
|
||||
checked={settings.showStartingPlayer}
|
||||
onChange={() => {
|
||||
setSettings({
|
||||
...settings,
|
||||
showStartingPlayer: !settings.showStartingPlayer,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</ToggleContainer>
|
||||
<Description>
|
||||
On start or reset of game, will pick a random player who will
|
||||
start first if this is enabled.
|
||||
</Description>
|
||||
</SettingContainer>
|
||||
<SettingContainer>
|
||||
<ToggleContainer>
|
||||
<FormLabel>Keep Awake</FormLabel>
|
||||
<Switch
|
||||
checked={settings.keepAwake}
|
||||
onChange={() => {
|
||||
setSettings({ ...settings, keepAwake: !settings.keepAwake });
|
||||
}}
|
||||
/>
|
||||
</ToggleContainer>
|
||||
<Description>
|
||||
Will prevent device from going to sleep while this app is open if
|
||||
this is enabled.
|
||||
</Description>
|
||||
</SettingContainer>
|
||||
<SettingContainer>
|
||||
<ToggleContainer>
|
||||
<FormLabel>Go fullscreen on start (Android only)</FormLabel>
|
||||
<Switch
|
||||
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>
|
||||
{!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>
|
||||
</>
|
||||
)}
|
||||
<Separator height="1px" />
|
||||
<SettingContainer>
|
||||
<Paragraph>
|
||||
{/* @ts-expect-error is defined in vite.config.ts*/}
|
||||
Current version: {APP_VERSION}{' '}
|
||||
{isLatestVersion && (
|
||||
<span className="text-sm text-text-secondary">(latest)</span>
|
||||
)}
|
||||
</Paragraph>
|
||||
{!isLatestVersion && newVersion && (
|
||||
<Paragraph className="text-text-secondary text-lg text-center">
|
||||
New version ({newVersion}) is available!{' '}
|
||||
</Paragraph>
|
||||
<>
|
||||
<div className="flex relative w-full max-w-[548px]">
|
||||
<button
|
||||
onClick={closeModal}
|
||||
className="flex absolute top-10 right-0 z-10 w-10 h-10 text-common-white bg-primary-main items-center justify-center rounded-full border-solid border-primary-dark border-2"
|
||||
>
|
||||
X
|
||||
</button>
|
||||
</div>
|
||||
<ModalWrapper>
|
||||
<Container>
|
||||
<h2 className="text-center text-2xl mb-2">⚙️ Settings ⚙️</h2>
|
||||
<Separator height="1px" />
|
||||
<SettingContainer>
|
||||
<ToggleContainer>
|
||||
<FormLabel>Show Start Player</FormLabel>
|
||||
<Switch
|
||||
checked={settings.showStartingPlayer}
|
||||
onChange={() => {
|
||||
setSettings({
|
||||
...settings,
|
||||
showStartingPlayer: !settings.showStartingPlayer,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</ToggleContainer>
|
||||
<Description>
|
||||
On start or reset of game, will pick a random player who will
|
||||
start first if this is enabled.
|
||||
</Description>
|
||||
</SettingContainer>
|
||||
<SettingContainer>
|
||||
<ToggleContainer>
|
||||
<FormLabel>Keep Awake</FormLabel>
|
||||
<Switch
|
||||
checked={settings.keepAwake}
|
||||
onChange={() => {
|
||||
setSettings({
|
||||
...settings,
|
||||
keepAwake: !settings.keepAwake,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</ToggleContainer>
|
||||
<Description>
|
||||
Will prevent device from going to sleep while this app is open
|
||||
if this is enabled.
|
||||
</Description>
|
||||
</SettingContainer>
|
||||
<SettingContainer>
|
||||
<ToggleContainer>
|
||||
<FormLabel>Go fullscreen on start (Android only)</FormLabel>
|
||||
<Switch
|
||||
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>
|
||||
{!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>
|
||||
</>
|
||||
)}
|
||||
</SettingContainer>
|
||||
{!isLatestVersion && newVersion && (
|
||||
<Separator height="1px" />
|
||||
<SettingContainer>
|
||||
<Paragraph>
|
||||
{/* @ts-expect-error is defined in vite.config.ts*/}
|
||||
Current version: {APP_VERSION}{' '}
|
||||
{isLatestVersion && (
|
||||
<span className="text-sm text-text-secondary">(latest)</span>
|
||||
)}
|
||||
</Paragraph>
|
||||
{!isLatestVersion && newVersion && (
|
||||
<Paragraph className="text-text-secondary text-lg text-center">
|
||||
New version ({newVersion}) is available!{' '}
|
||||
</Paragraph>
|
||||
)}
|
||||
</SettingContainer>
|
||||
{!isLatestVersion && newVersion && (
|
||||
<Button
|
||||
variant="contained"
|
||||
style={{ marginTop: '0.25rem', marginBottom: '0.25rem' }}
|
||||
onClick={() => window?.location?.reload()}
|
||||
>
|
||||
<span>Update</span>
|
||||
<span className="text-xs"> (reload app)</span>
|
||||
</Button>
|
||||
)}
|
||||
<Separator height="1px" />
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
style={{ marginTop: '0.25rem', marginBottom: '0.25rem' }}
|
||||
onClick={() => window?.location?.reload()}
|
||||
onClick={closeModal}
|
||||
style={{ marginTop: '0.25rem' }}
|
||||
>
|
||||
<span>Update</span>
|
||||
<span className="text-xs"> (reload app)</span>
|
||||
Save and Close
|
||||
</Button>
|
||||
)}
|
||||
<Separator height="1px" />
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={closeModal}
|
||||
style={{ marginTop: '0.25rem' }}
|
||||
>
|
||||
Save and Close
|
||||
</Button>
|
||||
</Container>
|
||||
</ModalWrapper>
|
||||
</Container>
|
||||
</ModalWrapper>
|
||||
</>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -176,7 +176,7 @@ const Start = () => {
|
||||
Life Trinket
|
||||
</h1>
|
||||
|
||||
<div className="overflow-hidden items-center flex flex-col max-w-[548px] mb-8 px-4">
|
||||
<div className="overflow-hidden items-center flex flex-col max-w-[548px] w-full mb-8 px-4">
|
||||
<FormControl focused={false} style={{ width: '100%' }}>
|
||||
<FormLabel>Number of Players</FormLabel>
|
||||
<SliderWrapper>
|
||||
|
||||
@@ -6,6 +6,9 @@ import type { Config } from 'tailwindcss';
|
||||
export default {
|
||||
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
screens: {
|
||||
modalSm: '548px',
|
||||
},
|
||||
extend: {
|
||||
gridTemplateAreas: {
|
||||
onePlayerLandscape: ['player0 player0'],
|
||||
@@ -53,10 +56,10 @@ export default {
|
||||
},
|
||||
text: {
|
||||
primary: '#F5F5F5',
|
||||
secondary: '#b3b39b',
|
||||
secondary: '#76A6A5',
|
||||
},
|
||||
action: {
|
||||
disabled: '#5E714C',
|
||||
disabled: '#234A47',
|
||||
},
|
||||
common: {
|
||||
white: '#F9FFE3',
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react-swc';
|
||||
import { defineConfig } from 'vite';
|
||||
import { VitePWA } from 'vite-plugin-pwa';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
plugins: [
|
||||
react(),
|
||||
VitePWA({
|
||||
registerType: 'autoUpdate',
|
||||
workbox: {
|
||||
clientsClaim: true,
|
||||
skipWaiting: true,
|
||||
},
|
||||
}),
|
||||
],
|
||||
build: {
|
||||
minify: 'esbuild',
|
||||
rollupOptions: {
|
||||
|
||||
Reference in New Issue
Block a user