Skip to content

Commit

Permalink
feat: support uploading binary file (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
z0gSh1u authored Oct 9, 2024
1 parent 992023d commit dc50a05
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 17 deletions.
2 changes: 1 addition & 1 deletion packages/secretnote-lite/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@alipay/secretnote-lite",
"version": "0.0.44",
"version": "0.0.45",
"license": "Apache-2.0",
"author": "vectorse@126.com",
"repository": "https://github.com/secretflow/secretnote/tree/main/packages/secretnote",
Expand Down
13 changes: 11 additions & 2 deletions packages/secretnote-lite/src/modules/file/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,15 @@ export class FileService {
return list.content.some((file: any) => file.name === name);
}

async uploadFile(nodeData: DataNode, name: string, content: string) {
/**
* Upload file via Jupyter Server. For binary files, use `format='base64'` and base64-encoded `content`.
*/
async uploadFile(
nodeData: DataNode,
name: string,
content: string,
format: 'text' | 'base64' = 'text',
) {
const serverId = nodeData.key as string;
const server = await this.serverManager.getServerDetail(serverId);
if (server) {
Expand All @@ -105,7 +113,8 @@ export class FileService {
name,
path,
type: 'file',
format: 'text',
format,
...(format === 'base64' ? { mimetype: 'application/octet-stream' } : {}),
});
}
}
Expand Down
36 changes: 27 additions & 9 deletions packages/secretnote-lite/src/modules/file/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,18 @@ export const FileComponent = () => {
}
};

const uploadFile = async (nodeData: DataNode, file: File) => {
/**
* Handle the upload file action.
*/
const uploadFile = async (
nodeData: DataNode,
file: File,
format: 'text' | 'base64' = 'text',
) => {
setIsUploading(true);
const content = await readFile(file);
const content = await readFile(file, format);
try {
await fileService.uploadFile(nodeData, file.name, content);
await fileService.uploadFile(nodeData, file.name, content, format);
await fileService.getFileTree();
message.success(l10n.t('文件上传成功'));
} catch (e) {
Expand All @@ -95,7 +102,7 @@ export const FileComponent = () => {
}
};

const uploadRender = (nodeData: DataNode) => {
const uploadRender = (nodeData: DataNode, format: 'text' | 'base64' = 'text') => {
const props: UploadProps = {
beforeUpload: async (file) => {
const isExisted = await fileService.isFileExist(nodeData, file.name);
Expand All @@ -110,19 +117,25 @@ export const FileComponent = () => {
cancelText: l10n.t('取消'),
okType: 'danger',
async onOk(close) {
await uploadFile(nodeData, file);
await uploadFile(nodeData, file, format);
return close(Promise.resolve);
},
});
} else {
uploadFile(nodeData, file);
uploadFile(nodeData, file, format);
}

return false;
},
fileList: [],
};
return <Upload {...props}>{l10n.t('上传到文件夹')}</Upload>;
return (
<Upload {...props}>
{l10n.t(
format === 'text' ? '上传到文件夹 (文本文件)' : '上传到文件夹 (二进制文件)',
)}
</Upload>
);
};

const getFileIcon = (nodeData: DataNode) => {
Expand All @@ -142,8 +155,13 @@ export const FileComponent = () => {

const folderMenuItems: Menu[] = [
{
key: 'upload',
label: uploadRender(nodeData),
key: 'uploadText',
label: uploadRender(nodeData, 'text'),
icon: <UploadIcon size={12} />,
},
{
key: 'uploadBinary',
label: uploadRender(nodeData, 'base64'),
icon: <UploadIcon size={12} />,
},
];
Expand Down
25 changes: 20 additions & 5 deletions packages/secretnote-lite/src/utils/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,29 @@ const saveAs = (blob: Blob, filename: string) => {
}
};

export async function readFile(file: File): Promise<string> {
/**
* Read file as text or base64 string.
*/
export async function readFile(
file: File,
format: 'text' | 'base64' = 'text',
): Promise<string> {
return await new Promise<string>((resolve, reject) => {
try {
const reader = new FileReader();
reader.addEventListener('loadend', () => {
resolve(reader.result?.toString() || '');
});
reader.readAsText(file);
if (format === 'text') {
reader.addEventListener('loadend', () => {
resolve(reader.result?.toString() || '');
});
reader.readAsText(file);
} else if (format === 'base64') {
reader.addEventListener('loadend', () => {
// remove base64 prelude added by the browser
const base64 = (reader.result as string).replace(/data:.*base64,/, '');
resolve(base64 || '');
});
reader.readAsDataURL(file);
}
} catch (e) {
reject(e);
}
Expand Down

0 comments on commit dc50a05

Please sign in to comment.