aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/ComparisonBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/ComparisonBox.tsx')
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx99
1 files changed, 79 insertions, 20 deletions
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index 6d4af2f3e..f844892c5 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -1,9 +1,9 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
-import { action, computed, makeObservable, observable } from 'mobx';
+import { action, computed, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { returnFalse, returnNone, setupMoveUpEvents } from '../../../ClientUtils';
+import { returnFalse, returnNone, returnTrue, setupMoveUpEvents } from '../../../ClientUtils';
import { emptyFunction } from '../../../Utils';
import { Doc, Opt } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
@@ -27,6 +27,7 @@ import { FormattedTextBox } from './formattedText/FormattedTextBox';
import ReactLoading from 'react-loading';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
+import { tickStep } from 'd3';
@observer
export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@@ -37,7 +38,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
constructor(props: FieldViewProps) {
super(props);
makeObservable(this);
- // this._isAnyChildContentActive = true;
}
@observable private _inputValue = '';
@@ -63,12 +63,19 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
@computed get clipHeight() {
return NumCast(this.layoutDoc[this.clipHeightKey], 200);
}
+ get revealOp() {
+ return this.layoutDoc[`_${this._props.fieldKey}_revealOp`];
+ }
get clipHeightKey() {
return '_' + this._props.fieldKey + '_clipHeight';
}
componentDidMount() {
this._props.setContentViewBox?.(this);
+ reaction(
+ () => this._props.isSelected(),
+ selected => !selected && (this.childActive = false)
+ );
}
protected createDropTarget = (ele: HTMLDivElement | null, fieldKey: string, disposerId: number) => {
this._disposers[disposerId]?.();
@@ -98,7 +105,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
emptyFunction,
action((moveEv, doubleTap) => {
if (doubleTap) {
- this._isAnyChildContentActive = true;
+ this.childActive = true;
if (!this.dataDoc[this.fieldKey + '_1'] && !this.dataDoc[this.fieldKey]) this.dataDoc[this.fieldKey + '_1'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
if (!this.dataDoc[this.fieldKey + '_2'] && !this.dataDoc[this.fieldKey + '_alternate']) this.dataDoc[this.fieldKey + '_2'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
}
@@ -106,7 +113,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
false,
undefined,
action(() => {
- if (this._isAnyChildContentActive) return;
+ if (this.childActive) return;
this._animating = 'all 200ms';
// on click, animate slider movement to the targetWidth
this.layoutDoc[this.clipWidthKey] = (targetWidth * 100) / this._props.PanelWidth();
@@ -247,7 +254,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
hoverFlip = (side: string | undefined) => {
if (this.layoutDoc[`_${this._props.fieldKey}_revealOp`] === 'hover') this.layoutDoc[`_${this._props.fieldKey}_usePath`] = side;
};
-
/**
* Creates the button used to flip the flashcards.
*/
@@ -259,7 +265,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
className="formattedTextBox-alternateButton"
onPointerDown={e =>
setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, () => {
- console.log(this.layoutDoc[`_${this._props.fieldKey}_revealOp`]);
if (!this.layoutDoc[`_${this._props.fieldKey}_revealOp`] || this.layoutDoc[`_${this._props.fieldKey}_revealOp`] === 'flip') {
this.flipFlashcard();
@@ -271,6 +276,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
style={{
background: usepath === 'alternate' ? 'white' : 'black',
color: usepath === 'alternate' ? 'black' : 'white',
+ display: 'inline-block',
}}>
<div key="alternate" className="formattedTextBox-flip">
<FontAwesomeIcon icon="turn-up" size="1x" />
@@ -280,6 +286,37 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
);
}
+ @computed get flashcardMenu() {
+ return (
+ <div>
+ <Tooltip
+ title={
+ this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? (
+ <div className="dash-tooltip">Flip to front side to use GPT</div>
+ ) : (
+ <div className="dash-tooltip">Ask GPT to create an answer on the back side of the flashcard</div>
+ )
+ }>
+ <div style={{ position: 'absolute', bottom: '3px', right: '55px', cursor: 'pointer' }} onPointerDown={e => (!this.layoutDoc[`_${this._props.fieldKey}_usePath`] ? this.askGPT(GPTCallType.CHATCARD) : null)}>
+ <FontAwesomeIcon icon="lightbulb" size="xl" />
+ </div>
+ </Tooltip>
+ <Tooltip title={<div className="dash-tooltip">Hover to reveal</div>}>
+ <div
+ style={{ position: 'absolute', bottom: '3px', right: '25px', cursor: 'pointer' }}
+ onClick={e => (this.revealOp === 'hover' ? (this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'flip') : (this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'hover'))}>
+ <FontAwesomeIcon color={this.revealOp === 'hover' ? 'blue' : 'black'} icon="layer-group" size="xl" />
+ </div>
+ </Tooltip>
+ {this.overlayAlternateIcon}
+ </div>
+ );
+ }
+
+ @action activateContent = () => {
+ this.childActive = true;
+ };
+
@action handleRenderGPTClick = () => {
// Call the GPT model and get the output
this.layoutDoc[`_${this._props.fieldKey}_usePath`] = 'alternate';
@@ -320,8 +357,12 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
const rubricText = ' Rubric: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text);
const queryText = questionText + ' UserAnswer: ' + this._inputValue + '. ' + rubricText;
this._loading = true;
+ const doc = DocCast(this.dataDoc[this.props.fieldKey + '_0']);
if (callType == GPTCallType.CHATCARD) {
- DocCast(this.dataDoc[this.props.fieldKey + '_0'])[DocData].text = '';
+ if (StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text) === '') {
+ this._loading = false;
+ return;
+ }
this.flipFlashcard();
}
try {
@@ -330,7 +371,13 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
console.error('GPT call failed');
return;
}
- this.animateRes(0, res, callType);
+ // this.animateRes(0, res, callType);
+ if (callType == GPTCallType.CHATCARD) {
+ DocCast(this.dataDoc[this.props.fieldKey + '_0'])[DocData].text = res;
+ // this.flipFlashcard();
+ }
+ if (callType == GPTCallType.QUIZ) this._outputValue = res;
+ // DocCast(this.dataDoc[this.props.fieldKey + '_0'])[DocData].text = res;
// this._outputValue = res;
console.log(res);
} catch (err) {
@@ -341,10 +388,11 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
layoutWidth = () => NumCast(this.layoutDoc.width, 200);
layoutHeight = () => NumCast(this.layoutDoc.height, 200);
- specificMenu = (): void => {
- const cm = ContextMenu.Instance;
- cm.addItem({ description: 'Create an Answer on the Back', event: () => this.askGPT(GPTCallType.CHATCARD), icon: 'pencil' });
- };
+ // specificMenu = (): void => {
+ // const cm = ContextMenu.Instance;
+ // cm.addItem({ description: 'Create an Answer on the Back', event: () => this.askGPT(GPTCallType.CHATCARD), icon: 'pencil' });
+ // };
+ @observable childActive = false;
render() {
const clearButton = (which: string) => (
@@ -378,12 +426,13 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
removeDocument={whichSlot.endsWith('1') ? this.remDoc1 : this.remDoc2}
NativeWidth={this.layoutWidth}
NativeHeight={this.layoutHeight}
- isContentActive={emptyFunction}
+ isContentActive={() => this.childActive}
isDocumentActive={returnFalse}
+ dontSelect={returnTrue}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
- styleProvider={this._isAnyChildContentActive ? this._props.styleProvider : this.docStyleProvider}
+ styleProvider={this.childActive ? this._props.styleProvider : this.docStyleProvider}
hideLinkButton
- pointerEvents={this._isAnyChildContentActive ? undefined : returnNone}
+ pointerEvents={this.childActive ? undefined : returnNone}
/>
<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`
@@ -394,7 +443,15 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
);
};
const displayBox = (which: string, index: number, cover: number) => (
- <div className={`${index === 0 ? 'before' : 'after'}Box-cont`} key={which} style={{ width: this._props.PanelWidth() }} onPointerDown={e => this.registerSliding(e, cover)} ref={ele => this.createDropTarget(ele, which, index)}>
+ <div
+ className={`${index === 0 ? 'before' : 'after'}Box-cont`}
+ key={which}
+ style={{ width: this._props.PanelWidth() }}
+ onPointerDown={e => {
+ this.registerSliding(e, cover);
+ this.activateContent();
+ }}
+ ref={ele => this.createDropTarget(ele, which, index)}>
{displayDoc(which)}
</div>
);
@@ -431,6 +488,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
<textarea
value={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? this._outputValue : this._inputValue}
onChange={this.handleInputChange}
+ onScroll={e => e.stopPropagation()}
readOnly={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate'}></textarea>
{this._loading ? (
@@ -457,7 +515,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
return (
<div
className={`comparisonBox${this._props.isContentActive() ? '-interactive' : ''}`} /* change className to easily disable/enable pointer events in CSS */
- onContextMenu={this.specificMenu}
+ // onContextMenu={this.specificMenu}
style={{ display: 'flex', flexDirection: 'column' }}
onMouseEnter={() => {
this.hoverFlip('alternate');
@@ -473,7 +531,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
<ReactLoading type="spin" height={30} width={30} color={'blue'} />
</div>
) : null}
- {this.overlayAlternateIcon}
+ {this.flashcardMenu}
+ {/* {this.overlayAlternateIcon} */}
</div>
);
}
@@ -491,7 +550,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
left: `calc(${this.clipWidth + '%'} - 0.5px)`,
cursor: this.clipWidth < 5 ? 'e-resize' : this.clipWidth / 100 > (this._props.PanelWidth() - 5) / this._props.PanelWidth() ? 'w-resize' : undefined,
}}
- onPointerDown={e => !this._isAnyChildContentActive && this.registerSliding(e, this._props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */
+ onPointerDown={e => !this.childActive && this.registerSliding(e, this._props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */
>
<div className="slide-handle" />
</div>