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 } from 'browndash-components'; import ReactLoading from 'react-loading'; import { AiOutlineSend } from 'react-icons/ai'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './ImageLabelHandler.scss'; import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT'; import { InkData } from '../../../../fields/InkField'; import { ButtonType } from '../../nodes/FontIconBox/FontIconBox'; import { SVGToBezier } from '../../../util/bezierFit'; const { parse, stringify } = require('svgson'); @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 _drawingTypeToolTip = 'Create Geometric Drawing'; @observable private _drawingTypeIcon: 'star' | 'splotch' = 'star'; @observable private _alpha: number | undefined = undefined; // number between 0 and 1 that determines how rounded a drawing will be // @observable public strokes: InkData[] = []; private _addToDocFunc: (strokeList: InkData[], alpha?: number) => void = () => {}; constructor(props: any) { super(props); makeObservable(this); SmartDrawHandler.Instance = this; } @action setIsLoading = (isLoading: boolean) => { this._isLoading = isLoading; }; @action setUserInput = (input: string) => { this._userInput = input; }; @action displaySmartDrawHandler = (x: number, y: number, addToDoc: (strokeList: InkData[], alpha?: number) => void) => { this._pageX = x; this._pageY = y; this._display = true; this._addToDocFunc = addToDoc; }; @action hideSmartDrawHandler = () => { this._display = false; }; @action drawWithGPT = async (startPoint: { X: number; Y: number }, input: string) => { console.log('start point is', startPoint); this.setIsLoading(true); try { const res = await gptAPICall(input, GPTCallType.DRAW); if (!res) { console.error('GPT call failed'); return; } console.log('GPT response:', res); const svg = res.match(/]*>([\s\S]*?)<\/svg>/g); console.log('svg', svg); if (svg) { const svgObject = await parse(svg[0]); console.log('svg object', svgObject); const svgStrokes: any = svgObject.children; const beziers: InkData[] = []; svgStrokes.forEach((stroke: any) => { const convertedBezier: InkData = SVGToBezier(stroke.name, stroke.attributes); beziers.push( convertedBezier.map(point => { return { X: point.X + startPoint.X, Y: point.Y + startPoint.Y }; }) ); }); this._addToDocFunc(beziers); } // const strokes = res.trim().split(/\s*(?=\s*M)/); // prettier-ignore // const parsedSegments: InkData[] = []; // console.log('strokes', strokes); // strokes.forEach(stroke => { // stroke = stroke.replace(/C\s*\((\d+,\d+)\)\s*\((\d+,\d+)\)\s*\((\d+,\d+)\)/g, (c, p1, p2, p3) => { // return `C (${p1}) (${p2}) (${p3}) (${p3})`; // }); // const coordStrings = stroke.match(/(\d+,\d+)/g); // const coords: InkData = []; // if (coordStrings) { // coordStrings.forEach(coord => { // const xy = coord.split(','); // coords.push({ X: parseInt(xy[0]), Y: parseInt(xy[1]) }); // }); // coords.pop(); // parsedSegments.push(coords); // } // console.log('coords', coords); // }); // this._addToDocFunc(parsedSegments); } catch (err) { console.error('GPT call failed', err); } this.setIsLoading(false); this.setUserInput(''); this.hideSmartDrawHandler(); }; changeDrawingType = () => { if (this._drawingTypeIcon === 'star') { this._drawingTypeIcon = 'splotch'; this._drawingTypeToolTip = 'Create Rounded Drawing'; this._alpha = 0.2; } else { this._drawingTypeIcon = 'star'; this._drawingTypeToolTip = 'Create Geometric Drawing'; this._alpha = 0; } }; render() { if (this._display) { return (
} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} /> { this.setUserInput(e.target.value); }} placeholder="Enter item to draw" /> } color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '14px' }} onClick={this.changeDrawingType} /> {/* } color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '14px' }} onClick={() => { this._alpha = 0; }} /> */}
); } else { return <>; } } }