diff options
Diffstat (limited to 'src/client/views/smartdraw')
| -rw-r--r-- | src/client/views/smartdraw/DrawingFillHandler.tsx | 109 | ||||
| -rw-r--r-- | src/client/views/smartdraw/SmartDrawHandler.scss | 1 | ||||
| -rw-r--r-- | src/client/views/smartdraw/SmartDrawHandler.tsx | 83 | ||||
| -rw-r--r-- | src/client/views/smartdraw/StickerPalette.tsx | 61 |
4 files changed, 130 insertions, 124 deletions
diff --git a/src/client/views/smartdraw/DrawingFillHandler.tsx b/src/client/views/smartdraw/DrawingFillHandler.tsx index c672bc718..f773957e7 100644 --- a/src/client/views/smartdraw/DrawingFillHandler.tsx +++ b/src/client/views/smartdraw/DrawingFillHandler.tsx @@ -1,8 +1,6 @@ -import { imageUrlToBase64 } from '../../../ClientUtils'; import { Doc, StrListCast } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; import { List } from '../../../fields/List'; -import { DocCast, ImageCast } from '../../../fields/Types'; +import { DocCast, ImageCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { Upload } from '../../../server/SharedMediaTypes'; import { gptDescribeImage } from '../../apis/gpt/GPT'; @@ -14,23 +12,29 @@ import { AspectRatioLimits, FireflyDimensionsMap, FireflyImageDimensions, Firefl 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 docData = drawing[DocData]; - const tags = StrListCast(docData.tags).map(tag => tag.slice(1)); + const tags = StrListCast(drawing.$tags).map(tag => tag.slice(1)); const styles = tags.filter(tag => FireflyStylePresets.has(tag)); - const styleDocs = !Doc.Links(drawing).length - ? styleDoc && !tags.length - ? [styleDoc] - : [] - : Doc.Links(drawing) - .map(link => Doc.getOppositeAnchor(link, drawing)) - .map(anchor => anchor && DocCast(anchor.embedContainer)); - const styleUrl = await DocumentView.GetDocImage(styleDocs.filter(doc => doc?.data instanceof ImageField).lastElement())?.then(styleImg => { - const hrefParts = ImageCast(styleImg).url.href.split('.'); - return `${hrefParts.slice(0, -1).join('.')}_o.${hrefParts.lastElement()}`; - }); + 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 => { - if (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]; @@ -38,44 +42,43 @@ export class DrawingFillHandler { if (aspectRatio < AspectRatioLimits[FireflyImageDimensions.Portrait]) return FireflyDimensionsMap[FireflyImageDimensions.Portrait]; return FireflyDimensionsMap[FireflyImageDimensions.Square]; })(); - const { href } = ImageCast(imageField).url; const hrefParts = href.split('.'); const structureUrl = `${hrefParts.slice(0, -1).join('.')}_o.${hrefParts.lastElement()}`; - return imageUrlToBase64(structureUrl) - .then(gptDescribeImage) - .then((prompt, newPrompt = user_prompt || prompt) => - Networking.PostToServer('/queryFireflyImageFromStructure', { prompt: `${newPrompt}`, width: dims.width, height: dims.height, structureUrl, strength, presets: styles, styleUrl }) - .then(res => { - const genratedDocs = DocCast(drawing.ai_firefly_generatedDocs) ?? Docs.Create.MasonryDocument([], { _width: 400, _height: 400 }); - drawing[DocData].ai_firefly_generatedDocs = genratedDocs; - (res as Upload.ImageInformation[]).map(info => - Doc.AddDocToList( - genratedDocs, - undefined, - Docs.Create.ImageDocument(info.accessPaths.agnostic.client, { - ai: 'firefly', - tags: new List<string>(['@ai']), - title: newPrompt, - _data_usePath: 'alternate:hover', - data_alternates: new List<Doc>([drawing]), - ai_firefly_prompt: newPrompt, - _width: 500, - data_nativeWidth: info.nativeWidth, - data_nativeHeight: info.nativeHeight, - }), - undefined, - undefined, - true - ) - ); - if (!DocumentView.getFirstDocumentView(genratedDocs)) DocumentViewInternal.addDocTabFunc(genratedDocs, OpenWhere.addRight); - }) - .catch(e => { - if (e.toString().includes('Dropbox') && confirm('Create image failed. Try authorizing DropBox?\r\n' + e.toString().replace(/^[^"]*/, ''))) { - 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(); - } else alert(e.toString()); - }) - ); // prettier-ignore:q + 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<string>(['@ai']), + title: newPrompt, + _data_usePath: 'alternate:hover', + data_alternates: new List<Doc>([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 } }); }; diff --git a/src/client/views/smartdraw/SmartDrawHandler.scss b/src/client/views/smartdraw/SmartDrawHandler.scss index cca7d77c7..e80f1122b 100644 --- a/src/client/views/smartdraw/SmartDrawHandler.scss +++ b/src/client/views/smartdraw/SmartDrawHandler.scss @@ -73,5 +73,6 @@ .edit-box { display: flex; flex-direction: row; + color: black; } } diff --git a/src/client/views/smartdraw/SmartDrawHandler.tsx b/src/client/views/smartdraw/SmartDrawHandler.tsx index 1cceabed3..3976ec39e 100644 --- a/src/client/views/smartdraw/SmartDrawHandler.tsx +++ b/src/client/views/smartdraw/SmartDrawHandler.tsx @@ -10,9 +10,11 @@ import { INode, parse } from 'svgson'; import { imageUrlToBase64, setupMoveUpEvents } from '../../../ClientUtils'; import { unimplementedFunction } from '../../../Utils'; import { Doc, DocListCast } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; import { InkData, InkField, InkTool } from '../../../fields/InkField'; +import { List } from '../../../fields/List'; import { BoolCast, ImageCast, NumCast, StrCast } from '../../../fields/Types'; +import { PointData } from '../../../pen-gestures/GestureTypes'; +import { Upload } from '../../../server/SharedMediaTypes'; import { Networking } from '../../Network'; import { GPTCallType, gptAPICall, gptDrawingColor } from '../../apis/gpt/GPT'; import { DocumentType } from '../../documents/DocumentTypes'; @@ -26,9 +28,6 @@ import { MarqueeView } from '../collections/collectionFreeForm'; import { ActiveInkArrowEnd, ActiveInkArrowStart, ActiveInkBezierApprox, ActiveInkColor, ActiveInkDash, ActiveInkFillColor, ActiveInkWidth, ActiveIsInkMask, DocumentView } from '../nodes/DocumentView'; import { FireflyDimensionsMap, FireflyImageData, FireflyImageDimensions } from './FireflyConstants'; import './SmartDrawHandler.scss'; -import { Upload } from '../../../server/SharedMediaTypes'; -import { PointData } from '../../../pen-gestures/GestureTypes'; -import { List } from '../../../fields/List'; export interface DrawingOptions { text?: string; @@ -62,7 +61,6 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { static Instance: SmartDrawHandler; private _lastInput: DrawingOptions = { text: '', complexity: 5, size: 350, autoColor: true, x: 0, y: 0 }; - private _lastResponse: string = ''; private _selectedDocs: Doc[] = []; @observable private _display: boolean = false; @@ -98,7 +96,7 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { CollectionFreeForm, FormattedTextBox, StickerPalette) to define how a drawing document should be added or removed in their respective locations (to the freeform canvas, to the sticker palette's preview, etc.) */ - public AddDrawing: (doc: Doc, opts: DrawingOptions, gptRes: string, x?: number, y?: number) => void = unimplementedFunction; + public AddDrawing: (doc: Doc, opts: DrawingOptions, x?: number, y?: number) => void = unimplementedFunction; public RemoveDrawing: (useLastContainer: boolean, doc?: Doc) => void = unimplementedFunction; /** * This creates the ink document that represents a drawing, so it goes through the strokes that make up the drawing, @@ -106,7 +104,7 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { * classes to customize the way the drawing docs get created. For example, the freeform canvas has a different way of * defining document bounds, so CreateDrawingDoc is redefined when that class calls gpt draw functions. */ - public static CreateDrawingDoc: (strokeList: [InkData, string, string][], opts: DrawingOptions, gptRes: string, containerDoc?: Doc) => Doc | undefined = (strokeList: [InkData, string, string][], opts: DrawingOptions) => { + public static CreateDrawingDoc: (strokeList: [InkData, string, string][], opts: DrawingOptions, gptRes: string, containerDoc?: Doc) => Doc | undefined = (strokeList: [InkData, string, string][], opts: DrawingOptions, gptRes: string) => { const drawing: Doc[] = []; strokeList.forEach((stroke: [InkData, string, string]) => { const bounds = InkField.getBounds(stroke[0]); @@ -131,7 +129,14 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { drawing.push(inkDoc); }); - return MarqueeView.getCollection(drawing, undefined, true, { left: 1, top: 1, width: 1, height: 1 }); + const drawn = MarqueeView.getCollection(drawing, undefined, true, { left: 1, top: 1, width: 1, height: 1 }); + + drawn.$ai_drawing = true; + drawn.$ai_drawing_complexity = opts.complexity; + drawn.$ai_drawing_colored = opts.autoColor; + drawn.$ai_drawing_size = opts.size; + drawn.$ai_drawing_data = gptRes; + return drawn; }; @action @@ -147,15 +152,16 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { * the regenerate popup show by user command. */ @action - displayRegenerate = (x: number, y: number) => { + displayRegenerate = (x: number, y: number, scale: number) => { this._selectedDocs = [DocumentView.SelectedDocs()?.lastElement()]; [this._pageX, this._pageY] = [x, y]; + this._scale = scale; this._display = false; this.ShowRegenerate = true; this._showEditBox = false; - const docData = this._selectedDocs[0][DocData]; - this._lastResponse = StrCast(docData.drawingData); - this._lastInput = { text: StrCast(docData.ai_drawing_input), complexity: NumCast(docData.ai_drawing_complexity), size: NumCast(docData.ai_drawing_size), autoColor: BoolCast(docData.ai_drawing_colored), x: this._pageX, y: this._pageY }; + const docData = this._selectedDocs[0]; + this._regenInput = StrCast(docData.$ai_prompt, StrCast(docData.title)); + this._lastInput = { text: StrCast(docData.$ai_prompt), complexity: NumCast(docData.$ai_drawing_complexity), size: NumCast(docData.$ai_drawing_size), autoColor: BoolCast(docData.$ai_drawing_colored), x: this._pageX, y: this._pageY }; }; /** @@ -169,9 +175,6 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { this._isLoading = false; this._showOptions = false; this._userInput = ''; - this._complexity = 5; - this._size = 350; - this._autoColor = true; Doc.ActiveTool = InkTool.None; } }; @@ -185,7 +188,6 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { this.ShowRegenerate = false; this._isLoading = false; this._regenInput = ''; - this._lastInput = { text: '', complexity: 5, size: 350, autoColor: true, x: 0, y: 0 }; } }; @@ -209,7 +211,9 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { this._isLoading = true; this._canInteract = false; if (this.ShowRegenerate) { - await this.regenerate(this._selectedDocs, undefined, undefined, this._regenInput).then(action(() => (this._showEditBox = false))); + this._lastInput.x = X; + this._lastInput.y = Y; + await this.regenerate(this._selectedDocs).then(action(() => (this._showEditBox = false))); } else { this._showOptions = false; try { @@ -235,13 +239,15 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { */ drawWithGPT = async (screenPt: { X: number; Y: number }, input: string, complexity: number, size: number, autoColor: boolean) => { if (input) { - this._lastInput = { text: input, complexity: complexity, size: size, autoColor: autoColor, x: screenPt.X, y: screenPt.Y }; + this._lastInput = { text: input, complexity, size, autoColor, x: screenPt.X, y: screenPt.Y }; const res = await gptAPICall(`"${input}", "${complexity}", "${size}"`, GPTCallType.DRAW, undefined, true); if (res) { const strokeData = await this.parseSvg(res, { X: 0, Y: 0 }, false, autoColor); const drawingDoc = strokeData && SmartDrawHandler.CreateDrawingDoc(strokeData.data, strokeData.lastInput, strokeData.lastRes); - drawingDoc && this.AddDrawing(drawingDoc, this._lastInput, res, screenPt.X, screenPt.Y); - drawingDoc && this._selectedDocs.push(drawingDoc); + if (drawingDoc) { + this.AddDrawing(drawingDoc, this._lastInput, screenPt.X, screenPt.Y); + this._selectedDocs.push(drawingDoc); + } return strokeData; } else { console.error('GPT call failed'); @@ -256,7 +262,7 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { createImageWithFirefly = (input: string, seed?: number): Promise<FireflyImageData | Doc | undefined> => { this._lastInput.text = input; return SmartDrawHandler.CreateWithFirefly(input, this._imgDims, seed).then(doc => { - doc instanceof Doc && this.AddDrawing(doc, this._lastInput, input, this._pageX, this._pageY); + doc instanceof Doc && this.AddDrawing(doc, this._lastInput, this._pageX, this._pageY); return doc; }); }; /** @@ -302,8 +308,8 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { _width: Math.min(400, dims.width), _height: (Math.min(400, dims.width) * dims.height) / dims.width, ai: 'firefly', - ai_firefly_seed: +(newseed ?? 0), - ai_firefly_prompt: input, + ai_prompt_seed: +(newseed ?? 0), + ai_prompt: input, }); }) .catch(e => { @@ -317,33 +323,30 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { * @param doc the drawing Docs to regenerate */ @action - regenerate = (drawingDocs: Doc[], lastInput?: DrawingOptions, lastResponse?: string, regenInput?: string, changeInPlace?: boolean) => { - if (lastInput) this._lastInput = lastInput; - if (lastResponse) this._lastResponse = lastResponse; + regenerate = (drawingDocs: Doc[], regenInput?: string, changeInPlace?: boolean) => { if (regenInput) this._regenInput = regenInput; return Promise.all( drawingDocs.map(async doc => { switch (doc.type) { case DocumentType.IMG: { const func = changeInPlace ? this.recreateImageWithFirefly : this.createImageWithFirefly; - const newPrompt = doc.ai_firefly_prompt ? `${doc.ai_firefly_prompt} ~~~ ${this._regenInput}` : this._regenInput; - return this._regenInput ? func(newPrompt, NumCast(doc?.ai_firefly_seed)) : func(this._lastInput.text || StrCast(doc.ai_firefly_prompt)); + const newPrompt = doc.ai_prompt && doc.ai_prompt !== this._regenInput ? `${doc.ai_prompt} ~~~ ${this._regenInput}` : this._regenInput; + return this._regenInput ? func(newPrompt, NumCast(doc?.ai_prompt_seed)) : func(this._lastInput.text || StrCast(doc.ai_prompt)); } case DocumentType.COL: { try { const res = await (async () => { if (this._regenInput) { - const prompt = `This is your previously generated svg code: ${this._lastResponse} for the user input "${this._lastInput.text}". Please regenerate it with the provided specifications.`; + const prompt = `This is your previously generated svg code: ${doc.$ai_drawing_data} for the user input "${doc.ai_prompt}". Please regenerate it with the provided specifications.`; this._lastInput.text = `${this._lastInput.text} ~~~ ${this._regenInput}`; return gptAPICall(`"${this._regenInput}"`, GPTCallType.DRAW, prompt, true); } - return gptAPICall(`"${this._lastInput.text}", "${this._lastInput.complexity}", "${this._lastInput.size}"`, GPTCallType.DRAW, undefined, true); + return gptAPICall(`"${doc.$ai_prompt}", "${doc.$ai_drawing_complexity}", "${doc.$ai_drawing_size}"`, GPTCallType.DRAW, undefined, true); })(); if (res) { - const strokeData = await this.parseSvg(res, { X: this._lastInput.x ?? 0, Y: this._lastInput.y ?? 0 }, true, lastInput?.autoColor || this._autoColor); - this.RemoveDrawing !== unimplementedFunction && this.RemoveDrawing(true, doc); + const strokeData = await this.parseSvg(res, { X: 0, Y: 0 }, true, this._autoColor); const drawingDoc = strokeData && SmartDrawHandler.CreateDrawingDoc(strokeData.data, strokeData.lastInput, strokeData.lastRes); - drawingDoc && this.AddDrawing(drawingDoc, this._lastInput, res); + drawingDoc && this.AddDrawing(drawingDoc, this._lastInput, this._lastInput.x, this._lastInput.y); } else { console.error('GPT call failed'); } @@ -364,7 +367,6 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { const svg = res.match(/<svg[^>]*>([\s\S]*?)<\/svg>/g); if (svg) { - this._lastResponse = svg[0]; const svgObject = await parse(svg[0]); console.log(res, svgObject); const svgStrokes: INode[] = svgObject.children; @@ -399,12 +401,12 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { */ colorWithGPT = async (drawing: Doc) => { const img = await DocumentView.GetDocImage(drawing); - const { href } = ImageCast(img).url; + const { href } = ImageCast(img)?.url ?? { href: '' }; const hrefParts = href.split('.'); const hrefComplete = `${hrefParts[0]}_o.${hrefParts[1]}`; try { const hrefBase64 = await imageUrlToBase64(hrefComplete); - const strokes = DocListCast(drawing[DocData].data); + const strokes = DocListCast(drawing.$data); const coords: string[] = []; strokes.forEach((stroke, i) => { const inkingStroke = DocumentView.getDocumentView(stroke)?.ComponentView as InkingStroke; @@ -423,14 +425,14 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { */ colorStrokes = undoable((res: string, drawing: Doc) => { const colorList = res.match(/\{.*?\}/g); - const strokes = DocListCast(drawing[DocData].data); + const strokes = DocListCast(drawing.$data); colorList?.forEach((colors, index) => { const strokeAndFill = colors.match(/#[0-9A-Fa-f]{6}/g); if (strokeAndFill && strokeAndFill.length == 2) { - strokes[index][DocData].color = strokeAndFill[0]; + strokes[index].$color = strokeAndFill[0]; const inkStroke = DocumentView.getDocumentView(strokes[index])?.ComponentView as InkingStroke; const { inkData } = inkStroke.inkScaledData(); - InkingStroke.IsClosed(inkData) ? (strokes[index][DocData].fillColor = strokeAndFill[1]) : (strokes[index][DocData].fillColor = undefined); + InkingStroke.IsClosed(inkData) ? (strokes[index].$fillColor = strokeAndFill[1]) : (strokes[index].$fillColor = undefined); } }); }, 'color strokes'); @@ -577,6 +579,7 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { type="text" autoFocus value={this._userInput} + onPointerDown={e => e.stopPropagation()} onChange={action(e => this._canInteract && (this._userInput = e.target.value))} placeholder="Enter item to draw" onKeyDown={this.handleKeyPress} @@ -664,7 +667,7 @@ export class SmartDrawHandler extends ObservableReactComponent<object> { <div className="regenerate-box"> <IconButton tooltip="Regenerate" - icon={this._isLoading && this._regenInput === '' ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <FontAwesomeIcon icon={'rotate'} />} + icon={this._isLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <FontAwesomeIcon icon={'rotate'} />} color={SettingsManager.userColor} onClick={() => this.handleSendClick(this._pageX, this._pageY)} /> diff --git a/src/client/views/smartdraw/StickerPalette.tsx b/src/client/views/smartdraw/StickerPalette.tsx index e3305851a..6ef3d26ad 100644 --- a/src/client/views/smartdraw/StickerPalette.tsx +++ b/src/client/views/smartdraw/StickerPalette.tsx @@ -9,8 +9,7 @@ import ReactLoading from 'react-loading'; import { returnEmptyFilter, returnFalse, returnTrue } from '../../../ClientUtils'; import { emptyFunction, numberRange } from '../../../Utils'; import { Doc, DocListCast, returnEmptyDoclist } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; -import { ImageCast, NumCast } from '../../../fields/Types'; +import { ImageCast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; @@ -26,7 +25,7 @@ import { DrawingOptions, SmartDrawHandler } from './SmartDrawHandler'; import './StickerPalette.scss'; interface StickerPaletteProps { - Document: Doc; + Doc: Doc; } enum StickerPaletteMode { @@ -57,10 +56,10 @@ export class StickerPalette extends ObservableReactComponent<StickerPaletteProps if (!doc.savedAsSticker) { const docView = DocumentView.getDocumentView(doc); await docView?.ComponentView?.updateIcon?.(true); - const { clone } = await Doc.MakeClone(doc); + const { clone } = Doc.MakeClone(doc); clone.title = doc.title; - const image = ImageCast(doc.icon, ImageCast(clone[Doc.LayoutFieldKey(clone)]))?.url?.href; - Doc.AddDocToList(Doc.MyStickers, 'data', makeUserTemplateButtonOrImage(clone, image)); + const image = ImageCast(doc.icon, ImageCast(clone[Doc.LayoutDataKey(clone)]))?.url?.href; + Doc.MyStickers && Doc.AddDocToList(Doc.MyStickers, 'data', makeUserTemplateButtonOrImage(clone, image)); doc.savedAsSticker = true; } }; @@ -133,7 +132,7 @@ export class StickerPalette extends ObservableReactComponent<StickerPaletteProps this._canInteract = true; this._opts = { text: '', complexity: 5, size: 200, autoColor: true, x: 0, y: 0 }; this._gptRes = []; - this._props.Document[DocData].data = undefined; + this._props.Doc.$data = undefined; }); /** @@ -143,14 +142,14 @@ export class StickerPalette extends ObservableReactComponent<StickerPaletteProps @undoBatch generateDrawings = action(() => { this._isLoading = true; - const prevDrawings = DocListCast(this._props.Document[DocData].data); - this._props.Document[DocData].data = undefined; + const prevDrawings = DocListCast(this._props.Doc.$data); + this._props.Doc.$data = undefined; SmartDrawHandler.Instance.AddDrawing = this.addDrawing; this._canInteract = false; Promise.all( - numberRange(3).map(i => { + numberRange(3).map(() => { return this._showRegenerate - ? SmartDrawHandler.Instance.regenerate(prevDrawings, this._opts, this._gptRes[i], this._userInput) + ? SmartDrawHandler.Instance.regenerate(prevDrawings, this._userInput) : SmartDrawHandler.Instance.drawWithGPT({ X: 0, Y: 0 }, this._userInput, this._opts.complexity || 0, this._opts.size || 0, !!this._opts.autoColor); }) ).then(() => { @@ -162,10 +161,10 @@ export class StickerPalette extends ObservableReactComponent<StickerPaletteProps }); @action - addDrawing = (drawing: Doc, opts: DrawingOptions, gptRes: string) => { - this._gptRes.push(gptRes); - drawing[DocData].freeform_fitContentsToBox = true; - Doc.AddDocToList(this._props.Document, 'data', drawing); + addDrawing = (drawing: Doc) => { + this._gptRes.push(StrCast(drawing.$ai_drawing_data)); + drawing.$freeform_fitContentsToBox = true; + Doc.AddDocToList(this._props.Doc, 'data', drawing); }; /** @@ -174,19 +173,18 @@ export class StickerPalette extends ObservableReactComponent<StickerPaletteProps * presses the "save drawing" button. */ saveDrawing = () => { - const cIndex = NumCast(this._props.Document.carousel_index); - const focusedDrawing = DocListCast(this._props.Document.data)[cIndex]; - const docData = focusedDrawing[DocData]; - docData.title = this._opts.text?.match(/^(.*?)~~~.*$/)?.[1] || this._opts.text; - docData.ai_drawing_input = this._opts.text; - docData.ai_drawing_complexity = this._opts.complexity; - docData.ai_drawing_colored = this._opts.autoColor; - docData.ai_drawing_size = this._opts.size; - docData.ai_drawing_data = this._gptRes[cIndex]; - docData.ai = 'gpt'; + const cIndex = NumCast(this._props.Doc.carousel_index); + const focusedDrawing = DocListCast(this._props.Doc.data)[cIndex]; + focusedDrawing.$title = this._opts.text?.match(/^(.*?)~~~.*$/)?.[1] || this._opts.text; + focusedDrawing.$ai_prompt = this._opts.text; + focusedDrawing.$ai_drawing_complexity = this._opts.complexity; + focusedDrawing.$ai_drawing_colored = this._opts.autoColor; + focusedDrawing.$ai_drawing_size = this._opts.size; + focusedDrawing.$ai_drawing_data = this._gptRes[cIndex]; + focusedDrawing.$ai = 'gpt'; focusedDrawing.width = this._opts.size; - docData.x = this._opts.x; - docData.y = this._opts.y; + focusedDrawing.x = this._opts.x; + focusedDrawing.y = this._opts.y; StickerPalette.addToPalette(focusedDrawing).then(() => this.resetPalette(true)); }; @@ -315,7 +313,7 @@ export class StickerPalette extends ObservableReactComponent<StickerPaletteProps <> {this.renderCreateInput()} {this.renderCreateOptions()} - {this.renderDoc(this._props.Document, (r: DocumentView) => { + {this.renderDoc(this._props.Doc, (r: DocumentView) => { this._docCarouselView = r; })} <div className="palette-buttons"> @@ -329,9 +327,10 @@ export class StickerPalette extends ObservableReactComponent<StickerPaletteProps ); renderPaletteView = () => ( <> - {this.renderDoc(Doc.MyStickers, (r: DocumentView) => { - this._docView = r; - })} + {Doc.MyStickers && + this.renderDoc(Doc.MyStickers, (r: DocumentView) => { + this._docView = r; + })} <Button text="Add" icon={<FontAwesomeIcon icon="square-plus" />} color={SettingsManager.userColor} onClick={() => this.setPaletteMode(StickerPaletteMode.create)} /> </> ); |
