Integrate ai auto-fill into edit form
This commit is contained in:
parent
e2e8c8edda
commit
097496a739
@ -99,7 +99,7 @@ export default function FieldSetWithStatus({
|
||||
options={tagOptions}
|
||||
onChange={onChange}
|
||||
className={clsx(Boolean(error) && 'error')}
|
||||
readOnly={readOnly || pending}
|
||||
readOnly={readOnly || pending || loading}
|
||||
/>
|
||||
: <input
|
||||
ref={inputRef}
|
||||
@ -114,7 +114,7 @@ export default function FieldSetWithStatus({
|
||||
type={type}
|
||||
autoComplete="off"
|
||||
autoCapitalize={!capitalize ? 'off' : undefined}
|
||||
readOnly={readOnly || pending}
|
||||
readOnly={readOnly || pending || loading}
|
||||
className={clsx(
|
||||
type === 'text' && 'w-full',
|
||||
Boolean(error) && 'error',
|
||||
|
||||
@ -10,7 +10,7 @@ export type AiImageQuery =
|
||||
'description-small' |
|
||||
'description' |
|
||||
'description-large' |
|
||||
'semantic';
|
||||
'description-semantic';
|
||||
|
||||
export const AI_IMAGE_QUERIES: Record<AiImageQuery, string> = {
|
||||
'title': 'Provide a short title for this image in 3 words or less',
|
||||
@ -20,7 +20,7 @@ export const AI_IMAGE_QUERIES: Record<AiImageQuery, string> = {
|
||||
'description-small': 'Describe this image succinctly',
|
||||
'description': 'Describe this image',
|
||||
'description-large': 'Describe this image in detail',
|
||||
'semantic': 'List up to 5 things in this image without description as a comma-separated list',
|
||||
'description-semantic': 'List up to 5 things in this image without description as a comma-separated list',
|
||||
};
|
||||
|
||||
export const streamAiImageQuery = (imageBase64: string, query: AiImageQuery) =>
|
||||
|
||||
@ -24,11 +24,21 @@ export default function useImageQueries() {
|
||||
|
||||
const [
|
||||
requestSemantic,
|
||||
semantic,
|
||||
semanticDescription,
|
||||
isLoadingSemantic,
|
||||
] = useImageQuery(imageData, 'semantic');
|
||||
] = useImageQuery(imageData, 'description-semantic');
|
||||
|
||||
const isLoading = isLoadingTitleCaption || isLoadingTags || isLoadingSemantic;
|
||||
const hasContent = Boolean(
|
||||
title ||
|
||||
caption ||
|
||||
tags ||
|
||||
semanticDescription
|
||||
);
|
||||
|
||||
const isLoading =
|
||||
isLoadingTitleCaption ||
|
||||
isLoadingTags ||
|
||||
isLoadingSemantic;
|
||||
|
||||
const request = useCallback(async () => {
|
||||
if (!isLoading) {
|
||||
@ -44,8 +54,9 @@ export default function useImageQueries() {
|
||||
title,
|
||||
caption,
|
||||
tags,
|
||||
semantic,
|
||||
semanticDescription,
|
||||
isReady,
|
||||
hasContent,
|
||||
isLoading,
|
||||
isLoadingTitleCaption,
|
||||
isLoadingTags,
|
||||
|
||||
@ -120,6 +120,33 @@ export default function PhotoForm({
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (aiContent?.hasContent) {
|
||||
setFormData(data => ({
|
||||
...data,
|
||||
title: aiContent.title,
|
||||
caption: aiContent.caption,
|
||||
tags: aiContent.tags,
|
||||
semanticDescription: aiContent.semanticDescription,
|
||||
}));
|
||||
}
|
||||
}, [aiContent]);
|
||||
|
||||
const isFieldGeneratingAi = (key: keyof PhotoFormData) => {
|
||||
switch (key) {
|
||||
case 'title':
|
||||
return aiContent?.isLoadingTitleCaption;
|
||||
case 'caption':
|
||||
return aiContent?.isLoadingTitleCaption;
|
||||
case 'tags':
|
||||
return aiContent?.isLoadingTags;
|
||||
case 'semanticDescription':
|
||||
return aiContent?.isLoadingSemantic;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-8 max-w-[38rem]">
|
||||
{debugBlur && blurError &&
|
||||
@ -158,10 +185,6 @@ export default function PhotoForm({
|
||||
height={height}
|
||||
/>}
|
||||
</div>
|
||||
<div>Title: {aiContent?.title}</div>
|
||||
<div>Caption: {aiContent?.caption}</div>
|
||||
<div>Tags: {aiContent?.tags}</div>
|
||||
<div>Semantic: {aiContent?.semantic}</div>
|
||||
<form
|
||||
action={type === 'create' ? createPhotoAction : updatePhotoAction}
|
||||
onSubmit={() => blur()}
|
||||
@ -228,7 +251,9 @@ export default function PhotoForm({
|
||||
placeholder={loadingMessage && !formData[key]
|
||||
? loadingMessage
|
||||
: undefined}
|
||||
loading={loadingMessage && !formData[key] ? true : false}
|
||||
loading={
|
||||
(loadingMessage && !formData[key] ? true : false) ||
|
||||
isFieldGeneratingAi(key)}
|
||||
type={type}
|
||||
/>)}
|
||||
<div className="flex gap-3">
|
||||
|
||||
@ -80,7 +80,7 @@ const FORM_METADATA = (
|
||||
: undefined,
|
||||
},
|
||||
semanticDescription: {
|
||||
label: 'semantic description',
|
||||
label: 'semantic description (not visible)',
|
||||
capitalize: true,
|
||||
validateStringMaxLength: STRING_MAX_LENGTH_LONG,
|
||||
hide: !aiTextGeneration,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user