mirror of https://github.com/fantasticit/think.git
refactor: lint code
This commit is contained in:
parent
1dac849b61
commit
76cdcff589
|
@ -0,0 +1,6 @@
|
|||
node_modules
|
||||
**/.next/**
|
||||
**/_next/**
|
||||
**/dist/**
|
||||
./packages/client/src/tiptap/next.config.js
|
||||
./packages/client/src/tiptap/wrappers/mind/mind-elixir/iconfont/iconfont.js
|
|
@ -0,0 +1,47 @@
|
|||
module.exports = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
ecmaVersion: 8,
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
impliedStrict: true,
|
||||
experimentalObjectRestSpread: true,
|
||||
},
|
||||
allowImportExportEverywhere: true,
|
||||
project: ['./packages/client/tsconfig.json'],
|
||||
},
|
||||
plugins: ['@typescript-eslint', 'react-hooks'],
|
||||
extends: ['eslint:recommended', 'plugin:react/recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
env: {
|
||||
es6: true,
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
rules: {
|
||||
'func-names': 0,
|
||||
'no-shadow': 0,
|
||||
'@typescript-eslint/no-shadow': 0,
|
||||
'@typescript-eslint/explicit-function-return-type': 0,
|
||||
'@typescript-eslint/no-unused-vars': [0, { argsIgnorePattern: '^_' }],
|
||||
'@typescript-eslint/no-use-before-define': 0,
|
||||
'@typescript-eslint/ban-ts-ignore': 0,
|
||||
'@typescript-eslint/no-empty-function': 0,
|
||||
'@typescript-eslint/ban-ts-comment': 0,
|
||||
'@typescript-eslint/no-var-requires': 0,
|
||||
'@typescript-eslint/no-explicit-any': 0,
|
||||
'@typescript-eslint/no-this-alias': 0,
|
||||
'@typescript-eslint/explicit-module-boundary-types': 0,
|
||||
'@typescript-eslint/ban-types': 0,
|
||||
'react-hooks/rules-of-hooks': 2,
|
||||
'react-hooks/exhaustive-deps': 1,
|
||||
'react/prop-types': 0,
|
||||
'testing-library/no-unnecessary-act': 0,
|
||||
'react/react-in-jsx-scope': 0,
|
||||
},
|
||||
ignorePatterns: ['dist/', 'node_modules', 'scripts', 'examples'],
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
module.exports = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: './packages/server/tsconfig.json',
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['@typescript-eslint/eslint-plugin'],
|
||||
extends: ['plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
|
||||
root: true,
|
||||
env: {
|
||||
node: true,
|
||||
jest: true,
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/interface-name-prefix': 'off',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
},
|
||||
};
|
14
package.json
14
package.json
|
@ -20,8 +20,10 @@
|
|||
"pm2": "pnpm run pm2:server && pnpm run pm2:client",
|
||||
"pm2:server": "pnpm run --dir packages/server pm2",
|
||||
"pm2:client": "pnpm run --dir packages/client pm2",
|
||||
"lint:client": "eslint --fix './packages/client/**/*.{ts,tsx,js,jsx}' -c '.eslintrc.client.js'",
|
||||
"lint:server": "eslint --fix './packages/server/src/*.{ts,js}' -c '.eslintrc.server.js'",
|
||||
"format": "concurrently \"pnpm:format:*\"",
|
||||
"format:ts": "prettier --write --parser typescript \"git status\"",
|
||||
"format:ts": "prettier --write --parser typescript \"packages/**/*.{ts,tsx,js,jsx}\"",
|
||||
"format:css": "stylelint --fix --formatter verbose --allow-empty-input \"packages/**/*.{css,scss,sass}\"",
|
||||
"prepare": "husky install",
|
||||
"precommit": "lint-staged"
|
||||
|
@ -36,6 +38,16 @@
|
|||
"node": ">=16.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.21.0",
|
||||
"@typescript-eslint/parser": "^5.21.0",
|
||||
"eslint": "^8.14.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.29.4",
|
||||
"eslint-plugin-react-hooks": "^4.5.0",
|
||||
"eslint-plugin-simple-import-sort": "^7.0.0",
|
||||
"husky": "^7.0.4",
|
||||
"lint-staged": "^12.4.1",
|
||||
"prettier": "^2.3.2",
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
const semi = require('@douyinfe/semi-next').default({});
|
||||
/* eslint-disable */
|
||||
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
|
||||
const { getConfig } = require('@think/config');
|
||||
const config = getConfig();
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = semi({
|
||||
const nextConfig = require('@douyinfe/semi-next').default({})({
|
||||
assetPrefix: config.assetPrefix,
|
||||
env: {
|
||||
SERVER_API_URL: config?.client?.apiUrl,
|
||||
|
|
|
@ -22,7 +22,7 @@ export const Banner: React.FC<IProps> = ({ type, description, duration = 0 }) =>
|
|||
return () => {
|
||||
clearTimeout(timer.current);
|
||||
};
|
||||
}, [duration]);
|
||||
}, [duration, toggleVisible]);
|
||||
|
||||
if (!visible) return null;
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ const defaultEmpty = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const runRender = (fn, ...args) => (typeof fn === 'function' ? fn.apply(null, args) : fn);
|
||||
const runRender = (fn, ...args) => (typeof fn === 'function' ? fn(...args) : fn);
|
||||
|
||||
export const DataRender: React.FC<IProps> = ({
|
||||
loading,
|
||||
|
|
|
@ -28,7 +28,7 @@ export const LoadingWrap: React.FC<IProps> = ({ loading, delay = 200, loadingCon
|
|||
return () => {
|
||||
clearTimeout(timer.current);
|
||||
};
|
||||
}, [delay, loading]);
|
||||
}, [delay, loading, toggleShowLoading]);
|
||||
|
||||
if (loading) {
|
||||
return showLoading ? loadingContent : null;
|
||||
|
|
|
@ -31,6 +31,7 @@ interface IProps {
|
|||
const { Paragraph } = Typography;
|
||||
const { Column } = Table;
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
const renderChecked = (onChange, authKey: 'readable' | 'editable') => (checked, docAuth) => {
|
||||
const handle = (evt) => {
|
||||
const data = {
|
||||
|
@ -67,8 +68,8 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId })
|
|||
};
|
||||
|
||||
useEffect(() => {
|
||||
const handler = (users) => {
|
||||
const newCollaborationUsers = users
|
||||
const handler = (mentionUsers) => {
|
||||
const newCollaborationUsers = mentionUsers
|
||||
.filter(Boolean)
|
||||
.filter((state) => state.user)
|
||||
.map((state) => ({ ...state.user, clientId: state.clientId }));
|
||||
|
@ -90,6 +91,7 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId })
|
|||
|
||||
setCollaborationUsers(newCollaborationUsers);
|
||||
};
|
||||
|
||||
event.on(JOIN_USER, handler);
|
||||
|
||||
return () => {
|
||||
|
|
|
@ -16,10 +16,11 @@ interface IProps {
|
|||
const { Text } = Typography;
|
||||
|
||||
export const CommentItem: React.FC<IProps> = ({ comment, replyComment, editComment, deleteComment }) => {
|
||||
if (!comment) return null;
|
||||
const { user } = useUser();
|
||||
const { createUser = {} } = comment;
|
||||
|
||||
if (!comment) return null;
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
<div className={styles.leftWrap}>
|
||||
|
|
|
@ -33,7 +33,7 @@ export const DocumentDeletor: React.FC<IProps> = ({ wikiId, documentId, onDelete
|
|||
okButtonProps: { loading, type: 'danger' },
|
||||
style: { maxWidth: '96vw' },
|
||||
});
|
||||
}, [wikiId, documentId, api, loading, onDelete]);
|
||||
}, [wikiId, api, loading, onDelete]);
|
||||
|
||||
return (
|
||||
<Text type="danger" onClick={deleteAction}>
|
||||
|
|
|
@ -15,6 +15,7 @@ interface IProps {
|
|||
const { Text } = Typography;
|
||||
const { Column } = Table;
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
const renderChecked = (onChange, authKey: 'readable' | 'editable') => (checked, data) => {
|
||||
const handle = (evt) => {
|
||||
const ret = {
|
||||
|
|
|
@ -27,8 +27,6 @@ interface IProps {
|
|||
}
|
||||
|
||||
export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
|
||||
if (!documentId) return null;
|
||||
|
||||
const [container, setContainer] = useState<HTMLDivElement>();
|
||||
const { width: windowWidth } = useWindowSize();
|
||||
const { width, fontSize } = useDocumentStyle();
|
||||
|
@ -43,6 +41,8 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
|
|||
Router.push(`/wiki/${document.wikiId}/document/${document.id}/edit`);
|
||||
}, [document]);
|
||||
|
||||
if (!documentId) return null;
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
<Header className={styles.headerWrap}>
|
||||
|
|
|
@ -12,7 +12,7 @@ interface IProps {
|
|||
|
||||
export const DocumentContent: React.FC<IProps> = ({ document, createUserContainerSelector }) => {
|
||||
const c = safeJSONParse(document.content);
|
||||
let json = c.default || c;
|
||||
const json = c.default || c;
|
||||
|
||||
const editor = useEditor({
|
||||
editable: false,
|
||||
|
|
|
@ -37,8 +37,6 @@ interface IProps {
|
|||
}
|
||||
|
||||
export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo = true }) => {
|
||||
if (!documentId) return null;
|
||||
|
||||
const { data, loading, error, query } = usePublicDocument(documentId);
|
||||
const { width, fontSize } = useDocumentStyle();
|
||||
const editorWrapClassNames = useMemo(() => {
|
||||
|
@ -72,6 +70,8 @@ export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo =
|
|||
});
|
||||
}, [error, query]);
|
||||
|
||||
if (!documentId) return null;
|
||||
|
||||
return (
|
||||
<Layout className={styles.wrap}>
|
||||
<Header className={styles.headerWrap}>
|
||||
|
|
|
@ -32,7 +32,7 @@ export const DocumentVersion: React.FC<IProps> = ({ documentId, onSelect }) => {
|
|||
const close = useCallback(() => {
|
||||
toggleVisible(false);
|
||||
setSelectedVersion(null);
|
||||
}, []);
|
||||
}, [toggleVisible]);
|
||||
|
||||
const select = useCallback(
|
||||
(version) => {
|
||||
|
@ -46,20 +46,20 @@ export const DocumentVersion: React.FC<IProps> = ({ documentId, onSelect }) => {
|
|||
if (!selectedVersion || !onSelect) return;
|
||||
onSelect(safeJSONParse(selectedVersion.data, { default: {} }).default);
|
||||
close();
|
||||
}, [selectedVersion]);
|
||||
}, [selectedVersion, close, onSelect]);
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
refresh();
|
||||
}
|
||||
}, [visible]);
|
||||
}, [visible, refresh]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!editor) return;
|
||||
if (!data.length) return;
|
||||
if (selectedVersion) return;
|
||||
select(data[0]);
|
||||
}, [editor, data, selectedVersion]);
|
||||
}, [editor, data, selectedVersion, select]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -60,15 +60,12 @@ export const GridSelect = ({
|
|||
[onSelect]
|
||||
);
|
||||
|
||||
const onHover = useCallback(
|
||||
debounce(({ x, y, isCellDisabled }) => {
|
||||
if (isCellDisabled) {
|
||||
return setHoverCell(null);
|
||||
}
|
||||
setHoverCell({ x, y });
|
||||
}, 5),
|
||||
[disabled]
|
||||
);
|
||||
const onHover = useCallback(({ x, y, isCellDisabled }) => {
|
||||
if (isCellDisabled) {
|
||||
return setHoverCell(null);
|
||||
}
|
||||
setHoverCell({ x, y });
|
||||
}, []);
|
||||
|
||||
const cells = useMemo(() => {
|
||||
const cells = [];
|
||||
|
|
|
@ -40,7 +40,7 @@ const MessagesRender = ({ messageData, loading, error, onClick = null, page = 1,
|
|||
<>
|
||||
{messages.map((msg) => {
|
||||
return (
|
||||
<div className={styles.itemWrap} onClick={() => handleRead(msg.id)}>
|
||||
<div key={msg.id} className={styles.itemWrap} onClick={() => handleRead(msg.id)}>
|
||||
<Link href={msg.url}>
|
||||
<a className={styles.item}>
|
||||
<div className={styles.leftWrap}>
|
||||
|
@ -140,7 +140,7 @@ const MessageBox = () => {
|
|||
readMessage(msg.id);
|
||||
},
|
||||
});
|
||||
}, [unreadMsgs]);
|
||||
}, [unreadMsgs, readMessage]);
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
|
|
|
@ -112,7 +112,7 @@ export const Resizeable: React.FC<IProps> = ({
|
|||
},
|
||||
},
|
||||
});
|
||||
}, [maxWidth, isEditable]);
|
||||
}, [maxWidth, isEditable, onChange, onChangeEnd]);
|
||||
|
||||
useEffect(() => {
|
||||
Object.assign($container.current.style, {
|
||||
|
|
|
@ -40,7 +40,6 @@ interface IProps {
|
|||
}
|
||||
|
||||
export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTemplate, deleteTemplate }) => {
|
||||
if (!user) return null;
|
||||
const { width: windowWidth } = useWindowSize();
|
||||
const [title, setTitle] = useState(data.title);
|
||||
const provider = useMemo(() => {
|
||||
|
@ -51,7 +50,7 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
|
|||
user,
|
||||
docType: 'template',
|
||||
});
|
||||
}, [data, user.token]);
|
||||
}, [data, user]);
|
||||
const editor = useEditor({
|
||||
editable: true,
|
||||
extensions: [...BaseKit, DocumentWithTitle, getCollaborationExtension(provider)],
|
||||
|
@ -59,7 +58,9 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
|
|||
try {
|
||||
const title = transaction.doc.content.firstChild.content.firstChild.textContent;
|
||||
setTitle(title);
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
},
|
||||
});
|
||||
const [isPublic, setPublic] = useState(false);
|
||||
|
@ -76,7 +77,7 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
|
|||
deleteTemplate().then(() => {
|
||||
goback();
|
||||
});
|
||||
}, [deleteTemplate]);
|
||||
}, [deleteTemplate, goback]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!data) return;
|
||||
|
@ -99,6 +100,8 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
|
|||
};
|
||||
}, []);
|
||||
|
||||
if (!user) return null;
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
<header>
|
||||
|
|
|
@ -38,7 +38,7 @@ export const TemplateList: React.FC<IProps> = ({
|
|||
const start = (page - 1) * pageSize;
|
||||
const end = page * pageSize;
|
||||
return arr.slice(start, end);
|
||||
}, [data, page]);
|
||||
}, [data, page, pageSize]);
|
||||
|
||||
return (
|
||||
<DataRender
|
||||
|
|
|
@ -21,8 +21,6 @@ interface IProps {
|
|||
}
|
||||
|
||||
export const Editor: React.FC<IProps> = ({ user, data, loading, error }) => {
|
||||
if (!user) return null;
|
||||
|
||||
const c = safeJSONParse(data.content);
|
||||
let json = c.default || c;
|
||||
|
||||
|
@ -44,6 +42,8 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error }) => {
|
|||
return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth;
|
||||
}, [width]);
|
||||
|
||||
if (!user) return null;
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
<Layout className={styles.contentWrap}>
|
||||
|
|
|
@ -26,7 +26,7 @@ export const Documents: React.FC<IProps> = ({ wikiId }) => {
|
|||
const [publicDocumentIds, setPublicDocumentIds] = useState([]); // 公开的
|
||||
const privateDocumentIds = useMemo(() => {
|
||||
return documents.filter((doc) => !publicDocumentIds.includes(doc.id)).map((doc) => doc.id);
|
||||
}, [tocs, publicDocumentIds]);
|
||||
}, [documents, publicDocumentIds]);
|
||||
|
||||
const submit = () => {
|
||||
const data = { nextStatus, publicDocumentIds, privateDocumentIds };
|
||||
|
@ -77,7 +77,7 @@ export const Documents: React.FC<IProps> = ({ wikiId }) => {
|
|||
if (!documents.length) return;
|
||||
const activeIds = documents.filter((doc) => isPublicDocument(doc.status)).map((doc) => doc.id);
|
||||
setPublicDocumentIds(activeIds);
|
||||
}, [tocs]);
|
||||
}, [tocs, documents]);
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
|
@ -115,7 +115,11 @@ export const Documents: React.FC<IProps> = ({ wikiId }) => {
|
|||
</Title>
|
||||
<RadioGroup direction="vertical" value={nextStatus} onChange={(e) => setNextStatus(e.target.value)}>
|
||||
{WIKI_STATUS_LIST.map((status) => {
|
||||
return <Radio value={status.value}>{status.label}</Radio>;
|
||||
return (
|
||||
<Radio key={status.value} value={status.value}>
|
||||
{status.label}
|
||||
</Radio>
|
||||
);
|
||||
})}
|
||||
</RadioGroup>
|
||||
</div>
|
||||
|
|
|
@ -20,7 +20,7 @@ export const AddUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) => {
|
|||
setUserName('');
|
||||
toggleVisible(false);
|
||||
});
|
||||
}, [onOk, userName, userRole]);
|
||||
}, [onOk, userName, userRole, toggleVisible]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
@ -40,7 +40,11 @@ export const AddUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) => {
|
|||
<Space>
|
||||
<Select value={userRole} onChange={setUserRole} style={{ width: 120 }}>
|
||||
{WIKI_USER_ROLES.map((wikiStatus) => {
|
||||
return <Select.Option value={wikiStatus.value}>{wikiStatus.label}</Select.Option>;
|
||||
return (
|
||||
<Select.Option key={wikiStatus.value} value={wikiStatus.value}>
|
||||
{wikiStatus.label}
|
||||
</Select.Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
<Input
|
||||
|
|
|
@ -15,7 +15,7 @@ export const EditUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) =>
|
|||
setUserRole(WikiUserRole.normal);
|
||||
toggleVisible(false);
|
||||
});
|
||||
}, [onOk, userRole]);
|
||||
}, [onOk, userRole, toggleVisible]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
@ -33,7 +33,11 @@ export const EditUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) =>
|
|||
) : null}
|
||||
<Select value={userRole} onChange={setUserRole} style={{ width: '100%' }}>
|
||||
{WIKI_USER_ROLES.map((wikiStatus) => {
|
||||
return <Select.Option value={wikiStatus.value}>{wikiStatus.label}</Select.Option>;
|
||||
return (
|
||||
<Select.Option key={wikiStatus.value} value={wikiStatus.value}>
|
||||
{wikiStatus.label}
|
||||
</Select.Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
<Button theme="solid" block style={{ margin: '24px 0' }} onClick={handleOk}>
|
||||
|
|
|
@ -47,7 +47,7 @@ export const WikiTocs: React.FC<IProps> = ({
|
|||
return () => {
|
||||
event.off(REFRESH_TOCS, handler);
|
||||
};
|
||||
}, []);
|
||||
}, [refresh]);
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
|
|
|
@ -56,7 +56,7 @@ const AddDocument = () => {
|
|||
return () => {
|
||||
event.off(CREATE_DOCUMENT, handler);
|
||||
};
|
||||
}, []);
|
||||
}, [toggleVisible]);
|
||||
|
||||
return (
|
||||
<DocumenCreatorForm wikiId={wikiId} parentDocumentId={documentId} visible={visible} toggleVisible={toggleVisible} />
|
||||
|
@ -85,7 +85,7 @@ export const Tree = ({ data, docAsLink, getDocLink, parentIds, activeId, isShare
|
|||
{isShareMode ? null : renderBtn(item)}
|
||||
</div>
|
||||
),
|
||||
[isShareMode]
|
||||
[isShareMode, docAsLink, getDocLink, renderBtn]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -148,12 +148,12 @@ export const usePublicDocument = (documentId: string) => {
|
|||
})
|
||||
.catch(setError);
|
||||
},
|
||||
[documentId, error]
|
||||
[fetch, documentId]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
queryData();
|
||||
}, [documentId]);
|
||||
}, [documentId, queryData]);
|
||||
|
||||
return {
|
||||
data: document,
|
||||
|
|
|
@ -14,18 +14,21 @@ export const useUser = () => {
|
|||
window.localStorage.removeItem('token');
|
||||
mutate(null);
|
||||
Router.replace('/login');
|
||||
}, []);
|
||||
}, [mutate]);
|
||||
|
||||
const login = useCallback((data) => {
|
||||
HttpClient.post<IUser>('/user/login', data).then((res) => {
|
||||
const user = res as unknown as ILoginUser;
|
||||
mutate(user);
|
||||
setStorage('user', JSON.stringify(user));
|
||||
user.token && setStorage('token', user.token);
|
||||
const next = router.query?.redirect || '/';
|
||||
Router.replace(next as string);
|
||||
});
|
||||
}, []);
|
||||
const login = useCallback(
|
||||
(data) => {
|
||||
HttpClient.post<IUser>('/user/login', data).then((res) => {
|
||||
const user = res as unknown as ILoginUser;
|
||||
mutate(user);
|
||||
setStorage('user', JSON.stringify(user));
|
||||
user.token && setStorage('token', user.token);
|
||||
const next = router.query?.redirect || '/';
|
||||
Router.replace(next as string);
|
||||
});
|
||||
},
|
||||
[mutate, router.query?.redirect]
|
||||
);
|
||||
|
||||
const updateUser = async (patch: Pick<IUser, 'email' | 'avatar'>) => {
|
||||
const res = await HttpClient.patch('/user/update', patch);
|
||||
|
@ -36,7 +39,7 @@ export const useUser = () => {
|
|||
|
||||
useEffect(() => {
|
||||
mutate();
|
||||
}, []);
|
||||
}, [mutate]);
|
||||
|
||||
return {
|
||||
user: data,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable */
|
||||
'use strict';
|
||||
|
||||
var deselectCurrent = require('toggle-selection');
|
||||
|
@ -59,7 +60,7 @@ function copy(text, options) {
|
|||
window.clipboardData.clearData();
|
||||
var format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting['default'];
|
||||
if (Array.isArray(text)) {
|
||||
text.forEach((item) => {
|
||||
text.forEach(function (item) {
|
||||
if (typeof item === 'string') {
|
||||
window.clipboardData.setData(item, item);
|
||||
} else {
|
||||
|
@ -73,7 +74,7 @@ function copy(text, options) {
|
|||
// all other browsers
|
||||
e.clipboardData.clearData();
|
||||
if (Array.isArray(text)) {
|
||||
text.forEach((item) => {
|
||||
text.forEach(function (item) {
|
||||
if (typeof item === 'string') {
|
||||
e.clipboardData.setData(item, item);
|
||||
} else {
|
||||
|
@ -106,7 +107,7 @@ function copy(text, options) {
|
|||
debug && console.warn('trying IE specific stuff');
|
||||
try {
|
||||
if (Array.isArray(text)) {
|
||||
text.forEach((item) => {
|
||||
text.forEach(function (item) {
|
||||
if (typeof item === 'string') {
|
||||
window.clipboardData.setData(item, item);
|
||||
} else {
|
||||
|
|
|
@ -39,7 +39,7 @@ export const useDocumentStyle = () => {
|
|||
|
||||
useEffect(() => {
|
||||
mutate();
|
||||
}, []);
|
||||
}, [mutate]);
|
||||
|
||||
return {
|
||||
width: (data && data.width) || DEFAULT_WIDTH,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useRef } from 'react';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import { useWindowSize } from 'hooks/use-window-size';
|
||||
import { setStorage, getStorage } from 'helpers/storage';
|
||||
|
@ -21,14 +21,17 @@ export const useDragableWidth = () => {
|
|||
runTimeWidthRef.current = size;
|
||||
};
|
||||
|
||||
const toggleCollapsed = (collapsed = null) => {
|
||||
const isBool = typeof collapsed === 'boolean';
|
||||
const nextCollapsed = isBool ? collapsed : !isCollapsed;
|
||||
let nextWidth = nextCollapsed ? COLLAPSED_WIDTH : MIN_WIDTH;
|
||||
setStorage(key, nextWidth);
|
||||
mutate();
|
||||
runTimeWidthRef.current = nextWidth;
|
||||
};
|
||||
const toggleCollapsed = useCallback(
|
||||
(collapsed = null) => {
|
||||
const isBool = typeof collapsed === 'boolean';
|
||||
const nextCollapsed = isBool ? collapsed : !isCollapsed;
|
||||
const nextWidth = nextCollapsed ? COLLAPSED_WIDTH : MIN_WIDTH;
|
||||
setStorage(key, nextWidth);
|
||||
mutate();
|
||||
runTimeWidthRef.current = nextWidth;
|
||||
},
|
||||
[isCollapsed, mutate]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
mutate();
|
||||
|
@ -36,14 +39,14 @@ export const useDragableWidth = () => {
|
|||
return () => {
|
||||
runTimeWidthRef.current = null;
|
||||
};
|
||||
}, []);
|
||||
}, [mutate]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!windowSize.width) return;
|
||||
if (windowSize.width <= 765) {
|
||||
toggleCollapsed(true);
|
||||
}
|
||||
}, [windowSize.width]);
|
||||
}, [windowSize.width, toggleCollapsed]);
|
||||
|
||||
return {
|
||||
width: data,
|
||||
|
|
|
@ -34,7 +34,7 @@ export const Recent = () => {
|
|||
{recentDocs.length ? (
|
||||
recentDocs.map((doc) => {
|
||||
return (
|
||||
<div className={styles.itemWrap}>
|
||||
<div className={styles.itemWrap} key={doc.id}>
|
||||
<Link
|
||||
href={{
|
||||
pathname: '/wiki/[wikiId]/document/[documentId]',
|
||||
|
|
|
@ -88,7 +88,7 @@ export const Wiki = () => {
|
|||
{starWikis.length ? (
|
||||
starWikis.map((wiki) => {
|
||||
return (
|
||||
<div className={styles.itemWrap}>
|
||||
<div className={styles.itemWrap} key={wiki.id}>
|
||||
<Link
|
||||
href={{
|
||||
pathname: '/wiki/[wikiId]',
|
||||
|
|
|
@ -34,7 +34,7 @@ export const Recent = () => {
|
|||
{recentDocs.length ? (
|
||||
recentDocs.map((doc) => {
|
||||
return (
|
||||
<div className={styles.itemWrap}>
|
||||
<div className={styles.itemWrap} key={doc.id}>
|
||||
<Link
|
||||
href={{
|
||||
pathname: '/wiki/[wikiId]/document/[documentId]',
|
||||
|
|
|
@ -88,7 +88,7 @@ export const Wiki = () => {
|
|||
{starWikis.length ? (
|
||||
starWikis.map((wiki) => {
|
||||
return (
|
||||
<div className={styles.itemWrap}>
|
||||
<div className={styles.itemWrap} key={wiki.id}>
|
||||
<Link
|
||||
href={{
|
||||
pathname: '/wiki/[wikiId]',
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import type { AppProps } from 'next/app';
|
||||
import Head from 'next/head';
|
||||
import React from 'react';
|
||||
import { useTheme } from 'hooks/use-theme';
|
||||
import 'viewerjs/dist/viewer.css';
|
||||
import 'styles/globals.scss';
|
||||
|
|
|
@ -67,7 +67,7 @@ const RecentDocs = () => {
|
|||
)}
|
||||
/>,
|
||||
],
|
||||
[]
|
||||
[refresh]
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Link from 'next/link';
|
||||
import React from 'react';
|
||||
import { Form, Button, Layout, Space, Typography } from '@douyinfe/semi-ui';
|
||||
import { useUser } from 'data/user';
|
||||
import { Seo } from 'components/seo';
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import Router from 'next/router';
|
||||
import Link from 'next/link';
|
||||
import { Form, Button, Layout, Space, Typography, Modal } from '@douyinfe/semi-ui';
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { NextPage } from 'next';
|
||||
import { DocumentPublicReader } from 'components/document/reader/public';
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { NextPage } from 'next';
|
||||
import { PublicDoubleColumnLayout } from 'layouts/public-double-column';
|
||||
import { WikiPublicTocs } from 'components/wiki/tocs/public';
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { NextPage } from 'next';
|
||||
import { PublicDoubleColumnLayout } from 'layouts/public-double-column';
|
||||
import { usePublicWikiHomeDoc } from 'data/wiki';
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { NextPage } from 'next';
|
||||
import React from 'react';
|
||||
import { DocumentEditor } from 'components/document/editor';
|
||||
|
||||
interface IProps {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { NextPage } from 'next';
|
||||
import React from 'react';
|
||||
import { DoubleColumnLayout } from 'layouts/double-column';
|
||||
import { WikiTocs } from 'components/wiki/tocs';
|
||||
import { DocumentReader } from 'components/document/reader';
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { NextPage } from 'next';
|
||||
import React from 'react';
|
||||
import { DoubleColumnLayout } from 'layouts/double-column';
|
||||
import { useWikiHomeDoc } from 'data/wiki';
|
||||
import { DataRender } from 'components/data-render';
|
||||
|
@ -14,7 +15,7 @@ const Page: NextPage<IProps> = ({ wikiId }) => {
|
|||
|
||||
return (
|
||||
<DoubleColumnLayout
|
||||
leftNode={<WikiTocs pageTitle="概览" wikiId={wikiId} />}
|
||||
leftNode={<WikiTocs wikiId={wikiId} />}
|
||||
rightNode={
|
||||
<DataRender
|
||||
loading={loading}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useCallback } from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { NextPage } from 'next';
|
||||
import Router, { useRouter } from 'next/router';
|
||||
import { DoubleColumnLayout } from 'layouts/double-column';
|
||||
|
@ -15,14 +15,17 @@ const Page: NextPage<IProps> = ({ wikiId }) => {
|
|||
tab?: string;
|
||||
};
|
||||
|
||||
const navigate = useCallback((tab = 'base') => {
|
||||
return () => {
|
||||
Router.push({
|
||||
pathname: `/wiki/${wikiId}/setting`,
|
||||
query: { tab },
|
||||
});
|
||||
};
|
||||
}, []);
|
||||
const navigate = useCallback(
|
||||
(tab = 'base') => {
|
||||
return () => {
|
||||
Router.push({
|
||||
pathname: `/wiki/${wikiId}/setting`,
|
||||
query: { tab },
|
||||
});
|
||||
};
|
||||
},
|
||||
[wikiId]
|
||||
);
|
||||
|
||||
return (
|
||||
<DoubleColumnLayout
|
||||
|
|
788
pnpm-lock.yaml
788
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue