/* eslint-disable react/jsx-props-no-spreading */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { action, computed, makeObservable, observable, trace } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { StopEvent, returnFalse, returnOne, returnTrue, returnZero } from '../../../ClientUtils'; import { emptyFunction } from '../../../Utils'; import { Doc, Opt } from '../../../fields/Doc'; import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; import { StyleProp } from '../StyleProp'; import { DocumentView } from '../nodes/DocumentView'; import { FieldViewProps } from '../nodes/FieldView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import './CollectionCarouselView.scss'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; enum cardMode { // PRACTICE = 'practice', STAR = 'star', // QUIZ = 'quiz', ALL = 'all', } enum practiceMode { PRACTICE = 'practice', QUIZ = 'quiz', NORMAL = 'normal', } enum practiceVal { MISSED = 'missed', CORRECT = 'correct', } @observer export class CollectionCarouselView extends CollectionSubView() { private _dropDisposer?: DragManager.DragDropDisposer; @observable private _practiceMessage: string | undefined; @observable private _filterMessage: string | undefined; get practiceField() { return this.fieldKey + "_practice"; } // prettier-ignore get sideField() { return "_" + this.fieldKey + "_usePath"; } // prettier-ignore get starField() { return "star"; } // prettier-ignore constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); // this.setModes(); this.layoutDoc.filterOp = cardMode.ALL; Doc.setDocFilter(this.Document, 'star', undefined, 'match'); this.layoutDoc.practiceMode = practiceMode.NORMAL; this.layoutDoc._carousel_index = 0; this.carouselItems.forEach(item => { item.layout[this.practiceField] = undefined}); //prettier-ignore console.log(this.carouselItems.length); } componentWillUnmount() { this._dropDisposer?.(); } protected createDashEventsTarget = (ele: HTMLDivElement | null) => { this._dropDisposer?.(); if (ele) { this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc); } }; @computed get carouselItems() { this.childLayoutPairs.map(pair => { pair.layout.embedContainer = this.Document; }); return this.childLayoutPairs.filter(pair => pair.layout.type !== DocumentType.LINK); } @computed get marginX() { return NumCast(this.layoutDoc.caption_xMargin, 50); } @action setPracticeMessage = (mes: string | undefined) => { this._practiceMessage = mes; }; @action setFilterMessage = (mes: string | undefined) => { this._filterMessage = mes; }; setModes = () => { this.layoutDoc.filterOp = cardMode.ALL; Doc.setDocFilter(this.Document, 'data_star', undefined, 'match'); this.layoutDoc.practiceMode = practiceMode.NORMAL; this.layoutDoc._carousel_index = 0; }; move = (dir: number) => { const moveToCardWithField = (match: (doc: Doc) => boolean): boolean => { let startInd = (NumCast(this.layoutDoc._carousel_index) + dir) % this.carouselItems.length; while (!match(this.carouselItems?.[startInd].layout) && (startInd + this.carouselItems.length) % this.carouselItems.length !== this.layoutDoc._carousel_index) { startInd = (startInd + dir + this.carouselItems.length) % this.carouselItems.length; } if (match(this.carouselItems?.[startInd].layout)) { this.layoutDoc._carousel_index = startInd; return true; } return match(this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout); }; switch (this.layoutDoc.practiceMode && this.layoutDoc.filterOp) { case practiceMode.PRACTICE && cardMode.ALL: if (!moveToCardWithField((doc: Doc) => doc[this.practiceField] !== practiceVal.CORRECT)) { this._practiceMessage = 'Finished! Unselect practice mode to view all flashcards.'; this.carouselItems.forEach(item => { item.layout[this.practiceField] = undefined}); //prettier-ignore } break; case !practiceMode.PRACTICE && cardMode.STAR: if (!moveToCardWithField((doc: Doc) => !!doc[this.starField])) { this._filterMessage = 'No starred items. Unselect this view to see all flashcards and star them.'; } break; case practiceMode.PRACTICE && cardMode.STAR: if (!moveToCardWithField((doc: Doc) => doc[this.practiceField] !== practiceVal.CORRECT && doc[this.starField] === true)) { this._filterMessage = 'No flashcards to show! Unselect mode to view all flashcards.'; this._practiceMessage = undefined; } break; default: moveToCardWithField(returnTrue); } }; /** * Goes to the next Doc in the stack subject to the currently selected filter option. */ advance = (e: React.MouseEvent) => { e.stopPropagation(); this.move(1); }; /** * Goes to the previous Doc in the stack subject to the currently selected filter option. */ goback = (e: React.MouseEvent) => { e.stopPropagation(); this.move(-1); }; /* * Stars the document when the star button is pressed. */ star = (e: React.MouseEvent) => { e.stopPropagation(); const curDoc = this.carouselItems[NumCast(this.layoutDoc._carousel_index)]; curDoc.layout[this.starField] = curDoc.layout[this.starField] ? undefined : true; // if (!curDoc.layout[this.starField]) this.move(1); // this.layoutDoc._carousel_index = undefined; }; /* * Sets a flashcard to either missed or correct depending on if they got the question right in practice mode. */ setPracticeVal = (e: React.MouseEvent, val: string) => { e.stopPropagation(); const curDoc = this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)]; curDoc.layout[this.practiceField] = val; this.advance(e); }; captionStyleProvider = (doc: Doc | undefined, captionProps: Opt, property: string) => { // first look for properties on the document in the carousel, then fallback to properties on the container const childValue = doc?.['caption_' + property] ? this._props.styleProvider?.(doc, captionProps, property) : undefined; return childValue ?? this._props.styleProvider?.(this.layoutDoc, captionProps, property); }; panelHeight = () => this._props.PanelHeight() - (StrCast(this.layoutDoc._layout_showCaption) ? 50 : 0); onContentDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); onContentClick = () => ScriptCast(this.layoutDoc.onChildClick); captionWidth = () => this._props.PanelWidth() - 2 * this.marginX; setPracticeMode = (mode: practiceMode) => { this.layoutDoc.practiceMode = mode; this.carouselItems?.map(doc => (doc.layout[this.practiceField] = undefined)); switch (mode) { case practiceMode.QUIZ: this.carouselItems?.map(doc => (doc.layout[this.sideField] = undefined)); break; case practiceMode.NORMAL: this.setPracticeMessage(undefined); break; } }; setFilterMode = (mode: cardMode) => { this.layoutDoc.filterOp = mode; switch (mode) { case cardMode.STAR: // Doc.setDocFilter(this.Document, 'data_star', true, 'match'); this.move(1); break; default: this.setFilterMessage(undefined); // prettier-ignore // Doc.setDocFilter(this.Document, 'data_star', true, 'remove'); } }; @computed get content() { trace(); if (this.layoutDoc._carousel_index === this.carouselItems.length && this.layoutDoc._carousel_index !== 0) { this.move(1); } const index = NumCast(this.layoutDoc._carousel_index); const curDoc = this.carouselItems?.[index]; const captionProps = { ...this._props, NativeScaling: returnOne, PanelWidth: this.captionWidth, fieldKey: 'caption', setHeight: undefined, setContentView: undefined }; const carouselShowsCaptions = StrCast(this.layoutDoc._layout_showCaption); return !(curDoc?.layout instanceof Doc) ? null : ( <>
{!carouselShowsCaptions ? null : (
)} ); } containsDifTypes = (): boolean => { return this.carouselItems.filter(doc => !doc.layout._layout_isFlashcard).length !== 0; }; addFlashcard() { const newDoc = Docs.Create.ComparisonDocument('', { _layout_isFlashcard: true, _width: 300, _height: 300 }); this.addDocument?.(newDoc); // DocUtils.copyDragFactory(newDoc); // this._props.addDocument?.(); // newDoc.layout = this.layoutDoc; // newDoc.data = this.dataDoc; // Doc.AddDocToList() // this._props.parent._props.addDocument(); // this.childLayoutPairs.push({ newDoc.layout, newDoc.data}); // this._props.addDocument?.(newDoc); // console.log('HERE'); } @computed get buttons() { if (!this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)]) return null; return ( <>
{!this.containsDifTypes() ? (
{/*
*/}
) : null} {this.layoutDoc.practiceMode === practiceMode.PRACTICE ? (
this.setPracticeVal(e, practiceVal.MISSED)}>
this.setPracticeVal(e, practiceVal.CORRECT)}>
) : null} ); } togglePracticeMode = (mode: practiceMode) => { if (mode === this.layoutDoc.practiceMode) { this.setPracticeMode(practiceMode.NORMAL); // this.setPracticeMessage("undefined"); } else this.setPracticeMode(mode); }; toggleFilterMode = () => { this.layoutDoc.filterOp === cardMode.STAR ? this.setFilterMode(cardMode.ALL) : this.setFilterMode(cardMode.STAR)}; //prettier-ignore setColor = (mode: practiceMode | cardMode, which: string) => { return which === mode ? 'white' : 'light gray'}; //prettier-ignore @computed get menu() { return (
this.togglePracticeMode(practiceMode.QUIZ)}>
this.togglePracticeMode(practiceMode.PRACTICE)}>
this.toggleFilterMode()}>
); } render() { return (
{!this._practiceMessage && !this._filterMessage ? ( this.content ) : (

{this._filterMessage} {'\n'} {this._practiceMessage}

)} {!this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)] && this.layoutDoc.practiceMode === practiceMode.PRACTICE ?

Add flashcards

: null}

Recently missed!

{!this.containsDifTypes() && this.carouselItems.length !== 0 ? this.menu : null} {this.Document._chromeHidden || (!this._filterMessage && !this._practiceMessage) ? this.buttons : null}
); } }