mirror of https://github.com/msgbyte/tailchat
refactor: AvatarUploader -> ImageUploader
parent
51c7111621
commit
a765bb0248
@ -1,52 +0,0 @@
|
|||||||
import { blobUrlToFile } from '@/utils/file-helper';
|
|
||||||
import clsx from 'clsx';
|
|
||||||
import React, { PropsWithChildren, useState } from 'react';
|
|
||||||
import { uploadFile, UploadFileResult, useAsyncRequest } from 'tailchat-shared';
|
|
||||||
import { ImagePicker } from './ImagePicker';
|
|
||||||
|
|
||||||
export const AvatarUploader: React.FC<
|
|
||||||
PropsWithChildren<{
|
|
||||||
circle?: boolean;
|
|
||||||
className?: string;
|
|
||||||
onUploadSuccess: (fileInfo: UploadFileResult) => void;
|
|
||||||
}>
|
|
||||||
> = React.memo((props) => {
|
|
||||||
const [uploadProgress, setUploadProgress] = useState(0); // 0 - 100
|
|
||||||
const [{ loading }, handlePickImage] = useAsyncRequest(
|
|
||||||
async (blobUrl: string) => {
|
|
||||||
const file = await blobUrlToFile(blobUrl);
|
|
||||||
|
|
||||||
const fileInfo = await uploadFile(file, {
|
|
||||||
onProgress(percent) {
|
|
||||||
const uploadProgress = Number((percent * 100).toFixed());
|
|
||||||
console.log(`进度:${uploadProgress}`);
|
|
||||||
setUploadProgress(uploadProgress);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('上传成功', fileInfo);
|
|
||||||
props.onUploadSuccess(fileInfo);
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ImagePicker
|
|
||||||
className={clsx('relative', {
|
|
||||||
'rounded-full overflow-hidden': props.circle,
|
|
||||||
})}
|
|
||||||
disabled={loading}
|
|
||||||
onChange={handlePickImage}
|
|
||||||
>
|
|
||||||
{loading && (
|
|
||||||
<div
|
|
||||||
className="absolute bottom-0 left-0 h-1"
|
|
||||||
style={{ width: `${uploadProgress}%` }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{props.children}
|
|
||||||
</ImagePicker>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
AvatarUploader.displayName = 'AvatarUploader';
|
|
@ -0,0 +1,64 @@
|
|||||||
|
import { blobUrlToFile } from '@/utils/file-helper';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import React, { PropsWithChildren, useState } from 'react';
|
||||||
|
import { uploadFile, UploadFileResult, useAsyncRequest } from 'tailchat-shared';
|
||||||
|
import { ImagePicker } from './ImagePicker';
|
||||||
|
|
||||||
|
interface ImageUploaderProps extends PropsWithChildren {
|
||||||
|
circle?: boolean;
|
||||||
|
aspect?: number;
|
||||||
|
className?: string;
|
||||||
|
onUploadSuccess: (fileInfo: UploadFileResult) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ImageUploader: React.FC<ImageUploaderProps> = React.memo(
|
||||||
|
(props) => {
|
||||||
|
const aspect = props.aspect ?? 1;
|
||||||
|
const [uploadProgress, setUploadProgress] = useState(0); // 0 - 100
|
||||||
|
const [{ loading }, handlePickImage] = useAsyncRequest(
|
||||||
|
async (blobUrl: string) => {
|
||||||
|
const file = await blobUrlToFile(blobUrl);
|
||||||
|
|
||||||
|
const fileInfo = await uploadFile(file, {
|
||||||
|
onProgress(percent) {
|
||||||
|
const uploadProgress = Number((percent * 100).toFixed());
|
||||||
|
console.log(`进度:${uploadProgress}`);
|
||||||
|
setUploadProgress(uploadProgress);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('上传成功', fileInfo);
|
||||||
|
props.onUploadSuccess(fileInfo);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ImagePicker
|
||||||
|
className={clsx(props.className, 'relative overflow-hidden', {
|
||||||
|
'rounded-full': props.circle,
|
||||||
|
})}
|
||||||
|
aspect={aspect}
|
||||||
|
disabled={loading}
|
||||||
|
onChange={handlePickImage}
|
||||||
|
>
|
||||||
|
{loading && (
|
||||||
|
<div
|
||||||
|
className="absolute bottom-0 left-0 h-1"
|
||||||
|
style={{ width: `${uploadProgress}%` }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{props.children}
|
||||||
|
</ImagePicker>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
ImageUploader.displayName = 'ImageUploader';
|
||||||
|
|
||||||
|
export const AvatarUploader: React.FC<ImageUploaderProps> = React.memo(
|
||||||
|
(props) => {
|
||||||
|
return <ImageUploader aspect={1} circle={true} {...props}></ImageUploader>;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
AvatarUploader.displayName = 'AvatarUploader';
|
Loading…
Reference in New Issue