From dbc609d3711c60d70eab1332c01547f47d68e389 Mon Sep 17 00:00:00 2001 From: Lancelot Owczarczak Date: Thu, 7 Dec 2023 17:57:52 +0100 Subject: [PATCH] :sparkles: react/components: Add ImageGenerated Component (#115) * :sparkles: react/components: Add ImageGenerated Component * :zap: models: Add model in generateImage, removed provider * :zap: react/components: Add model in ImageGenerated --- lib/components/ImageGenerated.tsx | 33 +++++++++++++++++++++++++++++++ lib/components/index.tsx | 11 ++++++++++- lib/image.ts | 29 +++++++++++++++------------ 3 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 lib/components/ImageGenerated.tsx diff --git a/lib/components/ImageGenerated.tsx b/lib/components/ImageGenerated.tsx new file mode 100644 index 0000000..1c17c65 --- /dev/null +++ b/lib/components/ImageGenerated.tsx @@ -0,0 +1,33 @@ +import React, { useState, useEffect } from "react"; +import { usePolyfire } from "../hooks"; + +export interface ImageGeneratedProps extends React.HTMLAttributes { + prompt: string; + model: string; + loadingElement?: React.JSX.Element | string; +} + +export function ImageGenerated({ + prompt, + loadingElement, + model, + ...props +}: ImageGeneratedProps): React.ReactElement { + const { + auth: { status }, + models: { generateImage }, + } = usePolyfire(); + + const [imageUrl, setImageUrl] = useState(); + + useEffect(() => { + if (status === "authenticated" && prompt) { + generateImage(prompt, { model }).then(({ url }) => setImageUrl(url)); + } + }, [status, generateImage, prompt]); + + if (imageUrl) { + return {prompt}; + } + return <>{loadingElement}; +} diff --git a/lib/components/index.tsx b/lib/components/index.tsx index d3293ce..fa327c2 100644 --- a/lib/components/index.tsx +++ b/lib/components/index.tsx @@ -1,5 +1,14 @@ import { TextGenerated, TextGeneratedProps } from "./TextGenerated"; import { TextSummary, TextSummaryProps } from "./TextSummary"; import { AutoCompleteInput } from "./AutoCompleteInput"; +import { ImageGenerated, ImageGeneratedProps } from "./ImageGenerated"; -export { TextGenerated, TextGeneratedProps, TextSummary, TextSummaryProps, AutoCompleteInput }; +export { + TextGenerated, + TextGeneratedProps, + TextSummary, + TextSummaryProps, + AutoCompleteInput, + ImageGenerated, + ImageGeneratedProps, +}; diff --git a/lib/image.ts b/lib/image.ts index c9054d0..9cc70f4 100644 --- a/lib/image.ts +++ b/lib/image.ts @@ -4,7 +4,7 @@ import { InputClientOptions, defaultOptions } from "./clientOpts"; import { ApiError, ErrorData } from "./helpers/error"; export type ImageGenerationOptions = { - provider?: "openai"; + model?: "dall-e-2" | "dall-e-3" | string; }; const ImageGenerationResponseType = t.type({ @@ -13,23 +13,26 @@ const ImageGenerationResponseType = t.type({ export async function generateImage( prompt: string, - options: ImageGenerationOptions = {}, + { model }: ImageGenerationOptions = {}, clientOptions: InputClientOptions = {}, ): Promise> { try { const { token, endpoint } = await defaultOptions(clientOptions); - const { provider = "openai" } = options; - const image = await axios.get( - `${endpoint}/image/generate?p=${encodeURIComponent( - prompt, - )}&provider=${encodeURIComponent(provider)}&format=json`, - { - headers: { - "X-Access-Token": token, - }, + const url = new URL(`${endpoint}/image/generate`); + + url.searchParams.append("p", prompt); + url.searchParams.append("format", "json"); + + if (model) { + url.searchParams.append("model", model); + } + + const image = await axios.get(url.toString(), { + headers: { + "X-Access-Token": token, }, - ); + }); if (!ImageGenerationResponseType.is(image.data)) { throw new ApiError({ @@ -57,7 +60,7 @@ export type ImageGenerationClient = { export default function client(clientOptions: InputClientOptions = {}): ImageGenerationClient { return { - generateImage: (prompt: string, options: ImageGenerationOptions) => + generateImage: (prompt: string, options: ImageGenerationOptions = {}) => generateImage(prompt, options, clientOptions), }; }