diff options
| author | alyssaf16 <alyssa_feinberg@brown.edu> | 2024-10-06 15:15:06 -0400 |
|---|---|---|
| committer | alyssaf16 <alyssa_feinberg@brown.edu> | 2024-10-06 15:15:06 -0400 |
| commit | fbff73033b6c0f9b1214e9013c155ff085e7a737 (patch) | |
| tree | e5a278de98cb71fa023af7b85e20aafaf5ab03bf /src/client/views/pdf/AnchorMenu.tsx | |
| parent | fa54fdf2bf9bf8523da393a81ec1ac1cd4fa0f4c (diff) | |
| parent | e61b2b356e761dfefda9d09bbbfc3c4a8d943f2c (diff) | |
Merge branch 'alyssa-starter' of https://github.com/brown-dash/Dash-Web into alyssa-starter
Diffstat (limited to 'src/client/views/pdf/AnchorMenu.tsx')
| -rw-r--r-- | src/client/views/pdf/AnchorMenu.tsx | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index 6dd036cf6..bff112017 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -1,21 +1,24 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { ColorPicker, Group, IconButton, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components'; -import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction } from 'mobx'; +import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { ColorResult } from 'react-color'; +import ReactLoading from 'react-loading'; import { ClientUtils, returnFalse, setupMoveUpEvents } from '../../../ClientUtils'; import { emptyFunction, unimplementedFunction } from '../../../Utils'; import { Doc, Opt } from '../../../fields/Doc'; +import { DocData } from '../../../fields/DocSymbols'; import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT'; import { Docs } from '../../documents/Documents'; import { SettingsManager } from '../../util/SettingsManager'; +import { undoBatch } from '../../util/UndoManager'; import { AntimodeMenu, AntimodeMenuProps } from '../AntimodeMenu'; import { LinkPopup } from '../linking/LinkPopup'; import { DocumentView } from '../nodes/DocumentView'; +import { DrawingOptions, SmartDrawHandler } from '../smartdraw/SmartDrawHandler'; import './AnchorMenu.scss'; import { GPTPopup, GPTPopupMode } from './GPTPopup/GPTPopup'; -import ReactLoading from 'react-loading'; @observer export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> { @@ -44,6 +47,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> { @observable private _selectedText: string = ''; @observable private _x: number = 0; @observable private _y: number = 0; + @observable private _isLoading: boolean = false; @action public setSelectedText = (txt: string) => { this._selectedText = txt.trim(); @@ -78,6 +82,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> { public get Active() { return this._left > 0; } + public AddDrawingAnnotation: (doc: Doc) => void = unimplementedFunction; public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined; componentWillUnmount() { @@ -137,10 +142,9 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> { transferToFlashcard = (text: string, x: number, y: number) => { // put each question generated by GPT on the front of the flashcard - var senArr = text.trim().split('Question: '); - var collectionArr: Doc[] = []; + const senArr = text.trim().split('Question: '); + const collectionArr: Doc[] = []; for (let i = 1; i < senArr.length; i++) { - console.log('Arr ' + i + ': ' + senArr[i]); const newDoc = Docs.Create.ComparisonDocument(senArr[i], { _layout_isFlashcard: true, _width: 300, _height: 300 }); newDoc.text = senArr[i]; @@ -164,6 +168,35 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> { this._loading = false; }; + /** + * Creates a GPT drawing based on selected text. + */ + gptDraw = async (e: React.PointerEvent) => { + try { + SmartDrawHandler.Instance.AddDrawing = this.createDrawingAnnotation; + runInAction(() => (this._isLoading = true)); + await SmartDrawHandler.Instance.drawWithGPT({ X: e.clientX, Y: e.clientY }, this._selectedText, 5, 100, true); + runInAction(() => (this._isLoading = false)); + } catch (err) { + console.error(err); + } + }; + + /** + * Defines how a GPT drawing should be added to the current document. + */ + @undoBatch + createDrawingAnnotation = action((drawing: Doc, opts: DrawingOptions, gptRes: string) => { + this.AddDrawingAnnotation(drawing); + const docData = drawing[DocData]; + docData.title = opts.text.match(/^(.*?)~~~.*$/)?.[1] || opts.text; + docData.drawingInput = opts.text; + docData.drawingComplexity = opts.complexity; + docData.drawingColored = opts.autoColor; + docData.drawingSize = opts.size; + docData.drawingData = gptRes; + }); + pointerDown = (e: React.PointerEvent) => { setupMoveUpEvents( this, @@ -249,6 +282,14 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> { {/* Adds a create flashcards option to the anchor menu, which calls the gptFlashcard method. */} <IconButton tooltip="Create flashcards" onPointerDown={this.gptFlashcards} icon={<FontAwesomeIcon icon="id-card" size="lg" />} color={SettingsManager.userColor} /> <IconButton tooltip="Create labels" onPointerDown={this.makeLabels} icon={<FontAwesomeIcon icon="tag" size="lg" />} color={SettingsManager.userColor} /> + {this._selectedText && ( + <IconButton + tooltip="Create drawing" + onPointerDown={e => this.gptDraw(e)} + icon={this._isLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <FontAwesomeIcon icon="paintbrush" size="lg" />} + color={SettingsManager.userColor} + /> + )} {AnchorMenu.Instance.OnAudio === unimplementedFunction ? null : ( <IconButton tooltip="Click to Record Annotation" // |
