Merge pull request 'Перенос рендера иконок на сторону сервера' (#8) from feature/no-js-icons into master
Reviewed-on: #8
This commit is contained in:
commit
9fcb8df996
16 changed files with 527 additions and 159 deletions
359
package-lock.json
generated
359
package-lock.json
generated
|
|
@ -11,7 +11,8 @@
|
||||||
"@formatjs/intl-durationformat": "^0.10.1"
|
"@formatjs/intl-durationformat": "^0.10.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify/svelte": "^5.2.1",
|
"@iconify/css-svelte": "^1.0.0",
|
||||||
|
"@iconify/json": "^2.2.439",
|
||||||
"@react2svelte/swipeable": "^0.1.4",
|
"@react2svelte/swipeable": "^0.1.4",
|
||||||
"@svelte-put/dragscroll": "^4.0.0",
|
"@svelte-put/dragscroll": "^4.0.0",
|
||||||
"@sveltejs/adapter-auto": "^7.0.0",
|
"@sveltejs/adapter-auto": "^7.0.0",
|
||||||
|
|
@ -41,9 +42,24 @@
|
||||||
"tailwindcss": "^4.0.9",
|
"tailwindcss": "^4.0.9",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
|
"unplugin-icons": "^23.0.1",
|
||||||
"vite": "^7.3.1"
|
"vite": "^7.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@antfu/install-pkg": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"package-manager-detector": "^1.3.0",
|
||||||
|
"tinyexec": "^1.0.1"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
"version": "7.29.0",
|
"version": "7.29.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
|
||||||
|
|
@ -2252,10 +2268,10 @@
|
||||||
"url": "https://github.com/sponsors/nzakas"
|
"url": "https://github.com/sponsors/nzakas"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@iconify/svelte": {
|
"node_modules/@iconify/css-svelte": {
|
||||||
"version": "5.2.1",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@iconify/svelte/-/svelte-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@iconify/css-svelte/-/css-svelte-1.0.0.tgz",
|
||||||
"integrity": "sha512-zHmsIPmnIhGd5gc95bNN5FL+GifwMZv7M2rlZEpa7IXYGFJm/XGHdWf6PWQa6OBoC+R69WyiPO9NAj5wjfjbow==",
|
"integrity": "sha512-S9kZ+U/hQ+QVHZVLKu06xiVi0rII4DJCh2Z6M1m7IOyECBD7A1emk5pRx4fWG9Zp7ZOHL8dWO90sxtsaOPZBJw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -2265,7 +2281,18 @@
|
||||||
"url": "https://github.com/sponsors/cyberalien"
|
"url": "https://github.com/sponsors/cyberalien"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"svelte": ">5.0.0"
|
"svelte": ">4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@iconify/json": {
|
||||||
|
"version": "2.2.439",
|
||||||
|
"resolved": "https://registry.npmjs.org/@iconify/json/-/json-2.2.439.tgz",
|
||||||
|
"integrity": "sha512-DFpo7ZqntngeDaVFtsj+AydUrJoEPW0FIpMrmngo3iHxLXpqcNe5lhztPqvVBoXllbohomcA1YRjRO/ljo7AnQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@iconify/types": "*",
|
||||||
|
"pathe": "^2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@iconify/types": {
|
"node_modules/@iconify/types": {
|
||||||
|
|
@ -2275,6 +2302,18 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@iconify/utils": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@antfu/install-pkg": "^1.1.0",
|
||||||
|
"@iconify/types": "^2.0.0",
|
||||||
|
"mlly": "^1.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@jridgewell/gen-mapping": {
|
"node_modules/@jridgewell/gen-mapping": {
|
||||||
"version": "0.3.13",
|
"version": "0.3.13",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||||
|
|
@ -2455,19 +2494,6 @@
|
||||||
"node": ">= 8.0.0"
|
"node": ">= 8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/pluginutils/node_modules/picomatch": {
|
|
||||||
"version": "2.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
|
||||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.6"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.57.1",
|
"version": "4.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz",
|
||||||
|
|
@ -2846,9 +2872,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sveltejs/adapter-auto": {
|
"node_modules/@sveltejs/adapter-auto": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-7.0.1.tgz",
|
||||||
"integrity": "sha512-ImDWaErTOCkRS4Gt+5gZuymKFBobnhChXUZ9lhUZLahUgvA4OOvRzi3sahzYgbxGj5nkA6OV0GAW378+dl/gyw==",
|
"integrity": "sha512-dvuPm1E7M9NI/+canIQ6KKQDU2AkEefEZ2Dp7cY6uKoPq9Z/PhOXABe526UdW2mN986gjVkuSLkOYIBnS/M2LQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|
@ -2866,9 +2892,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sveltejs/kit": {
|
"node_modules/@sveltejs/kit": {
|
||||||
"version": "2.50.2",
|
"version": "2.51.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.50.2.tgz",
|
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.51.0.tgz",
|
||||||
"integrity": "sha512-875hTUkEbz+MyJIxWbQjfMaekqdmEKUUfR7JyKcpfMRZqcGyrO9Gd+iS1D/Dx8LpE5FEtutWGOtlAh4ReSAiOA==",
|
"integrity": "sha512-BkcfxVVYmfxHGYLugemb7TWW+y/MNZbxXHXJ141lyyi2ozq0Q4kbqoV0cBGlh7F0vNtCMvfr7UPnxIaBjcP9gg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -3275,6 +3301,13 @@
|
||||||
"undici-types": "~7.16.0"
|
"undici-types": "~7.16.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/trusted-types": {
|
||||||
|
"version": "2.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
|
||||||
|
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/unist": {
|
"node_modules/@types/unist": {
|
||||||
"version": "2.0.11",
|
"version": "2.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
|
||||||
|
|
@ -3686,6 +3719,13 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/confbox": {
|
||||||
|
"version": "0.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz",
|
||||||
|
"integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/convert-source-map": {
|
"node_modules/convert-source-map": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||||
|
|
@ -4170,6 +4210,13 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/exsolve": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
|
|
@ -4917,6 +4964,24 @@
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/local-pkg": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mlly": "^1.7.4",
|
||||||
|
"pkg-types": "^2.3.0",
|
||||||
|
"quansync": "^0.2.11"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/locate-character": {
|
"node_modules/locate-character": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
|
||||||
|
|
@ -5085,19 +5150,6 @@
|
||||||
"node": ">=8.6"
|
"node": ">=8.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/micromatch/node_modules/picomatch": {
|
|
||||||
"version": "2.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
|
||||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.6"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/minimatch": {
|
"node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
|
@ -5121,6 +5173,38 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mlly": {
|
||||||
|
"version": "1.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
|
||||||
|
"integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"acorn": "^8.15.0",
|
||||||
|
"pathe": "^2.0.3",
|
||||||
|
"pkg-types": "^1.3.1",
|
||||||
|
"ufo": "^1.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mlly/node_modules/confbox": {
|
||||||
|
"version": "0.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
|
||||||
|
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/mlly/node_modules/pkg-types": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"confbox": "^0.1.8",
|
||||||
|
"mlly": "^1.7.4",
|
||||||
|
"pathe": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mri": {
|
"node_modules/mri": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
|
||||||
|
|
@ -5190,8 +5274,7 @@
|
||||||
"https://github.com/sponsors/sxzz",
|
"https://github.com/sponsors/sxzz",
|
||||||
"https://opencollective.com/debug"
|
"https://opencollective.com/debug"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/optionator": {
|
"node_modules/optionator": {
|
||||||
"version": "0.9.4",
|
"version": "0.9.4",
|
||||||
|
|
@ -5243,6 +5326,13 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/package-manager-detector": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/parent-module": {
|
"node_modules/parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
|
|
@ -5283,6 +5373,13 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/pathe": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
|
|
@ -5291,18 +5388,30 @@
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "4.0.3",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=8.6"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pkg-types": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"confbox": "^0.2.2",
|
||||||
|
"exsolve": "^1.0.7",
|
||||||
|
"pathe": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.5.6",
|
"version": "8.5.6",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
|
||||||
|
|
@ -5590,6 +5699,23 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/quansync": {
|
||||||
|
"version": "0.2.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
|
||||||
|
"integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/sxzz"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/queue-microtask": {
|
"node_modules/queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
|
|
@ -5957,9 +6083,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/svelte": {
|
"node_modules/svelte": {
|
||||||
"version": "5.50.2",
|
"version": "5.51.0",
|
||||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.50.2.tgz",
|
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.51.0.tgz",
|
||||||
"integrity": "sha512-WCxzm3BBf+Ase6RwiDPR4G36cM4Kb0NuhmLK6x44I+D6reaxizDDg8kBkk4jT/19+Rgmc44eZkOvMO6daoSFIw==",
|
"integrity": "sha512-TOtjs5SjPi1iCXJ7aHwQBY+PEyk0koIc1FCKNFyS9kQuN4FBma9nRuxM4f4A0b5SCdej812vf2Rcql2I0s9FZg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -5967,6 +6093,7 @@
|
||||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||||
"@sveltejs/acorn-typescript": "^1.0.5",
|
"@sveltejs/acorn-typescript": "^1.0.5",
|
||||||
"@types/estree": "^1.0.5",
|
"@types/estree": "^1.0.5",
|
||||||
|
"@types/trusted-types": "^2.0.7",
|
||||||
"acorn": "^8.12.1",
|
"acorn": "^8.12.1",
|
||||||
"aria-query": "^5.3.1",
|
"aria-query": "^5.3.1",
|
||||||
"axobject-query": "^4.1.0",
|
"axobject-query": "^4.1.0",
|
||||||
|
|
@ -5984,9 +6111,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/svelte-check": {
|
"node_modules/svelte-check": {
|
||||||
"version": "4.3.6",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.4.0.tgz",
|
||||||
"integrity": "sha512-uBkz96ElE3G4pt9E1Tw0xvBfIUQkeH794kDQZdAUk795UVMr+NJZpuFSS62vcmO/DuSalK83LyOwhgWq8YGU1Q==",
|
"integrity": "sha512-gB3FdEPb8tPO3Y7Dzc6d/Pm/KrXAhK+0Fk+LkcysVtupvAh6Y/IrBCEZNupq57oh0hcwlxCUamu/rq7GtvfSEg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -6159,6 +6286,16 @@
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tinyexec": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tinyglobby": {
|
"node_modules/tinyglobby": {
|
||||||
"version": "0.2.15",
|
"version": "0.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||||
|
|
@ -6176,6 +6313,19 @@
|
||||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tinyglobby/node_modules/picomatch": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
|
@ -6232,6 +6382,13 @@
|
||||||
"node": ">=14.17"
|
"node": ">=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ufo": {
|
||||||
|
"version": "1.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz",
|
||||||
|
"integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "7.16.0",
|
"version": "7.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
||||||
|
|
@ -6339,6 +6496,72 @@
|
||||||
"url": "https://opencollective.com/unified"
|
"url": "https://opencollective.com/unified"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/unplugin": {
|
||||||
|
"version": "2.3.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz",
|
||||||
|
"integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@jridgewell/remapping": "^2.3.5",
|
||||||
|
"acorn": "^8.15.0",
|
||||||
|
"picomatch": "^4.0.3",
|
||||||
|
"webpack-virtual-modules": "^0.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/unplugin-icons": {
|
||||||
|
"version": "23.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/unplugin-icons/-/unplugin-icons-23.0.1.tgz",
|
||||||
|
"integrity": "sha512-rv0XEJepajKzDLvRUWASM8K+8+/CCfZn2jtogXqg6RIp7kpatRc/aFrVJn8ANQA09e++lPEEv9yX8cC9enc+QQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@antfu/install-pkg": "^1.1.0",
|
||||||
|
"@iconify/utils": "^3.1.0",
|
||||||
|
"local-pkg": "^1.1.2",
|
||||||
|
"obug": "^2.1.1",
|
||||||
|
"unplugin": "^2.3.11"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@svgr/core": ">=7.0.0",
|
||||||
|
"@svgx/core": "^1.0.1",
|
||||||
|
"@vue/compiler-sfc": "^3.0.2",
|
||||||
|
"svelte": "^3.0.0 || ^4.0.0 || ^5.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@svgr/core": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@svgx/core": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@vue/compiler-sfc": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"svelte": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/unplugin/node_modules/picomatch": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
|
||||||
|
|
@ -6477,6 +6700,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vite/node_modules/picomatch": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vitefu": {
|
"node_modules/vitefu": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz",
|
||||||
|
|
@ -6498,6 +6734,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/webpack-virtual-modules": {
|
||||||
|
"version": "0.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
|
||||||
|
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
|
@ -6571,6 +6814,22 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/yaml": {
|
||||||
|
"version": "2.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
|
||||||
|
"integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
|
||||||
|
"extraneous": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"yaml": "bin.mjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/eemeli"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/yocto-queue": {
|
"node_modules/yocto-queue": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify/svelte": "^5.2.1",
|
"@iconify/css-svelte": "^1.0.0",
|
||||||
|
"@iconify/json": "^2.2.439",
|
||||||
"@react2svelte/swipeable": "^0.1.4",
|
"@react2svelte/swipeable": "^0.1.4",
|
||||||
"@svelte-put/dragscroll": "^4.0.0",
|
"@svelte-put/dragscroll": "^4.0.0",
|
||||||
"@sveltejs/adapter-auto": "^7.0.0",
|
"@sveltejs/adapter-auto": "^7.0.0",
|
||||||
|
|
@ -41,6 +42,7 @@
|
||||||
"tailwindcss": "^4.0.9",
|
"tailwindcss": "^4.0.9",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
|
"unplugin-icons": "^23.0.1",
|
||||||
"vite": "^7.3.1"
|
"vite": "^7.3.1"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|
|
||||||
8
src/app.d.ts
vendored
8
src/app.d.ts
vendored
|
|
@ -1,8 +1,14 @@
|
||||||
|
/// <reference types="svelte" />
|
||||||
|
/// <reference types="vite/client" />
|
||||||
|
/// <reference types="unplugin-icons/types/svelte" />
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
DurationFormatConstructor,
|
DurationFormatConstructor,
|
||||||
DurationFormatOptions as _DurationFormatOptions,
|
DurationFormatOptions as _DurationFormatOptions,
|
||||||
DurationInput as _DurationInput,
|
DurationInput as _DurationInput,
|
||||||
} from '@formatjs/intl-durationformat/src/types';
|
} from '@formatjs/intl-durationformat/src/types';
|
||||||
|
import type { Component } from 'svelte';
|
||||||
|
import 'unplugin-icons/types/svelte';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
// rndtrash: Терпим. https://github.com/microsoft/TypeScript/issues/60608
|
// rndtrash: Терпим. https://github.com/microsoft/TypeScript/issues/60608
|
||||||
|
|
@ -15,7 +21,7 @@ declare global {
|
||||||
namespace App {
|
namespace App {
|
||||||
interface Route {
|
interface Route {
|
||||||
label: string;
|
label: string;
|
||||||
icon: string;
|
icon?: Component | string;
|
||||||
href: string;
|
href: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,12 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
import {
|
||||||
BLOG_POST_FRESHNESS_MILLIS,
|
BLOG_POST_FRESHNESS_MILLIS,
|
||||||
blogPostTypeToIcon,
|
blogPostTypeToIconComponent,
|
||||||
blogPostTypeToString,
|
blogPostTypeToString,
|
||||||
EventStatus,
|
EventStatus,
|
||||||
postEventStatus
|
postEventStatus
|
||||||
} from '$lib/util/Blogs';
|
} from '$lib/util/Blogs';
|
||||||
import DateWidget from '$lib/components/DateWidget.svelte';
|
import DateWidget from '$lib/components/DateWidget.svelte';
|
||||||
import Icon from '@iconify/svelte';
|
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
|
|
@ -24,7 +23,7 @@
|
||||||
fullHeight = false
|
fullHeight = false
|
||||||
}: { post: App.BlogPost; size?: BlogCardSize; fullHeight?: boolean } = $props();
|
}: { post: App.BlogPost; size?: BlogCardSize; fullHeight?: boolean } = $props();
|
||||||
|
|
||||||
const type: App.BlogPostType = post.type ?? 'article';
|
const type: App.BlogPostType = $derived(post.type ?? 'article');
|
||||||
let isPostNew = $state(false);
|
let isPostNew = $state(false);
|
||||||
let isPostUpdated = $state(false);
|
let isPostUpdated = $state(false);
|
||||||
let isPostFresh = $derived(isPostNew || isPostUpdated);
|
let isPostFresh = $derived(isPostNew || isPostUpdated);
|
||||||
|
|
@ -35,6 +34,8 @@
|
||||||
);
|
);
|
||||||
let eventHasStarted = $derived(eventStatus === EventStatus.InProgress);
|
let eventHasStarted = $derived(eventStatus === EventStatus.InProgress);
|
||||||
|
|
||||||
|
const PostTypeIcon = $derived(blogPostTypeToIconComponent(type));
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const dateNow = new Date().valueOf();
|
const dateNow = new Date().valueOf();
|
||||||
isPostNew = dateNow - new Date(post.date!).valueOf() <= BLOG_POST_FRESHNESS_MILLIS;
|
isPostNew = dateNow - new Date(post.date!).valueOf() <= BLOG_POST_FRESHNESS_MILLIS;
|
||||||
|
|
@ -150,7 +151,7 @@
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="flex items-center gap-2 p-1 text-lg font-bold">
|
<div class="flex items-center gap-2 p-1 text-lg font-bold">
|
||||||
<Icon icon={blogPostTypeToIcon(type)} width={28} height={28} />
|
<PostTypeIcon width={28} height={28} />
|
||||||
<span class={shortClass('hidden', 'not-md:hidden')}>
|
<span class={shortClass('hidden', 'not-md:hidden')}>
|
||||||
{blogPostTypeToString(type)}
|
{blogPostTypeToString(type)}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Icon from '@iconify/svelte';
|
|
||||||
import { dateFormatLong, dateFormatShort } from '$lib/util/Dates';
|
import { dateFormatLong, dateFormatShort } from '$lib/util/Dates';
|
||||||
|
import type { Component } from 'svelte';
|
||||||
|
|
||||||
|
import PublishedIcon from '~icons/material-symbols/calendar-today';
|
||||||
|
import UpdatedIcon from '~icons/material-symbols/update';
|
||||||
|
import EventStartIcon from '~icons/material-symbols/rocket-launch';
|
||||||
|
import EventFinishIcon from '~icons/material-symbols/sports-score';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
dateString,
|
dateString,
|
||||||
|
|
@ -17,13 +22,13 @@
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
const typeToIcon = {
|
const typeToIcon = {
|
||||||
published: 'material-symbols:calendar-today',
|
published: PublishedIcon,
|
||||||
updated: 'material-symbols:update',
|
updated: UpdatedIcon,
|
||||||
eventStart: 'material-symbols:rocket-launch',
|
eventStart: EventStartIcon,
|
||||||
eventFinish: 'material-symbols:sports-score'
|
eventFinish: EventFinishIcon
|
||||||
};
|
};
|
||||||
|
|
||||||
const icon = type ? typeToIcon[type] : undefined;
|
const IconComponent: Component | undefined = $derived(type ? typeToIcon[type] : undefined);
|
||||||
|
|
||||||
const highlightClasses = (classes: string) => (highlight ? classes : '');
|
const highlightClasses = (classes: string) => (highlight ? classes : '');
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -38,8 +43,8 @@
|
||||||
)}
|
)}
|
||||||
{highlightClasses('text-slate-50')}"
|
{highlightClasses('text-slate-50')}"
|
||||||
>
|
>
|
||||||
{#if icon}
|
{#if IconComponent}
|
||||||
<Icon {icon} width={28} height={28} />
|
<IconComponent width={28} height={28} />
|
||||||
{/if}
|
{/if}
|
||||||
<span class="text-nowrap">
|
<span class="text-nowrap">
|
||||||
{dateString
|
{dateString
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,23 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Icon from '@iconify/svelte';
|
import type { Component } from 'svelte';
|
||||||
|
|
||||||
let className: string = '';
|
let {
|
||||||
export { className as class };
|
class: klass = '',
|
||||||
export let src: string | null = null;
|
src,
|
||||||
export let alt: string = "";
|
alt = '',
|
||||||
export let size: number = 32;
|
size = 32,
|
||||||
export let black: boolean = false;
|
black = false
|
||||||
|
}: {
|
||||||
|
class?: string;
|
||||||
|
src?: Component | string;
|
||||||
|
alt?: string;
|
||||||
|
size?: number;
|
||||||
|
black?: boolean;
|
||||||
|
} = $props();
|
||||||
|
|
||||||
|
const IconComponent: Component | undefined = $derived(
|
||||||
|
typeof src === 'function' ? src : undefined
|
||||||
|
);
|
||||||
|
|
||||||
function isUrl(src?: string) {
|
function isUrl(src?: string) {
|
||||||
return src?.startsWith('/') || src?.startsWith('http');
|
return src?.startsWith('/') || src?.startsWith('http');
|
||||||
|
|
@ -14,16 +25,14 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
class="{className} {black ? 'fill-slate-950' : 'fill-slate-50'} hover-icon"
|
class="{klass} {black ? 'fill-slate-950' : 'fill-slate-50'} hover-icon"
|
||||||
style:width="{size}px"
|
style:width="{size}px"
|
||||||
style:height="{size}px"
|
style:height="{size}px"
|
||||||
>
|
>
|
||||||
{#if src}
|
{#if IconComponent}
|
||||||
{#if isUrl(src)}
|
<IconComponent width={size} height={size} color={black ? '#020618' : '#f8fafc'} />
|
||||||
|
{:else if typeof src === 'string' && isUrl(src)}
|
||||||
<img {src} {alt} width={size} height={size} />
|
<img {src} {alt} width={size} height={size} />
|
||||||
{:else}
|
|
||||||
<Icon width={size} height={size} icon={src} color={black ? '#020618' : '#f8fafc'} />
|
|
||||||
{/if}
|
|
||||||
{:else}
|
{:else}
|
||||||
{alt ?? 'Без иконки'}
|
{alt ?? 'Без иконки'}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,27 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Icon from '@iconify/svelte';
|
import type { Component, Snippet } from 'svelte';
|
||||||
|
|
||||||
export let bgStrong: string;
|
let {
|
||||||
export let bgBleak: string;
|
icon: IconComponent,
|
||||||
export let icon: string;
|
bgStrong,
|
||||||
export let caption: string;
|
bgBleak,
|
||||||
|
caption,
|
||||||
|
children
|
||||||
|
}: {
|
||||||
|
icon: Component;
|
||||||
|
bgStrong: string;
|
||||||
|
bgBleak: string;
|
||||||
|
caption: string;
|
||||||
|
children: Snippet;
|
||||||
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="flex flex-col sm:flex-row">
|
<section class="flex flex-col sm:flex-row">
|
||||||
<div class="flex flex-row items-center gap-2 {bgStrong} p-2 text-slate-50">
|
<div class="flex flex-row items-center gap-2 {bgStrong} p-2 text-slate-50">
|
||||||
<Icon width={32} height={32} {icon} color={'#f8fafc'} />
|
<IconComponent width={32} height={32} color={'#f8fafc'} />
|
||||||
<span class="sm:hidden">{caption}</span>
|
<span class="sm:hidden">{caption}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="{bgBleak} p-4 sm:grow">
|
<div class="{bgBleak} p-4 sm:grow">
|
||||||
<slot />
|
{@render children()}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
import IconBlock from './IconBlock.svelte';
|
import IconBlock from './IconBlock.svelte';
|
||||||
|
import InfoIcon from '~icons/material-symbols/info';
|
||||||
|
|
||||||
|
let { children }: { children: Snippet } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<IconBlock
|
<IconBlock bgStrong="bg-blue-500" bgBleak="bg-blue-50" icon={InfoIcon} caption="Примечание">
|
||||||
bgStrong="bg-blue-500"
|
{@render children()}
|
||||||
bgBleak="bg-blue-50"
|
|
||||||
icon="material-symbols:info"
|
|
||||||
caption="Примечание"
|
|
||||||
>
|
|
||||||
<slot />
|
|
||||||
</IconBlock>
|
</IconBlock>
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,29 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
import { isLinkLocal, tryGetIcon } from '$lib/util/LinkResolver';
|
import { isLinkLocal, tryGetIcon } from '$lib/util/LinkResolver';
|
||||||
import HoverIcon from './HoverIcon.svelte';
|
import HoverIcon from '$lib/components/HoverIcon.svelte';
|
||||||
|
|
||||||
export let href: string;
|
let {
|
||||||
let className: string = '';
|
href,
|
||||||
export { className as class };
|
class: klass = '',
|
||||||
export let customIcon: string | null = null;
|
customIcon = null,
|
||||||
|
children
|
||||||
|
}: { href: string; class?: string; customIcon?: string | null; children: Snippet } = $props();
|
||||||
|
|
||||||
|
const iconSrc = $derived(customIcon ?? tryGetIcon(href));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
{href}
|
{href}
|
||||||
class="{className} flex flex-row drop-shadow-2xl transition-all hover:scale-110"
|
class="{klass} flex flex-row drop-shadow-2xl transition-all hover:scale-110"
|
||||||
target={isLinkLocal(href) ? '_self' : '_blank'}
|
target={isLinkLocal(href) ? '_self' : '_blank'}
|
||||||
>
|
>
|
||||||
<div class="shrink-0 rounded-l-xl bg-slate-800 p-2">
|
<div class="shrink-0 rounded-l-xl bg-slate-800 p-2">
|
||||||
<HoverIcon src={customIcon ?? tryGetIcon(href)} class="text-sm uppercase" />
|
<HoverIcon src={iconSrc} class="text-sm uppercase" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="flex shrink-0 grow flex-nowrap items-center justify-center rounded-r-xl bg-slate-100 p-2 text-2xl text-nowrap text-slate-950"
|
class="flex shrink-0 grow flex-nowrap items-center justify-center rounded-r-xl bg-slate-100 p-2 text-2xl text-nowrap text-slate-950"
|
||||||
>
|
>
|
||||||
<slot />
|
{@render children()}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -1,23 +1,32 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
import { MediaQuery } from 'svelte/reactivity';
|
import { MediaQuery } from 'svelte/reactivity';
|
||||||
import HoverIcon from './HoverIcon.svelte';
|
import HoverIcon from './HoverIcon.svelte';
|
||||||
import { isLinkLocal, tryGetIcon } from '$lib/util/LinkResolver';
|
import { isLinkLocal, tryGetIcon } from '$lib/util/LinkResolver';
|
||||||
|
|
||||||
export let href: string;
|
let {
|
||||||
let className: string = '';
|
href,
|
||||||
export { className as class };
|
class: klass = '',
|
||||||
export let customIcon: string | null = null;
|
customIcon = null,
|
||||||
|
children
|
||||||
|
}: { href: string; class?: string; customIcon?: string | null; children: Snippet } = $props();
|
||||||
|
|
||||||
|
const iconSrc = $derived(customIcon ?? tryGetIcon(href));
|
||||||
|
|
||||||
const sm = new MediaQuery('width >= 40rem', false);
|
const sm = new MediaQuery('width >= 40rem', false);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<a {href} class="{className} group inline-block no-underline" target={isLinkLocal(href) ? '_self' : '_blank'}>
|
<a
|
||||||
|
{href}
|
||||||
|
class="{klass} group inline-block no-underline"
|
||||||
|
target={isLinkLocal(href) ? '_self' : '_blank'}
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
class="inline-block size-6 rounded-sm bg-emerald-800 p-0.5 align-bottom transition-all group-hover:scale-110 sm:size-8 sm:rounded-xl sm:p-1"
|
class="inline-block size-6 rounded-sm bg-emerald-800 p-0.5 align-bottom transition-all group-hover:scale-110 sm:size-8 sm:rounded-xl sm:p-1"
|
||||||
>
|
>
|
||||||
<HoverIcon src={customIcon ?? tryGetIcon(href)} size={sm.current ? 24 : 20} />
|
<HoverIcon src={iconSrc} size={sm.current ? 24 : 20} />
|
||||||
</span>
|
</span>
|
||||||
<span class="text-emerald-900 underline">
|
<span class="text-emerald-900 underline">
|
||||||
<slot />
|
{@render children()}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
import IconBlock from './IconBlock.svelte';
|
import IconBlock from './IconBlock.svelte';
|
||||||
|
import WarningIcon from '~icons/material-symbols/warning';
|
||||||
|
|
||||||
|
let { children }: { children: Snippet } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<IconBlock
|
<IconBlock bgStrong="bg-yellow-500" bgBleak="bg-yellow-50" icon={WarningIcon} caption="Внимание">
|
||||||
bgStrong="bg-yellow-500"
|
{@render children()}
|
||||||
bgBleak="bg-yellow-50"
|
|
||||||
icon="material-symbols:warning"
|
|
||||||
caption="Внимание"
|
|
||||||
>
|
|
||||||
<slot />
|
|
||||||
</IconBlock>
|
</IconBlock>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import type { Component } from "svelte";
|
||||||
|
|
||||||
export const THUMBNAIL_DEFAULT = "https://teasanctuary.ru/common/background-day.webp";
|
export const THUMBNAIL_DEFAULT = "https://teasanctuary.ru/common/background-day.webp";
|
||||||
export const BLOG_POST_FRESHNESS_MILLIS = 3 * 24 * 60 * 60 * 1000; // 3 дня
|
export const BLOG_POST_FRESHNESS_MILLIS = 3 * 24 * 60 * 60 * 1000; // 3 дня
|
||||||
|
|
||||||
|
|
@ -97,16 +99,20 @@ const bptToString: Record<App.BlogPostType, string> = {
|
||||||
'update': 'Обновление'
|
'update': 'Обновление'
|
||||||
};
|
};
|
||||||
|
|
||||||
const bptToIcon: Record<App.BlogPostType, string> = {
|
import ArticleIcon from '~icons/material-symbols/article';
|
||||||
'article': 'material-symbols:article',
|
import EventIcon from '~icons/material-symbols/event';
|
||||||
'event': 'material-symbols:event',
|
import UpdateIcon from '~icons/material-symbols/autorenew';
|
||||||
'update': 'material-symbols:autorenew'
|
|
||||||
|
const bptToIcon: Record<App.BlogPostType, Component> = {
|
||||||
|
'article': ArticleIcon,
|
||||||
|
'event': EventIcon,
|
||||||
|
'update': UpdateIcon
|
||||||
};
|
};
|
||||||
|
|
||||||
export function blogPostTypeToString(type: App.BlogPostType): string {
|
export function blogPostTypeToString(type: App.BlogPostType): string {
|
||||||
return bptToString[type] ?? bptToString['article'];
|
return bptToString[type] ?? bptToString['article'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function blogPostTypeToIcon(type: App.BlogPostType): string {
|
export function blogPostTypeToIconComponent(type: App.BlogPostType): Component {
|
||||||
return bptToIcon[type] ?? bptToIcon['article'];
|
return bptToIcon[type] ?? bptToIcon['article'];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,47 @@
|
||||||
|
import type { Component } from "svelte";
|
||||||
|
import { browser } from '$app/environment';
|
||||||
|
|
||||||
|
import DefaultLinkIcon from '~icons/material-symbols/link';
|
||||||
|
import SteamIcon from '~icons/simple-icons/steam';
|
||||||
|
import TelegramIcon from '~icons/simple-icons/telegram';
|
||||||
|
import TwitterIcon from '~icons/simple-icons/x';
|
||||||
|
import GitHubIcon from '~icons/simple-icons/github';
|
||||||
|
import YouTubeIcon from '~icons/simple-icons/youtube';
|
||||||
|
import ItchIoIcon from '~icons/simple-icons/itchdotio';
|
||||||
|
import DiscordIcon from '~icons/simple-icons/discord';
|
||||||
|
import GameBananaIcon from '~icons/simple-icons/gamebanana';
|
||||||
|
import BlueSkyIcon from '~icons/simple-icons/bluesky';
|
||||||
|
import HamsterIcon from '~icons/fluent-emoji-high-contrast/hamster';
|
||||||
|
import GitIcon from '~icons/devicon-plain/git';
|
||||||
|
import EmailIcon from '~icons/material-symbols/alternate-email';
|
||||||
|
import RssIcon from '~icons/material-symbols/rss-feed';
|
||||||
|
|
||||||
|
type LinkIcon = Component | string;
|
||||||
|
|
||||||
// TODO: чашки на иконках выглядят страшненько, пока что пусть лучше будет голая ссылка
|
// TODO: чашки на иконках выглядят страшненько, пока что пусть лучше будет голая ссылка
|
||||||
const icons: Record<string, string> = {
|
const icons: Record<string, LinkIcon> = {
|
||||||
none: 'material-symbols:link',
|
none: DefaultLinkIcon,
|
||||||
'steamcommunity.com': 'simple-icons:steam',
|
'steamcommunity.com': SteamIcon,
|
||||||
'steampowered.com': 'simple-icons:steam',
|
'steampowered.com': SteamIcon,
|
||||||
't.me': 'simple-icons:telegram',
|
't.me': TelegramIcon,
|
||||||
'twitter.com': 'simple-icons:x',
|
'twitter.com': TwitterIcon,
|
||||||
'x.com': 'simple-icons:x',
|
'x.com': TwitterIcon,
|
||||||
'github.com': 'simple-icons:github',
|
'github.com': GitHubIcon,
|
||||||
'youtube.com': 'simple-icons:youtube',
|
'youtube.com': YouTubeIcon,
|
||||||
'itch.io': 'simple-icons:itchdotio',
|
'itch.io': ItchIoIcon,
|
||||||
'discord.com': 'simple-icons:discord',
|
'discord.com': DiscordIcon,
|
||||||
'discord.gg': 'simple-icons:discord',
|
'discord.gg': DiscordIcon,
|
||||||
'gamebanana.com': 'simple-icons:gamebanana',
|
'gamebanana.com': GameBananaIcon,
|
||||||
'bsky.app': 'simple-icons:bluesky',
|
'bsky.app': BlueSkyIcon,
|
||||||
'bsky.social': 'simple-icons:bluesky',
|
'bsky.social': BlueSkyIcon,
|
||||||
// https://хамяк.рф
|
// https://хамяк.рф
|
||||||
'xn--80auf8a2c.xn--p1ai': 'fluent-emoji-high-contrast:hamster',
|
'xn--80auf8a2c.xn--p1ai': HamsterIcon,
|
||||||
// 'teasanctuary.ru': '/icons/tea-sanctuary-white.svg',
|
// 'teasanctuary.ru': '/icons/tea-sanctuary-white.svg',
|
||||||
'hl.teasanctuary.ru': '/icons/half-life.svg',
|
'hl.teasanctuary.ru': '/icons/half-life.svg',
|
||||||
'git.teasanctuary.ru': 'devicon-plain:git',
|
'git.teasanctuary.ru': GitIcon,
|
||||||
// localhost: '/icons/tea-sanctuary-white.svg',
|
// localhost: '/icons/tea-sanctuary-white.svg',
|
||||||
email: 'material-symbols:alternate-email',
|
email: EmailIcon,
|
||||||
rss: 'material-symbols:rss-feed'
|
rss: RssIcon
|
||||||
};
|
};
|
||||||
|
|
||||||
// Особые случаи, когда одним доменом второго уровня не ограничишься (например, randomtrash.itch.io)
|
// Особые случаи, когда одним доменом второго уровня не ограничишься (например, randomtrash.itch.io)
|
||||||
|
|
@ -51,7 +71,9 @@ const specialResolvers: Record<string, (url: URL) => string> = {
|
||||||
'steampowered.com': (url) => 'steampowered.com',
|
'steampowered.com': (url) => 'steampowered.com',
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIconFromUrl(url: URL): string | undefined {
|
function getIconNameFromUrl(url?: URL): string | undefined {
|
||||||
|
if (!url) return undefined;
|
||||||
|
|
||||||
const href = url.href;
|
const href = url.href;
|
||||||
if (href.startsWith('mailto:'))
|
if (href.startsWith('mailto:'))
|
||||||
return 'email';
|
return 'email';
|
||||||
|
|
@ -66,15 +88,16 @@ function getIconFromUrl(url: URL): string | undefined {
|
||||||
return hostname;
|
return hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tryGetIcon(link: string): string {
|
const baseURI = browser ? document.baseURI : 'https://teasanctuary.ru';
|
||||||
|
export function tryGetIcon(link: string): LinkIcon {
|
||||||
let url: URL;
|
let url: URL;
|
||||||
try {
|
try {
|
||||||
url = new URL(link, document.baseURI);
|
url = new URL(link, baseURI);
|
||||||
} catch {
|
} catch {
|
||||||
return icons['none'];
|
return icons['none'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return icons[getIconFromUrl(url) ?? ''] ?? icons['none'];
|
return icons[getIconNameFromUrl(url) ?? ''] ?? icons['none'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,42 @@
|
||||||
import { page } from '$app/state';
|
import { page } from '$app/state';
|
||||||
import '$src/syntax-highlight.css'; // https://github.com/PrismJS/prism-themes
|
import '$src/syntax-highlight.css'; // https://github.com/PrismJS/prism-themes
|
||||||
import NavBar from '$lib/components/NavBar.svelte';
|
import NavBar from '$lib/components/NavBar.svelte';
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
|
import TeaIcon from '~icons/material-symbols/emoji-food-beverage';
|
||||||
|
import TeamIcon from '~icons/material-symbols/groups';
|
||||||
|
import BlogIcon from '~icons/material-symbols/newspaper';
|
||||||
|
import ProjectsIcon from '~icons/material-symbols/work';
|
||||||
|
import ContactsIcon from '~icons/material-symbols/chat';
|
||||||
|
|
||||||
|
let { children }: { children: Snippet } = $props();
|
||||||
|
|
||||||
const routes: App.Route[] = [
|
const routes: App.Route[] = [
|
||||||
{ label: 'главная', icon: 'material-symbols:emoji-food-beverage', href: '/' },
|
{
|
||||||
{ label: 'команда', icon: 'material-symbols:groups', href: '/team' },
|
label: 'главная',
|
||||||
{ label: 'блог', icon: 'material-symbols:newspaper', href: '/blog' },
|
icon: TeaIcon,
|
||||||
{ label: 'проекты', icon: 'material-symbols:work', href: '/projects' },
|
href: '/'
|
||||||
{ label: 'контакты', icon: 'material-symbols:chat', href: '/contact' }
|
},
|
||||||
|
{
|
||||||
|
label: 'команда',
|
||||||
|
icon: TeamIcon,
|
||||||
|
href: '/team'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'блог',
|
||||||
|
icon: BlogIcon,
|
||||||
|
href: '/blog'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'проекты',
|
||||||
|
icon: ProjectsIcon,
|
||||||
|
href: '/projects'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'контакты',
|
||||||
|
icon: ContactsIcon,
|
||||||
|
href: '/contact'
|
||||||
|
}
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -33,7 +62,7 @@
|
||||||
<NavBar {routes} />
|
<NavBar {routes} />
|
||||||
<div class="flex grow-1 flex-col overflow-auto">
|
<div class="flex grow-1 flex-col overflow-auto">
|
||||||
<div class="relative grow-1">
|
<div class="relative grow-1">
|
||||||
<slot />
|
{@render children()}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="bg-emerald-950">
|
<footer class="bg-emerald-950">
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
import { page } from '$app/state';
|
import { page } from '$app/state';
|
||||||
import DateWidget from '$lib/components/DateWidget.svelte';
|
import DateWidget from '$lib/components/DateWidget.svelte';
|
||||||
import InfoBlock from '$lib/components/InfoBlock.svelte';
|
import InfoBlock from '$lib/components/InfoBlock.svelte';
|
||||||
import Icon from '@iconify/svelte';
|
import PersonIcon from '~icons/material-symbols/person';
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
import {
|
import {
|
||||||
blogPostTypeToIcon,
|
blogPostTypeToIconComponent,
|
||||||
blogPostTypeToString,
|
blogPostTypeToString,
|
||||||
EventStatus,
|
EventStatus,
|
||||||
postEventStatus
|
postEventStatus
|
||||||
|
|
@ -16,16 +16,19 @@
|
||||||
|
|
||||||
let { data }: { data: PageData } = $props();
|
let { data }: { data: PageData } = $props();
|
||||||
|
|
||||||
const isPublic = !!data.blogPost.date;
|
const isPublic = $derived(!!data.blogPost.date);
|
||||||
const authors =
|
const authors = $derived(
|
||||||
data.blogPost.authors == null
|
data.blogPost.authors == null
|
||||||
? []
|
? []
|
||||||
: typeof data.blogPost.authors === 'string'
|
: typeof data.blogPost.authors === 'string'
|
||||||
? [data.blogPost.authors]
|
? [data.blogPost.authors]
|
||||||
: data.blogPost.authors;
|
: data.blogPost.authors
|
||||||
const type: App.BlogPostType = data.blogPost.type ?? 'article';
|
);
|
||||||
|
const type: App.BlogPostType = $derived(data.blogPost.type ?? 'article');
|
||||||
let eventStatus = $state(EventStatus.NotEvent);
|
let eventStatus = $state(EventStatus.NotEvent);
|
||||||
|
|
||||||
|
const PostTypeIcon = $derived(blogPostTypeToIconComponent(type));
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// HACK: rndtrash: NodeJS использует другой тип данных для таймаутов
|
// HACK: rndtrash: NodeJS использует другой тип данных для таймаутов
|
||||||
let eventTimeout: ReturnType<typeof setTimeout> | undefined = undefined;
|
let eventTimeout: ReturnType<typeof setTimeout> | undefined = undefined;
|
||||||
|
|
@ -81,7 +84,7 @@
|
||||||
<DateWidget dateString={data.blogPost.dateChanged} type="updated" />
|
<DateWidget dateString={data.blogPost.dateChanged} type="updated" />
|
||||||
{/if}
|
{/if}
|
||||||
<div class="flex items-center gap-2 p-1 text-lg font-bold">
|
<div class="flex items-center gap-2 p-1 text-lg font-bold">
|
||||||
<Icon icon={blogPostTypeToIcon(type)} width={28} height={28} />
|
<PostTypeIcon width={28} height={28} />
|
||||||
<span>
|
<span>
|
||||||
{blogPostTypeToString(type)}
|
{blogPostTypeToString(type)}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -89,7 +92,7 @@
|
||||||
{#each authors as author}
|
{#each authors as author}
|
||||||
<!-- TODO: rndtrash: из-за 404 не даёт собрать сайт. href="/team/{author}" -->
|
<!-- TODO: rndtrash: из-за 404 не даёт собрать сайт. href="/team/{author}" -->
|
||||||
<a class="flex items-center gap-2 p-1 text-lg font-bold" href="#">
|
<a class="flex items-center gap-2 p-1 text-lg font-bold" href="#">
|
||||||
<Icon icon="material-symbols:person" width={28} height={28} />
|
<PersonIcon width={28} height={28} />
|
||||||
<span class="underline">
|
<span class="underline">
|
||||||
{author}
|
{author}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -156,7 +159,7 @@
|
||||||
class="prose
|
class="prose
|
||||||
sm:prose-xl
|
sm:prose-xl
|
||||||
prose-slate
|
prose-slate
|
||||||
prose-code:break-words
|
prose-code:wrap-break-word
|
||||||
prose-pre:drop-shadow-md
|
prose-pre:drop-shadow-md
|
||||||
prose-headings:font-disket
|
prose-headings:font-disket
|
||||||
prose-headings:mb-4
|
prose-headings:mb-4
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,14 @@ import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
import tailwindcss from "@tailwindcss/vite";
|
import tailwindcss from "@tailwindcss/vite";
|
||||||
import type { UserConfig } from 'vite';
|
import type { UserConfig } from 'vite';
|
||||||
import legacy from '@vitejs/plugin-legacy';
|
import legacy from '@vitejs/plugin-legacy';
|
||||||
|
import Icons from 'unplugin-icons/vite';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
plugins: [
|
plugins: [
|
||||||
sveltekit(),
|
sveltekit(),
|
||||||
|
Icons({
|
||||||
|
compiler: 'svelte',
|
||||||
|
}),
|
||||||
tailwindcss(),
|
tailwindcss(),
|
||||||
legacy({
|
legacy({
|
||||||
renderLegacyChunks: false
|
renderLegacyChunks: false
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue