aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-08-29 22:38:53 -0400
committerbobzel <zzzman@gmail.com>2024-08-29 22:38:53 -0400
commit4dd32452ad45ce0ed01fe577eb198a99ccd69754 (patch)
treebde2d57c8aff928b55be6cc748fc133b2df6867b
parentc26be511545d4570f3adcc15ecefae78e3d396df (diff)
cleaning up smartDrawHandler
-rw-r--r--src/client/util/CurrentUserUtils.ts2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/smartdraw/SmartDrawHandler.tsx488
3 files changed, 196 insertions, 296 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index cdf5505f8..ec8898b93 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -386,7 +386,6 @@ pie title Minerals in my tap water
{key: "Script", creator: opts => Docs.Create.ScriptingDocument(null, opts), opts: { _width: 200, _height: 250, }},
{key: "DataViz", creator: opts => Docs.Create.DataVizDocument("/users/rz/Downloads/addresses.csv", opts), opts: { _width: 300, _height: 300 }},
{key: "Chat", creator: Docs.Create.ChatDocument, opts: { _width: 300, _height: 300, }},
- {key: "AnnoPalette",creator: Docs.Create.AnnoPaletteDocument, opts: {_width: 300, _height: 300, _dropAction: dropActionType.move }},
{key: "Header", creator: headerTemplate, opts: { _width: 300, _height: 120, _header_pointerEvents: "all", _header_height: 50, _header_fontSize: 9,_layout_autoHeightMargins: 50, _layout_autoHeight: true, treeView_HideUnrendered: true}},
{key: "ViewSlide", creator: slideView, opts: { _width: 400, _height: 300, _xMargin: 3, _yMargin: 3,}},
{key: "Trail", creator: Docs.Create.PresDocument, opts: { _width: 400, _height: 30, _type_collection: CollectionViewType.Stacking, dropAction: dropActionType.embed, treeView_HideTitle: true, _layout_fitWidth:true, layout_boxShadow: "0 0" }},
@@ -429,7 +428,6 @@ pie title Minerals in my tap water
{ toolTip: "Tap or drag to create a bullet slide", title: "PPT Slide", icon: "person-chalkboard", dragFactory: doc.emptySlide as Doc, clickFactory: DocCast(doc.emptySlide), openFactoryLocation: OpenWhere.overlay,funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a view slide", title: "View Slide", icon: "address-card", dragFactory: doc.emptyViewSlide as Doc, clickFactory: DocCast(doc.emptyViewSlide), openFactoryLocation: OpenWhere.overlay,funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a data note", title: "DataNote", icon: "window-maximize", dragFactory: doc.emptyHeader as Doc, clickFactory: DocCast(doc.emptyHeader), openFactoryAsDelegate: true, funcs: { hidden: "IsNoviceMode()"} },
- { toolTip: "Tap or drag to create an annotation palette",title: "Annotation Palette", icon: "palette", dragFactory: doc.emptyAnnoPalette as Doc, clickFactory: DocCast(doc.emptyAnnoPalette)},
{ toolTip: "Toggle a Calculator REPL", title: "replviewer", icon: "calculator", clickFactory: '<ScriptingRepl />' as unknown as Doc, openFactoryLocation: OpenWhere.overlay}, // hack: clickFactory is not a Doc but will get interpreted as a custom UI by the openDoc() onClick script
// { toolTip: "Toggle an UndoStack", title: "undostacker", icon: "calculator", clickFactory: "<UndoStack />" as any, openFactoryLocation: OpenWhere.overlay},
].map(tuple => (
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index c0f01383d..76549a423 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -2006,7 +2006,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
SmartDrawHandler.Instance.CreateDrawingDoc = this.createDrawingDoc;
SmartDrawHandler.Instance.AddDrawing = this.addDrawing;
SmartDrawHandler.Instance.RemoveDrawing = this.removeDrawing;
- !SmartDrawHandler.Instance._showRegenerate ? SmartDrawHandler.Instance.displayRegenerate(this._downX, this._downY - 10) : SmartDrawHandler.Instance.hideRegenerate();
+ !SmartDrawHandler.Instance.ShowRegenerate ? SmartDrawHandler.Instance.displayRegenerate(this._downX, this._downY - 10) : SmartDrawHandler.Instance.hideRegenerate();
}),
icon: 'pen-to-square',
});
diff --git a/src/client/views/smartdraw/SmartDrawHandler.tsx b/src/client/views/smartdraw/SmartDrawHandler.tsx
index aa10dcead..59d362d26 100644
--- a/src/client/views/smartdraw/SmartDrawHandler.tsx
+++ b/src/client/views/smartdraw/SmartDrawHandler.tsx
@@ -1,29 +1,29 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Slider, Switch } from '@mui/material';
+import { Button, IconButton } from 'browndash-components';
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 { gptAPICall, GPTCallType, gptDrawingColor } from '../../apis/gpt/GPT';
-import { InkData, InkField, InkTool } from '../../../fields/InkField';
-import { SVGToBezier, SVGType } from '../../util/bezierFit';
+import ReactLoading from 'react-loading';
import { INode, parse } from 'svgson';
-import { Slider, Switch } from '@mui/material';
+import { unimplementedFunction } from '../../../Utils';
import { Doc, DocListCast } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
-import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, DocumentView } from '../nodes/DocumentView';
+import { InkData, InkField, InkTool } from '../../../fields/InkField';
import { BoolCast, ImageCast, NumCast, StrCast } from '../../../fields/Types';
-import './SmartDrawHandler.scss';
-import { unimplementedFunction } from '../../../Utils';
+import { ImageField } from '../../../fields/URLField';
+import { GPTCallType, gptAPICall, gptDrawingColor } from '../../apis/gpt/GPT';
import { Docs } from '../../documents/Documents';
-import { MarqueeView } from '../collections/collectionFreeForm';
-import { ImageField, URLField } from '../../../fields/URLField';
-import { CollectionCardView } from '../collections/CollectionCardDeckView';
+import { SettingsManager } from '../../util/SettingsManager';
+import { undoable } from '../../util/UndoManager';
+import { SVGToBezier, SVGType } from '../../util/bezierFit';
import { InkingStroke } from '../InkingStroke';
-import { undoBatch } from '../../util/UndoManager';
+import { ObservableReactComponent } from '../ObservableReactComponent';
+import { CollectionCardView } from '../collections/CollectionCardDeckView';
+import { MarqueeView } from '../collections/collectionFreeForm';
+import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, DocumentView } from '../nodes/DocumentView';
+import './SmartDrawHandler.scss';
export interface DrawingOptions {
text: string;
@@ -35,10 +35,14 @@ export interface DrawingOptions {
}
@observer
-// eslint-disable-next-line @typescript-eslint/no-empty-object-type
-export class SmartDrawHandler extends ObservableReactComponent<{}> {
+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 _selectedDoc: Doc | undefined = undefined;
+ private _errorOccurredOnce = false;
+
@observable private _display: boolean = false;
@observable private _pageX: number = 0;
@observable private _pageY: number = 0;
@@ -47,18 +51,21 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
@observable private _userInput: string = '';
@observable private _showOptions: boolean = false;
@observable private _showEditBox: boolean = false;
- @observable public _showRegenerate: boolean = false;
@observable private _complexity: number = 5;
@observable private _size: number = 200;
@observable private _autoColor: boolean = true;
@observable private _regenInput: string = '';
@observable private _canInteract: boolean = true;
- private _lastInput: DrawingOptions = { text: '', complexity: 5, size: 350, autoColor: true, x: 0, y: 0 };
- private _lastResponse: string = '';
- private _selectedDoc: Doc | undefined = undefined;
- private _errorOccurredOnce = false;
+ @observable public ShowRegenerate: boolean = false;
+
+ constructor(props: object) {
+ super(props);
+ makeObservable(this);
+ SmartDrawHandler.Instance = this;
+ }
+ public AddDrawing: (doc: Doc, opts: DrawingOptions, gptRes: string) => void = unimplementedFunction;
public RemoveDrawing: (doc?: Doc) => void = unimplementedFunction;
public CreateDrawingDoc: (strokeList: [InkData, string, string][], opts: DrawingOptions, gptRes: string, containerDoc?: Doc) => Doc | undefined = (strokeList: [InkData, string, string][], opts: DrawingOptions) => {
const drawing: Doc[] = [];
@@ -85,67 +92,21 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
drawing.push(inkDoc);
});
- const collection = MarqueeView.getCollection(drawing, undefined, true, { left: 1, top: 1, width: 1, height: 1 });
- return collection;
- };
- public AddDrawing: (doc: Doc, opts: DrawingOptions, gptRes: string) => void = unimplementedFunction;
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- constructor(props: any) {
- super(props);
- makeObservable(this);
- SmartDrawHandler.Instance = this;
- }
-
- @action
- setUserInput = (input: string) => {
- if (this._canInteract) this._userInput = input;
- };
-
- @action
- setRegenInput = (input: string) => {
- if (this._canInteract) this._regenInput = input;
- };
-
- @action
- setShowOptions = () => {
- this._showOptions = !this._showOptions;
- };
-
- @action
- setComplexity = (val: number) => {
- if (this._canInteract) this._complexity = val;
- };
-
- @action
- setSize = (val: number) => {
- if (this._canInteract) this._size = val;
- };
-
- @action
- setAutoColor = () => {
- if (this._canInteract) this._autoColor = !this._autoColor;
- };
-
- @action
- setEdit = () => {
- this._showEditBox = !this._showEditBox;
+ return MarqueeView.getCollection(drawing, undefined, true, { left: 1, top: 1, width: 1, height: 1 });
};
@action
displaySmartDrawHandler = (x: number, y: number) => {
- this._pageX = x;
- this._pageY = y;
+ [this._pageX, this._pageY] = [x, y];
this._display = true;
};
@action
displayRegenerate = (x: number, y: number) => {
this._selectedDoc = DocumentView.SelectedDocs()?.lastElement();
- this._pageX = x;
- this._pageY = y;
+ [this._pageX, this._pageY] = [x, y];
this._display = false;
- this._showRegenerate = true;
+ this.ShowRegenerate = true;
this._showEditBox = false;
const docData = this._selectedDoc[DocData];
this._lastResponse = StrCast(docData.drawingData);
@@ -154,7 +115,7 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
@action
hideSmartDrawHandler = () => {
- this._showRegenerate = false;
+ this.ShowRegenerate = false;
this._display = false;
this._isLoading = false;
this._showOptions = false;
@@ -168,17 +129,16 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
@action
hideRegenerate = () => {
if (!this._isLoading) {
- this._showRegenerate = false;
+ this.ShowRegenerate = false;
this._isLoading = false;
this._regenInput = '';
this._lastInput = { text: '', complexity: 5, size: 350, autoColor: true, x: 0, y: 0 };
}
};
- @action
- handleKeyPress = async (event: React.KeyboardEvent) => {
+ handleKeyPress = (event: React.KeyboardEvent) => {
if (event.key === 'Enter') {
- await this.handleSendClick();
+ this.handleSendClick();
}
};
@@ -186,7 +146,7 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
handleSendClick = async () => {
this._isLoading = true;
this._canInteract = false;
- if (this._showRegenerate) {
+ if (this.ShowRegenerate) {
await this.regenerate();
this._regenInput = '';
this._showEditBox = false;
@@ -195,7 +155,7 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
try {
await this.drawWithGPT({ X: this._pageX, Y: this._pageY }, this._userInput, this._complexity, this._size, this._autoColor);
this.hideSmartDrawHandler();
- this._showRegenerate = true;
+ this.ShowRegenerate = true;
} catch (err) {
if (this._errorOccurredOnce) {
console.error('GPT call failed', err);
@@ -222,10 +182,8 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
console.error('GPT call failed');
return;
}
- console.log(res);
const strokeData = await this.parseSvg(res, startPt, false, autoColor);
const drawingDoc = strokeData && this.CreateDrawingDoc(strokeData?.data, strokeData?.lastInput, strokeData?.lastRes);
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
drawingDoc && this.AddDrawing(drawingDoc, this._lastInput, res);
this._errorOccurredOnce = false;
@@ -254,12 +212,9 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
console.error('GPT call failed');
return;
}
- console.log(res);
const strokeData = await this.parseSvg(res, { X: this._lastInput.x, Y: this._lastInput.y }, true, lastInput?.autoColor || this._autoColor);
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
this.RemoveDrawing !== unimplementedFunction && this.RemoveDrawing(this._selectedDoc);
const drawingDoc = strokeData && this.CreateDrawingDoc(strokeData?.data, strokeData?.lastInput, strokeData?.lastRes);
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
drawingDoc && this.AddDrawing(drawingDoc, this._lastInput, res);
return strokeData;
} catch (err) {
@@ -278,13 +233,10 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
const svgObject = await parse(svg[0]);
const svgStrokes: INode[] = svgObject.children;
const strokeData: [InkData, string, string][] = [];
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
svgStrokes.forEach(child => {
const convertedBezier: InkData = SVGToBezier(child.name as SVGType, 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 };
- }),
+ convertedBezier.map(point => ({ X: point.X + startPoint.X - this._size / 1.5, Y: point.Y + startPoint.Y - this._size / 2 })),
(regenerate ? this._lastInput.autoColor : autoColor) ? child.attributes.stroke : '',
(regenerate ? this._lastInput.autoColor : autoColor) ? child.attributes.fill : '',
]);
@@ -298,7 +250,7 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
*/
colorWithGPT = async (drawing: Doc) => {
const img = await this.getIcon(drawing);
- const { href } = (img as URLField).url;
+ const { href } = ImageCast(img).url;
const hrefParts = href.split('.');
const hrefComplete = `${hrefParts[0]}_o.${hrefParts[1]}`;
try {
@@ -308,20 +260,9 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
strokes.forEach((stroke, i) => {
const inkingStroke = DocumentView.getDocumentView(stroke)?.ComponentView as InkingStroke;
const { inkData } = inkingStroke.inkScaledData();
- coords.push(
- `${i + 1}. ${inkData
- .filter((point, index) => {
- return index % 4 === 0 || index == inkData.length - 1;
- })
- .map(point => {
- return `(${point.X.toString()}, ${point.Y.toString()})`;
- })}`
- );
+ coords.push(`${i + 1}. ${inkData.filter((point, index) => index % 4 === 0 || index == inkData.length - 1).map(point => `(${point.X.toString()}, ${point.Y.toString()})`)}`);
});
- const response = await gptDrawingColor(hrefBase64, coords);
- console.log(response);
- const colorResponse = await gptAPICall(response, GPTCallType.COLOR, undefined);
- console.log(colorResponse);
+ const colorResponse = await gptDrawingColor(hrefBase64, coords).then(response => gptAPICall(response, GPTCallType.COLOR, undefined));
this.colorStrokes(colorResponse, drawing);
} catch (error) {
console.log('GPT call failed', error);
@@ -331,8 +272,7 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
/**
* Function that parses the GPT color response and sets the selected stroke(s) to the new color.
*/
- @undoBatch
- colorStrokes = (res: string, drawing: Doc) => {
+ colorStrokes = undoable((res: string, drawing: Doc) => {
const colorList = res.match(/\{.*?\}/g);
const strokes = DocListCast(drawing[DocData].data);
colorList?.forEach((colors, index) => {
@@ -341,213 +281,175 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
strokes[index][DocData].color = strokeAndFill[0];
const inkStroke = DocumentView.getDocumentView(strokes[index])?.ComponentView as InkingStroke;
const { inkData } = inkStroke.inkScaledData();
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
InkingStroke.IsClosed(inkData) ? (strokes[index][DocData].fillColor = strokeAndFill[1]) : (strokes[index][DocData].fillColor = undefined);
}
});
- };
+ }, 'color strokes');
/**
* Gets an image snapshot of a doc. In this class, it's used to snapshot a selected ink stroke/group to use for GPT color.
*/
async getIcon(doc: Doc) {
const docView = DocumentView.getDocumentView(doc);
- console.log(doc);
if (docView) {
- console.log(docView);
docView.ComponentView?.updateIcon?.();
return new Promise<ImageField | undefined>(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 1000));
}
return undefined;
}
- render() {
- if (this._display) {
- return (
- <div
- id="label-handler"
- className="smart-draw-handler"
- style={{
- display: this._display ? '' : 'none',
- left: this._pageX,
- ...(this._yRelativeToTop ? { top: Math.max(0, this._pageY) } : { bottom: this._pageY }),
- background: SettingsManager.userBackgroundColor,
- color: SettingsManager.userColor,
- }}>
- <div>
- <IconButton
- tooltip={'Cancel'}
- onClick={() => {
- this.hideSmartDrawHandler();
- this.hideRegenerate();
- }}
- icon={<FontAwesomeIcon icon="xmark" />}
- color={SettingsManager.userColor}
- style={{ width: '19px' }}
- />
- <input
- aria-label="Smart Draw Input"
- className="smartdraw-input"
- id="smartdraw-input"
- type="text"
- style={{ color: 'black' }}
- value={this._userInput}
- onChange={e => {
- this.setUserInput(e.target.value);
- }}
- placeholder="Enter item to draw"
- onKeyDown={this.handleKeyPress}
- />
- <IconButton tooltip="Advanced Options" icon={<FontAwesomeIcon icon={this._showOptions ? 'caret-down' : 'caret-right'} />} color={SettingsManager.userColor} style={{ width: '14px' }} onClick={this.setShowOptions} />
- <Button
- style={{ alignSelf: 'flex-end' }}
- text="Send"
- icon={this._isLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />}
- iconPlacement="right"
- color={SettingsManager.userColor}
- onClick={this.handleSendClick}
- />
- </div>
- {this._showOptions && (
- <>
- <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-around' }}>
- <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', width: '30%' }}>
- Auto color
- <Switch
- sx={{
- '& .MuiSwitch-switchBase.Mui-checked': {
- color: SettingsManager.userColor,
- },
- '& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': {
- backgroundColor: SettingsManager.userVariantColor,
- },
- }}
- defaultChecked={true}
- value={this._autoColor}
- size="small"
- onChange={this.setAutoColor}
- />
- </div>
- <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', width: '31%' }}>
- Complexity
- <Slider
- sx={{
- '& .MuiSlider-thumb': {
- color: SettingsManager.userColor,
- '&.Mui-focusVisible, &:hover, &.Mui-active': {
- boxShadow: `0px 0px 0px 8px${SettingsManager.userColor.slice(0, 7)}10`,
- },
- },
- '& .MuiSlider-track': {
- color: SettingsManager.userVariantColor,
- },
- '& .MuiSlider-rail': {
- color: SettingsManager.userColor,
- },
- }}
- style={{ width: '80%' }}
- min={1}
- max={10}
- step={1}
- size="small"
- value={this._complexity}
- onChange={(e, val) => {
- this.setComplexity(val as number);
- }}
- valueLabelDisplay="auto"
- />
- </div>
- <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', width: '39%' }}>
- Size (in pixels)
- <Slider
- sx={{
- '& .MuiSlider-thumb': {
- color: SettingsManager.userColor,
- '&.Mui-focusVisible, &:hover, &.Mui-active': {
- boxShadow: `0px 0px 0px 8px${SettingsManager.userColor.slice(0, 7)}20`,
- },
- },
- '& .MuiSlider-track': {
- color: SettingsManager.userVariantColor,
- },
- '& .MuiSlider-rail': {
- color: SettingsManager.userColor,
- },
- }}
- style={{ width: '80%' }}
- min={50}
- max={700}
- step={10}
- size="small"
- value={this._size}
- onChange={(e, val) => {
- this.setSize(val as number);
- }}
- valueLabelDisplay="auto"
- />
- </div>
- </div>
- </>
- )}
+ renderDisplay() {
+ return (
+ <div
+ id="label-handler"
+ className="smart-draw-handler"
+ style={{
+ display: this._display ? '' : 'none',
+ left: this._pageX,
+ ...(this._yRelativeToTop ? { top: Math.max(0, this._pageY) } : { bottom: this._pageY }),
+ background: SettingsManager.userBackgroundColor,
+ color: SettingsManager.userColor,
+ }}>
+ <div>
+ <IconButton
+ tooltip="Cancel"
+ onClick={() => {
+ this.hideSmartDrawHandler();
+ this.hideRegenerate();
+ }}
+ icon={<FontAwesomeIcon icon="xmark" />}
+ color={SettingsManager.userColor}
+ style={{ width: '19px' }}
+ />
+ <input
+ aria-label="Smart Draw Input"
+ className="smartdraw-input"
+ type="text"
+ style={{ color: 'black' }}
+ value={this._userInput}
+ onChange={action(e => this._canInteract && (this._userInput = e.target.value))}
+ placeholder="Enter item to draw"
+ onKeyDown={this.handleKeyPress}
+ />
+ <IconButton
+ tooltip="Advanced Options"
+ icon={<FontAwesomeIcon icon={this._showOptions ? 'caret-down' : 'caret-right'} />}
+ color={SettingsManager.userColor}
+ style={{ width: '14px' }}
+ onClick={action(() => (this._showOptions = !this._showOptions))}
+ />
+ <Button
+ style={{ alignSelf: 'flex-end' }}
+ text="Send"
+ icon={this._isLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />}
+ iconPlacement="right"
+ color={SettingsManager.userColor}
+ onClick={this.handleSendClick}
+ />
</div>
- );
- } else if (this._showRegenerate) {
- return (
- <div
- id="smartdraw-options-menu"
- className="smart-draw-handler"
- style={{
- left: this._pageX,
- ...(this._yRelativeToTop ? { top: Math.max(0, this._pageY) } : { bottom: this._pageY }),
- background: SettingsManager.userBackgroundColor,
- color: SettingsManager.userColor,
- }}>
- <div
- style={{
- display: 'flex',
- flexDirection: 'row',
- }}>
- <IconButton
- tooltip="Regenerate"
- icon={this._isLoading && this._regenInput === '' ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <FontAwesomeIcon icon={'rotate'} />}
- color={SettingsManager.userColor}
- onClick={this.handleSendClick}
- />
- <IconButton tooltip="Edit with GPT" icon={<FontAwesomeIcon icon="pen-to-square" />} color={SettingsManager.userColor} onClick={this.setEdit} />
- {this._showEditBox && (
- <div
- style={{
- display: 'flex',
- flexDirection: 'row',
- }}>
- <input
- aria-label="Edit instructions input"
- className="smartdraw-input"
- id="regen-input"
- type="text"
- style={{ color: 'black' }}
- value={this._regenInput}
- onChange={e => {
- this.setRegenInput(e.target.value);
- }}
- onKeyDown={this.handleKeyPress}
- placeholder="Edit instructions"
- />
- <Button
- style={{ alignSelf: 'flex-end' }}
- text="Send"
- icon={this._isLoading && this._regenInput !== '' ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />}
- iconPlacement="right"
- color={SettingsManager.userColor}
- onClick={this.handleSendClick}
- />
- </div>
- )}
+ {this._showOptions && (
+ <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-around' }}>
+ <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', width: '30%' }}>
+ Auto color
+ <Switch
+ sx={{
+ '& .MuiSwitch-switchBase.Mui-checked': { color: SettingsManager.userColor },
+ '& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': { backgroundColor: SettingsManager.userVariantColor },
+ }}
+ defaultChecked={true}
+ value={this._autoColor}
+ size="small"
+ onChange={action(e => this._canInteract && (this._autoColor = !this._autoColor))}
+ />
+ </div>
+ <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', width: '31%' }}>
+ Complexity
+ <Slider
+ sx={{
+ '& .MuiSlider-track': { color: SettingsManager.userVariantColor },
+ '& .MuiSlider-rail': { color: SettingsManager.userColor },
+ '& .MuiSlider-thumb': { color: SettingsManager.userColor, '&.Mui-focusVisible, &:hover, &.Mui-active': { boxShadow: `0px 0px 0px 8px${SettingsManager.userColor.slice(0, 7)}10` } },
+ }}
+ style={{ width: '80%' }}
+ min={1}
+ max={10}
+ step={1}
+ size="small"
+ value={this._complexity}
+ onChange={action((e, val) => this._canInteract && (this._complexity = val as number))}
+ valueLabelDisplay="auto"
+ />
+ </div>
+ <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', width: '39%' }}>
+ Size (in pixels)
+ <Slider
+ sx={{
+ '& .MuiSlider-track': { color: SettingsManager.userVariantColor },
+ '& .MuiSlider-rail': { color: SettingsManager.userColor },
+ '& .MuiSlider-thumb': { color: SettingsManager.userColor, '&.Mui-focusVisible, &:hover, &.Mui-active': { boxShadow: `0px 0px 0px 8px${SettingsManager.userColor.slice(0, 7)}20` } },
+ }}
+ style={{ width: '80%' }}
+ min={50}
+ max={700}
+ step={10}
+ size="small"
+ value={this._size}
+ onChange={action((e, val) => this._canInteract && (this._size = val as number))}
+ valueLabelDisplay="auto"
+ />
+ </div>
</div>
+ )}
+ </div>
+ );
+ }
+
+ renderRegenerate() {
+ return (
+ <div
+ className="smart-draw-handler"
+ style={{
+ left: this._pageX,
+ ...(this._yRelativeToTop ? { top: Math.max(0, this._pageY) } : { bottom: this._pageY }),
+ background: SettingsManager.userBackgroundColor,
+ color: SettingsManager.userColor,
+ }}>
+ <div style={{ display: 'flex', flexDirection: 'row' }}>
+ <IconButton
+ tooltip="Regenerate"
+ icon={this._isLoading && this._regenInput === '' ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <FontAwesomeIcon icon={'rotate'} />}
+ color={SettingsManager.userColor}
+ onClick={this.handleSendClick}
+ />
+ <IconButton tooltip="Edit with GPT" icon={<FontAwesomeIcon icon="pen-to-square" />} color={SettingsManager.userColor} onClick={action(() => (this._showEditBox = !this._showEditBox))} />
+ {this._showEditBox && (
+ <div style={{ display: 'flex', flexDirection: 'row' }}>
+ <input
+ aria-label="Edit instructions input"
+ className="smartdraw-input"
+ type="text"
+ style={{ color: 'black' }}
+ value={this._regenInput}
+ onChange={action(e => this._canInteract && (this._regenInput = e.target.value))}
+ onKeyDown={this.handleKeyPress}
+ placeholder="Edit instructions"
+ />
+ <Button
+ style={{ alignSelf: 'flex-end' }}
+ text="Send"
+ icon={this._isLoading && this._regenInput !== '' ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />}
+ iconPlacement="right"
+ color={SettingsManager.userColor}
+ onClick={this.handleSendClick}
+ />
+ </div>
+ )}
</div>
- );
- } else {
- return <></>;
- }
+ </div>
+ );
+ }
+
+ render() {
+ return this._display ? this.renderDisplay() : this.ShowRegenerate ? this.renderRegenerate() : null;
}
}