aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/MainView.tsx1
-rw-r--r--src/client/views/collections/CollectionCarouselView.scss42
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx53
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx73
-rw-r--r--src/client/views/nodes/DocumentView.tsx14
5 files changed, 147 insertions, 36 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 31d88fb87..541b15006 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -548,6 +548,7 @@ export class MainView extends ObservableReactComponent<{}> {
fa.faRobot,
fa.faSatellite,
fa.faStar,
+ fa.faFilePen,
]
);
}
diff --git a/src/client/views/collections/CollectionCarouselView.scss b/src/client/views/collections/CollectionCarouselView.scss
index 975b352cf..c4679e888 100644
--- a/src/client/views/collections/CollectionCarouselView.scss
+++ b/src/client/views/collections/CollectionCarouselView.scss
@@ -50,7 +50,7 @@
}
.carouselView-star {
top: 0;
- right: 20;
+ left: 0;
}
.carouselView-remove {
top: 80%;
@@ -60,6 +60,46 @@
top: 80%;
right: 52%;
}
+.carouselView-quiz {
+ position: absolute;
+ display: flex;
+ top: 5px;
+ right: 8px;
+ &:hover {
+ color: white;
+ }
+}
+
+.carouselView-practice {
+ position: absolute;
+ display: flex;
+ top: 22px;
+ right: 8px;
+ &:hover {
+ color: white;
+ }
+}
+.carouselView-starFilter {
+ position: absolute;
+ display: flex;
+ top: 40px;
+ right: 7px;
+ &:hover {
+ color: white;
+ }
+}
+
+.carouselView-menu {
+ position: absolute;
+ display: flex;
+ top: 2px;
+ right: 2px;
+ width: 30;
+ height: 60;
+ border-radius: 5px;
+ color: rgba(255, 255, 255, 0.5);
+ background: rgba(0, 0, 0, 0.1);
+}
.carouselView-back:hover,
.carouselView-fwd:hover {
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 53d14e6e0..8da808065 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -19,6 +19,7 @@ import { FieldViewProps } from '../nodes/FieldView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import './CollectionCarouselView.scss';
import { CollectionSubView } from './CollectionSubView';
+import { Tooltip } from '@mui/material';
enum cardMode {
PRACTICE = 'practice',
@@ -143,22 +144,26 @@ export class CollectionCarouselView extends CollectionSubView() {
captionWidth = () => this._props.PanelWidth() - 2 * this.marginX;
setFilterMode = (mode: cardMode) => {
this.layoutDoc.filterOp = mode;
+ console.log('MODE' + mode);
+ console.log('FILT' + this.layoutDoc.filterOp + ';');
if (mode == cardMode.STAR) this.move(1);
- if (mode == cardMode.QUIZ) this.carouselItems?.map(doc => (doc.layout[this.sideField] = undefined));
+ if (mode == cardMode.QUIZ) {
+ this.carouselItems?.map(doc => (doc.layout[this.sideField] = undefined));
+ }
this.carouselItems?.map(doc => (doc.layout[this.practiceField] = undefined));
};
- specificMenu = (): void => {
- const cm = ContextMenu.Instance;
+ // specificMenu = (): void => {
+ // const cm = ContextMenu.Instance;
- const revealOptions = cm.findByDescription('Filter Flashcards');
- const revealItems: ContextMenuProps[] = revealOptions && 'subitems' in revealOptions ? revealOptions.subitems : [];
- revealItems.push({description: 'All', event: () => {this.setFilterMode(cardMode.ALL);}, icon: 'layer-group',}); // prettier-ignore
- revealItems.push({description: 'Star', event: () => {this.setFilterMode(cardMode.STAR);}, icon: 'star',}); // prettier-ignore
- revealItems.push({description: 'Practice Mode', event: () => {this.setFilterMode(cardMode.PRACTICE);}, icon: 'check',}); // prettier-ignore
- cm.addItem({description: 'Quiz Cards', event: () => {this.setFilterMode(cardMode.QUIZ);}, icon: 'pencil',}); // prettier-ignore
- !revealOptions && cm.addItem({ description: 'Filter Flashcards', addDivider: false, noexpand: true, subitems: revealItems, icon: 'layer-group' });
- //cm.addItem({description: 'Quiz Cards', event: () => {this.layoutDoc.filterOp = cardMode.QUIZ; this.clearContent()});
- };
+ // const revealOptions = cm.findByDescription('Filter Flashcards');
+ // const revealItems: ContextMenuProps[] = revealOptions && 'subitems' in revealOptions ? revealOptions.subitems : [];
+ // revealItems.push({description: 'All', event: () => {this.setFilterMode(cardMode.ALL);}, icon: 'layer-group',}); // prettier-ignore
+ // revealItems.push({description: 'Star', event: () => {this.setFilterMode(cardMode.STAR);}, icon: 'star',}); // prettier-ignore
+ // revealItems.push({description: 'Practice Mode', event: () => {this.setFilterMode(cardMode.PRACTICE);}, icon: 'check',}); // prettier-ignore
+ // cm.addItem({description: 'Quiz Cards', event: () => {this.setFilterMode(cardMode.QUIZ);}, icon: 'pencil',}); // prettier-ignore
+ // !revealOptions && cm.addItem({ description: 'Filter Flashcards', addDivider: false, noexpand: true, subitems: revealItems, icon: 'layer-group' });
+ // //cm.addItem({description: 'Quiz Cards', event: () => {this.layoutDoc.filterOp = cardMode.QUIZ; this.clearContent()});
+ // };
@computed get content() {
const index = NumCast(this.layoutDoc._carousel_index);
const curDoc = this.carouselItems?.[index];
@@ -226,6 +231,28 @@ export class CollectionCarouselView extends CollectionSubView() {
);
}
+ @computed get menu() {
+ return (
+ <div className="carouselView-menu">
+ <Tooltip title="Practice flashcards using GPT">
+ <div key="back" className="carouselView-quiz" onClick={e => (this.layoutDoc.filterOp === cardMode.QUIZ ? this.setFilterMode(cardMode.ALL) : this.setFilterMode(cardMode.QUIZ))}>
+ <FontAwesomeIcon icon="file-pen" color={this.layoutDoc.filterOp === cardMode.QUIZ ? 'white' : 'light gray'} size="1x" />
+ </div>
+ </Tooltip>
+ <Tooltip title={this.layoutDoc.filterOp === cardMode.PRACTICE ? 'Exit practice mode' : 'Practice flashcards manually'}>
+ <div key="back" className="carouselView-practice" onClick={e => (this.layoutDoc.filterOp === cardMode.PRACTICE ? this.setFilterMode(cardMode.ALL) : this.setFilterMode(cardMode.PRACTICE))}>
+ <FontAwesomeIcon icon="check" color={this.layoutDoc.filterOp === cardMode.PRACTICE ? 'white' : 'light gray'} size="1x" />
+ </div>
+ </Tooltip>
+ <Tooltip title={this.layoutDoc.filterOp === cardMode.STAR ? 'Show all cards' : 'Show only starred cards'}>
+ <div key="back" className="carouselView-starFilter" onClick={e => (!this.layoutDoc.filterOp ? this.setFilterMode(cardMode.ALL) : this.setFilterMode(cardMode.STAR))}>
+ <FontAwesomeIcon icon="filter" color={this.layoutDoc.filterOp === cardMode.STAR || !this.layoutDoc.filterOp ? 'white' : 'light gray'} size="1x" />
+ </div>
+ </Tooltip>
+ </div>
+ );
+ }
+
render() {
return (
<div
@@ -250,6 +277,7 @@ export class CollectionCarouselView extends CollectionSubView() {
<p
style={{
color: 'red',
+ fontWeight: 'bold',
zIndex: '999',
position: 'relative',
left: '10px',
@@ -263,6 +291,7 @@ export class CollectionCarouselView extends CollectionSubView() {
}}>
Recently missed!
</p>
+ {this.menu}
{this.Document._chromeHidden || !this.layoutDoc.filterOp ? null : this.buttons}
</div>
);
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index f844892c5..084723d56 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -45,6 +45,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
@observable private _loading = false;
@observable private _errorMessage = '';
@observable private _outputMessage = '';
+ @observable private _isEmpty = false;
+
+ public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined;
@action handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
this._inputValue = e.target.value;
@@ -162,23 +165,29 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
};
clearDoc = undoable((fieldKey: string) => {
- delete this.dataDoc[fieldKey];
- this.dataDoc[fieldKey] = 'empty';
+ // delete this.dataDoc[fieldKey];
+ this.dataDoc[fieldKey] = undefined;
+ this._isEmpty = true;
+ // this.dataDoc[fieldKey] = 'empty';
+ console.log('HERE' + fieldKey + ';');
}, 'clear doc');
// clearDoc = (fieldKey: string) => delete this.dataDoc[fieldKey];
moveDoc = (doc: Doc, addDocument: (document: Doc | Doc[]) => boolean, which: string) => this.remDoc(doc, which) && addDocument(doc);
addDoc = (doc: Doc, which: string) => {
- if (this.dataDoc[which] && this.dataDoc[which] !== 'empty') return false;
+ if (this.dataDoc[which] && !this._isEmpty) return false;
this.dataDoc[which] = doc;
return true;
};
remDoc = (doc: Doc, which: string) => {
if (this.dataDoc[which] === doc) {
- this.dataDoc[which] = 'empty';
+ this._isEmpty = true;
+ // this.dataDoc[which] = 'empty';
+ console.log('HEREEEE');
this.dataDoc[which] = undefined;
return true;
}
+ console.log('FALSE');
return false;
};
@@ -268,8 +277,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
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 ?? ''));
+ // 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 ?? ''));
}
})
}
@@ -297,10 +306,31 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
<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)}>
+ <div style={{ position: 'absolute', bottom: '3px', right: '56px', 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>Create a flashcard pile</div>}>
+ <div
+ style={{ position: 'absolute', bottom: '3px', right: '80px', cursor: 'pointer' }}
+ onPointerDown={e => {
+ const collectionArr: Doc[] = [];
+ collectionArr.push(this.Document);
+ const newCol = Docs.Create.CarouselDocument(collectionArr, {
+ _width: NumCast(this.layoutDoc['_' + this._props.fieldKey + '_width'], 250),
+ _height: NumCast(this.layoutDoc['_' + this._props.fieldKey + '_width'], 200),
+ _layout_fitWidth: false,
+ _layout_autoHeight: true,
+ });
+ newCol['x'] = e.clientX - 820;
+ newCol['y'] = e.clientY - 640;
+ this._props.addDocument?.(newCol);
+ this._props.removeDocument?.(this.Document);
+ this.Document.embedContainer = newCol;
+ }}>
+ <FontAwesomeIcon icon="folder-plus" size="xl" />
+ </div>
+ </Tooltip>
<Tooltip title={<div className="dash-tooltip">Hover to reveal</div>}>
<div
style={{ position: 'absolute', bottom: '3px', right: '25px', cursor: 'pointer' }}
@@ -308,11 +338,18 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
<FontAwesomeIcon color={this.revealOp === 'hover' ? 'blue' : 'black'} icon="layer-group" size="xl" />
</div>
</Tooltip>
- {this.overlayAlternateIcon}
+ {/* <Tooltip title={<div className="dash-tooltip">Remove this side of the flashcard</div>}>
+ <div
+ style={{ position: 'absolute', bottom: '3px', right: '80px', cursor: 'pointer' }}
+ onPointerDown={e => this.closeDown(e, this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? this._props.fieldKey + '_1' : this._props.fieldKey + '_0')}>
+ <FontAwesomeIcon color={this.revealOp === 'hover' ? 'blue' : 'black'} icon="trash-can" size="xl" />
+ </div>
+ </Tooltip> */}
+ {/* {this.overlayAlternateIcon} */}
</div>
);
}
-
+ // this.closeDown(e, this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? this.fieldKey + '_0' : this.fieldKey + '_1')}
@action activateContent = () => {
this.childActive = true;
};
@@ -434,7 +471,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
hideLinkButton
pointerEvents={this.childActive ? undefined : returnNone}
/>
- <div style={{ position: 'absolute', top: '-5px', left: '2px' }}>{layoutString ? null : clearButton(whichSlot)}</div>
+ {/* <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">
@@ -452,7 +489,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
this.activateContent();
}}
ref={ele => this.createDropTarget(ele, which, index)}>
- {displayDoc(which)}
+ {!this._isEmpty ? displayDoc(which) : null}
+ {/* {this.dataDoc[this.fieldKey + '_0'] !== 'empty' ? displayDoc(which) : null} */}
</div>
);
@@ -460,7 +498,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
const side = this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 1 : 0;
// add text box to each side when comparison box is first created
- if (!(this.dataDoc[this.fieldKey + '_0'] || this.dataDoc[this.fieldKey + '_0'] === 'empty')) {
+ // (!this.dataDoc[this.fieldKey + '_0'] && this.dataDoc[this._props.fieldKey + '_0'] !== 'empty')
+ if (!this.dataDoc[this.fieldKey + '_0'] && !this._isEmpty) {
const dataSplit = StrCast(this.dataDoc.data).split('Answer');
const newDoc = Docs.Create.TextDocument(dataSplit[1]);
// if there is text from the pdf ai cards, put the question on the front side.
@@ -468,7 +507,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
newDoc[DocData].text = dataSplit[1];
this.addDoc(newDoc, this.fieldKey + '_0');
}
- if (!(this.dataDoc[this.fieldKey + '_1'] || this.dataDoc[this.fieldKey + '_1'] === 'empty')) {
+ if (!this.dataDoc[this.fieldKey + '_1'] && !this._isEmpty) {
const dataSplit = StrCast(this.dataDoc.data).split('Answer');
const newDoc = Docs.Create.TextDocument(dataSplit[0]);
// if there is text from the pdf ai cards, put the answer on the alternate side.
@@ -478,6 +517,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
}
// render the QuizCards
+ console.log('GERE' + DocCast(this.Document.embedContainer).filterOp);
if (DocCast(this.Document.embedContainer) && DocCast(this.Document.embedContainer).filterOp === 'quiz') {
const text = StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text);
return (
@@ -489,6 +529,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
value={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? this._outputValue : this._inputValue}
onChange={this.handleInputChange}
onScroll={e => e.stopPropagation()}
+ placeholder={!this.layoutDoc[`_${this._props.fieldKey}_usePath`] ? 'Enter a response for GPT to evaluate.' : ''}
readOnly={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate'}></textarea>
{this._loading ? (
@@ -516,7 +557,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
<div
className={`comparisonBox${this._props.isContentActive() ? '-interactive' : ''}`} /* change className to easily disable/enable pointer events in CSS */
// onContextMenu={this.specificMenu}
- style={{ display: 'flex', flexDirection: 'column' }}
+ style={{ display: 'flex', flexDirection: 'column', overflow: 'hidden' }}
onMouseEnter={() => {
this.hoverFlip('alternate');
}}
@@ -531,8 +572,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
<ReactLoading type="spin" height={30} width={30} color={'blue'} />
</div>
) : null}
- {this.flashcardMenu}
- {/* {this.overlayAlternateIcon} */}
+ {this._props.isContentActive() ? this.flashcardMenu : null}
+ {this.overlayAlternateIcon}
</div>
);
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2f3357791..d4c31a5b3 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -566,13 +566,13 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
!appearance && appearanceItems.length && cm.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'compass' });
// creates menu for the user to select how to reveal the flashcards
- if (this.Document._layout_isFlashcard) {
- const revealOptions = cm.findByDescription('Reveal Options');
- const revealItems: ContextMenuProps[] = revealOptions && 'subitems' in revealOptions ? revealOptions.subitems : [];
- revealItems.push({ description: 'Hover', event: () => { this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'hover'; }, icon: 'hand-point-up' }); // prettier-ignore
- revealItems.push({ description: 'Flip', event: () => { this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'flip'; }, icon: 'rotate' }); // prettier-ignore
- !revealOptions && cm.addItem({ description: 'Reveal Options', addDivider: false, noexpand: true, subitems: revealItems, icon: 'layer-group' });
- }
+ // if (this.Document._layout_isFlashcard) {
+ // const revealOptions = cm.findByDescription('Reveal Options');
+ // const revealItems: ContextMenuProps[] = revealOptions && 'subitems' in revealOptions ? revealOptions.subitems : [];
+ // revealItems.push({ description: 'Hover', event: () => { this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'hover'; }, icon: 'hand-point-up' }); // prettier-ignore
+ // revealItems.push({ description: 'Flip', event: () => { this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'flip'; }, icon: 'rotate' }); // prettier-ignore
+ // !revealOptions && cm.addItem({ description: 'Reveal Options', addDivider: false, noexpand: true, subitems: revealItems, icon: 'layer-group' });
+ // }
if (this._props.bringToFront) {
const zorders = cm.findByDescription('ZOrder...');