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.tsx60
1 files changed, 41 insertions, 19 deletions
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index f6c33d6ba..e0c360132 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -1,7 +1,7 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import axios from 'axios';
-import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction, trace } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import ReactLoading from 'react-loading';
@@ -30,6 +30,7 @@ import './ComparisonBox.scss';
import { DocumentView } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
+import { TraceMobx } from '../../../fields/util';
const API_URL = 'https://api.unsplash.com/search/photos';
@@ -63,8 +64,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
* @param useDoc doc to fill in instead of creating a Doc
* @returns the resulting flashcard Doc
*/
- public static createFlashcard(tuple: string, frontKey: string, backKey: string, useDoc?: Doc) {
- const [ktoken, atoken] = [ComparisonBox.ktoken, ComparisonBox.atoken];
+ public static createFlashcard(tuple3: string, frontKey: string, backKey: string, useDoc?: Doc) {
+ const [qtoken, ktoken, atoken] = [ComparisonBox.qtoken, ComparisonBox.ktoken, ComparisonBox.atoken];
+ const [title, tuple] = tuple3.split(qtoken);
const question = (tuple.includes(ktoken) ? tuple.split(ktoken)[0] : tuple).split(atoken)[0];
const rest = tuple.replace(question, '');
// prettier-ignore
@@ -82,7 +84,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
useDoc[DocData][backKey] = back;
return useDoc;
}
- return Docs.Create.FlashcardDocument('flashcard', front, back, { _width: 300, _height: 300 });
+ return Docs.Create.FlashcardDocument(title, front, back, { _width: 300, _height: 300 });
};
return keyword && keyword.toLowerCase() !== 'none' ? ComparisonBox.fetchImages(keyword).then(img => fillInFlashcard(img)) : fillInFlashcard();
}
@@ -95,12 +97,13 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
public static createFlashcardDeck(text: string, width: number, height: number, front: string, back: string) {
return Promise.all(
text
- .split(ComparisonBox.qtoken)
+ .toLowerCase()
+ .split(ComparisonBox.ttoken)
.filter(t => t)
.map(tuple => ComparisonBox.createFlashcard(tuple, front, back))
).then(docs => {
return Docs.Create.CarouselDocument(docs, {
- title: 'flashcard deck',
+ title: text,
_width: width,
_height: height,
_layout_fitWidth: false,
@@ -112,9 +115,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
}
private SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
- static qtoken = 'Question: ';
- static ktoken = 'Keyword: ';
- static atoken = 'Answer: ';
+ static qtoken = 'question: ';
+ static ktoken = 'keyword: ';
+ static atoken = 'answer: ';
+ static ttoken = 'title: ';
private _slideTiming = 200;
private _sideBtnWidth = 35;
private _closeRef = React.createRef<HTMLDivElement>();
@@ -140,19 +144,28 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
this._reactDisposer.select = reaction(
() => this._props.isSelected(),
selected => {
- if (selected && this.revealOp !== flashcardRevealOp.SLIDE) this.activateContent();
- !selected && (this._childActive = false);
+ if (selected) {
+ switch (this.revealOp) {
+ default:
+ case flashcardRevealOp.FLIP: this.activateContent(); break;
+ case flashcardRevealOp.SLIDE: break;
+ } // prettier-ignore
+ } else {
+ this._childActive = false;
+ }
}, // what it should update to
{ fireImmediately: true }
);
- this._reactDisposer.hover = reaction(
- () => this._props.isContentActive(),
- hover => {
- if (!hover) {
- this.revealOp === flashcardRevealOp.FLIP && this.animateFlipping(this.frontKey);
- this.revealOp === flashcardRevealOp.SLIDE && this.animateSliding(this._props.PanelWidth() - 3);
+ this._reactDisposer.inactive = reaction(
+ () => !this._props.isContentActive(),
+ inactive => {
+ if (inactive) {
+ switch (this.revealOp) {
+ case flashcardRevealOp.FLIP: this.animateFlipping(this.frontKey); break;
+ case flashcardRevealOp.SLIDE: this.animateSliding(this._props.PanelWidth() - 3); break;
+ } // prettier-ignore
}
- }, // what it should update to
+ },
{ fireImmediately: true }
);
}
@@ -183,7 +196,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
@computed get containerDoc() { return this._props.docViewPath().slice(-2)[0]?.Document; } // prettier-ignore
@computed get isQuizMode() { return this.containerDoc?.practiceMode === practiceMode.QUIZ; } // prettier-ignore
- @computed get isFlashcard() { return BoolCast(this.Document.layout_isFlashcard); } // prettier-ignore
+ @computed get isFlashcard() { return StrCast(this.Document.layout_flashcardType); } // prettier-ignore
@computed get frontKey() { return this._props.fieldKey + '_front'; } // prettier-ignore
@computed get backKey() { return this._props.fieldKey + '_back'; } // prettier-ignore
@computed get frontText() { return RTFCast(DocCast(this.dataDoc[this.frontKey]).text)?.Text; } // prettier-ignore
@@ -194,7 +207,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
@computed get clipWidth() { return NumCast(this.layoutDoc[this.clipWidthKey], this.isFlashcard ? 100: 50); } // prettier-ignore
@computed get clipHeight() { return NumCast(this.layoutDoc[this.clipHeightKey], 200); } // prettier-ignore
@computed get revealOp() { return StrCast(this.layoutDoc[this.revealOpKey], StrCast(this.containerDoc?.revealOp, this.isFlashcard ? flashcardRevealOp.FLIP : flashcardRevealOp.SLIDE)) as flashcardRevealOp; } // prettier-ignore
+ set revealOp(op:flashcardRevealOp) { this.layoutDoc[this.revealOpKey] = op; } // prettier-ignore
@computed get revealOpHover() { return BoolCast(this.layoutDoc[this.revealOpKey+"_hover"], BoolCast(this.containerDoc?.revealOp_hover)); } // prettier-ignore
+ set revealOpHover(on:boolean) { this.layoutDoc[this.revealOpKey+"_hover"] = on; } // prettier-ignore
@computed get loading() { return this._loading; } // prettier-ignore
set loading(value) { runInAction(() => { this._loading = value; })} // prettier-ignore
@@ -613,6 +628,12 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
const appearance = ContextMenu.Instance.findByDescription('Appearance...');
const appearanceItems = appearance?.subitems ?? [];
appearanceItems.push({ description: 'Create ChatCard', event: () => this.askGPT(GPTCallType.CHATCARD), icon: 'id-card' });
+ appearanceItems.push({
+ description: 'Reveal by ' + (this.revealOp === flashcardRevealOp.FLIP ? 'Sliding' : 'Flipping'),
+ event: () => (this.revealOp = this.revealOp === flashcardRevealOp.FLIP ? flashcardRevealOp.SLIDE : flashcardRevealOp.FLIP),
+ icon: 'id-card',
+ });
+ appearanceItems.push({ description: (this.revealOpHover ? 'Click ' : 'Hover ') + ' to reveal', event: () => (this.revealOpHover = !this.revealOpHover), icon: 'id-card' });
!appearance && ContextMenu.Instance.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'eye' });
};
@@ -789,6 +810,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
);
render() {
+ TraceMobx();
const renderMode = new Map<flashcardRevealOp, () => JSX.Element>([
[flashcardRevealOp.FLIP, this.renderAsFlip],
[flashcardRevealOp.SLIDE, this.renderAsBeforeAfter]]); // prettier-ignore