{"version":3,"file":"Toolbar.mjs","names":["imageMessages","Flexbox"],"sources":["../../../src/Image/components/Toolbar.tsx"],"sourcesContent":["import { message } from 'antd';\nimport {\n  Copy,\n  Download,\n  FlipHorizontal,\n  FlipVertical,\n  RotateCcw,\n  RotateCw,\n  ZoomIn,\n  ZoomOut,\n} from 'lucide-react';\nimport { type ToolbarRenderInfoType } from 'rc-image/lib/Preview';\nimport { memo, type ReactNode, useCallback, useState } from 'react';\n\nimport ActionIcon from '@/ActionIcon';\nimport { Flexbox } from '@/Flex';\nimport imageMessages from '@/i18n/resources/en/image';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport { TooltipGroup } from '@/Tooltip';\nimport { getClipboardBlob } from '@/utils/blobToPng';\nimport { downloadBlob } from '@/utils/downloadBlob';\n\nimport { styles } from '../style';\n\nconst getFileNameFromUrl = (url: string): string => {\n  try {\n    const pathname = new URL(url).pathname;\n    const match = pathname.match(/\\/([^/]+)$/);\n    return match ? decodeURIComponent(match[1]) : 'image';\n  } catch {\n    return 'image';\n  }\n};\n\nconst getExtensionFromMimeType = (mimeType: string): string => {\n  const map: Record<string, string> = {\n    'image/svg+xml': 'svg',\n    'image/png': 'png',\n    'image/jpeg': 'jpg',\n    'image/jpg': 'jpg',\n    'image/webp': 'webp',\n    'image/gif': 'gif',\n  };\n  return map[mimeType?.toLowerCase()] || mimeType?.split('/')[1]?.split('+')[0] || 'png';\n};\n\nexport interface ToolbarProps {\n  children?: ReactNode;\n  info: Omit<ToolbarRenderInfoType, 'current' | 'total'>;\n  maxScale: number;\n  minScale: number;\n}\n\nconst Toolbar = memo<ToolbarProps>(({ children, info, minScale, maxScale }) => {\n  const { t } = useTranslation(imageMessages);\n  const [containerEl, setContainerEl] = useState<HTMLElement | null>(null);\n  const [copyLoading, setCopyLoading] = useState(false);\n  const [downloadLoading, setDownloadLoading] = useState(false);\n  const {\n    transform: { scale },\n    actions: { onFlipY, onFlipX, onRotateLeft, onRotateRight, onZoomOut, onZoomIn },\n    image: { url },\n  } = info;\n\n  const handleDownload = useCallback(async () => {\n    setDownloadLoading(true);\n    try {\n      const response = await fetch(url, { mode: 'cors' });\n      const blob = await response.blob();\n      const blobUrl = URL.createObjectURL(blob);\n      let fileName = getFileNameFromUrl(url);\n      const ext = getExtensionFromMimeType(blob.type);\n      if (!fileName.includes('.')) {\n        fileName = `${fileName}.${ext}`;\n      } else if (fileName.endsWith('.svg+xml')) {\n        fileName = fileName.replace(/\\.svg\\+xml$/i, '.svg');\n      }\n      await downloadBlob(blobUrl, fileName);\n      URL.revokeObjectURL(blobUrl);\n      message.success(t('image.downloadSuccess'));\n    } catch {\n      message.error(t('image.downloadFailed'));\n    } finally {\n      setDownloadLoading(false);\n    }\n  }, [url, t]);\n\n  const handleCopy = useCallback(async () => {\n    setCopyLoading(true);\n    try {\n      const response = await fetch(url, { mode: 'cors' });\n      const blob = await response.blob();\n      const clipboardBlob = await getClipboardBlob(blob);\n      await navigator.clipboard.write([new ClipboardItem(clipboardBlob)]);\n      message.success(t('image.copySuccess'));\n    } catch {\n      message.error(t('image.copyFailed'));\n    } finally {\n      setCopyLoading(false);\n    }\n  }, [url, t]);\n\n  return (\n    <TooltipGroup popupContainer={containerEl ?? undefined}>\n      <Flexbox horizontal className={styles.toolbar} gap={4} ref={setContainerEl}>\n        <ActionIcon icon={FlipHorizontal} title={t('image.flipHorizontal')} onClick={onFlipX} />\n        <ActionIcon icon={FlipVertical} title={t('image.flipVertical')} onClick={onFlipY} />\n        <ActionIcon icon={RotateCcw} title={t('image.rotateLeft')} onClick={onRotateLeft} />\n        <ActionIcon icon={RotateCw} title={t('image.rotateRight')} onClick={onRotateRight} />\n        <ActionIcon\n          disabled={scale === minScale}\n          icon={ZoomOut}\n          title={t('image.zoomOut')}\n          onClick={onZoomOut}\n        />\n        <ActionIcon\n          disabled={scale === maxScale}\n          icon={ZoomIn}\n          title={t('image.zoomIn')}\n          onClick={onZoomIn}\n        />\n        <ActionIcon\n          icon={Copy}\n          loading={copyLoading}\n          title={t('image.copy')}\n          onClick={handleCopy}\n        />\n        <ActionIcon\n          icon={Download}\n          loading={downloadLoading}\n          title={t('image.download')}\n          onClick={handleDownload}\n        />\n        {children}\n      </Flexbox>\n    </TooltipGroup>\n  );\n});\n\nexport default Toolbar;\n"],"mappings":"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"}