import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; import { SettingsManager } from '../../../util/SettingsManager'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { Button, IconButton, Size } from 'browndash-components'; import ReactLoading from 'react-loading'; import { AiOutlineSend } from 'react-icons/ai'; import './ImageLabelHandler.scss'; import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT'; import { InkData } from '../../../../fields/InkField'; import { SVGToBezier } from '../../../util/bezierFit'; const { parse } = require('svgson'); import { Slider, Switch } from '@mui/material'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { Flex } from '@adobe/react-spectrum'; import { Row } from 'react-aria-components'; import { UndoManager } from '../../../util/UndoManager'; import e from 'cors'; @observer export class SmartDrawHandler extends ObservableReactComponent<{}> { static Instance: SmartDrawHandler; @observable private _display: boolean = false; @observable private _pageX: number = 0; @observable private _pageY: number = 0; @observable private _yRelativeToTop: boolean = true; @observable private _isLoading: boolean = false; @observable private _userInput: string = ''; @observable private _showOptions: boolean = false; @observable private _menuIcon: string = 'caret-right'; @observable private _complexity: number = 5; @observable private _size: number = 300; @observable private _autoColor: boolean = true; @observable private _showRegenerate: boolean = false; private _addToDocFunc: (strokeList: [InkData, string, string][]) => void = () => {}; private _lastX: number = 0; private _lastY: number = 0; constructor(props: any) { super(props); makeObservable(this); SmartDrawHandler.Instance = this; } @action setUserInput = (input: string) => { this._userInput = input; }; @action displaySmartDrawHandler = (x: number, y: number, addToDoc: (strokeData: [InkData, string, string][]) => void) => { this._pageX = x; this._pageY = y; this._display = true; this._addToDocFunc = addToDoc; }; hideSmartDrawHandler = () => { this._showRegenerate = false; this._display = false; this._isLoading = false; this._showOptions = false; this._menuIcon = 'caret-right'; }; hideRegenerate = () => { this._showRegenerate = false; this._userInput = ''; this._complexity = 5; this._size = 300; this._autoColor = true; this._isLoading = false; }; toggleMenu = () => { this._showOptions = !this._showOptions; this._menuIcon === 'caret-right' ? (this._menuIcon = 'caret-down') : (this._menuIcon = 'caret-right'); }; @action drawWithGPT = async (e: React.MouseEvent, startPoint: { X: number; Y: number }, input: string, regenerate: boolean = false) => { if (this._userInput === '') return; e.stopPropagation(); this._lastX = startPoint.X; this._lastY = startPoint.Y; this._isLoading = true; this._showOptions = false; try { const res = await gptAPICall(`"${input}", "${this._complexity}", "${this._size}"`, GPTCallType.DRAW); if (!res) { console.error('GPT call failed'); return; } const svg = res.match(/]*>([\s\S]*?)<\/svg>/g); if (svg) { const svgObject = await parse(svg[0]); const svgStrokes: any = svgObject.children; const strokeData: [InkData, string, string][] = []; svgStrokes.forEach((child: any) => { const convertedBezier: InkData = SVGToBezier(child.name, child.attributes); strokeData.push([ convertedBezier.map(point => { return { X: point.X + startPoint.X - this._size / 1.5, Y: point.Y + startPoint.Y - this._size / 2 }; }), this._autoColor ? child.attributes.stroke : undefined, this._autoColor ? child.attributes.fill : undefined, ]); }); if (regenerate) UndoManager.Undo(); this._addToDocFunc(strokeData); } } catch (err) { console.error('GPT call failed', err); } this.hideSmartDrawHandler(); this._showRegenerate = true; }; regenerate = (e: React.MouseEvent) => { this.drawWithGPT(e, { X: this._lastX, Y: this._lastY }, `Regenerate the item "${this._userInput}"`, true); }; render() { if (this._display) { return (
{ this.hideSmartDrawHandler(); this.hideRegenerate(); }} icon={} color={SettingsManager.userColor} style={{ width: '19px' }} /> { this.setUserInput(e.target.value); }} placeholder="Enter item to draw" /> } color={SettingsManager.userColor} style={{ width: '14px' }} onClick={() => { this._showOptions = !this._showOptions; }} />
{this._showOptions && ( <>
Auto color (this._autoColor = !this._autoColor)} />
Complexity { this._complexity = val as number; }} valueLabelDisplay="auto" />
Size (in pixels) { this._size = val as number; }} valueLabelDisplay="auto" />
)}
); } else if (this._showRegenerate) { return (
} color={SettingsManager.userColor} style={{ width: '19px' }} /> : } color={SettingsManager.userColor} onClick={e => { this.regenerate(e); }} />
); } else { return <>; } } }