Merge pull request #312 from Discours/feature/vercel_cashe

Add headers
This commit is contained in:
Kosta 2023-11-14 00:06:10 +02:00 committed by GitHub
commit 3f3bd798e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 136 additions and 313 deletions

View File

@ -66,6 +66,7 @@ module.exports = {
'unicorn/consistent-function-scoping': 'warn',
'unicorn/no-array-callback-reference': 'warn',
'unicorn/no-array-method-this-argument': 'warn',
'unicorn/no-for-loop': 'off',
'sonarjs/no-duplicate-string': ['warn', { threshold: 5 }],

32
api/edge-ssr.js Normal file
View File

@ -0,0 +1,32 @@
import { renderPage } from 'vike/server'
export const config = {
runtime: 'edge'
}
export default async function handler(request) {
const { url, cookies } = request
const pageContext = await renderPage({ urlOriginal: url, cookies })
const { httpResponse, errorWhileRendering, is404 } = pageContext
if (errorWhileRendering && !is404) {
console.error(errorWhileRendering)
return new Response('', { status: 500 })
}
if (!httpResponse) {
return new Response()
}
const { body, statusCode, headers: headersArray } = httpResponse
const headers = headersArray.reduce((acc, [name, value]) => {
acc[name] = value
return acc
}, {})
headers['Cache-Control'] = 's-maxage=1, stale-while-revalidate'
return new Response(body, { status: statusCode, headers })
}

View File

@ -1,27 +0,0 @@
import { renderPage } from 'vike/server'
export default async function handler(req, res) {
const { url, cookies } = req
const pageContext = await renderPage({ urlOriginal: url, cookies })
const { httpResponse, errorWhileRendering, is404 } = pageContext
if (errorWhileRendering && !is404) {
console.error(errorWhileRendering)
res.statusCode = 500
res.end()
return
}
if (!httpResponse) {
res.statusCode = 200
res.end()
return
}
const { body, statusCode, contentType } = httpResponse
res.statusCode = statusCode
res.setHeader('Content-Type', contentType)
res.end(body)
}

227
package-lock.json generated
View File

@ -13,7 +13,6 @@
"i18next": "22.4.15",
"i18next-icu": "2.3.0",
"intl-messageformat": "10.5.3",
"just-throttle": "4.2.0",
"mailgun.js": "8.2.1"
},
"devDependencies": {
@ -76,7 +75,6 @@
"bootstrap": "5.3.2",
"clsx": "2.0.0",
"cross-env": "7.0.3",
"debounce": "1.2.1",
"eslint": "8.53.0",
"eslint-config-stylelint": "20.0.0",
"eslint-import-resolver-typescript": "3.6.1",
@ -90,7 +88,6 @@
"fast-deep-equal": "3.1.3",
"graphql": "16.6.0",
"graphql-tag": "2.12.6",
"html-to-json-parser": "1.1.0",
"husky": "8.0.3",
"hygen": "6.2.11",
"i18next-http-backend": "2.2.0",
@ -100,11 +97,6 @@
"lint-staged": "15.0.2",
"loglevel": "1.8.1",
"loglevel-plugin-prefix": "0.8.4",
"markdown-it": "13.0.1",
"markdown-it-container": "3.0.0",
"markdown-it-implicit-figures": "0.11.0",
"markdown-it-mark": "3.0.1",
"markdown-it-replace-link": "1.2.0",
"nanostores": "0.7.4",
"prettier": "3.0.3",
"prettier-eslint": "16.1.2",
@ -123,6 +115,7 @@
"stylelint-order": "6.0.3",
"stylelint-scss": "5.3.0",
"swiper": "9.4.1",
"throttle-debounce": "5.0.0",
"typescript": "5.2.2",
"typograf": "7.1.0",
"uniqolor": "1.1.0",
@ -5102,6 +5095,15 @@
"throttle-debounce": "^3.0.1"
}
},
"node_modules/@remirror/core-helpers/node_modules/throttle-debounce": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz",
"integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/@remirror/types": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@remirror/types/-/types-1.0.1.tgz",
@ -8287,78 +8289,6 @@
"node": ">=6.0.0"
}
},
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dev": true,
"optional": true,
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/dom-serializer/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true,
"optional": true,
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"optional": true
},
"node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dev": true,
"optional": true,
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dev": true,
"optional": true,
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/dot-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
@ -8412,9 +8342,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.4.579",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.579.tgz",
"integrity": "sha512-bJKvA+awBIzYR0xRced7PrQuRIwGQPpo6ZLP62GAShahU9fWpsNN2IP6BSP1BLDDSbxvBVRGAMWlvVVq3npmLA==",
"version": "1.4.581",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.581.tgz",
"integrity": "sha512-6uhqWBIapTJUxgPTCHH9sqdbxIMPt7oXl0VcAL1kOtlU6aECdcMncCrX5Z7sHQ/invtrC9jUQUef7+HhO8vVFw==",
"dev": true
},
"node_modules/emittery": {
@ -8466,6 +8396,7 @@
"resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
"integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
"dev": true,
"peer": true,
"engines": {
"node": ">=0.12"
},
@ -8558,9 +8489,9 @@
}
},
"node_modules/es-module-lexer": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz",
"integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==",
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
"integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
"dev": true
},
"node_modules/es-set-tostringtag": {
@ -9101,9 +9032,9 @@
}
},
"node_modules/eslint-plugin-n": {
"version": "16.3.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.3.0.tgz",
"integrity": "sha512-/XZLH5CUXGK3laz3xYFNza8ZxLCq8ZNW6MsVw5z3d5hc2AwZzi0fPiySFZHQTdVDOHGs2cGv91aqzWmgBdq2gQ==",
"version": "16.3.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.3.1.tgz",
"integrity": "sha512-w46eDIkxQ2FaTHcey7G40eD+FhTXOdKudDXPUO2n9WNcslze/i/HT2qJ3GXjHngYSGDISIgPNhwGtgoix4zeOw==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
@ -9111,6 +9042,7 @@
"eslint-plugin-es-x": "^7.1.0",
"get-tsconfig": "^4.7.0",
"ignore": "^5.2.4",
"is-builtin-module": "^3.2.1",
"is-core-module": "^2.12.1",
"minimatch": "^3.1.2",
"resolve": "^1.22.2",
@ -9794,9 +9726,9 @@
}
},
"node_modules/flat-cache": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz",
"integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
"integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
"dev": true,
"dependencies": {
"flatted": "^3.2.9",
@ -9804,7 +9736,7 @@
"rimraf": "^3.0.2"
},
"engines": {
"node": ">=12.0.0"
"node": "^10.12.0 || >=12.0.0"
}
},
"node_modules/flatted": {
@ -10649,48 +10581,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/html-to-json-parser": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/html-to-json-parser/-/html-to-json-parser-1.1.0.tgz",
"integrity": "sha512-j6JiUBhIQkC+guahmh0VKwQRrnsROpUaRWAQyRlu5tp6atQg9ljeU70eBtpHSJwNALFNo//VOozvif7AQlfOtA==",
"dev": true,
"dependencies": {
"xmldom": "^0.6.0"
}
},
"node_modules/htmlparser2": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
"dev": true,
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"optional": true,
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1",
"entities": "^4.4.0"
}
},
"node_modules/htmlparser2/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true,
"optional": true,
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/http-proxy-agent": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz",
@ -13946,11 +13836,6 @@
"node": ">=4.0"
}
},
"node_modules/just-throttle": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/just-throttle/-/just-throttle-4.2.0.tgz",
"integrity": "sha512-/iAZv1953JcExpvsywaPKjSzfTiCLqeguUTE6+VmK15mOcwxBx7/FHrVvS4WEErMR03TRazH8kcBSHqMagYIYg=="
},
"node_modules/kebab-case": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/kebab-case/-/kebab-case-1.0.2.tgz",
@ -14070,6 +13955,7 @@
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
"integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
"dev": true,
"peer": true,
"dependencies": {
"uc.micro": "^1.0.1"
}
@ -14985,10 +14871,11 @@
}
},
"node_modules/markdown-it": {
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz",
"integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==",
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz",
"integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==",
"dev": true,
"peer": true,
"dependencies": {
"argparse": "^2.0.1",
"entities": "~3.0.1",
@ -15000,37 +14887,6 @@
"markdown-it": "bin/markdown-it.js"
}
},
"node_modules/markdown-it-container": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-container/-/markdown-it-container-3.0.0.tgz",
"integrity": "sha512-y6oKTq4BB9OQuY/KLfk/O3ysFhB3IMYoIWhGJEidXt1NQFocFK2sA2t0NYZAMyMShAGL6x5OPIbrmXPIqaN9rw==",
"dev": true
},
"node_modules/markdown-it-implicit-figures": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/markdown-it-implicit-figures/-/markdown-it-implicit-figures-0.11.0.tgz",
"integrity": "sha512-ed32u3O8pTEM3TKgeBTMKw8ce86L8u5L41CuLvGee3yevYOq+1BoxjI84m/f7RcUaATcKgXTgZwieadvOH4afg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/markdown-it-mark": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.1.tgz",
"integrity": "sha512-HyxjAu6BRsdt6Xcv6TKVQnkz/E70TdGXEFHRYBGLncRE9lBFwDNLVtFojKxjJWgJ+5XxUwLaHXy+2sGBbDn+4A==",
"dev": true
},
"node_modules/markdown-it-replace-link": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/markdown-it-replace-link/-/markdown-it-replace-link-1.2.0.tgz",
"integrity": "sha512-tIsShJvQOYwTHjIPhE1SWo12HjOtpEqSQfVoApm3fuIkVcZrSE7zK3iW8kXcaJYasf8Ddf+VbH5fNXCzfejOrQ==",
"dev": true,
"optionalDependencies": {
"dom-serializer": "^2.0.0",
"htmlparser2": "^8.0.1"
}
},
"node_modules/mathml-tag-names": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
@ -15051,7 +14907,8 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
"integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
"dev": true
"dev": true,
"peer": true
},
"node_modules/meow": {
"version": "10.1.5",
@ -18252,12 +18109,12 @@
"dev": true
},
"node_modules/throttle-debounce": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz",
"integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.0.tgz",
"integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==",
"dev": true,
"engines": {
"node": ">=10"
"node": ">=12.22"
}
},
"node_modules/through": {
@ -18574,7 +18431,8 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
"dev": true
"dev": true,
"peer": true
},
"node_modules/unbox-primitive": {
"version": "1.0.2",
@ -19699,15 +19557,6 @@
}
}
},
"node_modules/xmldom": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz",
"integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==",
"dev": true,
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/y-prosemirror": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/y-prosemirror/-/y-prosemirror-1.2.1.tgz",

View File

@ -34,7 +34,6 @@
"i18next": "22.4.15",
"i18next-icu": "2.3.0",
"intl-messageformat": "10.5.3",
"just-throttle": "4.2.0",
"mailgun.js": "8.2.1"
},
"devDependencies": {
@ -97,7 +96,6 @@
"bootstrap": "5.3.2",
"clsx": "2.0.0",
"cross-env": "7.0.3",
"debounce": "1.2.1",
"eslint": "8.53.0",
"eslint-config-stylelint": "20.0.0",
"eslint-import-resolver-typescript": "3.6.1",
@ -111,7 +109,6 @@
"fast-deep-equal": "3.1.3",
"graphql": "16.6.0",
"graphql-tag": "2.12.6",
"html-to-json-parser": "1.1.0",
"husky": "8.0.3",
"hygen": "6.2.11",
"i18next-http-backend": "2.2.0",
@ -121,11 +118,6 @@
"lint-staged": "15.0.2",
"loglevel": "1.8.1",
"loglevel-plugin-prefix": "0.8.4",
"markdown-it": "13.0.1",
"markdown-it-container": "3.0.0",
"markdown-it-implicit-figures": "0.11.0",
"markdown-it-mark": "3.0.1",
"markdown-it-replace-link": "1.2.0",
"nanostores": "0.7.4",
"prettier": "3.0.3",
"prettier-eslint": "16.1.2",
@ -144,6 +136,7 @@
"stylelint-order": "6.0.3",
"stylelint-scss": "5.3.0",
"swiper": "9.4.1",
"throttle-debounce": "5.0.0",
"typescript": "5.2.2",
"typograf": "7.1.0",
"uniqolor": "1.1.0",

View File

@ -69,6 +69,7 @@ img {
&[data-float='left'],
&[data-float='right'] {
@include font-size(2.2rem);
line-height: 1.4;
@include media-breakpoint-up(sm) {
@ -417,7 +418,7 @@ img {
}
.shoutStatsItemViews {
color: rgb(0 0 0 / 0.4);
color: rgb(0 0 0 / 40%);
cursor: default;
font-weight: normal;
margin-left: auto;
@ -460,7 +461,8 @@ img {
.shoutStatsItemAdditionalDataItem {
font-weight: normal;
display: inline-block;
//margin-left: 2rem;
// margin-left: 2rem;
margin-right: 0;
margin-bottom: 0;
cursor: default;

View File

@ -6,7 +6,6 @@ import { Popover } from '../../_shared/Popover'
import { Icon } from '../../_shared/Icon'
import styles from './AudioPlayer.module.scss'
import { GrowingTextarea } from '../../_shared/GrowingTextarea'
import MD from '../MD'
import { MediaItem } from '../../../pages/types'
import SimplifiedEditor from '../../Editor/SimplifiedEditor'
@ -146,12 +145,12 @@ export const PlayerPlaylist = (props: Props) => {
<div class={styles.descriptionBlock}>
<Show when={mi.body}>
<div class={styles.description}>
<MD body={mi.body} />
<div innerHTML={mi.body} />
</div>
</Show>
<Show when={mi.lyrics}>
<div class={styles.lyrics}>
<MD body={mi.lyrics} />
<div innerHTML={mi.lyrics} />
</div>
</Show>
</div>

View File

@ -4,7 +4,7 @@
transition: background-color 0.3s;
position: relative;
list-style: none;
background: rgb(0 0 0 / 0.1);
background: rgb(0 0 0 / 10%);
@include media-breakpoint-down(sm) {
padding-right: 0;

View File

@ -2,7 +2,6 @@ import { Show, createMemo, createSignal, For, lazy, Suspense } from 'solid-js'
import { clsx } from 'clsx'
import { getPagePath } from '@nanostores/router'
import MD from '../MD'
import { Userpic } from '../../Author/Userpic'
import { CommentRatingControl } from '../CommentRatingControl'
import { CommentDate } from '../CommentDate'
@ -171,7 +170,7 @@ export const Comment = (props: Props) => {
</div>
</Show>
<div class={styles.commentBody}>
<Show when={editMode()} fallback={<MD body={body()} />}>
<Show when={editMode()} fallback={<div innerHTML={body()} />}>
<Suspense fallback={<p>{t('Loading')}</p>}>
<SimplifiedEditor
initialContent={comment().body}

View File

@ -2,7 +2,6 @@ import { createEffect, For, createMemo, onMount, Show, createSignal, onCleanup }
import { Title } from '@solidjs/meta'
import { clsx } from 'clsx'
import { getPagePath } from '@nanostores/router'
import MD from './MD'
import type { Author, Shout } from '../../graphql/types.gen'
import { useSession } from '../../context/session'
import { useLocalize } from '../../context/localize'
@ -318,7 +317,7 @@ export const FullArticle = (props: Props) => {
description={m.body}
/>
<Show when={m?.body}>
<MD body={m.body} />
<div innerHTML={m.body} />
</Show>
</div>
)}
@ -327,11 +326,7 @@ export const FullArticle = (props: Props) => {
</Show>
<Show when={body()}>
<div id="shoutBody" class={styles.shoutBody}>
<Show when={!body().startsWith('<')} fallback={<div innerHTML={body()} />}>
<MD body={body()} />
</Show>
</div>
<div id="shoutBody" class={styles.shoutBody} innerHTML={body()} />
</Show>
</article>

View File

@ -1,24 +0,0 @@
import MD from 'markdown-it'
import mdfig from 'markdown-it-implicit-figures'
import mdmark from 'markdown-it-mark'
import mdcustom from 'markdown-it-container'
import mdlinks from 'markdown-it-replace-link'
import { createMemo } from 'solid-js'
const mit = MD({
html: true,
linkify: true,
typographer: true
})
mit.use(mdmark)
mit.use(mdcustom)
mit.use(mdfig, {
dataType: false, // <figure data-type="image">
figcaption: true // <figcaption>alternative text</figcaption>
})
mit.use(mdlinks)
export default (props: { body: string }) => {
const body = createMemo(() => (props.body.startsWith('<') ? props.body : mit.render(props.body)))
return <div innerHTML={body()} />
}

View File

@ -64,7 +64,7 @@ export const AuthorBadge = (props: Props) => {
return isSubscribing() ? t('subscribing...') : t('Subscribe')
})
const unsubscribeValue = () => {
const unsubscribeValue = createMemo(() => {
if (props.iconButtons) {
return <Icon name="author-unsubscribe" class={stylesButton.icon} />
}
@ -75,7 +75,7 @@ export const AuthorBadge = (props: Props) => {
<span class={styles.actionButtonLabelHovered}>{t('Unfollow')}</span>
</>
)
}
})
return (
<div class={clsx(styles.AuthorBadge, { [styles.nameOnly]: props.nameOnly })}>

View File

@ -97,20 +97,22 @@ export const AuthorCard = (props: Props) => {
}
})
const followButtonText = () => {
const followButtonText = createMemo(() => {
if (isSubscribing()) {
return t('subscribing...')
} else if (subscribed()) {
}
if (subscribed()) {
return (
<>
<span class={stylesButton.buttonSubscribeLabel}>{t('Following')}</span>
<span class={stylesButton.buttonSubscribeLabelHovered}>{t('Unfollow')}</span>
</>
)
} else {
return t('Follow')
}
}
return t('Follow')
})
return (
<div class={clsx(styles.author, 'row')}>

View File

@ -1,9 +1,8 @@
import { createEffect, createSignal, Show } from 'solid-js'
import type { Editor, JSONContent } from '@tiptap/core'
import type { Editor } from '@tiptap/core'
import { Icon } from '../../_shared/Icon'
import { InlineForm } from '../InlineForm'
import styles from './EditorFloatingMenu.module.scss'
import HTMLParser from 'html-to-json-parser'
import { useLocalize } from '../../../context/localize'
import { Modal } from '../../Nav/Modal'
import { Menu } from './Menu'
@ -20,10 +19,17 @@ type FloatingMenuProps = {
}
const embedData = async (data) => {
const result = (await HTMLParser(data, false)) as JSONContent
if ('type' in result && result.type === 'iframe') {
return result.attributes
const element = document.createRange().createContextualFragment(data)
const { attributes } = element.firstChild as HTMLIFrameElement
const result: { src: string } = { src: '' }
for (let i = 0; i < attributes.length; i++) {
const attribute = attributes[i]
result[attribute.name] = attribute.value
}
return result
}
export const EditorFloatingMenu = (props: FloatingMenuProps) => {
@ -39,8 +45,8 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
}
const validateEmbed = async (value) => {
const iframeData = (await HTMLParser(value, false)) as JSONContent
if (iframeData.type !== 'iframe') {
const element = document.createRange().createContextualFragment(value)
if (element.firstChild?.nodeName !== 'IFRAME') {
return t('Error')
}
}

View File

@ -24,6 +24,7 @@ import { apiClient } from '../../../utils/apiClient'
import { RANDOM_TOPICS_COUNT } from '../../Views/Home'
import { Link } from './Link'
import { Subscribe } from '../../_shared/Subscribe'
import { ShowOnlyOnClient } from '../../_shared/ShowOnlyOnClient'
type Props = {
title?: string
@ -527,8 +528,9 @@ export const Header = (props: Props) => {
</ul>
</div>
</nav>
<Snackbar />
<ShowOnlyOnClient>
<Snackbar />
</ShowOnlyOnClient>
</div>
</header>
)

View File

@ -9,7 +9,7 @@ import { PAGE_SIZE, useNotifications } from '../../context/notifications'
import { NotificationView } from './NotificationView'
import { EmptyMessage } from './EmptyMessage'
import { Button } from '../_shared/Button'
import throttle from 'just-throttle'
import { throttle } from 'throttle-debounce'
import { useSession } from '../../context/session'
type Props = {
@ -132,7 +132,7 @@ export const NotificationsPanel = (props: Props) => {
setIsLoading(false)
}
}
const handleScrollThrottled = throttle(handleScroll, 50)
const handleScrollThrottled = throttle(50, handleScroll)
onMount(() => {
scrollContainerRef.current.addEventListener('scroll', handleScrollThrottled)

View File

@ -2,11 +2,10 @@ import { For, Show, createSignal, createEffect, on, onMount, onCleanup } from 's
import { clsx } from 'clsx'
import { DEFAULT_HEADER_OFFSET } from '../../stores/router'
import { useLocalize } from '../../context/localize'
import debounce from 'debounce'
import { Icon } from '../_shared/Icon'
import styles from './TableOfContents.module.scss'
import { isDesktop } from '../../utils/media-query'
import throttle from 'just-throttle'
import { throttle, debounce } from 'throttle-debounce'
interface Props {
variant: 'article' | 'editor'
@ -49,12 +48,12 @@ export const TableOfContents = (props: Props) => {
setAreHeadingsLoaded(true)
}
const debouncedUpdateHeadings = debounce(updateHeadings, 500)
const debouncedUpdateHeadings = debounce(500, updateHeadings)
const updateActiveHeader = throttle(() => {
const updateActiveHeader = throttle(50, () => {
const newActiveIndex = headings().findLastIndex((heading) => isInViewport(heading))
setActiveHeaderIndex(newActiveIndex)
}, 50)
})
createEffect(
on(

View File

@ -40,8 +40,10 @@
width: 54px;
height: 54px;
padding: 16px;
&:hover {
background: var(--background-color-invert);
img {
filter: invert(1);
}

View File

@ -1,6 +1,6 @@
import { createSignal, For, Show } from 'solid-js'
import { For, onMount, Show } from 'solid-js'
import { Icon } from '../Icon'
import { register } from 'swiper/element/bundle'
import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper'
import { SwiperRef } from './swiper'
import { clsx } from 'clsx'
@ -13,19 +13,13 @@ type Props = {
title?: string
}
register()
SwiperCore.use([Pagination, Navigation, Manipulation])
export const ArticleCardSwiper = (props: Props) => {
const [slideIndex, setSlideIndex] = createSignal(0)
const mainSwipeRef: { current: SwiperRef } = { current: null }
const handleSlideChange = () => {
setSlideIndex(mainSwipeRef.current.swiper.activeIndex)
}
onMount(async () => {
const { register } = await import('swiper/element/bundle')
register()
SwiperCore.use([Pagination, Navigation, Manipulation])
})
return (
<div class={clsx(styles.Swiper, styles.articleMode, styles.ArticleCardSwiper)}>
<Show when={props.title}>
@ -38,7 +32,6 @@ export const ArticleCardSwiper = (props: Props) => {
ref={(el) => (mainSwipeRef.current = el)}
centered-slides={true}
observer={true}
onSlideChange={handleSlideChange}
space-between={20}
breakpoints={{
576: { spaceBetween: 20, slidesPerView: 1.5 },

View File

@ -1,9 +1,8 @@
import { createEffect, createSignal, For, Show, on } from 'solid-js'
import { createEffect, createSignal, For, Show, on, onMount } from 'solid-js'
import { MediaItem, UploadedFile } from '../../../pages/types'
import { Icon } from '../Icon'
import { Popover } from '../Popover'
import { useLocalize } from '../../../context/localize'
import { register } from 'swiper/element/bundle'
import { DropArea } from '../DropArea'
import { createFileUploader } from '@solid-primitives/upload'
import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper'
@ -28,10 +27,6 @@ type Props = {
onImageChange?: (index: number, value: MediaItem) => void
}
register()
SwiperCore.use([Pagination, Navigation, Manipulation])
export const ImageSwiper = (props: Props) => {
const { t } = useLocalize()
const [loading, setLoading] = createSignal(false)
@ -139,6 +134,12 @@ export const ImageSwiper = (props: Props) => {
handleSlideDescriptionChange(slideIndex(), 'body', slideBody())
}
onMount(async () => {
const { register } = await import('swiper/element/bundle')
register()
SwiperCore.use([Pagination, Navigation, Manipulation])
})
return (
<div class={clsx(styles.Swiper, props.editorMode ? styles.editorMode : styles.articleMode)}>
<div class={styles.container}>

View File

@ -38,8 +38,8 @@
}
.container {
margin: auto;
// max-width: 800px;
margin: auto;
position: relative;
padding: 24px 0;
display: flex;
@ -177,12 +177,12 @@
}
&.prev {
background-image: linear-gradient(to right, #000, rgb(0 0 0 / 0));
background-image: linear-gradient(to right, #000, rgb(0 0 0 / 0%));
left: 0;
}
&.next {
background-image: linear-gradient(to left, #000, rgb(0 0 0 / 0));
background-image: linear-gradient(to left, #000, rgb(0 0 0 / 0%));
justify-content: end;
right: 0;
}
@ -239,11 +239,11 @@
height: auto;
&.prev {
left: -var(--navigation-reserve);
left: calc(0px - var(--navigation-reserve));
}
&.next {
right: -var(--navigation-reserve);
right: calc(0px - var(--navigation-reserve));
}
}

View File

@ -11,7 +11,6 @@ import { useSession } from '../../context/session'
import FloatingPanel from '../../components/_shared/FloatingPanel/FloatingPanel'
import { useSnackbar } from '../../context/snackbar'
import { useLocalize } from '../../context/localize'
import { Userpic } from '../../components/Author/Userpic'
import { createStore } from 'solid-js/store'
import { clone } from '../../utils/clone'
import SimplifiedEditor from '../../components/Editor/SimplifiedEditor'

View File

@ -2,7 +2,7 @@
"rewrites": [
{
"source": "/((?!assets/).*)",
"destination": "/api/ssr.mjs"
"destination": "/api/edge-ssr.js"
}
]
}