diff --git a/.vscode/react.code-snippets b/.vscode/react.code-snippets new file mode 100644 index 00000000..e59872a5 --- /dev/null +++ b/.vscode/react.code-snippets @@ -0,0 +1,63 @@ +// Place your Client workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and +// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope +// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is +// used to trigger the snippet and the body will be expanded and inserted. Possible variables are: +// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. +// Placeholders with the same ids are connected. +// Example: +// "Print to console": { +// "scope": "javascript,typescript", +// "prefix": "log", +// "body": [ +// "console.log('$1');", +// "$2" +// ], +// "description": "Log output to console" +// } +{ + "React functional component": { + "scope": "typescriptreact", + "prefix": "rfc", + "body": [ + "import React from 'react'", + "interface $1Props {", + " $2", + "}", + "export const $1 = (props: $1Props) => {", + " const { $3 } = props;", + "", + " return null;", + "};", + "$1.displayName = '$1';" + ] + }, + "React memo functional component": { + "scope": "typescriptreact", + "prefix": "rmc", + "body": [ + "import React from 'react';", + "", + "interface ${1:Component}Props {", + " $2", + "}", + "export const $1: React.FC<$1Props> = React.memo((props) => {", + " const { $3 } = props;", + "", + " return null;", + "});", + "$1.displayName = '$1';" + ] + }, + "React memo functional component pure": { + "scope": "typescriptreact", + "prefix": "rmcp", + "body": [ + "import React from 'react';", + "", + "export const ${1:Component}: React.FC = React.memo(() => {", + " return null;", + "});", + "$1.displayName = '$1';" + ] + } +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..0f53d7e7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "editor.rulers": [80] +} diff --git a/shared/index.tsx b/shared/index.tsx index 73d51647..db3dfde8 100644 --- a/shared/index.tsx +++ b/shared/index.tsx @@ -38,6 +38,7 @@ export { // model export { addFriendRequest } from './model/friend'; +export type { FriendRequest } from './model/friend'; export type { UserBaseInfo, UserLoginInfo } from './model/user'; export { loginWithEmail, diff --git a/shared/redux/hooks/useReduxCache.ts b/shared/redux/hooks/useReduxCache.ts index e43635ba..b4705071 100644 --- a/shared/redux/hooks/useReduxCache.ts +++ b/shared/redux/hooks/useReduxCache.ts @@ -26,7 +26,10 @@ function reduxHookCacheFactory( ) { const isFetchingDataIdQueue: string[] = []; // 正在请求的id列表 - return function hook(id: string, options?: CacheHookOptions): Partial { + return function useReduxCache( + id: string, + options?: CacheHookOptions + ): Partial { const data = useAppSelector( (state) => _get(state, ['cache', cacheScope, id]) as any ); diff --git a/web/src/components/IconBtn.tsx b/web/src/components/IconBtn.tsx new file mode 100644 index 00000000..8a58ac7a --- /dev/null +++ b/web/src/components/IconBtn.tsx @@ -0,0 +1,20 @@ +import { Icon } from '@iconify/react'; +import { Button, ButtonProps } from 'antd'; +import React from 'react'; + +interface IconBtnProps extends ButtonProps { + icon: string; +} +export const IconBtn: React.FC = React.memo( + ({ icon, ...props }) => { + return ( +