@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
130 lines (128 loc) • 4.38 kB
JavaScript
import FlexBasic_default from "../../Flex/FlexBasic.mjs";
import TooltipGroup_default from "../../Tooltip/TooltipGroup.mjs";
import ActionIcon_default from "../../ActionIcon/ActionIcon.mjs";
import { useTranslation } from "../../i18n/useTranslation.mjs";
import { downloadBlob } from "../../utils/downloadBlob.mjs";
import { styles } from "../style.mjs";
import image_default from "../../i18n/resources/en/image.mjs";
import { getClipboardBlob } from "../../utils/blobToPng.mjs";
import { memo, useCallback, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { message } from "antd";
import { Copy, Download, FlipHorizontal, FlipVertical, RotateCcw, RotateCw, ZoomIn, ZoomOut } from "lucide-react";
//#region src/Image/components/Toolbar.tsx
const getFileNameFromUrl = (url) => {
try {
const match = new URL(url).pathname.match(/\/([^/]+)$/);
return match ? decodeURIComponent(match[1]) : "image";
} catch {
return "image";
}
};
const getExtensionFromMimeType = (mimeType) => {
return {
"image/svg+xml": "svg",
"image/png": "png",
"image/jpeg": "jpg",
"image/jpg": "jpg",
"image/webp": "webp",
"image/gif": "gif"
}[mimeType?.toLowerCase()] || mimeType?.split("/")[1]?.split("+")[0] || "png";
};
const Toolbar = memo(({ children, info, minScale, maxScale }) => {
const { t } = useTranslation(image_default);
const [containerEl, setContainerEl] = useState(null);
const [copyLoading, setCopyLoading] = useState(false);
const [downloadLoading, setDownloadLoading] = useState(false);
const { transform: { scale }, actions: { onFlipY, onFlipX, onRotateLeft, onRotateRight, onZoomOut, onZoomIn }, image: { url } } = info;
const handleDownload = useCallback(async () => {
setDownloadLoading(true);
try {
const blob = await (await fetch(url, { mode: "cors" })).blob();
const blobUrl = URL.createObjectURL(blob);
let fileName = getFileNameFromUrl(url);
const ext = getExtensionFromMimeType(blob.type);
if (!fileName.includes(".")) fileName = `${fileName}.${ext}`;
else if (fileName.endsWith(".svg+xml")) fileName = fileName.replace(/\.svg\+xml$/i, ".svg");
await downloadBlob(blobUrl, fileName);
URL.revokeObjectURL(blobUrl);
message.success(t("image.downloadSuccess"));
} catch {
message.error(t("image.downloadFailed"));
} finally {
setDownloadLoading(false);
}
}, [url, t]);
const handleCopy = useCallback(async () => {
setCopyLoading(true);
try {
const clipboardBlob = await getClipboardBlob(await (await fetch(url, { mode: "cors" })).blob());
await navigator.clipboard.write([new ClipboardItem(clipboardBlob)]);
message.success(t("image.copySuccess"));
} catch {
message.error(t("image.copyFailed"));
} finally {
setCopyLoading(false);
}
}, [url, t]);
return /* @__PURE__ */ jsx(TooltipGroup_default, {
popupContainer: containerEl ?? void 0,
children: /* @__PURE__ */ jsxs(FlexBasic_default, {
horizontal: true,
className: styles.toolbar,
gap: 4,
ref: setContainerEl,
children: [
/* @__PURE__ */ jsx(ActionIcon_default, {
icon: FlipHorizontal,
title: t("image.flipHorizontal"),
onClick: onFlipX
}),
/* @__PURE__ */ jsx(ActionIcon_default, {
icon: FlipVertical,
title: t("image.flipVertical"),
onClick: onFlipY
}),
/* @__PURE__ */ jsx(ActionIcon_default, {
icon: RotateCcw,
title: t("image.rotateLeft"),
onClick: onRotateLeft
}),
/* @__PURE__ */ jsx(ActionIcon_default, {
icon: RotateCw,
title: t("image.rotateRight"),
onClick: onRotateRight
}),
/* @__PURE__ */ jsx(ActionIcon_default, {
disabled: scale === minScale,
icon: ZoomOut,
title: t("image.zoomOut"),
onClick: onZoomOut
}),
/* @__PURE__ */ jsx(ActionIcon_default, {
disabled: scale === maxScale,
icon: ZoomIn,
title: t("image.zoomIn"),
onClick: onZoomIn
}),
/* @__PURE__ */ jsx(ActionIcon_default, {
icon: Copy,
loading: copyLoading,
title: t("image.copy"),
onClick: handleCopy
}),
/* @__PURE__ */ jsx(ActionIcon_default, {
icon: Download,
loading: downloadLoading,
title: t("image.download"),
onClick: handleDownload
}),
children
]
})
});
});
var Toolbar_default = Toolbar;
//#endregion
export { Toolbar_default as default };
//# sourceMappingURL=Toolbar.mjs.map