Skip to content

Commit

Permalink
✨ feat: support actions render
Browse files Browse the repository at this point in the history
  • Loading branch information
ONLY-yours committed Aug 19, 2024
1 parent bdaa7c5 commit 401e352
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 43 deletions.
23 changes: 17 additions & 6 deletions src/ProSender/demos/actionsRender.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CheckCircleOutlined } from '@ant-design/icons';
import { ProChat, ProSender } from '@ant-design/pro-chat';
import { Card, Empty, Space } from 'antd';
import { Space, Tag } from 'antd';
import { useTheme } from 'antd-style';

export default () => {
Expand All @@ -11,16 +12,26 @@ export default () => {
return (
<ProSender
actions={{
actionsInfoRender: (defaultdom, fileList) => {
actionsInfoRender: (defaultdom, fileList, onRemove) => {
if (!fileList || fileList.length === 0) {
return <Empty />;
return;
}
return (
<Space>
{fileList.map((item) => {
console.log('item', item);

return <Card key={item.uid} style={{ width: 300 }} title={item.fileName} />;
return (
<Tag
icon={<CheckCircleOutlined />}
color="success"
key={item.uid}
closable
onClose={() => {
onRemove(item.uid);
}}
>
{item.name}
</Tag>
);
})}
</Space>
);
Expand Down
25 changes: 18 additions & 7 deletions src/ProSender/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@ import {
} from 'antd';
import { useContext, useEffect, useState } from 'react';
import EnterTypeButton from './components/EnterTypeButton.tsx';
import LocalStorageManager from './storageManager';
import LocalStorageManager from './storageManager.js';
import { useStyles } from './style';

type ActionsType = {
onFileUpload?: (file: File) => void;
onRemoveFile?: (file: UploadFile) => void;
actionsRender?: ([fileUpBtn, imgUpBtn]: Array<React.ReactNode>) => React.ReactNode;
actionsInfoRender?: (defaultdom: React.ReactNode, []: Array<UploadFile>) => React.ReactNode;
actionsInfoRender?: (
defaultdom?: React.ReactNode,
[]?: Array<UploadFile>,
onRemoveFile?: (uid: string) => Promise<{ key: string; success: boolean; error?: string }>,
) => React.ReactNode;
};

const ProSender = (
Expand Down Expand Up @@ -51,9 +57,10 @@ const ProSender = (
beforeUpload: (file) => {
localStorageManager
.storeFile(file)
.then((key) => {
const storedFiles = localStorageManager.getFiles([key]);
.then(async (key) => {
const storedFiles = await localStorageManager.getFiles([key]);
setFileList((prevList) => [...prevList, ...storedFiles]);
actions?.onFileUpload?.(file);
})
.catch((error) => {
message.error(error);
Expand Down Expand Up @@ -104,10 +111,11 @@ const ProSender = (
{...upload}
fileList={fileList}
listType="picture"
onRemove={(file) => {
const result = localStorageManager.removeFiles([file.uid]);
onRemove={async (file) => {
const result = await localStorageManager.removeFiles([file.uid]);
if (result[0].success) {
setFileList((prevList) => prevList.filter((item) => item.uid !== file.uid));
actions?.onRemoveFile?.(file);
} else {
message.error(result[0].error);
}
Expand All @@ -121,7 +129,10 @@ const ProSender = (
};

if (actions?.actionsInfoRender) {
return actions.actionsInfoRender(fileInputRender(), fileList);
return actions.actionsInfoRender(fileInputRender(), fileList, async (uid) => {
setFileList((prevList) => prevList.filter((item) => item.uid !== uid));
return await localStorageManager.removeFiles([uid]);
});
}
return fileInputRender();
};
Expand Down
75 changes: 45 additions & 30 deletions src/ProSender/storageManager.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
import { openDB } from 'idb';
import { v4 as uuidv4 } from 'uuid';

class LocalStorageManager {
class IndexedDBManager {
constructor(defaultExpiryTime = 60 * 60 * 1000) {
this.defaultExpiryTime = defaultExpiryTime; // 默认过期时间为 1 小时
this.dbPromise = openDB('file-store', 1, {
upgrade(db) {
db.createObjectStore('files', { keyPath: 'uid' });
},
});
}

// 存储数据方法,返回生成的唯一 key
storeFile(file) {
async storeFile(file) {
const key = uuidv4();
const expiry = new Date(new Date().getTime() + this.defaultExpiryTime);
const reader = new FileReader();

return new Promise((resolve, reject) => {
reader.readAsDataURL(file);
reader.onload = () => {
reader.onload = async () => {
const base64 = reader.result;
const fileInfo = {
uid: key,
name: file.name,
type: file.type,
size: file.size,
base64,
expiry,
};
localStorage.setItem(key, JSON.stringify(fileInfo));
resolve(key);
try {
const db = await this.dbPromise;
await db.put('files', fileInfo);
resolve(key);
} catch (e) {
reject('IndexedDB 存储失败');
}
};
reader.onerror = (error) => {
reject('文件读取失败');
Expand All @@ -32,22 +44,21 @@ class LocalStorageManager {
}

// 按照 keys 数组,返回批量取出存储的 files
getFiles(keys) {
return keys
.map((key) => {
const item = localStorage.getItem(key);
if (item) {
const fileInfo = JSON.parse(item);
if (new Date(fileInfo.expiry) > new Date()) {
return { ...fileInfo, uid: key };
} else {
localStorage.removeItem(key);
return null;
}
async getFiles(keys) {
const db = await this.dbPromise;
const files = await Promise.all(
keys.map(async (key) => {
const file = await db.get('files', key);
if (file && new Date(file.expiry) > new Date()) {
return file;
} else if (file) {
await db.delete('files', key);
return null;
}
return null;
})
.filter((file) => file !== null);
}),
);
return files.filter((file) => file !== null);
}

// 设置过期时间
Expand All @@ -56,17 +67,21 @@ class LocalStorageManager {
}

// 按照指定的 keys 从存储里面删除数据
removeFiles(keys) {
return keys.map((key) => {
const item = localStorage.getItem(key);
if (item) {
localStorage.removeItem(key);
return { key, success: true };
} else {
return { key, success: false, error: '文件不存在' };
}
});
async removeFiles(keys) {
const db = await this.dbPromise;
const results = await Promise.all(
keys.map(async (key) => {
const file = await db.get('files', key);
if (file) {
await db.delete('files', key);
return { key, success: true };
} else {
return { key, success: false, error: '文件不存在' };
}
}),
);
return results;
}
}

export default LocalStorageManager;
export default IndexedDBManager;

0 comments on commit 401e352

Please sign in to comment.