From 5414821f56baae1369c4233464dbb9571ac56f9d Mon Sep 17 00:00:00 2001 From: Roman Timashev Date: Wed, 20 Aug 2025 18:31:42 +0300 Subject: [PATCH 1/6] use node 22 --- .mise.toml | 2 -- mise.toml | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 .mise.toml create mode 100644 mise.toml diff --git a/.mise.toml b/.mise.toml deleted file mode 100644 index 126f6807..00000000 --- a/.mise.toml +++ /dev/null @@ -1,2 +0,0 @@ -[tools] -node = "20" diff --git a/mise.toml b/mise.toml new file mode 100644 index 00000000..6a0493c6 --- /dev/null +++ b/mise.toml @@ -0,0 +1,2 @@ +[tools] +node = "22" From 605ff872e84092087d1cc32f27c394d2aaf25430 Mon Sep 17 00:00:00 2001 From: Roman Timashev Date: Wed, 20 Aug 2025 18:38:40 +0300 Subject: [PATCH 2/6] move from next lint to eslint --- package-lock.json | 145 ++++++++++++++++++++++++++++++++++++++++------ package.json | 5 +- 2 files changed, 131 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index b5149c9a..32bc954c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "use-media": "^1.4.0" }, "devDependencies": { + "@eslint/eslintrc": "^3.3.1", "@types/classnames": "^2.2.10", "@types/markdown-it": "^12.2.3", "@types/node": "^18.13.0", @@ -90,16 +91,16 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -107,12 +108,56 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@eslint/js": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", @@ -1501,9 +1546,9 @@ "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" }, "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -2832,6 +2877,30 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -6015,20 +6084,45 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true + }, + "espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "requires": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + } + }, + "globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true + } } }, "@eslint/js": { @@ -6848,9 +6942,9 @@ "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" }, "acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true }, "acorn-jsx": { @@ -7537,6 +7631,23 @@ "text-table": "^0.2.0" }, "dependencies": { + "@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", diff --git a/package.json b/package.json index 1c0f51eb..7d4ac31f 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "start": "next start", "dev": "next dev --turbo", "build": "next build", - "lint": "next lint", - "format": "next lint --fix", + "lint": "eslint .", + "format": "eslint --fix .", "sitemap": "node scripts/sitemap.js", "feed": "node scripts/feed.js" }, @@ -37,6 +37,7 @@ "use-media": "^1.4.0" }, "devDependencies": { + "@eslint/eslintrc": "^3.3.1", "@types/classnames": "^2.2.10", "@types/markdown-it": "^12.2.3", "@types/node": "^18.13.0", From 85c0d8c4aba22e4abae8773b64c040fbead0996f Mon Sep 17 00:00:00 2001 From: Roman Timashev Date: Mon, 25 Aug 2025 19:05:44 +0300 Subject: [PATCH 3/6] add initial accessibility panel --- package-lock.json | 58 ++- package.json | 3 +- pages/_app.tsx | 5 +- src/components/AccessibilityButton/index.tsx | 11 +- src/components/AccessibilityPanel/index.tsx | 61 +++ .../AccessibilityPanel/panel.module.css | 433 ++++++++++++++++++ src/components/App/index.tsx | 5 +- src/components/Wrapper/index.tsx | 7 +- src/store/theme.ts | 162 +++++++ src/style/style.css | 32 +- src/ui/theme/Theme.tsx | 17 - src/ui/theme/ThemeContext.ts | 5 +- src/ui/theme/const.ts | 5 + src/ui/theme/types.ts | 7 +- src/ui/theme/useTheme.ts | 9 +- 15 files changed, 764 insertions(+), 56 deletions(-) create mode 100644 src/components/AccessibilityPanel/index.tsx create mode 100644 src/components/AccessibilityPanel/panel.module.css create mode 100644 src/store/theme.ts delete mode 100644 src/ui/theme/Theme.tsx create mode 100644 src/ui/theme/const.ts diff --git a/package-lock.json b/package-lock.json index 32bc954c..6cb8865f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,8 @@ "sharp": "^0.32.6", "sitemap": "^1.5.0", "typograf": "^6.11.1", - "use-media": "^1.4.0" + "use-media": "^1.4.0", + "valtio": "^2.1.7" }, "devDependencies": { "@eslint/eslintrc": "^3.3.1", @@ -1268,13 +1269,13 @@ "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "dev": true + "devOptional": true }, "node_modules/@types/react": { "version": "18.0.18", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.18.tgz", "integrity": "sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==", - "dev": true, + "devOptional": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1285,7 +1286,7 @@ "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true + "devOptional": true }, "node_modules/@types/sharp": { "version": "0.29.2", @@ -4735,6 +4736,12 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.1.tgz", + "integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==", + "license": "MIT" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -5911,6 +5918,30 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "node_modules/valtio": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/valtio/-/valtio-2.1.7.tgz", + "integrity": "sha512-DwJhCDpujuQuKdJ2H84VbTjEJJteaSmqsuUltsfbfdbotVfNeTE4K/qc/Wi57I9x8/2ed4JNdjEna7O6PfavRg==", + "license": "MIT", + "dependencies": { + "proxy-compare": "^3.0.1" + }, + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "react": ">=18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + } + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -6778,13 +6809,13 @@ "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "dev": true + "devOptional": true }, "@types/react": { "version": "18.0.18", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.18.tgz", "integrity": "sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==", - "dev": true, + "devOptional": true, "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -6795,7 +6826,7 @@ "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true + "devOptional": true }, "@types/sharp": { "version": "0.29.2", @@ -9131,6 +9162,11 @@ "react-is": "^16.13.1" } }, + "proxy-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.1.tgz", + "integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==" + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -9951,6 +9987,14 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "valtio": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/valtio/-/valtio-2.1.7.tgz", + "integrity": "sha512-DwJhCDpujuQuKdJ2H84VbTjEJJteaSmqsuUltsfbfdbotVfNeTE4K/qc/Wi57I9x8/2ed4JNdjEna7O6PfavRg==", + "requires": { + "proxy-compare": "^3.0.1" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 7d4ac31f..ae127516 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ "sharp": "^0.32.6", "sitemap": "^1.5.0", "typograf": "^6.11.1", - "use-media": "^1.4.0" + "use-media": "^1.4.0", + "valtio": "^2.1.7" }, "devDependencies": { "@eslint/eslintrc": "^3.3.1", diff --git a/pages/_app.tsx b/pages/_app.tsx index a0b03fc4..0c71cc1d 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -8,7 +8,6 @@ import App from "next/app" import Head from "next/head" import Script from "next/script" import { YMetrika } from "src/components/YMetrika" -import { Theme } from "@/ui/theme/Theme" import { ThemeColor } from "@/ui/ThemeColor" export default class MyApp extends App { @@ -51,9 +50,7 @@ export default class MyApp extends App { - - - + ) } diff --git a/src/components/AccessibilityButton/index.tsx b/src/components/AccessibilityButton/index.tsx index 1499d7b5..36d60a43 100644 --- a/src/components/AccessibilityButton/index.tsx +++ b/src/components/AccessibilityButton/index.tsx @@ -1,19 +1,18 @@ +import { theme, toggleTheme } from "@/store/theme" import { Button } from "@/ui/Button" import { HiOutlineEye, HiOutlineEyeOff } from "react-icons/hi" -import { useTheme } from "@/ui/theme/useTheme" +import { useSnapshot } from "valtio" export function AccessibilityButton() { - const { theme, setTheme } = useTheme() + const t = useSnapshot(theme) return ( + {/*Прослушать всё*/} diff --git a/src/components/AccessibilityPanel/panel.module.css b/src/components/AccessibilityPanel/panel.module.css index 6a3f2070..9587a847 100644 --- a/src/components/AccessibilityPanel/panel.module.css +++ b/src/components/AccessibilityPanel/panel.module.css @@ -6,25 +6,25 @@ }*/ .viewsettings { + display: flex; + flex-direction: column; + gap: 10px; + + color: black; background: white; z-index: 10; - display: block; - /*width: 96%;*/ font-size: 20px !important; line-height: 30px; - font-family: sans-serif, arial; + font-family: sans-serif; letter-spacing: normal !important; - position: fixed; - top: 0; + /*position: fixed; + top: 0;*/ margin: 10px; + padding: 10px; text-align: center; border: 2px solid; - /*border-right: 2px solid; - border-bottom: 2px solid; - border-bottom-right-radius: 25px; - border-bottom-left-radius: 25px;*/ } .viewsettings .row { @@ -32,12 +32,12 @@ flex-wrap: wrap; gap: 8px; justify-content: center; - - margin: 8px 0; } + .viewsettings p { margin: 0; } + .viewsettings a { border: 1px solid; text-decoration: none; @@ -67,367 +67,25 @@ margin-right: 8px; } -#mainContent { - padding-top: 60px; -} +.viewsettings button { + display: flex; + align-items: center; + gap: 4px; -.feedback label { - display: block; - margin: 16px 0 0 0; -} -.feedback input { - width: 50%; -} -.feedback textarea { - width: 50%; - height: 100px; -} -.feedback input[name="agree"] { - display: block; - width: 100px; -} -#captcha { - display: none; -} - -body.line_1_5 { - line-height: 1.5; -} -body.line_2_0 { - line-height: 2; -} -body.line_2_5 { - line-height: 2.5; -} - -.letter_spacing1 { - letter-spacing: normal; -} -.letter_spacing2 { - letter-spacing: 2px; -} -.letter_spacing4 { - letter-spacing: 4px; -} - -#btn-black-text { - background-color: white; - color: black; -} -#btn-white-text { - background-color: black; - color: white; -} -#btn-blue-text { - background-color: #9dd1ff; - color: #063462; -} -#btn-sand-text { - background-color: #f7f3d6; - color: #4d4b43; -} -#btn-brown-text { - background-color: #3b2716; - color: #a9e44d; -} - -body.imageOff #btn-hide-images, -body.imageOff img { - display: none; -} -body.imageOn #btn-show-images { - display: none; -} - -body.brailleOff #btn-off-braille { - display: none; -} -body.brailleOn #btn-on-braille { - display: none; -} -body.brailleOn { - font-family: "Kanischev_Braille" !important; -} - -body.noSerif #btn-font-sans { - display: none; -} -body.noSerif { - font-family: sans-serif, Arial; -} - -body.sans #btn-font-serif { - display: none; -} -body.sans { - font-family: serif, "Times New Roman"; -} - -body.BlackOnWhite { - background-color: white; - color: black; -} -body.BlackOnWhite a:link, -body.BlackOnWhite a:visited, -body.BlackOnWhite .viewsettings .block, -body.BlackOnWhite .viewsettings, -body.BlackOnWhite .additional_text, -body.BlackOnWhite .img-wrp::after, -body.BlackOnWhite .date { - color: black; -} -body.BlackOnWhite a#active { - color: white; - background-color: black; -} -body.BlackOnWhite .image_placeholder { - border: 1px solid black; -} -body.BlackOnWhite a:focus, -body.BlackOnWhite input:focus, -body.BlackOnWhite textarea:focus, -body.BlackOnWhite #attach_cont:focus, -body.BlackOnWhite button:focus { - outline: #000 solid 5px; -} -body.BlackOnWhite button, -body.BlackOnWhite input, -body.BlackOnWhite textarea { - background-color: #fff; - color: #000; - border: 1px solid #000; -} - -body.WhiteOnBlack { - background-color: black; - color: white; -} -body.WhiteOnBlack a:link, -body.WhiteOnBlack a:visited, -body.WhiteOnBlack .viewsettings .block, -body.WhiteOnBlack .viewsettings, -body.WhiteOnBlack .additional_text, -body.WhiteOnBlack .img-wrp::after, -body.WhiteOnBlack .date { - color: white; -} -body.WhiteOnBlack a#active { - color: black; - background-color: white; -} -body.WhiteOnBlack .image_placeholder { - border: 1px solid white; -} -body.WhiteOnBlack a:focus, -body.WhiteOnBlack input:focus, -body.WhiteOnBlack textarea:focus, -body.WhiteOnBlack #attach_cont:focus, -body.WhiteOnBlack button:focus { - outline: #fff solid 5px; -} -body.WhiteOnBlack button, -body.BlackOnWhite input, -body.BlackOnWhite textarea { - background-color: #000; - color: #fff; - border: 1px solid #fff; -} - -body.BlueOnBlue { - background-color: #9dd1ff; - color: #063462; -} -body.BlueOnBlue a:link, -body.BlueOnBlue a:visited, -body.BlueOnBlue .viewsettings .block, -body.BlueOnBlue .viewsettings, -body.BlueOnBlue .additional_text, -body.BlueOnBlue .img-wrp::after, -body.BlueOnBlue .date { - color: #063462; -} -body.BlueOnBlue a#active { - color: #9dd1ff; - background-color: #063462; -} -body.BlueOnBlue .image_placeholder { - border: 1px solid #063462; -} -body.BlueOnBlue a:focus, -body.BlueOnBlue input:focus, -body.BlueOnBlue textarea:focus, -body.BlueOnBlue #attach_cont:focus, -body.BlueOnBlue button:focus { - outline: #063462 solid 5px; -} -body.BlueOnBlue button, -body.BlueOnBlue input, -body.BlueOnBlue textarea { - background-color: #9dd1ff; - color: #063462; - border: 1px solid #063462; -} - -body.SandTheme { - background-color: #f7f3d6; - color: #4d4b43; -} -body.SandTheme a:link, -body.SandTheme a:visited, -body.SandTheme .viewsettings .block, -body.SandTheme .viewsettings, -body.SandTheme .additional_text, -body.SandTheme .img-wrp::after, -body.SandTheme .date { - color: #4d4b43; -} -body.SandTheme a#active { - color: #f7f3d6; - background-color: #4d4b43; -} -body.SandTheme .image_placeholder { - border: 1px solid #4d4b43; -} -body.SandTheme a:focus, -body.SandTheme input:focus, -body.SandTheme textarea:focus, -body.SandTheme #attach_cont:focus, -body.SandTheme button:focus { - outline: #4d4b43 solid 5px; -} -body.SandTheme button, -body.SandTheme input, -body.SandTheme textarea { - background-color: #f7f3d6; - color: #4d4b43; - border: 1px solid #4d4b43; -} - -body.BrownTheme { - background-color: #3b2716; - color: #a9e44d; -} -body.BrownTheme a:link, -body.BrownTheme a:visited, -body.BrownTheme .viewsettings .block, -body.BrownTheme .viewsettings, -body.BrownTheme .additional_text, -body.BrownTheme .img-wrp::after, -body.BrownTheme .date { - color: #a9e44d; -} -body.BrownTheme a#active { - color: #3b2716; - background-color: #a9e44d; -} -body.BrownTheme .image_placeholder { - border: 1px solid #a9e44d; -} -body.BrownTheme a:focus, -body.BrownTheme input:focus, -body.BrownTheme textarea:focus, -body.BrownTheme #attach_cont:focus, -body.BrownTheme button:focus { - outline: #a9e44d solid 5px; -} -body.BrownTheme button, -body.BrownTheme input, -body.BrownTheme textarea { - background-color: #3b2716; - color: #a9e44d; - border: 1px solid #a9e44d; -} - -ul#navmenu-h li a { - padding: 0 6px 0 6px; -} - -.news_list_item strong { - padding-bottom: 4px; - padding-right: 8px; -} - -.date { - display: block; -} - -.s-on { - background-position: 0 0; -} -.s-of { - background-position: 0 30px; -} -.image_alt { - width: 144px; - height: 144px; - border: 1px solid black; - font-size: 18px; - overflow: hidden; -} - -.gallery_album_thumbail { - display: block; - max-width: 150px; - max-height: 150px; - overflow: hidden; - word-wrap: break-word; -} - -ul#navmenu-h li a { - text-decoration: none; -} -ul#navmenu-h li a:hover { - text-decoration: underline; -} - -.additional_text { - margin: 0; - padding: 0; - font-size: 70%; - font-weight: normal; -} - -.image_placeholder { - font-size: 70%; - font-weight: normal; - margin: 5px; - text-align: center; - word-wrap: break-word; - overflow: hidden; - min-width: 100px; - min-height: 100px; -} - -.play-button { - display: block; - min-width: 30px; - min-height: 30px; + border: 1px solid; + font-size: 20px !important; + padding: 4px 10px; cursor: pointer; - text-align: right; + + color: black; + background-color: white; } -#playlist { - float: right; - display: block; - font-size: inherit; +.viewsettings button:hover { + background-color: #cfcfcf !important; + color: #000 !important; } -._afisha_table_content { - width: 100%; -} - -.img-wrp { - display: inline-block; - position: relative; -} - -.img-wrp::after { - content: attr(data-alt); - bottom: 0; - left: 0; - width: 100%; - z-index: 2; - font-size: 70%; - font-style: italic; - text-align: center; +.viewsettings button:focus { + outline: 1px solid !important; } diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index da843dfc..3e7bafb6 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -22,6 +22,7 @@ import qr0 from "src/assets/qr00.png" import qr1 from "src/assets/qr01.png" import Image from "next/image" import AccessibilityPanel from "../AccessibilityPanel" +import useAccessibility from "@/hooks/useAccessibility" const Gosuslugi = dynamic(import("../Gosuslugi").then(module => module.Gosuslugi), { ssr: false, @@ -37,6 +38,7 @@ export type AppProps = { export const App: React.FC = ({ showAuthor = false, menu, ...props }) => { const hideBreadcrumbs = useMobile() + const accessibility = useAccessibility() const router = useRouter() const blockStyle = { justifyContent: "center", @@ -50,6 +52,10 @@ export const App: React.FC = ({ showAuthor = false, menu, ...props }) + {!accessibility ? null : ( + + )} + @@ -145,8 +151,6 @@ export const App: React.FC = ({ showAuthor = false, menu, ...props }) )} > - - {props.children} diff --git a/src/components/Wrapper/index.tsx b/src/components/Wrapper/index.tsx index ec8041de..bae1a282 100644 --- a/src/components/Wrapper/index.tsx +++ b/src/components/Wrapper/index.tsx @@ -16,7 +16,7 @@ export const Wrapper: React.FC = props => { const t = useSnapshot(theme) return ( -
+
{props.header}
diff --git a/src/components/Wrapper/wrapper.module.css b/src/components/Wrapper/wrapper.module.css index 6b8d26b9..bb3a26a1 100644 --- a/src/components/Wrapper/wrapper.module.css +++ b/src/components/Wrapper/wrapper.module.css @@ -1,13 +1,15 @@ .container { - display: flex; - flex-direction: column; - background-color: var(--color-back-main); + display: flex; + flex-direction: column; - font-family: var(--text-font); - font-size: var(--font-size-default); + color: var(--color-text); + background-color: var(--color-back-main); + + font-family: var(--text-font); + font-size: var(--font-size-default); } .main { - min-height: 100vh; - flex: 1; + min-height: 100vh; + flex: 1; } diff --git a/src/hooks/useAccessibility.ts b/src/hooks/useAccessibility.ts new file mode 100644 index 00000000..c328c99f --- /dev/null +++ b/src/hooks/useAccessibility.ts @@ -0,0 +1,10 @@ +import { theme } from "@/store/theme" +import { useSnapshot } from "valtio" + +function useAccessibility(): boolean { + const t = useSnapshot(theme) + + return t.theme === "contrast" +} + +export default useAccessibility diff --git a/src/store/theme.ts b/src/store/theme.ts index 82506a94..b80e147c 100644 --- a/src/store/theme.ts +++ b/src/store/theme.ts @@ -1,11 +1,12 @@ -import { proxy, subscribe, useSnapshot } from "valtio" +import { proxy, subscribe } from "valtio" export type ThemeName = "default" | "contrast" export type ColorSchemeVariant = "black-on-white" | "white-on-black" | "blue-on-blue" | "brown-on-yellow" | "green-on-brown" +export type FontTypeVariant = "serif" | "sans-serif" const MIN_FONT_SIZE = 8 const MAX_FONT_SIZE = 48 -const CHANGE_FONT_SIZE_DELTA = 0.2 +const CHANGE_FONT_SIZE_DELTA = 1 function clamp(val: number, min: number, max: number): number { if (val < min) { @@ -19,7 +20,7 @@ function clamp(val: number, min: number, max: number): number { export type ThemeOptions = { theme: ThemeName - fontType: string + fontType: FontTypeVariant fontSize: number lineHeight: number letterSpacing: number @@ -32,7 +33,7 @@ export const theme = proxy({ fontSize: 14, lineHeight: 1.5, letterSpacing: 1, - fontType: "Times New Roman", + fontType: "sans-serif", showImages: true, colorScheme: "black-on-white", }) @@ -41,7 +42,7 @@ export function reset() { theme.fontSize = 14 theme.lineHeight = 1.5 theme.letterSpacing = 1 - theme.fontType = "Times New Roman" + theme.fontType = "sans-serif" theme.showImages = true theme.colorScheme = "black-on-white" } @@ -63,12 +64,12 @@ export function decreaseFontSize() { theme.fontSize = clamp(theme.fontSize - CHANGE_FONT_SIZE_DELTA, MIN_FONT_SIZE, MAX_FONT_SIZE) } -export function setSerifFont() { +export function setSansSerifFont() { theme.fontType = "sans-serif" } -export function setSansFont() { - theme.fontType = "Times New Roman" +export function setSerifFont() { + theme.fontType = "serif" } export function showImages() { @@ -123,29 +124,10 @@ export function setLetterSpacingFour() { theme.letterSpacing = 4 } -function getColor(scheme: ColorSchemeVariant): [string, string] { - switch (theme.colorScheme) { - case "black-on-white": - return ["black", "white"] - case "white-on-black": - return ["white", "black"] - case "blue-on-blue": - return ["oklch(32% 24% 253deg)", "oklch(84% 21% 245deg)"] - case "brown-on-yellow": - return ["oklch(41% 3% 92deg)", "oklch(96% 9% 101deg)"] - case "green-on-brown": - return ["oklch(85% 47% 128deg)", "oklch(29% 10% 61deg)"] - default: - return ["black", "white"] - } -} - const unsubscribe = subscribe(theme, () => { document.documentElement.style.setProperty("--font-size-default", `${theme.fontSize}pt`) - - document.documentElement.style.setProperty("--title-font", theme.fontType) - document.documentElement.style.setProperty("--text-font", theme.fontType) - + document.documentElement.style.setProperty("--font-size-second", `${theme.fontSize}pt`) + document.documentElement.style.setProperty("--font-size-accent", `${theme.fontSize}pt`) document.documentElement.style.setProperty("--article-line-height", `${theme.lineHeight}em`) if (theme.letterSpacing === 1) { document.documentElement.style.setProperty("--letter-spacing", "normal") @@ -153,10 +135,12 @@ const unsubscribe = subscribe(theme, () => { document.documentElement.style.setProperty("--letter-spacing", `${theme.letterSpacing}px`) } - const [t, b] = getColor(theme.colorScheme) - document.documentElement.style.setProperty("--color-text", t) - document.documentElement.style.setProperty("--color-text-second", t) - document.documentElement.style.setProperty("--color-text-opposite", b) - document.documentElement.style.setProperty("--color-back-main", b) - document.documentElement.style.setProperty("--color-back", b) + // TODO remove this from here and move this logic directly to body tag after moving from pages to app + document.body.classList.forEach(name => { + document.body.classList.remove(name) + }) + if (theme.theme === "contrast") { + document.body.classList.add("theme-contrast") + document.body.classList.add(theme.colorScheme); + } }) diff --git a/src/style/style.css b/src/style/style.css index 27791599..45c397a9 100644 --- a/src/style/style.css +++ b/src/style/style.css @@ -170,26 +170,9 @@ h3 { /* CONTRAST THEME */ .theme-contrast { - /* FONTS */ - /*--title-font: "Roboto", Helvetica, sans-serif;*/ - /*--text-font: "Roboto", Helvetica, sans-serif;*/ - - /* TEXT COLOR */ - /*--color-text: black; - --color-text-second: black; - --color-text-opposite: white; - --color-back-main: white; - --color-back: white; - --color-back-active: hsl(240, 10%, 20%); - --color-back-opposite: black; - --color-link: hsl(240, 10%, 40%); - --color-link-opposite: hsl(240, 10%, 60%);*/ - - --color-hover: white; - --color-hover-back: black; + /*margin-top: 235px;*/ /* EFFECTS */ - /* --radius: 0px; */ --shadow: none; --shadow-active: none; @@ -208,10 +191,98 @@ h3 { --border: 5px solid var(--color-back-opposite); } +.theme-contrast.font-sans-serif { + --title-font: "Roboto", Helvetica, sans-serif; + --text-font: "Roboto", Helvetica, sans-serif; +} + +.theme-contrast.font-serif { + --title-font: "Times New Roman", serif; + --text-font: "Times New Roman", serif; +} + +.theme-contrast.black-on-white { + --color-text: black; + --color-text-second: black; + --color-text-opposite: white; + --color-back-main: white; + --color-back: white; + --color-back-opposite: black; + + --color-hover: white; + --color-hover-back: black; + + --color-back-active: black; + --color-link: black; + --color-link-opposite: white; +} + +.theme-contrast.white-on-black { + --color-text: white; + --color-text-second: white; + --color-text-opposite: black; + --color-back-main: black; + --color-back: black; + --color-back-opposite: white; + + --color-hover: black; + --color-hover-back: white; + + /*--color-back-active: hsl(240, 10%, 20%);*/ + /*--color-link: hsl(240, 10%, 40%);*/ + /*--color-link-opposite: hsl(240, 10%, 60%);*/ +} + +.theme-contrast.blue-on-blue { + --color-text: oklch(32% 24% 253deg); + --color-text-second: oklch(32% 24% 253deg); + --color-text-opposite: oklch(84% 21% 245deg); + --color-back-main: oklch(84% 21% 245deg); + --color-back: oklch(84% 21% 245deg); + --color-back-opposite: oklch(32% 24% 253deg); + + --color-hover: oklch(84% 21% 245deg); + --color-hover-back: oklch(32% 24% 253deg); + + /*--color-back-active: hsl(240, 10%, 20%);*/ + /*--color-link: hsl(240, 10%, 40%);*/ + /*--color-link-opposite: hsl(240, 10%, 60%);*/ +} + +.theme-contrast.brown-on-yellow { + --color-text: oklch(41% 3% 92deg); + --color-text-second: oklch(41% 3% 92deg); + --color-text-opposite: oklch(96% 9% 101deg); + --color-back-main: oklch(96% 9% 101deg); + --color-back: oklch(96% 9% 101deg); + --color-back-opposite: oklch(41% 3% 92deg); + + --color-hover: oklch(96% 9% 101deg); + --color-hover-back: oklch(41% 3% 92deg); + + /*--color-back-active: hsl(240, 10%, 20%);*/ + /*--color-link: hsl(240, 10%, 40%);*/ + /*--color-link-opposite: hsl(240, 10%, 60%);*/ +} + +.theme-contrast.green-on-brown { + --color-text: oklch(85% 47% 128deg); + --color-text-second: oklch(85% 47% 128deg); + --color-text-opposite: oklch(29% 10% 61deg); + --color-back-main: oklch(29% 10% 61deg); + --color-back: oklch(29% 10% 61deg); + --color-back-opposite: oklch(85% 47% 128deg); + + --color-hover: oklch(29% 10% 61deg); + --color-hover-back: oklch(85% 47% 128deg); + + /*--color-back-active: hsl(240, 10%, 20%);*/ + /*--color-link: hsl(240, 10%, 40%);*/ + /*--color-link-opposite: hsl(240, 10%, 60%);*/ +} + .theme-contrast.no-images img { display: none; - /*opacity: 0.5;*/ - /*position: relative;*/ } /*.theme-contrast.no-images img:after { @@ -220,24 +291,3 @@ h3 { height: 100%; border: 1px solid black; }*/ - -/* CONTRAST + DARK THEME */ -@media (prefers-color-scheme: dark) { - .theme-contrast { - /* TEXT COLOR */ - --color-text: white; - --color-text-second: white; - --color-text-opposite: black; - - --color-back-main: black; - --color-back: black; - --color-back-opposite: white; - - /* --color-back-active: hsl(240, 10%, 20%); */ - /* --color-link: hsl(240, 10%, 40%); */ - /* --color-link-opposite: hsl(240, 10%, 60%); */ - - --color-hover: white; - --color-hover-back: white; - } -} diff --git a/src/ui/theme/ThemeContext.ts b/src/ui/theme/ThemeContext.ts deleted file mode 100644 index 736b3f8d..00000000 --- a/src/ui/theme/ThemeContext.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createContext } from "react" -import { DEFAULT } from "./const" -import { SetTheme, ThemeOptions } from "./types" - -export const ThemeContext = createContext<[ThemeOptions, SetTheme]>([DEFAULT, () => {}]) diff --git a/src/ui/theme/const.ts b/src/ui/theme/const.ts deleted file mode 100644 index 0c949a2a..00000000 --- a/src/ui/theme/const.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ThemeOptions } from "./types" - -export const DEFAULT: ThemeOptions = { - theme: "default", -} diff --git a/src/ui/theme/types.ts b/src/ui/theme/types.ts deleted file mode 100644 index 4eaf0946..00000000 --- a/src/ui/theme/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type ThemeOptions = { - theme: "default" | "contrast" - fontSize?: number -} -export type SetTheme = (theme: ThemeOptions["theme"]) => void diff --git a/src/ui/theme/useTheme.ts b/src/ui/theme/useTheme.ts deleted file mode 100644 index fe91ee77..00000000 --- a/src/ui/theme/useTheme.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { useContext } from "react" -import { ThemeContext } from "./ThemeContext" -import { SetTheme, ThemeOptions } from "./types" - -export type UseThemeResult = { - theme: ThemeOptions["theme"] - setTheme: SetTheme - // toggleTheme: -} - -export function useTheme(): UseThemeResult { - const [theme, setTheme] = useContext(ThemeContext) - - return { - setTheme, - theme: theme.theme ?? "default", - } -} From e5023e7709c7766e43e320485a7e56718324127b Mon Sep 17 00:00:00 2001 From: Roman Timashev Date: Mon, 25 Aug 2025 21:57:31 +0300 Subject: [PATCH 5/6] add play all button --- src/components/AccessibilityPanel/index.tsx | 16 ++++++++++-- src/components/AccessibilityPanel/voice.tsx | 27 +++++++++++++++++++++ src/play.ts | 20 +++++++++++++++ src/store/play.ts | 13 ++++++++++ 4 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 src/components/AccessibilityPanel/voice.tsx create mode 100644 src/play.ts create mode 100644 src/store/play.ts diff --git a/src/components/AccessibilityPanel/index.tsx b/src/components/AccessibilityPanel/index.tsx index c1a138ce..f81d1387 100644 --- a/src/components/AccessibilityPanel/index.tsx +++ b/src/components/AccessibilityPanel/index.tsx @@ -1,8 +1,14 @@ +import play from "@/play" +import { state as playState, setVoice } from "@/store/play" import { decreaseFontSize, hideImages, increaseFontSize, reset, setBlackOnWhite, setBlueOnBlue, setBrownOnYellow, setDefaultTheme, setGreenOnBrown, setLetterSpacingOne, setLetterSpacingTwo, setLetterSpacingFour, setLineHeightOneAndHalf, setLineHeightTwo, setLineHeightTwoAndHalf, setSerifFont, setSansSerifFont, setWhiteOnBlack, showImages } from "@/store/theme" -import { HiCog, HiOutlineEyeOff } from "react-icons/hi" +import { HiCog, HiOutlineEyeOff, HiPlay } from "react-icons/hi" +import { useSnapshot } from "valtio" import s from "./panel.module.css" +import VoiceSelect from "./voice" function AccessibilityPanel() { + const p = useSnapshot(playState) + return (
@@ -58,7 +64,13 @@ function AccessibilityPanel() { Обычная версия - {/*Прослушать всё*/} + + { + setVoice(event.target.value) + }} />
) diff --git a/src/components/AccessibilityPanel/voice.tsx b/src/components/AccessibilityPanel/voice.tsx new file mode 100644 index 00000000..58eb636d --- /dev/null +++ b/src/components/AccessibilityPanel/voice.tsx @@ -0,0 +1,27 @@ +function useVoices() { + return window.speechSynthesis + .getVoices() + .map(v => { + return { + name: `${v.name} (${v.lang})`, + value: v.name, + } + }) +} + +export type VoiceSelectProps = React.SelectHTMLAttributes + +function VoiceSelect(props: VoiceSelectProps) { + const voices = useVoices() + return ( + + ) +} + +export default VoiceSelect diff --git a/src/play.ts b/src/play.ts new file mode 100644 index 00000000..43b96e40 --- /dev/null +++ b/src/play.ts @@ -0,0 +1,20 @@ +import { state } from "./store/play"; + + +function play() { + const synth = window.speechSynthesis; + + const a = document.querySelector("article") + if (!a || !a.textContent) { + return + } + + const u = new SpeechSynthesisUtterance(a.textContent) + const voice = synth.getVoices().find((v) => v.name === state.voice); + if (voice) { + u.voice = voice + } + synth.speak(u) +} + +export default play diff --git a/src/store/play.ts b/src/store/play.ts new file mode 100644 index 00000000..6cb2d192 --- /dev/null +++ b/src/store/play.ts @@ -0,0 +1,13 @@ +import { proxy } from "valtio" + +type State = { + voice: string +} + +export const state = proxy({ + voice: "Milena", +}) + +export function setVoice(value: string) { + state.voice = value +} From 08b87afb126cdd81bcdbdcc2447f7788649ef898 Mon Sep 17 00:00:00 2001 From: Roman Timashev Date: Mon, 25 Aug 2025 21:59:39 +0300 Subject: [PATCH 6/6] semi --- src/play.ts | 6 +++--- src/store/theme.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/play.ts b/src/play.ts index 43b96e40..d5c1b3f2 100644 --- a/src/play.ts +++ b/src/play.ts @@ -1,8 +1,8 @@ -import { state } from "./store/play"; +import { state } from "./store/play" function play() { - const synth = window.speechSynthesis; + const synth = window.speechSynthesis const a = document.querySelector("article") if (!a || !a.textContent) { @@ -10,7 +10,7 @@ function play() { } const u = new SpeechSynthesisUtterance(a.textContent) - const voice = synth.getVoices().find((v) => v.name === state.voice); + const voice = synth.getVoices().find((v) => v.name === state.voice) if (voice) { u.voice = voice } diff --git a/src/store/theme.ts b/src/store/theme.ts index b80e147c..69b5384f 100644 --- a/src/store/theme.ts +++ b/src/store/theme.ts @@ -141,6 +141,6 @@ const unsubscribe = subscribe(theme, () => { }) if (theme.theme === "contrast") { document.body.classList.add("theme-contrast") - document.body.classList.add(theme.colorScheme); + document.body.classList.add(theme.colorScheme) } })