diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index f68ab0b..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,37 +0,0 @@ -module.exports = { - root: true, - ignorePatterns: 'dist/**', - overrides: [ - { - files: ['**/*.js', '**/*.jsx'], - extends: [ - 'sukka/node' - ], - env: { - es6: true - }, - parserOptions: { - ecmaVersion: 2021 - }, - rules: { - 'node/no-unpublished-require': 'off', - 'linebreak-style': ['error', process.platform === 'win32' ? 'win32' : 'unix'] - } - }, - { - files: ['**/*.ts', '**/*.tsx'], - extends: [ - 'sukka/react', - 'sukka/typescript' - ], - plugins: [ - 'react-hooks' - ], - parserOptions: { - project: [ - './tsconfig.json' - ] - } - } - ] -}; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..b0e16c5 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('eslint-config-sukka').sukka(); diff --git a/example/.nolluprc.js b/example/.nolluprc.js index aacf6f3..7f9432c 100644 --- a/example/.nolluprc.js +++ b/example/.nolluprc.js @@ -1,5 +1,5 @@ module.exports = { - contentBase: './example/public', - port: 9001, - hot: true + contentBase: './example/public', + port: 9001, + hot: true }; diff --git a/package.json b/package.json index 7399d2b..e30dfeb 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,20 @@ "name": "disqusjs", "version": "3.0.3-canary.1", "description": "Alternative DISQUS - Render comments components from Disqus API", + "homepage": "https://disqusjs.skk.moe", + "repository": { + "type": "git", + "url": "git+https://github.com/SukkaW/disqusjs.git" + }, + "bugs": { + "url": "https://github.com/SukkaW/disqusjs/issues" + }, "main": "dist/disqusjs.es2015.umd.js", - "types": "dist/disqusjs.es2015.umd.d.ts", "module": "dist/disqusjs.es2015.es.mjs", + "types": "dist/disqusjs.es2015.umd.d.ts", "files": [ - "dist/**/*", - "LICENSE" + "LICENSE", + "dist/**/*" ], "exports": { "./dist/": "./dist/", @@ -15,56 +23,56 @@ "./styles/disqusjs.css": "./dist/styles/disqusjs.css", ".": { "types": "./dist/disqusjs.es2015.umd.d.ts", - "module": "./dist/disqusjs.es2015.es.js", "import": "./dist/disqusjs.es2015.es.mjs", + "module": "./dist/disqusjs.es2015.es.js", "default": "./dist/disqusjs.es2015.umd.js" }, "./es2015": { "types": "./dist/disqusjs.es2015.umd.d.ts", - "module": "./dist/disqusjs.es2015.es.js", "import": "./dist/disqusjs.es2015.es.mjs", + "module": "./dist/disqusjs.es2015.es.js", "default": "./dist/disqusjs.es2015.umd.js" }, "./es2017": { "types": "./dist/disqusjs.es2017.umd.d.ts", - "module": "./dist/disqusjs.es2017.es.js", "import": "./dist/disqusjs.es2017.es.mjs", + "module": "./dist/disqusjs.es2017.es.js", "default": "./dist/disqusjs.es2017.umd.js" }, "./es2022": { "types": "./dist/disqusjs.es2022.umd.d.ts", - "module": "./dist/disqusjs.es2022.es.js", "import": "./dist/disqusjs.es2022.es.mjs", + "module": "./dist/disqusjs.es2022.es.js", "default": "./dist/disqusjs.es2022.umd.js" }, "./react/styles/disqusjs.css": "./dist/react/styles/disqusjs.css", "./react": { "types": "./dist/react/disqusjs.es2015.cjs.d.ts", - "module": "./dist/react/disqusjs.es2015.es.js", "import": "./dist/react/disqusjs.es2015.es.mjs", + "module": "./dist/react/disqusjs.es2015.es.js", "default": "./dist/react/disqusjs.es2015.cjs.js" }, "./react/es2015": { "types": "./dist/react/disqusjs.es2015.cjs.d.ts", - "module": "./dist/react/disqusjs.es2015.es.js", "import": "./dist/react/disqusjs.es2015.es.mjs", + "module": "./dist/react/disqusjs.es2015.es.js", "default": "./dist/react/disqusjs.es2015.cjs.js" }, "./react/es2017": { "types": "./dist/react/disqusjs.es2017.cjs.d.ts", - "module": "./dist/react/disqusjs.es2017.es.js", "import": "./dist/react/disqusjs.es2017.es.mjs", + "module": "./dist/react/disqusjs.es2017.es.js", "default": "./dist/react/disqusjs.es2017.cjs.js" }, "./react/es2022": { "types": "./dist/react/disqusjs.es2022.cjs.d.ts", - "module": "./dist/react/disqusjs.es2022.es.js", "import": "./dist/react/disqusjs.es2022.es.mjs", + "module": "./dist/react/disqusjs.es2022.es.js", "default": "./dist/react/disqusjs.es2022.cjs.js" }, "./browser": { - "module": "./dist/browser/disqusjs.es2018.es.min.js", "import": "./dist/browser/disqusjs.es2018.es.min.mjs", + "module": "./dist/browser/disqusjs.es2018.es.min.js", "default": "./dist/browser/disqusjs.es2015.umd.min.js" } }, @@ -75,11 +83,8 @@ "prepublishOnly": "npm run build", "prebuild:analyze": "rimraf dist", "build:analyze": "cross-env NODE_ENV=production ANALYZE=true rollup --configPlugin swc3 -c rollup.config.ts", - "dev": "nollup -c ./example/rollup.config.js --rc ./example/.nolluprc.js --environment NODE_ENV:development" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/SukkaW/disqusjs.git" + "dev": "nollup -c ./example/rollup.config.js --rc ./example/.nolluprc.js --environment NODE_ENV:development", + "lint": "eslint --format=sukka ." }, "keywords": [ "Disqus", @@ -90,63 +95,58 @@ ], "author": "Sukka ", "license": "MIT", - "bugs": { - "url": "https://github.com/SukkaW/disqusjs/issues" - }, - "homepage": "https://disqusjs.skk.moe", - "peerDependencies": { - "preact": "^10.7.1", - "react": "^16.11.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "preact": { - "optional": true - } + "dependencies": { + "foxact": "^0.2.26" }, "devDependencies": { - "@rollup/plugin-alias": "^5.0.0", - "@rollup/plugin-commonjs": "^25.0.4", - "@rollup/plugin-node-resolve": "^15.1.0", - "@rollup/plugin-replace": "^5.0.2", - "@swc/core": "^1.3.74", - "@swc/helpers": "^0.5.1", - "@types/node": "^18.17.5", - "@types/react": "^18.2.20", - "@types/react-dom": "^18.2.7", - "@typescript-eslint/eslint-plugin": "^6.3.0", - "@typescript-eslint/parser": "^6.3.0", + "@eslint-sukka/node": "^4.1.7", + "@eslint-sukka/react": "^4.1.7", + "@eslint-sukka/ts": "^4.1.7", + "@rollup/plugin-alias": "^5.0.1", + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^5.0.5", + "@swc/core": "^1.3.96", + "@swc/helpers": "^0.5.3", + "@types/node": "^20.9.0", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", "cross-env": "^7.0.3", - "eslint": "^8.47.0", - "eslint-config-sukka": "^3.0.4", - "eslint-import-resolver-typescript": "^3.6.0", - "eslint-plugin-import": "npm:eslint-plugin-i@^2.28.0-2", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.6.0", + "eslint": "^8.53.0", + "eslint-config-sukka": "^4.1.7", + "eslint-formatter-sukka": "^4.1.7", "nollup": "^0.21.0", - "preact": "^10.16.0", + "preact": "^10.19.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-refresh": "^0.9.0", - "rimraf": "^5.0.1", - "rollup": "^3.28.0", + "rimraf": "^5.0.5", + "rollup": "^4.4.0", "rollup-plugin-bundle-analyzer": "^1.6.6", "rollup-plugin-commonjs-alternate": "^0.8.0", - "rollup-plugin-dts": "^5.3.1", + "rollup-plugin-dts": "^6.1.0", "rollup-plugin-hot-css": "^0.7.2", "rollup-plugin-postcss": "^4.0.2", "rollup-plugin-react-refresh": "^0.0.3", "rollup-plugin-static-files": "^0.2.0", - "rollup-plugin-swc3": "^0.9.1", - "sass": "^1.65.1" + "rollup-plugin-swc3": "^0.10.3", + "sass": "^1.69.5" }, - "dependencies": { - "eslint-plugin-n": "^16.0.1", - "foxact": "^0.2.20" + "peerDependencies": { + "preact": "^10.7.1", + "react": "^16.11.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "preact": { + "optional": true + } }, "overrides": { + "rollup": "$rollup", + "eslint-plugin-import": "npm:eslint-plugin-i@latest", "function-bind": "npm:@nolyfill/function-bind@latest", "has": "npm:@nolyfill/has@latest", "has-proto": "npm:@nolyfill/has-proto@latest", @@ -161,6 +161,7 @@ "object.fromentries": "npm:@nolyfill/object.fromentries@latest", "object.hasown": "npm:@nolyfill/object.hasown@latest", "object.values": "npm:@nolyfill/object.values@latest", - "string.prototype.matchall": "npm:@nolyfill/string.prototype.matchall@latest" + "string.prototype.matchall": "npm:@nolyfill/string.prototype.matchall@latest", + "side-channel": "npm:@nolyfill/side-channel@latest" } } diff --git a/rollup.config.ts b/rollup.config.ts index 8bba813..0df365e 100644 --- a/rollup.config.ts +++ b/rollup.config.ts @@ -246,14 +246,13 @@ function stringHash(str: string) { let i = str.length; while (i) { - // eslint-disable-next-line no-bitwise -- performance hash = (hash * 33) ^ str.charCodeAt(--i); } /* JavaScript does bitwise operations (like XOR, above) on 32-bit signed * integers. Since we want the results to be always positive, convert the * signed int to an unsigned by doing an unsigned bitshift. */ - // eslint-disable-next-line no-bitwise -- performance + return hash >>> 0; } diff --git a/src/components/CommentList.tsx b/src/components/CommentList.tsx index a5ba027..44646f9 100644 --- a/src/components/CommentList.tsx +++ b/src/components/CommentList.tsx @@ -47,7 +47,7 @@ function DisqusJSPostItem({ comment, children, nesting }: DisqusJSCommentASTItem ) } {' '} - + {' '} { comment.createdAt && ( @@ -64,7 +64,7 @@ function DisqusJSPostItem({ comment, children, nesting }: DisqusJSCommentASTItem } - + {children} {comment.hasMore &&

切换至 完整 Disqus 模式 显示更多回复

} ); diff --git a/src/components/Disqus.tsx b/src/components/Disqus.tsx index 2ae986d..fb7ed88 100644 --- a/src/components/Disqus.tsx +++ b/src/components/Disqus.tsx @@ -69,6 +69,7 @@ export const Disqus = memo(({ } const getDisqusConfig = () => { + /* eslint-disable react/no-this-in-sfc -- "this" refers to Disqus config object */ return function (this: any) { if (identifier) { this.page.identifier = identifier; @@ -85,6 +86,7 @@ export const Disqus = memo(({ } ]; }; + /* eslint-enable react/no-this-in-sfc */ }; if (window.DISQUS && document.getElementById(EMBED_SCRIPT_ID)) { diff --git a/src/components/Disscussion.tsx b/src/components/Disscussion.tsx index a18443c..696ee45 100644 --- a/src/components/Disscussion.tsx +++ b/src/components/Disscussion.tsx @@ -25,18 +25,20 @@ const DisqusJSSortTypeRadio = ({ title, label }: DisqusJSSortTypeRadioProps) => { - return <> - - - ; + return ( + <> + + + + ); }; const DisqusJSSortTypeRadioGroup = memo(() => { @@ -169,7 +171,7 @@ const DisqusJSPosts = ({ id }: { id: string }) => { } }, [posts, resetAndFetchFirstPageOfPosts, id, isLoadingMorePosts, sortType]); - const comments = useMemo(() => posts.filter(Boolean).map(i => i.response).flat(), [posts]); + const comments = useMemo(() => posts.filter(Boolean).flatMap(i => i.response), [posts]); if (posts.length > 0) { return ( @@ -262,8 +264,7 @@ export const DisqusJSThread = () => { {totalComments === 0 ? - : - } + : } ); }; diff --git a/src/components/Error.tsx b/src/components/Error.tsx index ccd771c..86f3df1 100644 --- a/src/components/Error.tsx +++ b/src/components/Error.tsx @@ -3,11 +3,11 @@ import { DisqusJSForceDisqusModeButton, DisqusJSReTestModeButton, DisqusJSRetryB export const DisqusJSError = memo(() => (
- 评论基础模式加载失败,请 + 评论基础模式加载失败,请 {' '} 重载 {' '} - 或 + 或 {' '} 尝试完整 Disqus 模式
@@ -15,10 +15,10 @@ export const DisqusJSError = memo(() => ( export const DisqusJSCreateThread = memo(() => (
- 当前 Thread 尚未创建。是否切换至 + 当前 Thread 尚未创建。是否切换至 {' '} 完整 Disqus 模式 - ? + ?
)); diff --git a/src/index.tsx b/src/index.tsx index af057e3..736c471 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -35,23 +35,26 @@ export const DisqusJS = forwardRef(({ return (
, - , - , - , - + , + , + , + , + ]}>
diff --git a/src/lib/util.ts b/src/lib/util.ts index 67e364b..735674d 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -1,5 +1,4 @@ export function randomInt(min: number, max: number): number { - // eslint-disable-next-line no-bitwise -- performance return (Math.random() * (max - min + 1) + min) | 0; } @@ -15,8 +14,8 @@ let domParser: DOMParser | null = null; export const processCommentMessage = (str: string) => { const rawHtml = str - .replace(/a\.disquscdn\.com/g, 'c.disquscdn.com') - .replace(/https?:\/\/disq.us\/url\?url=(.+)%3A[\w-]+&cuid=\d+/gm, (_, $1: string) => decodeURIComponent($1)); + .replaceAll('a.disquscdn.com', 'c.disquscdn.com') + .replaceAll(/https?:\/\/disq.us\/url\?url=(.+)%3A[\w-]+&cuid=\d+/gm, (_, $1: string) => decodeURIComponent($1)); domParser ||= new DOMParser(); const doc = domParser.parseFromString(rawHtml, 'text/html'); @@ -42,29 +41,32 @@ export const checkDomainAccessiblity = (domain: string) => { return new Promise((resolve, reject) => { const img = new Image(); - const clear = () => { - img.onload = null; - img.onerror = null; - img.remove(); - }; - const timeout = setTimeout(() => { clear(); reject(); }, 3000); - img.onerror = () => { + function handleLoad() { clearTimeout(timeout); clear(); - reject(); - }; + resolve(); + } - img.onload = () => { + function handleError() { clearTimeout(timeout); clear(); - resolve(); - }; + reject(); + } + + function clear() { + img.removeEventListener('load', handleLoad); + img.removeEventListener('error', handleError); + img.remove(); + } + + img.addEventListener('error', handleError); + img.addEventListener('load', handleLoad); - img.src = `https://${domain}/favicon.ico?${+(new Date())}=${+(new Date())}`; + img.src = `https://${domain}/favicon.ico?${Date.now()}=${Date.now()}`; }); }; diff --git a/src/types.ts b/src/types.ts index fdead9e..844a1e9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -38,12 +38,12 @@ export namespace DisqusAPI { } export interface Thread extends Response { - response: { + response: Array<{ id: string, isClosed: boolean, posts: number, likes: number - }[] + }> } export interface Post { diff --git a/tsconfig.json b/tsconfig.json index 4ae0bde..8b24908 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,16 +2,16 @@ "compilerOptions": { "target": "es2018", "lib": ["esnext", "dom"], + "jsx": "react-jsx", + "jsxImportSource": "react", "module": "commonjs", - "declaration": true, "moduleResolution": "node", + "resolveJsonModule": false, + "declaration": true, "outDir": "./dist", - "strict": true, - "jsx":"react-jsx", - "jsxImportSource": "react", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, - "resolveJsonModule": false + "strict": true }, "include": ["src/**/*", "example/**/*", "rollup.config.ts"], "exclude": ["dist/**/*", "node_modules/**/*"]