diff --git a/src/components/CanvasBlurCapture.tsx b/src/components/CanvasBlurCapture.tsx index af8eea89..cce1ed31 100644 --- a/src/components/CanvasBlurCapture.tsx +++ b/src/components/CanvasBlurCapture.tsx @@ -72,18 +72,20 @@ export default function CanvasBlurCapture({ edgeCompensation * 2, ); onCapture(canvas.toDataURL('image/jpeg', quality)); + onError?.(''); refTimeouts.current.forEach(clearTimeout); refShouldCapture.current = false; } else { - console.error('Cannot get 2d context'); - onError?.('Cannot get 2d context'); + console.error('Cannot get 2d context ... retrying'); + onError?.('Cannot get 2d context ... retrying'); // Retry capture in case canvas is not available refTimeouts.current.push(setTimeout(capture, RETRY_DELAY)); } } else { // eslint-disable-next-line max-len - console.error('Cannot generate blur data: canvas/image not ready'); - onError?.('Cannot generate blur data: canvas/image not ready'); + console.error('Cannot generate blur data: canvas/image not ready ... retrying'); + // eslint-disable-next-line max-len + onError?.('Cannot generate blur data: canvas/image not ready ... retrying'); // Retry capture in case canvas is not available refTimeouts.current.push(setTimeout(capture, RETRY_DELAY)); } diff --git a/src/photo/ai/index.ts b/src/photo/ai/index.ts index a2ea7b8e..b8375008 100644 --- a/src/photo/ai/index.ts +++ b/src/photo/ai/index.ts @@ -6,15 +6,23 @@ export type ImageQuery = 'tags' | 'descriptionSmall' | 'descriptionMedium' | - 'descriptionLarge'; + 'descriptionLarge' | + 'rich' | + 'semantic'; export const IMAGE_QUERIES: Record = { - title: 'Provide a short title for this image', - caption: 'What is the caption of this image?', - tags: 'Describe this image three or less comma-separated keywords', + // title: 'Provide a short title for this image', + title: 'Provide a short title for this image in 3 words or less', + caption: 'What is a pithy caption for this image in 8 words or less?', + // eslint-disable-next-line max-len + tags: 'Describe this image three or less comma-separated keywords with no adjective or adverbs', descriptionSmall: 'Describe this image succinctly', descriptionMedium: 'Describe this image', descriptionLarge: 'Describe this image in detail', + // eslint-disable-next-line max-len + rich: 'What is a short title and pithy caption of 8 words or less for this image?', + // eslint-disable-next-line max-len + semantic: 'List up to 5 things in this image without description as a comma-separated list', }; export const streamImageQuery = (imageBase64: string, query: ImageQuery) => diff --git a/src/photo/ai/useImageQuery.ts b/src/photo/ai/useImageQuery.ts index 51e8ec93..9f0079eb 100644 --- a/src/photo/ai/useImageQuery.ts +++ b/src/photo/ai/useImageQuery.ts @@ -16,7 +16,7 @@ export default function useImageQuery( setIsLoading(true); try { const textStream = await streamImageQueryAction( - imageBase64 ?? '', + imageBase64, query, ); for await (const text of readStreamableValue(textStream)) { @@ -30,9 +30,12 @@ export default function useImageQuery( } }, [imageBase64, query]); + // Withhold streaming text if it's a null response + const isTextError = text.toLocaleLowerCase().startsWith('sorry'); + return [ request, - text, + isTextError ? '' : text, isLoading, error, ] as const; diff --git a/src/photo/form/PhotoForm.tsx b/src/photo/form/PhotoForm.tsx index 6a98bf41..e7068c69 100644 --- a/src/photo/form/PhotoForm.tsx +++ b/src/photo/form/PhotoForm.tsx @@ -120,12 +120,19 @@ export default function PhotoForm({ } }, []); - const [ - requestTitle, - title, - isLoadingTitle, - errorTitle, - ] = useImageQuery(imageData, 'title'); + // const [ + // requestTitle, + // title, + // isLoadingTitle, + // errorTitle, + // ] = useImageQuery(imageData, 'title'); + + // const [ + // requestCaption, + // caption, + // isLoadingCaption, + // errorCaption, + // ] = useImageQuery(imageData, 'caption'); const [ requestTags, @@ -135,18 +142,25 @@ export default function PhotoForm({ ] = useImageQuery(imageData, 'tags'); const [ - requestDescriptionSmall, - descriptionSmall, - isLoadingDescriptionSmall, - errorDescriptionSmall, - ] = useImageQuery(imageData, 'descriptionSmall'); + requestRich, + rich, + isLoadingRich, + errorRich, + ] = useImageQuery(imageData, 'rich'); + + // const [ + // requestDescriptionSmall, + // descriptionSmall, + // isLoadingDescriptionSmall, + // errorDescriptionSmall, + // ] = useImageQuery(imageData, 'descriptionSmall'); const [ - requestDescriptionLarge, - descriptionLarge, - isLoadingDescriptionLarge, - errorDescriptionLarge, - ] = useImageQuery(imageData, 'descriptionLarge'); + requestSemantic, + semantic, + isLoadingSemantic, + errorSemantic, + ] = useImageQuery(imageData, 'semantic'); const renderAiButton = ( label: string, @@ -180,12 +194,30 @@ export default function PhotoForm({ {blurError} }
- {renderAiButton( + {/* {renderAiButton( 'Title', requestTitle, isLoadingTitle, errorTitle, )} + {renderAiButton( + 'Caption', + requestCaption, + isLoadingCaption, + errorCaption, + )} + {renderAiButton( + 'Tags', + requestTags, + isLoadingTags, + errorTags, + )} */} + {renderAiButton( + 'Rich', + requestRich, + isLoadingRich, + errorRich, + )} {renderAiButton( 'Tags', requestTags, @@ -193,17 +225,17 @@ export default function PhotoForm({ errorTags, )} {renderAiButton( - 'Description (S)', + 'Semantic', + requestSemantic, + isLoadingSemantic, + errorSemantic, + )} + {/* {renderAiButton( + 'Description', requestDescriptionSmall, isLoadingDescriptionSmall, errorDescriptionSmall, - )} - {renderAiButton( - 'Description (L)', - requestDescriptionLarge, - isLoadingDescriptionLarge, - errorDescriptionLarge, - )} + )} */}
}
-

+ {/*

✨ TITLE: {title} {isLoadingTitle && <> }

+

+ ✨ CAPTION: {caption} {isLoadingCaption && <> + + + + } +

*/} +

+ ✨ RICH: {rich} {isLoadingRich && <> + + + + } +

✨ TAGS: {tags} {isLoadingTags && <> @@ -252,19 +298,19 @@ export default function PhotoForm({ }

- ✨ DESCRIPTION (S): {descriptionSmall} {isLoadingDescriptionSmall && <> + ✨ SEMANTIC: {semantic} {isLoadingSemantic && <> }

-

- ✨ DESCRIPTION (L): {descriptionLarge} {isLoadingDescriptionLarge && <> + {/*

+ ✨ DESCRIPTION: {descriptionSmall} {isLoadingDescriptionSmall && <> } -

+

*/}
blur()}