storytellurx-v1/app/components/chat/chat-image.tsx
Elias Rhouzlane cfe3526f6b fix: localize
2025-07-14 14:08:57 +02:00

68 lines
2.2 KiB
TypeScript

import cn from "@bureaudouble/outils/cn.ts";
import type { ImageGenerationPayload } from "../../actions/generate-image.ts";
import type { NarrativeMessage } from "../../game-engine/narrative-provider.tsx";
import {
gameStateToVariantState,
personaImageMessageVariants,
} from "../../game-engine/persona-styles.ts";
import { useTurn } from "../../game-engine/turn-provider.tsx";
import { Rationale } from "./chat-message.tsx";
import { useClientLocale } from "../../game-engine/locale-provider.tsx";
export const getImageDataFromMessage = (
message?: NarrativeMessage | null,
): ImageGenerationPayload | null => {
const imageGeneration = message?.parts
.filter((v) => v.type === "tool-invocation")
.flatMap((v) => v.toolInvocation)
.filter((v) => v.state === "result")
.map((v) => v.result as ImageGenerationPayload | undefined)
.filter((v) => v?.imageUrl)
.at(0);
return imageGeneration ?? null;
};
export const ImageDisplay: React.FC<{ className?: string }> = (
{ className },
) => {
const { t } = useClientLocale();
const { message, turnData } = useTurn();
if (!turnData) return;
const imageResponse = getImageDataFromMessage(message);
const visualPromptInstructionText =
"visualPromptInstruction" in turnData && turnData?.visualPromptInstruction
? turnData.visualPromptInstruction
: undefined;
if (!imageResponse) return null;
const { isLoadingImage, imageUrl } = imageResponse;
if (!isLoadingImage && !imageUrl && !visualPromptInstructionText) return null;
const variantState = gameStateToVariantState(turnData?.fullGameState);
return (
<div
data-id={imageUrl?.slice(-10)}
className={cn(personaImageMessageVariants(variantState), className)}
>
{(visualPromptInstructionText || (!imageUrl && !isLoadingImage)) && (
<Rationale
title={t("visualRationaleTitle")}
content={visualPromptInstructionText}
/>
)}
{isLoadingImage && <div data-image-loading />}
{imageUrl && !isLoadingImage && (
<img
data-image
src={imageUrl}
alt={visualPromptInstructionText}
loading="lazy"
/>
)}
</div>
);
};