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
|
||||
/tailwind.css
|
||||
*.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",
|
||||
"version": "0.0.1",
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^3.0.0",
|
||||
"@sveltejs/kit": "^2.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||
"@sveltejs/adapter-auto": "^3.1.1",
|
||||
"@sveltejs/kit": "^2.5.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.2",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-svelte": "^3.2.3",
|
||||
"svelte": "^4.2.7",
|
||||
"svelte": "5.0.0-next.54",
|
||||
"svelte-check": "^3.6.0",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"tslib": "^2.4.1",
|
||||
"tw-colors": "^3.3.1",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^5.0.3"
|
||||
"vite": "^5.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@alloc/quick-lru": {
|
||||
|
@ -824,6 +824,18 @@
|
|||
"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": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
|
||||
|
@ -854,6 +866,15 @@
|
|||
"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": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||
|
@ -1101,19 +1122,6 @@
|
|||
"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": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
||||
|
@ -1193,19 +1201,6 @@
|
|||
"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": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
|
@ -1357,13 +1352,14 @@
|
|||
"integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/estree-walker": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
|
||||
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
|
||||
"node_modules/esrap": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/esrap/-/esrap-1.2.1.tgz",
|
||||
"integrity": "sha512-dhkcOLfN/aDdMFI1iwPEcy/XqAZzGNfgfEJjZozy2tia6u0dQoZyXzkRshHTckuNsM+c0CYQndY+uRFe3N+AIQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0"
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15",
|
||||
"@types/estree": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
|
@ -1739,12 +1735,6 @@
|
|||
"@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": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
|
@ -1974,17 +1964,6 @@
|
|||
"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": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
|
@ -2641,28 +2620,27 @@
|
|||
}
|
||||
},
|
||||
"node_modules/svelte": {
|
||||
"version": "4.2.15",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.15.tgz",
|
||||
"integrity": "sha512-j9KJSccHgLeRERPlhMKrCXpk2TqL2m5Z+k+OBTQhZOhIdCCd3WfqV+ylPWeipEwq17P/ekiSFWwrVQv93i3bsg==",
|
||||
"version": "5.0.0-next.54",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.54.tgz",
|
||||
"integrity": "sha512-ik+hXhlKdZozs+EruogLXb5PVZD8X8ekNBwQGBYcTpj1FD0sgWZxvUEQV4m0rE5LaUL3J5cmO4e8daOuPxIK/A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15",
|
||||
"@jridgewell/trace-mapping": "^0.3.18",
|
||||
"@types/estree": "^1.0.1",
|
||||
"acorn": "^8.9.0",
|
||||
"@types/estree": "^1.0.5",
|
||||
"acorn": "^8.11.3",
|
||||
"acorn-typescript": "^1.4.13",
|
||||
"aria-query": "^5.3.0",
|
||||
"axobject-query": "^4.0.0",
|
||||
"code-red": "^1.0.3",
|
||||
"css-tree": "^2.3.1",
|
||||
"estree-walker": "^3.0.3",
|
||||
"is-reference": "^3.0.1",
|
||||
"esm-env": "^1.0.0",
|
||||
"esrap": "^1.2.1",
|
||||
"is-reference": "^3.0.2",
|
||||
"locate-character": "^3.0.0",
|
||||
"magic-string": "^0.30.4",
|
||||
"periscopic": "^3.1.0"
|
||||
"magic-string": "^0.30.5",
|
||||
"zimmerframe": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz",
|
||||
|
@ -3129,6 +3095,12 @@
|
|||
"engines": {
|
||||
"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",
|
||||
"preview": "vite preview",
|
||||
"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": {
|
||||
"@sveltejs/adapter-auto": "^3.0.0",
|
||||
"@sveltejs/kit": "^2.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||
"@sveltejs/adapter-auto": "^3.1.1",
|
||||
"@sveltejs/kit": "^2.5.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.2",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-svelte": "^3.2.3",
|
||||
"svelte": "^4.2.7",
|
||||
"svelte": "5.0.0-next.54",
|
||||
"svelte-check": "^3.6.0",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"tslib": "^2.4.1",
|
||||
"tw-colors": "^3.3.1",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^5.0.3"
|
||||
"vite": "^5.1.4"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
|
|
@ -3,4 +3,4 @@ export default {
|
|||
tailwindcss: {},
|
||||
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>
|
||||
import "../app.css";
|
||||
<script lang="ts">
|
||||
import ThemePicker, { type Theme } from "$lib/components/ThemePicker.svelte"
|
||||
import "../app.css"
|
||||
|
||||
let { data } = $props()
|
||||
|
||||
let theme = $state("dark" as Theme)
|
||||
</script>
|
||||
|
||||
<slot />
|
||||
<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>
|
||||
<h1>Welcome to the Prevent Computer Vision Syndrome App</h1>
|
||||
<button on:click={startApp}>Start Timer</button>
|
||||
<h1>Welcome to BreakOften!</h1>
|
||||
<a href="/timer">Start Timer</a>
|
||||
</main>
|
||||
|
||||
<style lang="postcss">
|
||||
main {
|
||||
text-align: center;
|
||||
margin: 100px auto;
|
||||
color: var(--text-color);
|
||||
}
|
||||
main {
|
||||
@apply text-center;
|
||||
@apply mx-auto my-64;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
h1 {
|
||||
@apply text-4xl mb-8;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 10px 20px;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
a {
|
||||
@apply inline-block;
|
||||
@apply rounded px-4 py-2;
|
||||
@apply transition duration-300 ease-in-out;
|
||||
@apply bg-primary text-white;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
@apply bg-primaryLight text-white;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
<script context="module">
|
||||
export async function load() {
|
||||
const res = await fetch("https://api.example.com/data");
|
||||
const data = await res.json();
|
||||
const res = await fetch("https://api.example.com/data")
|
||||
const data = await res.json()
|
||||
return {
|
||||
props: {
|
||||
data,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { writable } from "svelte/store";
|
||||
import type { Writable } from "svelte/store";
|
||||
import { onDestroy, onMount } from "svelte"
|
||||
import { 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_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 = 0.3 * 60 * 1000; // 2 minutes
|
||||
const LONG_BREAK_DURATION = 0.3 * 60 * 1000 // 2 minutes
|
||||
|
||||
let timer: number | null = null;
|
||||
let miniBreakCount = 0;
|
||||
let timer: number | null = null
|
||||
let miniBreakCount = 0
|
||||
|
||||
let audio: HTMLAudioElement | null = null;
|
||||
let audio: HTMLAudioElement | null = null
|
||||
|
||||
const playSound = () => {
|
||||
if (audio) {
|
||||
// audio.pause();
|
||||
audio.src = "/sounds/Bells.mp3";
|
||||
audio.volume = 0.4;
|
||||
audio.src = "/sounds/Bells.mp3"
|
||||
audio.volume = 0.4
|
||||
// audio.play();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const showNotification = (title: string, options: NotificationOptions) => {
|
||||
if (Notification.permission === "granted") {
|
||||
|
@ -43,138 +43,138 @@
|
|||
if (permission === "granted") {
|
||||
// new Notification(title, options);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const state: Writable<string> = writable("Ready");
|
||||
const timeLeftDisplay: Writable<string> = writable("");
|
||||
const timeLeft: Writable<number> = writable(MINI_BREAK_DURATION);
|
||||
const state: Writable<string> = writable("Ready")
|
||||
const timeLeftDisplay: Writable<string> = writable("")
|
||||
const timeLeft: Writable<number> = writable(MINI_BREAK_DURATION)
|
||||
|
||||
const startTimer = () => {
|
||||
if (timer) clearInterval(timer);
|
||||
if (timer) clearInterval(timer)
|
||||
|
||||
timer = setInterval(() => {
|
||||
timeLeft.update((currentTimeLeft) => {
|
||||
const newTimeLeft = currentTimeLeft - 1000;
|
||||
const newTimeLeft = currentTimeLeft - 1000
|
||||
if (newTimeLeft <= 0) {
|
||||
if ($state !== "Ready") {
|
||||
state.set("Ready");
|
||||
miniBreakCount++;
|
||||
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION));
|
||||
showNotification("Ready", { body: "Continue working!" });
|
||||
playSound(); // Adjust volume as needed
|
||||
return MINI_BREAK_DURATION;
|
||||
state.set("Ready")
|
||||
miniBreakCount++
|
||||
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION))
|
||||
showNotification("Ready", { body: "Continue working!" })
|
||||
playSound() // Adjust volume as needed
|
||||
return MINI_BREAK_DURATION
|
||||
}
|
||||
if (miniBreakCount === 3) {
|
||||
state.set("Long Break");
|
||||
miniBreakCount = 0;
|
||||
timeLeftDisplay.set(formatTime(LONG_BREAK_DURATION));
|
||||
state.set("Long Break")
|
||||
miniBreakCount = 0
|
||||
timeLeftDisplay.set(formatTime(LONG_BREAK_DURATION))
|
||||
showNotification("Long Break", {
|
||||
body: "Take a 5-minute break now!",
|
||||
});
|
||||
playSound(); // Adjust volume as needed
|
||||
return LONG_BREAK_DURATION;
|
||||
})
|
||||
playSound() // Adjust volume as needed
|
||||
return LONG_BREAK_DURATION
|
||||
} else {
|
||||
state.set("Mini Break");
|
||||
state.set("Mini Break")
|
||||
// miniBreakCount++;
|
||||
timeLeftDisplay.set(formatTime(MINI_BREAK_INTERVAL));
|
||||
timeLeftDisplay.set(formatTime(MINI_BREAK_INTERVAL))
|
||||
showNotification("Mini Break", {
|
||||
body: "Take a 20-second break now!",
|
||||
});
|
||||
playSound(); // Adjust volume as needed
|
||||
return MINI_BREAK_INTERVAL;
|
||||
})
|
||||
playSound() // Adjust volume as needed
|
||||
return MINI_BREAK_INTERVAL
|
||||
}
|
||||
}
|
||||
timeLeftDisplay.set(formatTime(newTimeLeft));
|
||||
return newTimeLeft;
|
||||
});
|
||||
}, 1000);
|
||||
};
|
||||
timeLeftDisplay.set(formatTime(newTimeLeft))
|
||||
return newTimeLeft
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
audio = document.createElement('audio');
|
||||
startTimer();
|
||||
});
|
||||
audio = document.createElement("audio")
|
||||
startTimer()
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
if (timer) clearInterval(timer);
|
||||
if (audio) audio = null;
|
||||
});
|
||||
if (timer) clearInterval(timer)
|
||||
if (audio) audio = null
|
||||
})
|
||||
|
||||
const skipBreak = () => {
|
||||
// if (timer) clearInterval(timer);
|
||||
if ($state === "Ready") {
|
||||
return;
|
||||
return
|
||||
}
|
||||
state.set("Ready");
|
||||
timeLeft.set(MINI_BREAK_DURATION);
|
||||
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION));
|
||||
state.set("Ready")
|
||||
timeLeft.set(MINI_BREAK_DURATION)
|
||||
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION))
|
||||
// startTimer();
|
||||
};
|
||||
}
|
||||
|
||||
const postponeBreak = () => {
|
||||
// if (timer) clearInterval(timer);
|
||||
state.set("Ready");
|
||||
state.set("Ready")
|
||||
// setTimeout(startTimer, 2 * MINI_BREAK_INTERVAL); // Postpone for 2 mini-break intervals
|
||||
timeLeft.set(MINI_BREAK_DURATION); // Corrected line
|
||||
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION)); // Use MINI_BREAK_INTERVAL directly
|
||||
};
|
||||
timeLeft.set(MINI_BREAK_DURATION) // Corrected line
|
||||
timeLeftDisplay.set(formatTime(MINI_BREAK_DURATION)) // Use MINI_BREAK_INTERVAL directly
|
||||
}
|
||||
|
||||
function formatTime(milliseconds: number) {
|
||||
const totalSeconds = Math.floor(milliseconds / 1000);
|
||||
const minutes = Math.floor(totalSeconds / 60);
|
||||
const seconds = totalSeconds % 60;
|
||||
const totalSeconds = Math.floor(milliseconds / 1000)
|
||||
const minutes = Math.floor(totalSeconds / 60)
|
||||
const seconds = totalSeconds % 60
|
||||
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>
|
||||
|
||||
<main class="min-h-screen flex items-center justify-center bg-gray-100">
|
||||
<div class="max-w-md p-6 bg-white rounded-md shadow-md">
|
||||
<h1 class="text-3xl mb-4 font-bold text-center">
|
||||
Prevent Computer Vision Syndrome
|
||||
<main>
|
||||
<div>
|
||||
<h1>
|
||||
Prevent CVS
|
||||
</h1>
|
||||
<p>{$state}</p>
|
||||
{#if $state !== "Ready"}
|
||||
<p>Time left until Ready: {$timeLeftDisplay}</p>
|
||||
<p>{$state}</p>
|
||||
<p>Time left until end of break: {$timeLeftDisplay}</p>
|
||||
{:else}
|
||||
<p>Time left until break: {$timeLeftDisplay}</p>
|
||||
{/if}
|
||||
{#if $state !== "Ready"}
|
||||
<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
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!--
|
||||
<style>
|
||||
|
||||
<style lang="postcss">
|
||||
main {
|
||||
text-align: center;
|
||||
margin: 100px auto;
|
||||
color: var(--text-color);
|
||||
@apply text-center;
|
||||
@apply mx-auto my-64;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 20px;
|
||||
@apply text-4xl mb-8;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 20px;
|
||||
@apply text-base mb-4;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 10px 20px;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
margin: 10px;
|
||||
@apply inline-block;
|
||||
@apply rounded px-4 py-2;
|
||||
@apply transition duration-300 ease-in-out;
|
||||
@apply bg-primary text-white;
|
||||
}
|
||||
</style> -->
|
||||
|
||||
button:hover {
|
||||
@apply bg-primaryLight text-white;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
import adapter from "@sveltejs/adapter-auto";
|
||||
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
|
||||
import adapter from "@sveltejs/adapter-auto"
|
||||
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"
|
||||
|
||||
/** @type {import('@sveltejs/kit').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
|
||||
// for more information about preprocessors
|
||||
preprocess: vitePreprocess(),
|
||||
|
@ -13,6 +26,6 @@ const config = {
|
|||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||
adapter: adapter(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default config;
|
||||
export default config
|
||||
|
|
|
@ -12,13 +12,15 @@ export default {
|
|||
light: {
|
||||
background: colors.slate[50],
|
||||
foreground: colors.slate[950],
|
||||
primary: colors.yellow[600],
|
||||
primary: colors.blue[600],
|
||||
primaryLight: colors.blue[800],
|
||||
},
|
||||
dark: {
|
||||
background: colors.slate[950],
|
||||
foreground: colors.slate[50],
|
||||
primary: colors.pink[600],
|
||||
primaryLight: colors.pink[800],
|
||||
},
|
||||
}),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { sveltekit } from "@sveltejs/kit/vite";
|
||||
import { defineConfig } from "vite";
|
||||
import { sveltekit } from "@sveltejs/kit/vite"
|
||||
import { defineConfig } from "vite"
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()],
|
||||
});
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue