From 2d9c797baf96efb54220b668c1a76fa4106030b9 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 20 May 2024 15:39:11 -0400
Subject: upated carousel modes

---
 .../views/collections/CollectionCarouselView.tsx   | 83 +++++++++++++---------
 1 file changed, 48 insertions(+), 35 deletions(-)

(limited to 'src/client/views/collections/CollectionCarouselView.tsx')

diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 282ac90fe..2adad68e0 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -5,24 +5,35 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { computed, makeObservable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { emptyFunction } from '../../../Utils';
 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 { DragManager } from '../../util/DragManager';
+import { ContextMenu } from '../ContextMenu';
+import { ContextMenuProps } from '../ContextMenuItem';
 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 } from './CollectionSubView';
-import { ContextMenu } from '../ContextMenu';
-import { ContextMenuProps } from '../ContextMenuItem';
 
+enum cardMode {
+    PRACTICE = 'practice',
+    STAR = 'star',
+    QUIZ = 'quiz',
+}
+enum practiceVal {
+    MISSED = 'missed',
+    CORRECT = 'correct',
+}
 @observer
 export class CollectionCarouselView extends CollectionSubView() {
     private _dropDisposer?: DragManager.DragDropDisposer;
+    get practiceField() { return this.fieldKey + "_practice"; } // prettier-ignore
+    get starField()     { return this.fieldKey + "_star"; } // prettier-ignore
 
     constructor(props: any) {
         super(props);
@@ -43,6 +54,9 @@ export class CollectionCarouselView extends CollectionSubView() {
     @computed get carouselItems() {
         return this.childLayoutPairs.filter(pair => pair.layout.type !== DocumentType.LINK);
     }
+    @computed get marginX() {
+        return NumCast(this.layoutDoc.caption_xMargin, 50);
+    }
 
     move = (dir: number) => {
         const moveToCardWithField = (match: (doc: Doc) => boolean): boolean => {
@@ -50,26 +64,28 @@ export class CollectionCarouselView extends CollectionSubView() {
             while (!match(this.carouselItems?.[startInd].layout) && (startInd + dir + this.carouselItems.length) % this.carouselItems.length !== this.layoutDoc._carousel_index) {
                 startInd = (startInd + dir + this.carouselItems.length) % this.carouselItems.length;
             }
-            this.layoutDoc._carousel_index = startInd;
-            return match(this.carouselItems?.[startInd].layout);
+            if (match(this.carouselItems?.[startInd].layout)) {
+                this.layoutDoc._carousel_index = startInd;
+                return true;
+            }
+            return match(this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout);
         };
         switch (StrCast(this.layoutDoc.filterOp)) {
-            case 'star':  // go to a flashcard that is starred, skip the ones that aren't
-                if (!moveToCardWithField((doc: Doc) => !!doc[`${this.fieldKey}_star`])) {
+            case cardMode.STAR:  // go to a flashcard that is starred, skip the ones that aren't
+                if (!moveToCardWithField((doc: Doc) => !!doc[this.starField])) {
                     this.layoutDoc.filterOp = undefined;  // if there aren't any starred, show all cards
                 }
                 break;
-            case 'practice': // go to a new index that is missed, skip the ones that are correct
-                if (!moveToCardWithField((doc: Doc) => doc[`${this.fieldKey}_missed`] !== 'correct')) {
+            case cardMode.PRACTICE: // go to a new index that is missed, skip the ones that are correct
+                if (!moveToCardWithField((doc: Doc) => doc[this.practiceField] !== practiceVal.CORRECT)) {
                     this.layoutDoc.filterOp = undefined;  // if all of the cards are correct, show all cards and exit practice mode
 
-                    // set all the cards to missed
-                    this.carouselItems.forEach(item => {
-                        item.layout[`${this.fieldKey}_missed`] = undefined;
+                    this.carouselItems.forEach(item => { // reset all the practice values
+                        item.layout[this.practiceField] = undefined;
                     });
                 }
                 break;
-            default: moveToCardWithField( returnTrue);
+            default: moveToCardWithField(returnTrue);
         } // prettier-ignore
     };
 
@@ -95,16 +111,16 @@ export class CollectionCarouselView extends CollectionSubView() {
     star = (e: React.MouseEvent) => {
         e.stopPropagation();
         const curDoc = this.carouselItems[NumCast(this.layoutDoc._carousel_index)];
-        curDoc.layout[`${this.fieldKey}_star`] = curDoc.layout[`${this.fieldKey}_star`] ? undefined : true;
+        curDoc.layout[this.starField] = curDoc.layout[this.starField] ? undefined : true;
     };
 
     /*
      * Sets a flashcard to either missed or correct depending on if they got the question right in practice mode.
      */
-    missed = (e: React.MouseEvent, val: string) => {
+    setPracticeVal = (e: React.MouseEvent, val: string) => {
         e.stopPropagation();
         const curDoc = this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)];
-        curDoc.layout[`${this.fieldKey}_missed`] = val;
+        curDoc.layout[this.practiceField] = val;
         this.advance(e);
     };
 
@@ -116,10 +132,18 @@ export class CollectionCarouselView extends CollectionSubView() {
     panelHeight = () => this._props.PanelHeight() - (StrCast(this.layoutDoc._layout_showCaption) ? 50 : 0);
     onContentDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick);
     onContentClick = () => ScriptCast(this.layoutDoc.onChildClick);
-    @computed get marginX() {
-        return NumCast(this.layoutDoc.caption_xMargin, 50);
-    }
     captionWidth = () => this._props.PanelWidth() - 2 * this.marginX;
+    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.layoutDoc.filterOp = undefined;},         icon: 'layer-group',}); // prettier-ignore
+        revealItems.push({description: 'Star',          event: () => {this.layoutDoc.filterOp = cardMode.STAR;},     icon: 'star',}); // prettier-ignore
+        revealItems.push({description: 'Practice Mode', event: () => {this.layoutDoc.filterOp = cardMode.PRACTICE;}, icon: 'check',}); // prettier-ignore
+        revealItems.push({description: 'Quiz Cards',    event: () => {this.layoutDoc.filterOp = cardMode.QUIZ;},     icon: 'pencil',}); // prettier-ignore
+        !revealOptions && cm.addItem({ description: 'Filter Flashcards', addDivider: false, noexpand: true, subitems: revealItems, icon: 'layer-group' });
+    };
     @computed get content() {
         const index = NumCast(this.layoutDoc._carousel_index);
         const curDoc = this.carouselItems?.[index];
@@ -175,28 +199,17 @@ export class CollectionCarouselView extends CollectionSubView() {
                     <FontAwesomeIcon icon="chevron-right" size="2x" />
                 </div>
                 <div key="star" className="carouselView-star" onClick={this.star}>
-                    <FontAwesomeIcon icon="star" color={this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout[`${this.fieldKey}_star`] ? 'yellow' : 'gray'} size="1x" />
+                    <FontAwesomeIcon icon="star" color={this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout[this.starField] ? 'yellow' : 'gray'} size="1x" />
                 </div>
-                <div key="remove" className="carouselView-remove" onClick={e => this.missed(e, 'missed')} style={{ visibility: this.layoutDoc.filterOp === 'practice' ? 'visible' : 'hidden' }}>
+                <div key="remove" className="carouselView-remove" onClick={e => this.setPracticeVal(e, practiceVal.MISSED)} style={{ visibility: this.layoutDoc.filterOp === cardMode.PRACTICE ? 'visible' : 'hidden' }}>
                     <FontAwesomeIcon icon="xmark" color="red" size="1x" />
                 </div>
-                <div key="check" className="carouselView-check" onClick={e => this.missed(e, 'correct')} style={{ visibility: this.layoutDoc.filterOp === 'practice' ? 'visible' : 'hidden' }}>
+                <div key="check" className="carouselView-check" onClick={e => this.setPracticeVal(e, practiceVal.CORRECT)} style={{ visibility: this.layoutDoc.filterOp === cardMode.PRACTICE ? 'visible' : 'hidden' }}>
                     <FontAwesomeIcon icon="check" color="green" size="1x" />
                 </div>
             </>
         );
     }
-    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.layoutDoc.filterOp = undefined;},  icon: 'layer-group',}); // prettier-ignore
-        revealItems.push({description: 'Star',          event: () => {this.layoutDoc.filterOp = 'star';},     icon: 'star',}); // prettier-ignore
-        revealItems.push({description: 'Practice Mode', event: () => {this.layoutDoc.filterOp = 'practice';}, icon: 'check',}); // prettier-ignore
-        revealItems.push({description: 'Quiz Cards',    event: () => {this.layoutDoc.filterOp = 'quiz';},     icon: 'pencil',}); // prettier-ignore
-        !revealOptions && cm.addItem({ description: 'Filter Flashcards', addDivider: false, noexpand: true, subitems: revealItems, icon: 'layer-group' });
-    };
 
     render() {
         return (
@@ -212,7 +225,7 @@ export class CollectionCarouselView extends CollectionSubView() {
                 {/* Displays a message to the user to add more flashcards if they are in practice mode and no flashcards are there. */}
                 <p
                     style={{
-                        display: !this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)] && this.layoutDoc.filterOp === 'practice' ? 'flex' : 'none',
+                        display: !this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)] && this.layoutDoc.filterOp === cardMode.PRACTICE ? 'flex' : 'none',
                         justifyContent: 'center',
                         alignItems: 'center',
                         height: '100%',
@@ -228,7 +241,7 @@ export class CollectionCarouselView extends CollectionSubView() {
                         position: 'relative',
                         left: '10px',
                         top: '10px',
-                        display: this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)] ? (this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout[`${this.fieldKey}_missed`] === 'missed' ? 'block' : 'none') : 'none',
+                        display: this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)] ? (this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout[this.practiceField] === practiceVal.MISSED ? 'block' : 'none') : 'none',
                     }}>
                     Recently missed!
                 </p>
-- 
cgit v1.2.3-70-g09d2

