Fix lots of bugs and refactor
This commit is contained in:
parent
4c980657ec
commit
2eb6a9c0ba
|
@ -27,4 +27,4 @@ vite.config.ts.timestamp-*
|
||||||
/src/lib/generated
|
/src/lib/generated
|
||||||
/tailwind.css
|
/tailwind.css
|
||||||
*.svelte-kit
|
*.svelte-kit
|
||||||
|
/.vite
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Ignore files for PNPM, NPM and YARN
|
||||||
|
pnpm-lock.yaml
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"semi": false,
|
||||||
|
"useTabs": false,
|
||||||
|
"singleQuote": false,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"printWidth": 80,
|
||||||
|
"plugins": ["prettier-plugin-svelte"],
|
||||||
|
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||||
|
}
|
|
@ -8,20 +8,20 @@
|
||||||
"name": "breakoften",
|
"name": "breakoften",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "^3.0.0",
|
"@sveltejs/adapter-auto": "^3.1.1",
|
||||||
"@sveltejs/kit": "^2.0.0",
|
"@sveltejs/kit": "^2.5.2",
|
||||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
"@sveltejs/vite-plugin-svelte": "^3.0.2",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"postcss": "^8.4.38",
|
"postcss": "^8.4.38",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"prettier-plugin-svelte": "^3.2.3",
|
"prettier-plugin-svelte": "^3.2.3",
|
||||||
"svelte": "^4.2.7",
|
"svelte": "5.0.0-next.54",
|
||||||
"svelte-check": "^3.6.0",
|
"svelte-check": "^3.6.0",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.3",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"tw-colors": "^3.3.1",
|
"tw-colors": "^3.3.1",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.0.0",
|
||||||
"vite": "^5.0.3"
|
"vite": "^5.1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@alloc/quick-lru": {
|
"node_modules/@alloc/quick-lru": {
|
||||||
|
@ -824,6 +824,18 @@
|
||||||
"vite": "^5.0.0"
|
"vite": "^5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@sveltejs/vite-plugin-svelte/node_modules/svelte-hmr": {
|
||||||
|
"version": "0.16.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz",
|
||||||
|
"integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20 || ^14.13.1 || >= 16"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"svelte": "^3.19.0 || ^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/cookie": {
|
"node_modules/@types/cookie": {
|
||||||
"version": "0.6.0",
|
"version": "0.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
|
||||||
|
@ -854,6 +866,15 @@
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/acorn-typescript": {
|
||||||
|
"version": "1.4.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn-typescript/-/acorn-typescript-1.4.13.tgz",
|
||||||
|
"integrity": "sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==",
|
||||||
|
"dev": true,
|
||||||
|
"peerDependencies": {
|
||||||
|
"acorn": ">=8.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ansi-regex": {
|
"node_modules/ansi-regex": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||||
|
@ -1101,19 +1122,6 @@
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/code-red": {
|
|
||||||
"version": "1.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz",
|
|
||||||
"integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.15",
|
|
||||||
"@types/estree": "^1.0.1",
|
|
||||||
"acorn": "^8.10.0",
|
|
||||||
"estree-walker": "^3.0.3",
|
|
||||||
"periscopic": "^3.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/color": {
|
"node_modules/color": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
||||||
|
@ -1193,19 +1201,6 @@
|
||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/css-tree": {
|
|
||||||
"version": "2.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
|
|
||||||
"integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"mdn-data": "2.0.30",
|
|
||||||
"source-map-js": "^1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cssesc": {
|
"node_modules/cssesc": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||||
|
@ -1357,13 +1352,14 @@
|
||||||
"integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==",
|
"integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/estree-walker": {
|
"node_modules/esrap": {
|
||||||
"version": "3.0.3",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/esrap/-/esrap-1.2.1.tgz",
|
||||||
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
|
"integrity": "sha512-dhkcOLfN/aDdMFI1iwPEcy/XqAZzGNfgfEJjZozy2tia6u0dQoZyXzkRshHTckuNsM+c0CYQndY+uRFe3N+AIQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "^1.0.0"
|
"@jridgewell/sourcemap-codec": "^1.4.15",
|
||||||
|
"@types/estree": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fast-glob": {
|
"node_modules/fast-glob": {
|
||||||
|
@ -1739,12 +1735,6 @@
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mdn-data": {
|
|
||||||
"version": "2.0.30",
|
|
||||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
|
|
||||||
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/merge2": {
|
"node_modules/merge2": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||||
|
@ -1974,17 +1964,6 @@
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/periscopic": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@types/estree": "^1.0.0",
|
|
||||||
"estree-walker": "^3.0.0",
|
|
||||||
"is-reference": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||||
|
@ -2641,28 +2620,27 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/svelte": {
|
"node_modules/svelte": {
|
||||||
"version": "4.2.15",
|
"version": "5.0.0-next.54",
|
||||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.15.tgz",
|
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.54.tgz",
|
||||||
"integrity": "sha512-j9KJSccHgLeRERPlhMKrCXpk2TqL2m5Z+k+OBTQhZOhIdCCd3WfqV+ylPWeipEwq17P/ekiSFWwrVQv93i3bsg==",
|
"integrity": "sha512-ik+hXhlKdZozs+EruogLXb5PVZD8X8ekNBwQGBYcTpj1FD0sgWZxvUEQV4m0rE5LaUL3J5cmO4e8daOuPxIK/A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ampproject/remapping": "^2.2.1",
|
"@ampproject/remapping": "^2.2.1",
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.15",
|
"@jridgewell/sourcemap-codec": "^1.4.15",
|
||||||
"@jridgewell/trace-mapping": "^0.3.18",
|
"@types/estree": "^1.0.5",
|
||||||
"@types/estree": "^1.0.1",
|
"acorn": "^8.11.3",
|
||||||
"acorn": "^8.9.0",
|
"acorn-typescript": "^1.4.13",
|
||||||
"aria-query": "^5.3.0",
|
"aria-query": "^5.3.0",
|
||||||
"axobject-query": "^4.0.0",
|
"axobject-query": "^4.0.0",
|
||||||
"code-red": "^1.0.3",
|
"esm-env": "^1.0.0",
|
||||||
"css-tree": "^2.3.1",
|
"esrap": "^1.2.1",
|
||||||
"estree-walker": "^3.0.3",
|
"is-reference": "^3.0.2",
|
||||||
"is-reference": "^3.0.1",
|
|
||||||
"locate-character": "^3.0.0",
|
"locate-character": "^3.0.0",
|
||||||
"magic-string": "^0.30.4",
|
"magic-string": "^0.30.5",
|
||||||
"periscopic": "^3.1.0"
|
"zimmerframe": "^1.1.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/svelte-check": {
|
"node_modules/svelte-check": {
|
||||||
|
@ -2687,18 +2665,6 @@
|
||||||
"svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0"
|
"svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/svelte-hmr": {
|
|
||||||
"version": "0.16.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz",
|
|
||||||
"integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": "^12.20 || ^14.13.1 || >= 16"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"svelte": "^3.19.0 || ^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/svelte-preprocess": {
|
"node_modules/svelte-preprocess": {
|
||||||
"version": "5.1.4",
|
"version": "5.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz",
|
||||||
|
@ -3129,6 +3095,12 @@
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 14"
|
"node": ">= 14"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/zimmerframe": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
14
package.json
14
package.json
|
@ -7,23 +7,25 @@
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
|
"lint": "prettier --check .",
|
||||||
|
"format": "prettier --write ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "^3.0.0",
|
"@sveltejs/adapter-auto": "^3.1.1",
|
||||||
"@sveltejs/kit": "^2.0.0",
|
"@sveltejs/kit": "^2.5.2",
|
||||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
"@sveltejs/vite-plugin-svelte": "^3.0.2",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"postcss": "^8.4.38",
|
"postcss": "^8.4.38",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"prettier-plugin-svelte": "^3.2.3",
|
"prettier-plugin-svelte": "^3.2.3",
|
||||||
"svelte": "^4.2.7",
|
"svelte": "5.0.0-next.54",
|
||||||
"svelte-check": "^3.6.0",
|
"svelte-check": "^3.6.0",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.3",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"tw-colors": "^3.3.1",
|
"tw-colors": "^3.3.1",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.0.0",
|
||||||
"vite": "^5.0.3"
|
"vite": "^5.1.4"
|
||||||
},
|
},
|
||||||
"type": "module"
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,4 +3,4 @@ export default {
|
||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
autoprefixer: {},
|
autoprefixer: {},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|
|
@ -10,4 +10,4 @@ declare global {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
export {}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<script lang="ts" context="module">
|
||||||
|
export const themes = ["light", "dark"] as const
|
||||||
|
export type Theme = (typeof themes)[number]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { slide } from "svelte/transition"
|
||||||
|
let { theme } = $props<{ theme: Theme }>()
|
||||||
|
|
||||||
|
function toggleTheme() {
|
||||||
|
const currentIndex = themes.indexOf(theme)
|
||||||
|
theme = themes[(currentIndex + 1) % themes.length]
|
||||||
|
}
|
||||||
|
|
||||||
|
let icon = $derived.by(() => {
|
||||||
|
if (theme === "light") return "🌞"
|
||||||
|
if (theme === "dark") return "🌙"
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#key theme}
|
||||||
|
<button transition:slide={{ axis: "x" }} onclick={toggleTheme}>
|
||||||
|
{icon}
|
||||||
|
</button>
|
||||||
|
{/key}
|
||||||
|
|
||||||
|
<slot />
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
button {
|
||||||
|
@apply absolute top-0 right-0;
|
||||||
|
@apply text-3xl;
|
||||||
|
@apply cursor-pointer;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,5 +1,27 @@
|
||||||
<script>
|
<script lang="ts">
|
||||||
import "../app.css";
|
import ThemePicker, { type Theme } from "$lib/components/ThemePicker.svelte"
|
||||||
</script>
|
import "../app.css"
|
||||||
|
|
||||||
<slot />
|
let { data } = $props()
|
||||||
|
|
||||||
|
let theme = $state("dark" as Theme)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div data-theme={theme}>
|
||||||
|
<ThemePicker bind:theme />
|
||||||
|
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
:global(body) {
|
||||||
|
@apply flex min-h-screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
@apply flex-1;
|
||||||
|
@apply flex flex-col;
|
||||||
|
@apply bg-background text-foreground;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -1,46 +1,26 @@
|
||||||
<!-- <script context="module">
|
|
||||||
export async function load() {
|
|
||||||
const res = await fetch("https://api.example.com/data");
|
|
||||||
const data = await res.json();
|
|
||||||
return {
|
|
||||||
props: {
|
|
||||||
data,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script> -->
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { goto } from "$app/navigation";
|
|
||||||
// import { writable } from "svelte/store";
|
|
||||||
|
|
||||||
const startApp = () => {
|
|
||||||
goto("/timer");
|
|
||||||
};
|
|
||||||
|
|
||||||
// const theme = writable("dark");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<h1>Welcome to the Prevent Computer Vision Syndrome App</h1>
|
<h1>Welcome to BreakOften!</h1>
|
||||||
<button on:click={startApp}>Start Timer</button>
|
<a href="/timer">Start Timer</a>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
main {
|
main {
|
||||||
text-align: center;
|
@apply text-center;
|
||||||
margin: 100px auto;
|
@apply mx-auto my-64;
|
||||||
color: var(--text-color);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 2.5rem;
|
@apply text-4xl mb-8;
|
||||||
margin-bottom: 20px;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
a {
|
||||||
padding: 10px 20px;
|
@apply inline-block;
|
||||||
font-size: 1rem;
|
@apply rounded px-4 py-2;
|
||||||
cursor: pointer;
|
@apply transition duration-300 ease-in-out;
|
||||||
}
|
@apply bg-primary text-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
@apply bg-primaryLight text-white;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,180 +1,180 @@
|
||||||
<script context="module">
|
<script context="module">
|
||||||
export async function load() {
|
export async function load() {
|
||||||
const res = await fetch("https://api.example.com/data");
|
const res = await fetch("https://api.example.com/data")
|
||||||
const data = await res.json();
|
const data = await res.json()
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
data,
|
data,
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onDestroy, onMount } from "svelte";
|
import { onDestroy, onMount } from "svelte"
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store"
|
||||||
import type { Writable } from "svelte/store";
|
import type { Writable } from "svelte/store"
|
||||||
|
|
||||||
const MINI_BREAK_DURATION = 0.15 * 60 * 1000; // 1 minutes
|
const MINI_BREAK_DURATION = 0.15 * 60 * 1000 // 1 minutes
|
||||||
// const MINI_BREAK_DURATION = 20 * 60 * 1000; // 20 minutes
|
// const MINI_BREAK_DURATION = 20 * 60 * 1000; // 20 minutes
|
||||||
const MINI_BREAK_INTERVAL = 5 * 1000; // 20 seconds
|
const MINI_BREAK_INTERVAL = 5 * 1000 // 20 seconds
|
||||||
// const LONG_BREAK_DURATION = 5 * 60 * 1000; // 5 minutes
|
// const LONG_BREAK_DURATION = 5 * 60 * 1000; // 5 minutes
|
||||||
const LONG_BREAK_DURATION = 0.3 * 60 * 1000; // 2 minutes
|
const LONG_BREAK_DURATION = 0.3 * 60 * 1000 // 2 minutes
|
||||||
|
|
||||||
let timer: number | null = null;
|
let timer: number | null = null
|
||||||
let miniBreakCount = 0;
|
let miniBreakCount = 0
|
||||||
|
|
||||||
let audio: HTMLAudioElement | null = null;
|
let audio: HTMLAudioElement | null = null
|
||||||
|
|
||||||
const playSound = () => {
|
const playSound = () => {
|
||||||
if (audio) {
|
if (audio) {
|
||||||
// audio.pause();
|
// audio.pause();
|
||||||
audio.src = "/sounds/Bells.mp3";
|
audio.src = "/sounds/Bells.mp3"
|
||||||
audio.volume = 0.4;
|
audio.volume = 0.4
|
||||||
// audio.play();
|
// audio.play();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const showNotification = (title: string, options: NotificationOptions) => {
|
const showNotification = (title: string, options: NotificationOptions) => {
|
||||||
if (Notification.permission === "granted") {
|
if (Notification.permission === "granted") {
|
||||||
// new Notification(title, options);
|
// new Notification(title, options);
|
||||||
} else if (Notification.permission !== "denied") {
|
} else if (Notification.permission !== "denied") {
|
||||||
Notification.requestPermission().then((permission) => {
|
Notification.requestPermission().then((permission) => {
|
||||||
if (permission === "granted") {
|
if (permission === "granted") {
|
||||||
// new Notification(title, options);
|
// new Notification(title, options);
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const state: Writable<string> = writable("Ready");
|
const state: Writable<string> = writable("Ready")
|
||||||
const timeLeftDisplay: Writable<string> = writable("");
|
const timeLeftDisplay: Writable<string> = writable("")
|
||||||
const timeLeft: Writable<number> = writable(MINI_BREAK_DURATION);
|
const timeLeft: Writable<number> = writable(MINI_BREAK_DURATION)
|
||||||
|
|
||||||
const startTimer = () => {
|
const startTimer = () => {
|
||||||
if (timer) clearInterval(timer);
|
if (timer) clearInterval(timer)
|
||||||
|
|
||||||
timer = setInterval(() => {
|
timer = setInterval(() => {
|
||||||
timeLeft.update((currentTimeLeft) => {
|
timeLeft.update((currentTimeLeft) => {
|
||||||
const newTimeLeft = currentTimeLeft - 1000;
|
const newTimeLeft = currentTimeLeft - 1000
|
||||||
if (newTimeLeft <= 0) {
|
if (newTimeLeft <= 0) {
|
||||||
if ($state !== "Ready") {
|
if ($state !== "Ready") {
|
||||||
state.set("Ready");
|
state.set("Ready")
|
||||||
miniBreakCount++;
|
miniBreakCount++
|
||||||
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION));
|
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION))
|
||||||
showNotification("Ready", { body: "Continue working!" });
|
showNotification("Ready", { body: "Continue working!" })
|
||||||
playSound(); // Adjust volume as needed
|
playSound() // Adjust volume as needed
|
||||||
return MINI_BREAK_DURATION;
|
return MINI_BREAK_DURATION
|
||||||
}
|
}
|
||||||
if (miniBreakCount === 3) {
|
if (miniBreakCount === 3) {
|
||||||
state.set("Long Break");
|
state.set("Long Break")
|
||||||
miniBreakCount = 0;
|
miniBreakCount = 0
|
||||||
timeLeftDisplay.set(formatTime(LONG_BREAK_DURATION));
|
timeLeftDisplay.set(formatTime(LONG_BREAK_DURATION))
|
||||||
showNotification("Long Break", {
|
showNotification("Long Break", {
|
||||||
body: "Take a 5-minute break now!",
|
body: "Take a 5-minute break now!",
|
||||||
});
|
})
|
||||||
playSound(); // Adjust volume as needed
|
playSound() // Adjust volume as needed
|
||||||
return LONG_BREAK_DURATION;
|
return LONG_BREAK_DURATION
|
||||||
} else {
|
} else {
|
||||||
state.set("Mini Break");
|
state.set("Mini Break")
|
||||||
// miniBreakCount++;
|
// miniBreakCount++;
|
||||||
timeLeftDisplay.set(formatTime(MINI_BREAK_INTERVAL));
|
timeLeftDisplay.set(formatTime(MINI_BREAK_INTERVAL))
|
||||||
showNotification("Mini Break", {
|
showNotification("Mini Break", {
|
||||||
body: "Take a 20-second break now!",
|
body: "Take a 20-second break now!",
|
||||||
});
|
})
|
||||||
playSound(); // Adjust volume as needed
|
playSound() // Adjust volume as needed
|
||||||
return MINI_BREAK_INTERVAL;
|
return MINI_BREAK_INTERVAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
timeLeftDisplay.set(formatTime(newTimeLeft));
|
timeLeftDisplay.set(formatTime(newTimeLeft))
|
||||||
return newTimeLeft;
|
return newTimeLeft
|
||||||
});
|
})
|
||||||
}, 1000);
|
}, 1000)
|
||||||
};
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
audio = document.createElement('audio');
|
audio = document.createElement("audio")
|
||||||
startTimer();
|
startTimer()
|
||||||
});
|
})
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if (timer) clearInterval(timer);
|
if (timer) clearInterval(timer)
|
||||||
if (audio) audio = null;
|
if (audio) audio = null
|
||||||
});
|
})
|
||||||
|
|
||||||
const skipBreak = () => {
|
const skipBreak = () => {
|
||||||
// if (timer) clearInterval(timer);
|
// if (timer) clearInterval(timer);
|
||||||
if ($state === "Ready") {
|
if ($state === "Ready") {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
state.set("Ready");
|
state.set("Ready")
|
||||||
timeLeft.set(MINI_BREAK_DURATION);
|
timeLeft.set(MINI_BREAK_DURATION)
|
||||||
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION));
|
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION))
|
||||||
// startTimer();
|
// startTimer();
|
||||||
};
|
}
|
||||||
|
|
||||||
const postponeBreak = () => {
|
const postponeBreak = () => {
|
||||||
// if (timer) clearInterval(timer);
|
// if (timer) clearInterval(timer);
|
||||||
state.set("Ready");
|
state.set("Ready")
|
||||||
// setTimeout(startTimer, 2 * MINI_BREAK_INTERVAL); // Postpone for 2 mini-break intervals
|
// setTimeout(startTimer, 2 * MINI_BREAK_INTERVAL); // Postpone for 2 mini-break intervals
|
||||||
timeLeft.set(MINI_BREAK_DURATION); // Corrected line
|
timeLeft.set(MINI_BREAK_DURATION) // Corrected line
|
||||||
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION)); // Use MINI_BREAK_INTERVAL directly
|
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION)) // Use MINI_BREAK_INTERVAL directly
|
||||||
};
|
}
|
||||||
|
|
||||||
function formatTime(milliseconds: number) {
|
function formatTime(milliseconds: number) {
|
||||||
const totalSeconds = Math.floor(milliseconds / 1000);
|
const totalSeconds = Math.floor(milliseconds / 1000)
|
||||||
const minutes = Math.floor(totalSeconds / 60);
|
const minutes = Math.floor(totalSeconds / 60)
|
||||||
const seconds = totalSeconds % 60;
|
const seconds = totalSeconds % 60
|
||||||
console.log(
|
console.log(
|
||||||
`${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`,
|
`${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`
|
||||||
);
|
)
|
||||||
|
|
||||||
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
|
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main class="min-h-screen flex items-center justify-center bg-gray-100">
|
<main>
|
||||||
<div class="max-w-md p-6 bg-white rounded-md shadow-md">
|
<div>
|
||||||
<h1 class="text-3xl mb-4 font-bold text-center">
|
<h1>
|
||||||
Prevent Computer Vision Syndrome
|
Prevent CVS
|
||||||
</h1>
|
</h1>
|
||||||
<p>{$state}</p>
|
{#if $state !== "Ready"}
|
||||||
{#if $state !== "Ready"}
|
<p>{$state}</p>
|
||||||
<p>Time left until Ready: {$timeLeftDisplay}</p>
|
<p>Time left until end of break: {$timeLeftDisplay}</p>
|
||||||
{:else}
|
{:else}
|
||||||
<p>Time left until break: {$timeLeftDisplay}</p>
|
<p>Time left until break: {$timeLeftDisplay}</p>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $state !== "Ready"}
|
{#if $state !== "Ready"}
|
||||||
<button
|
<button
|
||||||
class="px-4 py-2 bg-blue-500 text-white rounded-md shadow-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
|
on:click={skipBreak}>Skip Break</button
|
||||||
on:click={skipBreak}>Skip Break</button
|
>
|
||||||
>
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
</div>
|
</main>
|
||||||
</main>
|
|
||||||
|
|
||||||
<!--
|
<style lang="postcss">
|
||||||
<style>
|
main {
|
||||||
main {
|
@apply text-center;
|
||||||
text-align: center;
|
@apply mx-auto my-64;
|
||||||
margin: 100px auto;
|
}
|
||||||
color: var(--text-color);
|
|
||||||
}
|
h1 {
|
||||||
|
@apply text-4xl mb-8;
|
||||||
h1 {
|
}
|
||||||
font-size: 2.5rem;
|
|
||||||
margin-bottom: 20px;
|
p {
|
||||||
}
|
@apply text-base mb-4;
|
||||||
|
}
|
||||||
p {
|
|
||||||
font-size: 1.5rem;
|
button {
|
||||||
margin-bottom: 20px;
|
@apply inline-block;
|
||||||
}
|
@apply rounded px-4 py-2;
|
||||||
|
@apply transition duration-300 ease-in-out;
|
||||||
button {
|
@apply bg-primary text-white;
|
||||||
padding: 10px 20px;
|
}
|
||||||
font-size: 1rem;
|
|
||||||
cursor: pointer;
|
button:hover {
|
||||||
margin: 10px;
|
@apply bg-primaryLight text-white;
|
||||||
}
|
}
|
||||||
</style> -->
|
</style>
|
||||||
|
|
|
@ -1,8 +1,21 @@
|
||||||
import adapter from "@sveltejs/adapter-auto";
|
import adapter from "@sveltejs/adapter-auto"
|
||||||
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
|
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"
|
||||||
|
|
||||||
/** @type {import('@sveltejs/kit').Config} */
|
/** @type {import('@sveltejs/kit').Config} */
|
||||||
const config = {
|
const config = {
|
||||||
|
|
||||||
|
// vitePlugin: {
|
||||||
|
// dynamicCompileOptions({filename}){
|
||||||
|
// if(filename.includes('node_modules')){
|
||||||
|
// return {runes: undefined} // or false, check what works
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
|
||||||
|
// compilerOptions: {
|
||||||
|
// runes: true
|
||||||
|
// },
|
||||||
|
|
||||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||||
// for more information about preprocessors
|
// for more information about preprocessors
|
||||||
preprocess: vitePreprocess(),
|
preprocess: vitePreprocess(),
|
||||||
|
@ -13,6 +26,6 @@ const config = {
|
||||||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||||
adapter: adapter(),
|
adapter: adapter(),
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
export default config;
|
export default config
|
||||||
|
|
|
@ -12,13 +12,15 @@ export default {
|
||||||
light: {
|
light: {
|
||||||
background: colors.slate[50],
|
background: colors.slate[50],
|
||||||
foreground: colors.slate[950],
|
foreground: colors.slate[950],
|
||||||
primary: colors.yellow[600],
|
primary: colors.blue[600],
|
||||||
|
primaryLight: colors.blue[800],
|
||||||
},
|
},
|
||||||
dark: {
|
dark: {
|
||||||
background: colors.slate[950],
|
background: colors.slate[950],
|
||||||
foreground: colors.slate[50],
|
foreground: colors.slate[50],
|
||||||
primary: colors.pink[600],
|
primary: colors.pink[600],
|
||||||
|
primaryLight: colors.pink[800],
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
};
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { sveltekit } from "@sveltejs/kit/vite";
|
import { sveltekit } from "@sveltejs/kit/vite"
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite"
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [sveltekit()],
|
plugins: [sveltekit()],
|
||||||
});
|
})
|
||||||
|
|
Loading…
Reference in New Issue