feat : dreamgineer ask me try to use this and now im ran out of token sad [no ci]
This commit is contained in:
@@ -11,7 +11,7 @@ import { saveGuideOverview } from "@/app/admin/actions";
|
||||
import { AutosaveStatus } from "@/components/admin/autosave-status";
|
||||
import { MediaUploader } from "@/components/admin/media-uploader";
|
||||
import { MaterialPoster, type PosterBlendMode } from "@/components/public/material-poster";
|
||||
import { GuideImageExport } from "@/components/public/guide-image-export";
|
||||
import { TakumiImageExport } from "@/components/public/takumi-image-export";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
@@ -458,26 +458,16 @@ export function GuideOverviewForm({
|
||||
ลบภาพตัวละคร
|
||||
</Button>
|
||||
) : null}
|
||||
<GuideImageExport
|
||||
<TakumiImageExport
|
||||
width={1600}
|
||||
height={2000}
|
||||
format="png"
|
||||
disabled={!posterArt.url}
|
||||
fileName={`${guide.name}-materials.png`}
|
||||
allowWithoutNotes={false}
|
||||
captureClassName="p-0"
|
||||
>
|
||||
<MaterialPoster
|
||||
character={guide.character}
|
||||
characterArtUrl={posterArt.url}
|
||||
artworkOffsetX={posterArtOffset.x}
|
||||
artworkOffsetY={posterArtOffset.y}
|
||||
artworkScale={posterArtScale}
|
||||
topColors={posterTopColors}
|
||||
bottomColors={posterBottomColors}
|
||||
bleeding={bleeding}
|
||||
/>
|
||||
</GuideImageExport>
|
||||
preview
|
||||
template={{ kind: "materials", data: { character: guide.character, characterArtUrl: posterArt.url, artworkOffsetX: posterArtOffset.x, artworkOffsetY: posterArtOffset.y, artworkScale: posterArtScale, topColors: posterTopColors, bottomColors: posterBottomColors, bleeding } }}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2 rounded-lg border p-3">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import {
|
||||
CropIcon,
|
||||
DownloadIcon,
|
||||
GripVerticalIcon,
|
||||
ImageIcon,
|
||||
PlusIcon,
|
||||
@@ -41,6 +40,7 @@ import {
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { TakumiImageExport } from "@/components/public/takumi-image-export";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
@@ -80,7 +80,6 @@ import {
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Spinner } from "@/components/ui/spinner";
|
||||
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
|
||||
import { elementIconFilter } from "@/lib/catalog/element";
|
||||
import { rarityGradientClass } from "@/lib/catalog/rarity";
|
||||
@@ -699,7 +698,6 @@ export function OverviewImageGenerator({
|
||||
characters: Character[];
|
||||
elementIconUrls: Record<string, string | null>;
|
||||
}) {
|
||||
const captureRef = useRef<HTMLDivElement>(null);
|
||||
const [character, setCharacter] = useState<Character | null>(null);
|
||||
const [artworkUrl, setArtworkUrl] = useState<string | null>(null);
|
||||
const [artworkError, setArtworkError] = useState<string | null>(null);
|
||||
@@ -735,7 +733,6 @@ export function OverviewImageGenerator({
|
||||
coordinateGetter: sortableKeyboardCoordinates,
|
||||
}),
|
||||
);
|
||||
const [exporting, setExporting] = useState(false);
|
||||
const [backgroundUrl, setBackgroundUrl] = useState<string | null>(null);
|
||||
const [fadeColor, setFadeColor] = useState("#0E0200");
|
||||
const [fadeTint, setFadeTint] = useState(100);
|
||||
@@ -998,49 +995,6 @@ export function OverviewImageGenerator({
|
||||
}
|
||||
}
|
||||
|
||||
async function download() {
|
||||
const node = captureRef.current;
|
||||
if (
|
||||
!node ||
|
||||
!character ||
|
||||
!artworkUrl ||
|
||||
!normalizeHex(topColorStart) ||
|
||||
!normalizeHex(topColorEnd) ||
|
||||
!normalizeHex(bottomColorStart) ||
|
||||
!normalizeHex(bottomColorEnd) ||
|
||||
!normalizeHex(elementColorStart) ||
|
||||
!normalizeHex(elementColorEnd) ||
|
||||
!normalizeHex(fadeColor)
|
||||
)
|
||||
return;
|
||||
|
||||
setExporting(true);
|
||||
try {
|
||||
const { domToBlob, waitUntilLoad } = await import("modern-screenshot");
|
||||
await Promise.all([document.fonts.ready, waitUntilLoad(node)]);
|
||||
const blob = await domToBlob(node, {
|
||||
backgroundColor: "#000000",
|
||||
type: "image/png",
|
||||
width: 1000,
|
||||
height: 1000,
|
||||
scale: 3,
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = overviewFileName(character.key, displayRole);
|
||||
document.body.append(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
window.setTimeout(() => URL.revokeObjectURL(url), 0);
|
||||
toast.success("ดาวน์โหลดภาพ Overview แล้ว");
|
||||
} catch {
|
||||
toast.error("ส่งออกภาพไม่สำเร็จ กรุณาลองอีกครั้ง");
|
||||
} finally {
|
||||
setExporting(false);
|
||||
}
|
||||
}
|
||||
|
||||
const ready = Boolean(
|
||||
character &&
|
||||
artworkUrl &&
|
||||
@@ -1335,18 +1289,12 @@ export function OverviewImageGenerator({
|
||||
</FieldGroup>
|
||||
</CardContent>
|
||||
<CardFooter className="flex flex-col gap-2">
|
||||
<Button
|
||||
className="w-full"
|
||||
disabled={!ready || exporting}
|
||||
onClick={() => void download()}
|
||||
>
|
||||
{exporting ? (
|
||||
<Spinner data-icon="inline-start" />
|
||||
) : (
|
||||
<DownloadIcon data-icon="inline-start" />
|
||||
)}
|
||||
{exporting ? "กำลังส่งออก…" : "ดาวน์โหลด PNG 3000×3000"}
|
||||
</Button>
|
||||
<TakumiImageExport
|
||||
width={3000} height={3000} allowWithoutNotes={false} preview disabled={!ready}
|
||||
fileName={overviewFileName(character?.key ?? "overview", displayRole)}
|
||||
buttonLabel="ดาวน์โหลด PNG 3000×3000"
|
||||
template={{ kind: "overview", data: { composition, artworkUrl, character, role: displayRole, topColors: [topColorStart, topColorEnd], bottomColors: [bottomColorStart, bottomColorEnd], elementColors: [elementColorStart, elementColorEnd], elementGradientAngle, blendLayers, nameCardCrop, nameCardSize, elementIconUrls, disclaimerFontSize } }}
|
||||
/>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</div>
|
||||
@@ -1469,28 +1417,6 @@ export function OverviewImageGenerator({
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<div
|
||||
ref={captureRef}
|
||||
aria-hidden="true"
|
||||
className="pointer-events-none fixed top-0 -left-[10000px] order-5 size-[1000px]"
|
||||
>
|
||||
<OverviewPoster
|
||||
composition={composition}
|
||||
artworkUrl={artworkUrl}
|
||||
character={character}
|
||||
role={displayRole}
|
||||
topColors={[topColorStart, topColorEnd]}
|
||||
bottomColors={[bottomColorStart, bottomColorEnd]}
|
||||
elementColors={[elementColorStart, elementColorEnd]}
|
||||
elementGradientAngle={elementGradientAngle}
|
||||
blendLayers={blendLayers}
|
||||
nameCardCrop={nameCardCrop}
|
||||
nameCardSize={nameCardSize}
|
||||
elementIconUrls={elementIconUrls}
|
||||
disclaimerFontSize={disclaimerFontSize}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Dialog
|
||||
open={Boolean(pendingCrop)}
|
||||
onOpenChange={(open) => {
|
||||
|
||||
Reference in New Issue
Block a user