diff options
author | bobzel <zzzman@gmail.com> | 2024-10-10 18:27:25 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2024-10-10 18:27:25 -0400 |
commit | f75f15ae58b57644c28d42446c176289bbe55dd4 (patch) | |
tree | 1b86c941f0aa568adeff95c4559c7a2e82cd46d0 /src | |
parent | 386d640fe7fc4b443bc5f241f86e27424851dc4e (diff) |
adjusted hiding chrome for carousel. cleaned up some comparisonBox quiz code. removed create flashcard pile button from flashcard - would prefer carousel being added to marquee menu.
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/collections/CollectionCarouselView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/FlashcardPracticeUI.tsx | 46 | ||||
-rw-r--r-- | src/client/views/nodes/ComparisonBox.scss | 29 | ||||
-rw-r--r-- | src/client/views/nodes/ComparisonBox.tsx | 109 | ||||
-rw-r--r-- | src/client/views/pdf/AnchorMenu.tsx | 2 |
5 files changed, 106 insertions, 82 deletions
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 538eba356..aa447c7bf 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -184,7 +184,7 @@ export class CollectionCarouselView extends CollectionSubView() { } @computed get navButtons() { - return this.Document._chromeHidden || !this.curDoc() ? null : ( + return !this.curDoc() ? null : ( <> <div key="back" className="carouselView-back" style={{ transform: `scale(${this.uiBtnScaling})` }} onClick={this.goback}> <FontAwesomeIcon icon="chevron-left" size="2x" /> diff --git a/src/client/views/collections/FlashcardPracticeUI.tsx b/src/client/views/collections/FlashcardPracticeUI.tsx index 4e424f5cd..7697d308b 100644 --- a/src/client/views/collections/FlashcardPracticeUI.tsx +++ b/src/client/views/collections/FlashcardPracticeUI.tsx @@ -15,7 +15,7 @@ import { SnappingManager } from '../../util/SnappingManager'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { emptyFunction } from '../../../Utils'; -enum practiceMode { +export enum practiceMode { PRACTICE = 'practice', QUIZ = 'quiz', } @@ -172,27 +172,29 @@ export class FlashcardPracticeUI extends ObservableReactComponent<PracticeUIProp <> {this.emptyMessage} {this.practiceButtons} - <div className="FlashcardPracticeUI-menu" style={{ height: this.btnHeight(), width: this.btnHeight(), transform: `scale(${this._props.uiBtnScaling})` }}> - {!this.filterDoc || this._props.layoutDoc._chromeHidden ? null : ( - <DocumentView - {...this._props.docViewProps()} - Document={this.filterDoc} - TemplateDataDocument={undefined} - PanelWidth={this.btnWidth} - PanelHeight={this.btnHeight} - NativeWidth={returnZero} - NativeHeight={returnZero} - hideDecorations={BoolCast(this._props.layoutDoc.layout_hideDecorations)} - hideCaptions={true} - hideFilterStatus={true} - renderDepth={this._props.renderDepth + 1} - fitWidth={undefined} - showTags={false} - setContentViewBox={undefined} - /> - )} - {this.practiceModesMenu} - </div> + {this._props.layoutDoc._chromeHidden ? null : ( + <div className="FlashcardPracticeUI-menu" style={{ height: this.btnHeight(), width: this.btnHeight(), transform: `scale(${this._props.uiBtnScaling})` }}> + {!this.filterDoc ? null : ( + <DocumentView + {...this._props.docViewProps()} + Document={this.filterDoc} + TemplateDataDocument={undefined} + PanelWidth={this.btnWidth} + PanelHeight={this.btnHeight} + NativeWidth={returnZero} + NativeHeight={returnZero} + hideDecorations={BoolCast(this._props.layoutDoc.layout_hideDecorations)} + hideCaptions={true} + hideFilterStatus={true} + renderDepth={this._props.renderDepth + 1} + fitWidth={undefined} + showTags={false} + setContentViewBox={undefined} + /> + )} + {this.practiceModesMenu} + </div> + )} </> ); } diff --git a/src/client/views/nodes/ComparisonBox.scss b/src/client/views/nodes/ComparisonBox.scss index 8156c50f6..c328ef4bf 100644 --- a/src/client/views/nodes/ComparisonBox.scss +++ b/src/client/views/nodes/ComparisonBox.scss @@ -9,6 +9,7 @@ z-index: 0; pointer-events: none; display: flex; + flex-direction: column; p { // bcz: what is this styling for? if text in the comparison box is colored, then this causes it to render with a black outline color: rgb(0, 0, 0); @@ -32,8 +33,10 @@ padding-right: 5px; border-radius: 2px; height: 17%; - display: inline-block; bottom: 0; + overflow: hidden; + display: flex; + width: 100%; &.schema-header-button { color: gray; @@ -61,6 +64,29 @@ float: left; border-radius: 2px; } + .submit-buttonrecord { + border-radius: 2px; + } + .submit-buttonpronunciation { + display: inline-flex; + align-items: center; + } + .submit-buttonschema-header-button { + position: absolute; + top: 5px; + left: 11px; + z-index: 10; + width: 5px; + height: 5px; + cursor: pointer; + } + .submit-buttonsubmit { + border-radius: 2px; + margin-bottom: 3px; + width: 100%; + display: inline-flex; + align-items: center; + } } .dropbtn { @@ -194,6 +220,7 @@ .loading-spinner { display: flex; + position: absolute; justify-content: center; align-items: center; height: 90%; diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 9852228fa..ccbe98257 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 } from 'mobx'; +import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } 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 { practiceMode } from '../collections/FlashcardPracticeUI'; const API_URL = 'https://api.unsplash.com/search/photos'; @@ -122,18 +123,11 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() </Tooltip> )} {DocCast(this.Document.embedContainer)?.type_collection !== CollectionViewType.Freeform ? null : ( - <> - <Tooltip title={<div>Create a flashcard pile</div>}> - <div className="comparisonBox-button" onPointerDown={() => this.createFlashcardPile([this.Document], false)}> - <FontAwesomeIcon icon="folder-plus" size="xl" /> - </div> - </Tooltip> - <Tooltip title={<div className="dash-tooltip">Create new flashcard stack based on text</div>}> - <div className="comparisonBox-button" onClick={this.gptFlashcardPile}> - <FontAwesomeIcon icon="layer-group" size="xl" /> - </div> - </Tooltip> - </> + <Tooltip title={<div className="dash-tooltip">Create new flashcard stack based on text</div>}> + <div className="comparisonBox-button" onClick={this.gptFlashcardPile}> + <FontAwesomeIcon icon="layer-group" size="xl" /> + </div> + </Tooltip> )} </> )} @@ -153,7 +147,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() this._frontSide = !this._frontSide; }; - @action handleRenderGPTClick = async () => { + @action handleRenderGPTClick = () => { const phonTrans = DocCast(this.Document.audio) ? DocCast(this.Document.audio).phoneticTranscription : undefined; if (phonTrans) { this._inputValue = StrCast(phonTrans); @@ -490,20 +484,22 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() } try { const res = await gptAPICall(questionText, GPTCallType.FLASHCARD); - if (!res) { - console.error('GPT call failed'); - return; - } - if (callType == GPTCallType.CHATCARD) { - DocCast(this.dataDoc[this.props.fieldKey + '_0'])[DocData].text = res; - } else if (callType == GPTCallType.QUIZ) { - this._frontSide = true; - this._outputValue = res.replace(/UserAnswer/g, "user's answer").replace(/Rubric/g, 'rubric'); - } else if (callType === GPTCallType.FLASHCARD) { + runInAction(() => { + if (!res) { + console.error('GPT call failed'); + return; + } + if (callType == GPTCallType.CHATCARD) { + DocCast(this.dataDoc[this.props.fieldKey + '_0'])[DocData].text = res; + } else if (callType == GPTCallType.QUIZ) { + this._frontSide = true; + this._outputValue = res.replace(/UserAnswer/g, "user's answer").replace(/Rubric/g, 'rubric'); + } else if (callType === GPTCallType.FLASHCARD) { + this._loading = false; + return res; + } this._loading = false; - return res; - } - this._loading = false; + }); return res; } catch (err) { console.error('GPT call failed', err); @@ -725,24 +721,33 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() if (this.Document._layout_isFlashcard) { const side = this._frontSide ? 1 : 0; + const dataSplit = StrCast(this.dataDoc.data).includes('Keyword: ') ? StrCast(this.dataDoc.data).split('Keyword: ') : StrCast(this.dataDoc.data).split('Answer: '); + const textCreator = (which: number, title: string, text: string) => { + const newDoc = Docs.Create.TextDocument(text, { + title, // + _layout_autoHeight: true, + _layout_centered: true, + text_align: 'center', + _layout_fitWidth: true, + }); + this.addDoc(newDoc, this.fieldKey + '_' + which); + return newDoc; + }; // add text box to each side when comparison box is first created if (!this.dataDoc[this.fieldKey + '_0'] && !this._isEmpty) { - const dataSplit = StrCast(this.dataDoc.data).includes('Keyword: ') ? StrCast(this.dataDoc.data).split('Keyword: ') : StrCast(this.dataDoc.data).split('Answer: '); - const newDoc = Docs.Create.TextDocument(dataSplit[1], { title: 'answer', _layout_autoHeight: true, _layout_centered: true, text_align: 'center', _layout_fitWidth: true }); - this.addDoc(newDoc, this.fieldKey + '_0'); + textCreator(0, 'answer', dataSplit[1]); } if (!this.dataDoc[this.fieldKey + '_1'] && !this._isEmpty) { - const dataSplit = StrCast(this.dataDoc.data).includes('Keyword: ') ? StrCast(this.dataDoc.data).split('Keyword: ') : StrCast(this.dataDoc.data).split('Answer: '); - const newDoc = Docs.Create.TextDocument(dataSplit[0], { title: 'question', _layout_autoHeight: true, _layout_centered: true, text_align: 'center', _layout_fitWidth: true }); - this.addDoc(newDoc, this.fieldKey + '_1'); + const question = textCreator(1, 'question', dataSplit[0] || 'hint: Enter a topic, select this document and click the stack button to have GPT create a deck of cards'); + Doc.SelectOnLoad = dataSplit[0] ? undefined : question; } - if (DocCast(this.Document.embedContainer) && DocCast(this.Document.embedContainer).practiceMode === 'quiz') { + if (DocCast(this.Document.embedContainer).practiceMode === practiceMode.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' }}> + <div className={`comparisonBox${this._props.isContentActive() ? '-interactive' : ''}`}> <p style={{ color: 'white', padding: 10 }}>{text}</p> <p style={{ display: text === '' ? 'flex' : 'none', color: 'white', marginLeft: '10px' }}>Return to all flashcards and add text to both sides. </p> <div className="input-box"> @@ -757,38 +762,28 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() readOnly={this._frontSide}></textarea> {this._loading ? ( - <div className="loading-spinner" style={{ position: 'absolute' }}> + <div className="loading-spinner"> <ReactLoading type="spin" height={30} width={30} color={'blue'} /> </div> ) : null} </div> <div> - <div className="submit-button" style={{ overflow: 'hidden', display: 'flex', width: '100%' }}> - <div - className="submit-buttonschema-header-button" - onPointerDown={e => this.openContextMenu(e.clientX, e.clientY, false)} - style={{ position: 'absolute', top: '5px', left: '11px', zIndex: '100', width: '5px', height: '5px', cursor: 'pointer' }}> - <FontAwesomeIcon color={'white'} icon="caret-down" /> + <div className="submit-button"> + <div className="submit-buttonschema-header-button" onPointerDown={e => this.openContextMenu(e.clientX, e.clientY, false)}> + <FontAwesomeIcon color="white" icon="caret-down" /> </div> - <button className="submit-buttonrecord" onClick={this._listening ? this.stopListening : this.startListening} style={{ background: this._listening ? 'lightgray' : '', borderRadius: '2px' }}> + <button className="submit-buttonrecord" onClick={this._listening ? this.stopListening : this.startListening} style={{ background: this._listening ? 'lightgray' : '' }}> {<FontAwesomeIcon icon="microphone" size="lg" />} </button> - <div className="submit-buttonschema-header-button" onPointerDown={e => this.openContextMenu(e.clientX, e.clientY, true)} style={{ position: 'absolute', top: '5px', left: '50px', zIndex: '100', cursor: 'pointer' }}> - <FontAwesomeIcon color={'white'} icon="caret-down" /> + <div className="submit-buttonschema-header-button" onPointerDown={e => this.openContextMenu(e.clientX, e.clientY, true)} style={{ left: '50px', zIndex: '100' }}> + <FontAwesomeIcon color="white" icon="caret-down" /> </div> - <button className="submit-buttonpronunciation" onClick={this.evaluatePronunciation} style={{ display: 'inline-flex', alignItems: 'center' }}> + <button className="submit-buttonpronunciation" onClick={this.evaluatePronunciation}> Evaluate Pronunciation </button> - - {!this._frontSide ? ( - <button className="submit-buttonsubmit" type="button" onClick={this.handleRenderGPTClick} style={{ borderRadius: '2px', marginBottom: '3px', width: '100%' }}> - Submit - </button> - ) : ( - <button className="submit-buttonsubmit" type="button" onClick={this.handleRenderClick} style={{ display: 'inline-flex', alignItems: 'center', borderRadius: '2px', marginBottom: '3px', width: '100%' }}> - Redo the Question - </button> - )} + <button className="submit-buttonsubmit" type="button" onClick={this._frontSide ? this.handleRenderClick : this.handleRenderGPTClick}> + {this._frontSide ? 'Redo the Question' : 'Submit'} + </button> </div> </div> </div> @@ -804,7 +799,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() onMouseLeave={() => this.hoverFlip(false)}> {displayBox(`${this.fieldKey}_${side === 0 ? 1 : 0}`, side, this._props.PanelWidth() - 3)} {this._loading ? ( - <div className="loading-spinner" style={{ position: 'absolute' }}> + <div className="loading-spinner"> <ReactLoading type="spin" height={30} width={30} color={'blue'} /> </div> ) : null} diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index b204d3692..7243473e0 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -254,7 +254,7 @@ 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 flashcards" onPointerDown={this.gptFlashcards} icon={<FontAwesomeIcon icon="layer-group" size="lg" />} color={SettingsManager.userColor} /> <IconButton tooltip="Create labels" onPointerDown={this.makeLabels} icon={<FontAwesomeIcon icon="tag" size="lg" />} color={SettingsManager.userColor} /> {this._selectedText && ( <IconButton |