Skip to content

Commit

Permalink
chore: support png, gif, webp
Browse files Browse the repository at this point in the history
  • Loading branch information
ZuzooVn committed Sep 3, 2024
1 parent 1a5116c commit 2e3a566
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 17 deletions.
38 changes: 26 additions & 12 deletions web/app/components/base/app-icon-picker/Uploader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import classNames from 'classnames'

import { ImagePlus } from '../icons/src/vender/line/images'
import { useDraggableUploader } from './hooks'
import { isAnimatedImage } from './utils'
import { ALLOW_FILE_EXTENSIONS } from '@/types/app'

type UploaderProps = {
className?: string
onImageCropped?: (tempUrl: string, croppedAreaPixels: Area, fileName: string) => void
}
onImageCropped?: (tempUrl: string, croppedAreaPixels: Area, fileName: string, file?: File) => void }

const Uploader: FC<UploaderProps> = ({
className,
Expand All @@ -38,8 +38,11 @@ const Uploader: FC<UploaderProps> = ({

const handleLocalFileInput = (e: ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0]
if (file)
if (file) {
setInputImage({ file, url: URL.createObjectURL(file) })
if (isAnimatedImage(file))
onImageCropped?.(URL.createObjectURL(file), { x: 0, y: 0, width: 0, height: 0 }, file.name, file)
}
}

const {
Expand All @@ -52,6 +55,25 @@ const Uploader: FC<UploaderProps> = ({

const inputRef = createRef<HTMLInputElement>()

const handleShowImage = () => {
if (isAnimatedImage(inputImage?.file || { name: '' })) {
return (
<img src={inputImage?.url} alt='' />
)
}
return (
<Cropper
image={inputImage?.url}
crop={crop}
zoom={zoom}
aspect={1}
onCropChange={setCrop}
onCropComplete={onCropComplete}
onZoomChange={setZoom}
/>
)
}

return (
<div className={classNames(className, 'w-full px-3 py-1.5')}>
<div
Expand Down Expand Up @@ -79,15 +101,7 @@ const Uploader: FC<UploaderProps> = ({
</div>
<div className="text-xs pointer-events-none">Supports PNG, JPG, JPEG, WEBP and GIF</div>
</>
: <Cropper
image={inputImage.url}
crop={crop}
zoom={zoom}
aspect={1}
onCropChange={setCrop}
onCropComplete={onCropComplete}
onZoomChange={setZoom}
/>
: handleShowImage()
}
</div>
</div>
Expand Down
12 changes: 8 additions & 4 deletions web/app/components/base/app-icon-picker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useLocalFileUploader } from '../image-uploader/hooks'
import EmojiPickerInner from '../emoji-picker/Inner'
import Uploader from './Uploader'
import s from './style.module.css'
import getCroppedImg from './utils'
import getCroppedImg, { isAnimatedImage } from './utils'
import type { AppIconType, ImageFile } from '@/types/app'
import cn from '@/utils/classnames'
import { DISABLE_UPLOAD_IMAGE_AS_ICON } from '@/config'
Expand Down Expand Up @@ -69,9 +69,9 @@ const AppIconPicker: FC<AppIconPickerProps> = ({
},
})

const [imageCropInfo, setImageCropInfo] = useState<{ tempUrl: string; croppedAreaPixels: Area; fileName: string }>()
const handleImageCropped = async (tempUrl: string, croppedAreaPixels: Area, fileName: string) => {
setImageCropInfo({ tempUrl, croppedAreaPixels, fileName })
const [imageCropInfo, setImageCropInfo] = useState<{ tempUrl: string; croppedAreaPixels: Area; fileName: string; file?: File }>()
const handleImageCropped = async (tempUrl: string, croppedAreaPixels: Area, fileName: string, file?: File) => {
setImageCropInfo({ tempUrl, croppedAreaPixels, fileName, file })
}

const handleSelect = async () => {
Expand All @@ -88,6 +88,10 @@ const AppIconPicker: FC<AppIconPickerProps> = ({
if (!imageCropInfo)
return
setUploading(true)
if (isAnimatedImage({ name: imageCropInfo.fileName }) && imageCropInfo.file) {
handleLocalFileUpload(imageCropInfo.file)
return
}
const blob = await getCroppedImg(imageCropInfo.tempUrl, imageCropInfo.croppedAreaPixels)
const file = new File([blob], imageCropInfo.fileName, { type: blob.type })
handleLocalFileUpload(file)
Expand Down
6 changes: 5 additions & 1 deletion web/app/components/base/app-icon-picker/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ export default async function getCroppedImg(
resolve(file)
else
reject(new Error('Could not create a blob'))
}, 'image/jpeg')
}, 'image/png')
})
}

export function isAnimatedImage(file: { name: string }) {
return (file?.name?.endsWith('.webp') || file?.name?.endsWith('.gif'))
}

0 comments on commit 2e3a566

Please sign in to comment.