@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
1 lines • 6.62 kB
Source Map (JSON)
{"version":3,"file":"AvatarUploader.mjs","names":["emojiPickerMessages","Flexbox","Tag","Button"],"sources":["../../src/EmojiPicker/AvatarUploader.tsx"],"sourcesContent":["'use client';\n\nimport { type GetProp, message, Upload, type UploadProps } from 'antd';\nimport { cssVar } from 'antd-style';\nimport { ChevronLeftIcon, ImageUpIcon } from 'lucide-react';\nimport { memo, useCallback, useRef, useState } from 'react';\nimport AvatarEditor from 'react-avatar-editor';\n\nimport Button from '@/Button';\nimport { Center, Flexbox } from '@/Flex';\nimport emojiPickerMessages from '@/i18n/resources/en/emojiPicker';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport Icon from '@/Icon';\nimport Tag from '@/Tag';\nimport Text from '@/Text';\n\nimport { type AvatarUploaderProps } from './type';\n\ntype FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];\n\nconst { Dragger } = Upload;\n\nconst createUploadImageHandler = (onUploadImage: (base64: string) => void) => (file: any) => {\n const reader = new FileReader();\n reader.readAsDataURL(file);\n reader.addEventListener('load', () => {\n onUploadImage(String(reader.result));\n });\n};\n\nconst AvatarUploader = memo<AvatarUploaderProps>(\n ({ shape, onChange, texts, compressSize = 256, onUpload }) => {\n const editor = useRef<any>(null);\n const [previewImage, setPreviewImage] = useState('');\n const { t } = useTranslation(emojiPickerMessages);\n\n const fileTypeErrorText = texts?.fileTypeError ?? t('emojiPicker.fileTypeError');\n const draggerDescText = texts?.draggerDesc ?? t('emojiPicker.draggerDesc');\n const uploadBtnText = texts?.uploadBtn ?? t('emojiPicker.uploadBtn');\n\n const beforeUpload = useCallback(\n (file: FileType) => {\n const isJpgOrPng =\n file.type === 'image/jpeg' ||\n file.type === 'image/png' ||\n file.type === 'image/gif' ||\n file.type === 'image/webp';\n if (!isJpgOrPng) {\n message.error(fileTypeErrorText);\n return;\n }\n return createUploadImageHandler((avatar) => {\n setPreviewImage(avatar);\n })(file);\n },\n [fileTypeErrorText],\n );\n\n const handleUpload = () => {\n if (!editor.current) return;\n const canvasScaled = editor.current.getImageScaledToCanvas() as HTMLCanvasElement;\n const dataUrl = canvasScaled.toDataURL();\n onChange(dataUrl);\n\n if (!onUpload) return;\n\n // 使用 toBlob 直接获取 Blob,然后创建 File 对象\n canvasScaled.toBlob(\n (blob) => {\n if (blob) {\n const file = new File([blob], 'avatar.webp', { type: 'image/webp' });\n onUpload(file);\n }\n },\n 'image/webp',\n 0.95,\n ); // 0.95 是图片质量\n };\n\n return (\n <Flexbox padding={10} style={{ position: 'relative' }} width={'100%'}>\n {!previewImage && (\n <Dragger\n accept={'image'}\n beforeUpload={beforeUpload}\n itemRender={() => void 0}\n maxCount={1}\n multiple={false}\n >\n <Center gap={16} height={compressSize} width={compressSize}>\n <Icon color={cssVar.colorTextDescription} icon={ImageUpIcon} size={48} />\n <Text color={cssVar.colorTextSecondary}>{draggerDescText}</Text>\n <Center horizontal gap={4}>\n <Tag>JPG</Tag>\n <Tag>PNG</Tag>\n <Tag>GIF</Tag>\n <Tag>WEBP</Tag>\n </Center>\n </Center>\n </Dragger>\n )}\n {previewImage && (\n <Center gap={8} style={{ position: 'relative' }} width={'100%'}>\n <AvatarEditor\n border={0}\n borderRadius={shape === 'square' ? undefined : compressSize / 2}\n height={compressSize}\n image={previewImage}\n ref={editor}\n width={compressSize}\n />\n\n <Flexbox horizontal gap={8} style={{ position: 'relative' }} width={'100%'}>\n <Button\n icon={ChevronLeftIcon}\n style={{ flex: 'none' }}\n onClick={() => setPreviewImage('')}\n />\n <Button style={{ flex: 1, fontWeight: 500 }} type={'primary'} onClick={handleUpload}>\n {uploadBtnText}\n </Button>\n </Flexbox>\n </Center>\n )}\n </Flexbox>\n );\n },\n);\n\nAvatarUploader.displayName = 'AvatarUploader';\n\nexport default AvatarUploader;\n"],"mappings":";;;;;;;;;;;;;;;;AAoBA,MAAM,EAAE,YAAY;AAEpB,MAAM,4BAA4B,mBAA6C,SAAc;CAC3F,MAAM,SAAS,IAAI,WAAW;CAC9B,OAAO,cAAc,IAAI;CACzB,OAAO,iBAAiB,cAAc;EACpC,cAAc,OAAO,OAAO,MAAM,CAAC;CACrC,CAAC;AACH;AAEA,MAAM,iBAAiB,MACpB,EAAE,OAAO,UAAU,OAAO,eAAe,KAAK,eAAe;CAC5D,MAAM,SAAS,OAAY,IAAI;CAC/B,MAAM,CAAC,cAAc,mBAAmB,SAAS,EAAE;CACnD,MAAM,EAAE,MAAM,eAAeA,mBAAmB;CAEhD,MAAM,oBAAoB,OAAO,iBAAiB,EAAE,2BAA2B;CAC/E,MAAM,kBAAkB,OAAO,eAAe,EAAE,yBAAyB;CACzE,MAAM,gBAAgB,OAAO,aAAa,EAAE,uBAAuB;CAEnE,MAAM,eAAe,aAClB,SAAmB;EAMlB,IAAI,EAJF,KAAK,SAAS,gBACd,KAAK,SAAS,eACd,KAAK,SAAS,eACd,KAAK,SAAS,eACC;GACf,QAAQ,MAAM,iBAAiB;GAC/B;EACF;EACA,OAAO,0BAA0B,WAAW;GAC1C,gBAAgB,MAAM;EACxB,CAAC,CAAC,CAAC,IAAI;CACT,GACA,CAAC,iBAAiB,CACpB;CAEA,MAAM,qBAAqB;EACzB,IAAI,CAAC,OAAO,SAAS;EACrB,MAAM,eAAe,OAAO,QAAQ,uBAAuB;EAE3D,SADgB,aAAa,UACd,CAAC;EAEhB,IAAI,CAAC,UAAU;EAGf,aAAa,QACV,SAAS;GACR,IAAI,MAEF,SAAS,IADQ,KAAK,CAAC,IAAI,GAAG,eAAe,EAAE,MAAM,aAAa,CACtD,CAAC;EAEjB,GACA,cACA,GACF;CACF;CAEA,OACE,qBAACC,mBAAD;EAAS,SAAS;EAAI,OAAO,EAAE,UAAU,WAAW;EAAG,OAAO;YAA9D,CACG,CAAC,gBACA,oBAAC,SAAD;GACE,QAAQ;GACM;GACd,kBAAkB,KAAK;GACvB,UAAU;GACV,UAAU;aAEV,qBAAC,QAAD;IAAQ,KAAK;IAAI,QAAQ;IAAc,OAAO;cAA9C;KACE,oBAAC,MAAD;MAAM,OAAO,OAAO;MAAsB,MAAM;MAAa,MAAM;KAAK,CAAA;KACxE,oBAAC,MAAD;MAAM,OAAO,OAAO;gBAAqB;KAAsB,CAAA;KAC/D,qBAAC,QAAD;MAAQ,YAAA;MAAW,KAAK;gBAAxB;OACE,oBAACC,OAAD,EAAA,UAAK,MAAQ,CAAA;OACb,oBAACA,OAAD,EAAA,UAAK,MAAQ,CAAA;OACb,oBAACA,OAAD,EAAA,UAAK,MAAQ,CAAA;OACb,oBAACA,OAAD,EAAA,UAAK,OAAS,CAAA;MACR;;IACF;;EACD,CAAA,GAEV,gBACC,qBAAC,QAAD;GAAQ,KAAK;GAAG,OAAO,EAAE,UAAU,WAAW;GAAG,OAAO;aAAxD,CACE,oBAAC,cAAD;IACE,QAAQ;IACR,cAAc,UAAU,WAAW,KAAA,IAAY,eAAe;IAC9D,QAAQ;IACR,OAAO;IACP,KAAK;IACL,OAAO;GACR,CAAA,GAED,qBAACD,mBAAD;IAAS,YAAA;IAAW,KAAK;IAAG,OAAO,EAAE,UAAU,WAAW;IAAG,OAAO;cAApE,CACE,oBAACE,UAAD;KACE,MAAM;KACN,OAAO,EAAE,MAAM,OAAO;KACtB,eAAe,gBAAgB,EAAE;IAClC,CAAA,GACD,oBAACA,UAAD;KAAQ,OAAO;MAAE,MAAM;MAAG,YAAY;KAAI;KAAG,MAAM;KAAW,SAAS;eACpE;IACK,CAAA,CACD;KACH;IAEH;;AAEb,CACF;AAEA,eAAe,cAAc"}