diff options
Diffstat (limited to 'src/client/views/nodes/ComparisonBox.tsx')
-rw-r--r-- | src/client/views/nodes/ComparisonBox.tsx | 88 |
1 files changed, 60 insertions, 28 deletions
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index adb380f12..c0c173d9a 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -10,6 +10,7 @@ import { DocData } from '../../../fields/DocSymbols'; import { RichTextField } from '../../../fields/RichTextField'; import { DocCast, NumCast, RTFCast, StrCast, toList } from '../../../fields/Types'; import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT'; +import '../pdf/GPTPopup/GPTPopup.scss'; import { DocUtils } from '../../documents/DocUtils'; import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; @@ -23,6 +24,7 @@ import './ComparisonBox.scss'; import { DocumentView } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; +import ReactLoading from 'react-loading'; @observer export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @@ -33,17 +35,18 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() constructor(props: FieldViewProps) { super(props); makeObservable(this); + // this._isAnyChildContentActive = true; } - @observable inputValue = ''; - @observable outputValue = ''; - @observable loading = false; - @observable errorMessage = ''; - @observable outputMessage = ''; + @observable private _inputValue = ''; + @observable private _outputValue = ''; + @observable private _loading = false; + @observable private _errorMessage = ''; + @observable private _outputMessage = ''; @action handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { - this.inputValue = e.target.value; - console.log(this.inputValue); + this._inputValue = e.target.value; + console.log(this._inputValue); }; @observable _animating = ''; @@ -118,6 +121,12 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() } }; + // private onClick(e: React.PointerEvent<HTMLDivElement>) { + // setupMoveUpEvents( + // this, e, this.onPointerMOve, emptyFunction(), () => {this._isAnyChildContentActive = true;}, emptyFunction(), emptyFunction() + // ) + // } + @action private onPointerMove = ({ movementX }: PointerEvent) => { const width = movementX * this.ScreenToLocalBoxXf().Scale + (this.clipWidth / 100) * this._props.PanelWidth(); @@ -157,7 +166,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() }; remDoc = (doc: Doc, which: string) => { if (this.dataDoc[which] === doc) { - // this.dataDoc[which] = 'empty'; + this.dataDoc[which] = 'empty'; this.dataDoc[which] = undefined; return true; } @@ -251,6 +260,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() console.log(this.layoutDoc[`_${this._props.fieldKey}_revealOp`]); if (!this.layoutDoc[`_${this._props.fieldKey}_revealOp`] || this.layoutDoc[`_${this._props.fieldKey}_revealOp`] === 'flip') { this.flipFlashcard(); + console.log('Print Front of cards: ' + (RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text ?? '')); console.log('Print Back of cards: ' + (RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text ?? '')); } @@ -260,7 +270,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() background: usepath === 'alternate' ? 'white' : 'black', color: usepath === 'alternate' ? 'black' : 'white', }}> - <FontAwesomeIcon icon="turn-up" size="sm" /> + <div key="alternate" className="formattedTextBox-flip"> + <FontAwesomeIcon icon="turn-up" size="1x" /> + </div> </div> </Tooltip> ); @@ -269,8 +281,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() @action handleRenderGPTClick = () => { // Call the GPT model and get the output this.layoutDoc[`_${this._props.fieldKey}_usePath`] = 'alternate'; - this.outputValue = ''; - if (this.inputValue) this.askGPT(); + this._outputValue = ''; + if (this._inputValue) this.askGPT(); }; @action handleRenderClick = () => { @@ -278,6 +290,15 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() this.layoutDoc[`_${this._props.fieldKey}_usePath`] = undefined; }; + animateRes = (resIndex: number, newText: string) => { + if (resIndex < newText.length) { + // const marks = this._editorView?.state.storedMarks ?? []; + this._outputValue += newText[resIndex]; + // this._editorView?.dispatch(this._editorView?.state.tr.insertText(newText[resIndex]).setStoredMarks(this._outputValue)); + setTimeout(() => this.animateRes(resIndex + 1, newText), 20); + } + }; + /** * Calls the GPT model to create QuizCards. Evaluates how similar the user's response is to the alternate * side of the flashcard. @@ -285,19 +306,21 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() askGPT = async (): Promise<string | undefined> => { const questionText = 'Question: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text); const rubricText = ' Rubric: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text); - const queryText = questionText + ' UserAnswer: ' + this.inputValue + '. ' + rubricText; - + const queryText = questionText + ' UserAnswer: ' + this._inputValue + '. ' + rubricText; + this._loading = true; try { const res = await gptAPICall(queryText, GPTCallType.QUIZ); if (!res) { console.error('GPT call failed'); return; } - this.outputValue = res; + this.animateRes(0, '\n\n' + res); + // this._outputValue = res; console.log(res); } catch (err) { console.error('GPT call failed'); } + this._loading = false; }; layoutWidth = () => NumCast(this.layoutDoc.width, 200); layoutHeight = () => NumCast(this.layoutDoc.height, 200); @@ -306,11 +329,12 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() const clearButton = (which: string) => ( <Tooltip title={<div className="dash-tooltip">remove</div>}> <div + // style={{ position: 'relative', top: '0px', left: '10px' }} ref={this._closeRef} className={`clear-button ${which}`} onPointerDown={e => this.closeDown(e, which)} // prevent triggering slider movement in registerSliding > - <FontAwesomeIcon className={`clear-button ${which}`} icon="times" size="sm" /> + <FontAwesomeIcon className={`clear-button ${which}`} icon="times" size="xs" /> </div> </Tooltip> ); @@ -340,8 +364,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() hideLinkButton pointerEvents={this._isAnyChildContentActive ? undefined : returnNone} /> - {layoutString ? null : clearButton(whichSlot)} - </> // placeholder image if doc is missing + <div style={{ position: 'absolute', top: '-5px', left: '2px' }}>{layoutString ? null : clearButton(whichSlot)}</div> + </> // placeholder image if doc is missingleft: `${NumCast(this.layoutDoc.width, 200) - 33}px` ) : ( <div className="placeholder"> <FontAwesomeIcon className="upload-icon" icon="cloud-upload-alt" size="lg" /> @@ -377,25 +401,31 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() // render the QuizCards if (DocCast(this.Document.embedContainer) && DocCast(this.Document.embedContainer).filterOp === 'quiz') { + const text = StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text); return ( <div className={`comparisonBox${this._props.isContentActive() ? '-interactive' : ''}`} style={{ display: 'flex', flexDirection: 'column' }}> - <p style={{ color: 'white', padding: 10 }}>{StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text)}</p> - {/* {StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text)} */} + <p style={{ color: 'white', padding: 10 }}>{text}</p> + <p style={{ display: text === '' ? 'flex' : 'none', color: 'white', padding: 10 }}>Return to all flashcards and add text to both sides. </p> <div className="input-box"> <textarea - value={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? this.outputValue : this.inputValue} + value={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? this._outputValue : this._inputValue} onChange={this.handleInputChange} - readOnly={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate'} - /> + readOnly={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate'}></textarea> + + {this._loading ? ( + <div className="loading-spinner" style={{ position: 'absolute' }}> + <ReactLoading type="spin" height={30} width={30} color={'blue'} /> + </div> + ) : null} </div> - <div className="submit-button" style={{ display: this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 'none' : 'flex' }}> - <button type="button" onClick={this.handleRenderGPTClick}> + <div className="submit-button" style={{ overflow: 'hidden', display: this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 'none' : 'flex' }}> + <button type="button" onClick={this.handleRenderGPTClick} style={{ borderRadius: '2px', marginBottom: '3px' }}> Submit </button> </div> - <div className="submit-button" style={{ display: this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 'flex' : 'none' }}> - <button type="button" onClick={this.handleRenderClick}> - Edit Your Response + <div className="submit-button" style={{ overflow: 'hidden', marginBottom: '2px', display: this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 'flex' : 'none' }}> + <button type="button" onClick={this.handleRenderClick} style={{ borderRadius: '2px' }}> + Try Again </button> </div> </div> @@ -412,7 +442,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() }} onMouseLeave={() => { this.hoverFlip(undefined); - }}> + }} + // onPointerUp={() => (this._isAnyChildContentActive = true)} + > {displayBox(`${this.fieldKey}_${side === 0 ? 1 : 0}`, side, this._props.PanelWidth() - 3)} {this.overlayAlternateIcon} </div> |