Skip to content

Commit

Permalink
feat: 增加拖拽文件发送图片的功能
Browse files Browse the repository at this point in the history
  • Loading branch information
moonrailgun committed Jan 10, 2023
1 parent fdb1830 commit 338af09
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 3 deletions.
1 change: 1 addition & 0 deletions client/shared/i18n/langs/en-US/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"ke071c620": "Allow members to manage users, such as banning, removing users, etc.",
"ke17b2c87": "Do not upload pictures that violate local laws and regulations",
"ke187440d": "Panel type cannot be empty",
"ke3d797fd": "Drop files to send into current converse",
"ke59ffe49": "Muted, there are {{remain}} left",
"kea977d95": "The following users are offline",
"kec46a57f": "Add members",
Expand Down
1 change: 1 addition & 0 deletions client/shared/i18n/langs/zh-CN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"ke071c620": "允许成员管理用户,如禁言、移除用户等操作",
"ke17b2c87": "请勿上传违反当地法律法规的图片",
"ke187440d": "面板类型不能为空",
"ke3d797fd": "拖放文件以发送到当前会话",
"ke59ffe49": "禁言中, 还剩 {{remain}}",
"kea977d95": "以下用户已离线",
"kec46a57f": "添加成员",
Expand Down
2 changes: 2 additions & 0 deletions client/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
"qs": "^6.11.0",
"rc-tree": "^5.7.2",
"react": "18.2.0",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "18.2.0",
"react-easy-crop": "^3.5.3",
"react-helmet": "^6.1.0",
Expand Down
10 changes: 7 additions & 3 deletions client/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { pluginRootRoute } from './plugin/common';
import { PortalHost as FallbackPortalHost } from './components/Portal';
import isElectron from 'is-electron';
import { AppRouterApi } from './components/AppRouterApi';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

const AppRouter: any = isElectron() ? HashRouter : BrowserRouter;

Expand Down Expand Up @@ -55,9 +57,11 @@ const AppProvider: React.FC<PropsWithChildren> = React.memo((props) => {
<Suspense fallback={<LoadingSpinner />}>
<AppRouter>
<TcProvider>
<AntdProvider getPopupContainer={getPopupContainer}>
{props.children}
</AntdProvider>
<DndProvider backend={HTML5Backend}>
<AntdProvider getPopupContainer={getPopupContainer}>
{props.children}
</AntdProvider>
</DndProvider>
</TcProvider>
</AppRouter>
</Suspense>
Expand Down
62 changes: 62 additions & 0 deletions client/web/src/components/ChatBox/ChatInputBox/ChatDropArea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';
import { t, useMemoizedFn } from 'tailchat-shared';
import { DropTargetMonitor, useDrop } from 'react-dnd';
import { NativeTypes } from 'react-dnd-html5-backend';
import { useChatInputActionContext } from './context';
import { uploadMessageImage } from './utils';
import { getMessageTextDecorators } from '@/plugin/common';
import { Icon } from 'tailchat-design';

export const ChatDropArea: React.FC = React.memo(() => {
const actionContext = useChatInputActionContext();

const handleDrop = useMemoizedFn((files: File[]) => {
const images = files.filter((f) => f.type.startsWith('image/'));
if (images.length > 0) {
// 目前只取一张
const img = images[0];
uploadMessageImage(img).then(({ url, width, height }) => {
actionContext?.sendMsg(
getMessageTextDecorators().image(url, { width, height })
);
});
}
});

const [collectedProps, ref] = useDrop({
accept: [NativeTypes.FILE],
drop(item: { files: any[] }) {
handleDrop(item.files);
},
canDrop(item: any) {
return true;
},
collect: (monitor: DropTargetMonitor) => {
return {
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
};
},
});

if (!collectedProps.canDrop) {
return;
}

return (
<div
ref={ref}
className={
'absolute inset-0 bg-white bg-opacity-50 dark:bg-black dark:bg-opacity-50 p-4'
}
>
<div className="h-full w-full border-dashed border-8 flex flex-col justify-center items-center">
<div>
<Icon icon="mdi:cloud-upload" fontSize={128} />
</div>
<div className="text-xl font-bold">{t('拖放文件以发送到当前会话')}</div>
</div>
</div>
);
});
ChatDropArea.displayName = 'ChatDropArea';
3 changes: 3 additions & 0 deletions client/web/src/components/ChatBox/ChatInputBox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from 'tailchat-shared';
import { ChatInputEmotion } from './Emotion';
import _uniq from 'lodash/uniq';
import { ChatDropArea } from './ChatDropArea';

interface ChatInputBoxProps {
onSendMsg: (msg: string, meta?: SendMessagePayloadMeta) => void;
Expand Down Expand Up @@ -111,6 +112,8 @@ export const ChatInputBox: React.FC<ChatInputBoxProps> = React.memo((props) => {
<ChatInputEmotion />
<ChatInputAddon />
</div>

<ChatDropArea />
</div>
</div>
</ChatInputActionContext.Provider>
Expand Down
55 changes: 55 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 338af09

Please sign in to comment.