diff --git a/client/web/src/components/AvatarUploader.tsx b/client/web/src/components/AvatarUploader.tsx
deleted file mode 100644
index 2d53cbdd..00000000
--- a/client/web/src/components/AvatarUploader.tsx
+++ /dev/null
@@ -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 (
-
- {loading && (
-
- )}
-
- {props.children}
-
- );
-});
-AvatarUploader.displayName = 'AvatarUploader';
diff --git a/client/web/src/components/ImageUploader.tsx b/client/web/src/components/ImageUploader.tsx
new file mode 100644
index 00000000..a0c2effc
--- /dev/null
+++ b/client/web/src/components/ImageUploader.tsx
@@ -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 = 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 (
+
+ {loading && (
+
+ )}
+
+ {props.children}
+
+ );
+ }
+);
+ImageUploader.displayName = 'ImageUploader';
+
+export const AvatarUploader: React.FC = React.memo(
+ (props) => {
+ return ;
+ }
+);
+AvatarUploader.displayName = 'AvatarUploader';
diff --git a/client/web/src/components/modals/GroupDetail/Summary.tsx b/client/web/src/components/modals/GroupDetail/Summary.tsx
index a1ea6a31..7d272de0 100644
--- a/client/web/src/components/modals/GroupDetail/Summary.tsx
+++ b/client/web/src/components/modals/GroupDetail/Summary.tsx
@@ -1,4 +1,4 @@
-import { AvatarUploader } from '@/components/AvatarUploader';
+import { AvatarUploader } from '@/components/ImageUploader';
import { FullModalCommonTitle } from '@/components/FullModal/CommonTitle';
import {
DefaultFullModalInputEditorRender,
@@ -59,7 +59,6 @@ export const GroupSummary: React.FC<{
diff --git a/client/web/src/components/modals/SettingsView/Account.tsx b/client/web/src/components/modals/SettingsView/Account.tsx
index 7084ac79..63a38af3 100644
--- a/client/web/src/components/modals/SettingsView/Account.tsx
+++ b/client/web/src/components/modals/SettingsView/Account.tsx
@@ -1,13 +1,11 @@
-import { AvatarUploader } from '@/components/AvatarUploader';
+import { AvatarUploader } from '@/components/ImageUploader';
import {
DefaultFullModalInputEditorRender,
FullModalField,
} from '@/components/FullModal/Field';
import { openModal } from '@/components/Modal';
import { closeModal, pluginUserExtraInfo } from '@/plugin/common';
-import { getGlobalSocket } from '@/utils/global-state-helper';
import { setUserJWT } from '@/utils/jwt-helper';
-import { setGlobalUserLoginInfo } from '@/utils/user-helper';
import { Button, Divider, message, Tag, Typography } from 'antd';
import React, { useCallback } from 'react';
import { useNavigate } from 'react-router';
@@ -95,7 +93,6 @@ export const SettingsAccount: React.FC = React.memo(() => {