import { Doc, StrListCast } from '../../../fields/Doc'; import { List } from '../../../fields/List'; import { DocCast, ImageCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { Upload } from '../../../server/SharedMediaTypes'; import { gptDescribeImage } from '../../apis/gpt/GPT'; import { Docs } from '../../documents/Documents'; import { Networking } from '../../Network'; import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView'; import { OpenWhere } from '../nodes/OpenWhere'; import { AspectRatioLimits, FireflyDimensionsMap, FireflyImageDimensions, FireflyStylePresets } from './FireflyConstants'; const DashDropboxId = '2m86iveqdr9vzsa'; export class DrawingFillHandler { static authorizeDropbox = () => { window.open(`https://www.dropbox.com/oauth2/authorize?client_id=${DashDropboxId}&response_type=code&token_access_type=offline&redirect_uri=http://localhost:1050/refreshDropbox`, '_blank')?.focus(); }; static drawingToImage = async (drawing: Doc, strength: number, user_prompt: string, styleDoc?: Doc) => { const tags = StrListCast(drawing.$tags).map(tag => tag.slice(1)); const styles = tags.filter(tag => FireflyStylePresets.has(tag)); const styleDocs = [drawing].concat( drawing, ...Doc.Links(drawing) .map(link => Doc.getOppositeAnchor(link, drawing)) .map(anchor => DocCast(anchor?.annotationOn, anchor)) .map(anchor => anchor!), ...(styleDoc ? [styleDoc] : []) ); const styleUrl = tags.length ? undefined : await DocumentView.GetDocImage(styleDocs.filter(doc => doc?.data instanceof ImageField).lastElement())?.then(styleImg => { const hrefParts = ImageCast(styleImg)?.url.href.split('.'); return !hrefParts ? undefined : `${hrefParts.slice(0, -1).join('.')}_o.${hrefParts.lastElement()}`; }); return DocumentView.GetDocImage(drawing)?.then(imageField => { const href = ImageCast(imageField)?.url.href; if (href) { const aspectRatio = (drawing.width as number) / (drawing.height as number); const dims = (() => { if (aspectRatio > AspectRatioLimits[FireflyImageDimensions.Widescreen]) return FireflyDimensionsMap[FireflyImageDimensions.Widescreen]; if (aspectRatio > AspectRatioLimits[FireflyImageDimensions.Landscape]) return FireflyDimensionsMap[FireflyImageDimensions.Landscape]; if (aspectRatio < AspectRatioLimits[FireflyImageDimensions.Portrait]) return FireflyDimensionsMap[FireflyImageDimensions.Portrait]; return FireflyDimensionsMap[FireflyImageDimensions.Square]; })(); const hrefParts = href.split('.'); const structureUrl = `${hrefParts.slice(0, -1).join('.')}_o.${hrefParts.lastElement()}`; return gptDescribeImage(user_prompt, structureUrl).then(newPrompt => Networking.PostToServer('/queryFireflyImageFromStructure', { prompt: `${newPrompt}`, width: dims.width, height: dims.height, structureUrl, strength, presets: styles, styleUrl }) .then(res => { const error = ('error' in res && (res.error as string)) || ''; if (error.includes('Dropbox') && confirm('Create image failed. Try authorizing DropBox?\r\n' + error.replace(/^[^"]*/, ''))) { return DrawingFillHandler.authorizeDropbox(); } const genratedDocs = DocCast(drawing.ai_generatedDocs) ?? Docs.Create.MasonryDocument([], { title: StrCast(drawing.title) + ' AI Images', _width: 400, _height: 400 }); drawing.$ai_generatedDocs = genratedDocs; (res as Upload.ImageInformation[]).map(info => Doc.AddDocToList( genratedDocs, undefined, Docs.Create.ImageDocument(info.accessPaths.agnostic.client, { ai: 'firefly', ai_prompt: newPrompt, tags: new List(['@ai']), title: newPrompt, //_data_usePath: 'alternate:hover', data_alternates: new List([drawing]), _width: 500, data_nativeWidth: info.nativeWidth, data_nativeHeight: info.nativeHeight, }), undefined, undefined, true ) ); if (!DocumentView.getFirstDocumentView(genratedDocs)) DocumentViewInternal.addDocTabFunc(genratedDocs, OpenWhere.addRight); }) .catch(e => { alert(e.toString()); }) ); // prettier-ignore:q } }); }; }