feat : add language export and some image gen optimaize
This commit is contained in:
@@ -6,6 +6,11 @@ import { DownloadIcon } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
ExportLanguageToggle,
|
||||
useExportLanguage,
|
||||
type ExportLanguage,
|
||||
} from "@/components/public/export-language";
|
||||
import { Spinner } from "@/components/ui/spinner";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -21,6 +26,21 @@ function downloadFileName(value: string): string {
|
||||
return value.replace(/[\\/:*?"<>|]/gu, "-");
|
||||
}
|
||||
|
||||
export function imageExportFileName(
|
||||
fileName: string,
|
||||
language: ExportLanguage,
|
||||
withoutNotes: boolean,
|
||||
localized = true,
|
||||
): string {
|
||||
const selectedFileName = withoutNotes ? withoutNotesFileName(fileName) : fileName;
|
||||
const languageFileName = localized
|
||||
? (/\.[^.]+$/u.test(selectedFileName)
|
||||
? selectedFileName.replace(/(\.[^.]+)$/u, `-${language}$1`)
|
||||
: `${selectedFileName}-${language}`)
|
||||
: selectedFileName;
|
||||
return downloadFileName(languageFileName);
|
||||
}
|
||||
|
||||
export function GuideImageExport({
|
||||
children,
|
||||
fileName,
|
||||
@@ -31,6 +51,9 @@ export function GuideImageExport({
|
||||
allowWithoutNotes = true,
|
||||
captureClassName,
|
||||
buttonLabel = "ส่งออกภาพ",
|
||||
language: controlledLanguage,
|
||||
showLanguageSelector = true,
|
||||
localizeFileName = true,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
fileName: string;
|
||||
@@ -41,12 +64,17 @@ export function GuideImageExport({
|
||||
allowWithoutNotes?: boolean;
|
||||
captureClassName?: string;
|
||||
buttonLabel?: string;
|
||||
language?: ExportLanguage;
|
||||
showLanguageSelector?: boolean;
|
||||
localizeFileName?: boolean;
|
||||
}) {
|
||||
const captureRef = useRef<HTMLDivElement>(null);
|
||||
const [captureMode, setCaptureMode] = useState<
|
||||
"with-notes" | "without-notes" | null
|
||||
>(null);
|
||||
const capturing = captureMode !== null;
|
||||
const [storedLanguage, setStoredLanguage] = useExportLanguage();
|
||||
const language = controlledLanguage ?? storedLanguage;
|
||||
|
||||
useEffect(() => {
|
||||
if (!capturing) return;
|
||||
@@ -88,10 +116,11 @@ export function GuideImageExport({
|
||||
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.download = downloadFileName(
|
||||
captureMode === "without-notes"
|
||||
? withoutNotesFileName(fileName)
|
||||
: fileName,
|
||||
link.download = imageExportFileName(
|
||||
fileName,
|
||||
language,
|
||||
captureMode === "without-notes",
|
||||
localizeFileName,
|
||||
);
|
||||
link.href = url;
|
||||
document.body.append(link);
|
||||
@@ -109,10 +138,13 @@ export function GuideImageExport({
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [capturing, captureMode, fileName, format, height, width]);
|
||||
}, [capturing, captureMode, fileName, format, height, language, localizeFileName, width]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{showLanguageSelector ? (
|
||||
<ExportLanguageToggle language={language} onChange={setStoredLanguage} />
|
||||
) : null}
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{(["with-notes", "without-notes"] as const).filter((mode) => allowWithoutNotes || mode === "with-notes").map((mode) => (
|
||||
<Button
|
||||
@@ -144,12 +176,14 @@ export function GuideImageExport({
|
||||
>
|
||||
<div
|
||||
ref={captureRef}
|
||||
data-export-language={language}
|
||||
className={cn(
|
||||
"bg-background p-10 text-foreground",
|
||||
captureClassName,
|
||||
)}
|
||||
style={{ width, height }}
|
||||
>
|
||||
<style>{'[data-export-language="th"] [data-export-lang="en"],[data-export-language="en"] [data-export-lang="th"]{display:none!important}'}</style>
|
||||
{children}
|
||||
</div>
|
||||
</div>,
|
||||
|
||||
Reference in New Issue
Block a user