From d335e4694e5d45f6b273410664622ea1891073c8 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 20 May 2024 15:10:54 -0400 Subject: fixing flash card carousel code organization. lint fixes. --- .../views/collections/CollectionCarouselView.tsx | 130 ++++++++------------- src/client/views/collections/CollectionView.tsx | 14 --- .../collectionFreeForm/CollectionFreeFormView.tsx | 81 ++++++------- 3 files changed, 84 insertions(+), 141 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index c3ba04aa8..282ac90fe 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -6,7 +6,7 @@ import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { emptyFunction } from '../../../Utils'; -import { StopEvent, returnFalse, returnOne, returnZero } from '../../../ClientUtils'; +import { StopEvent, returnFalse, returnOne, returnTrue, returnZero } from '../../../ClientUtils'; import { Doc, Opt } from '../../../fields/Doc'; import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { DocumentType } from '../../documents/DocumentTypes'; @@ -17,6 +17,8 @@ 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'; @observer export class CollectionCarouselView extends CollectionSubView() { @@ -42,91 +44,49 @@ export class CollectionCarouselView extends CollectionSubView() { return this.childLayoutPairs.filter(pair => pair.layout.type !== DocumentType.LINK); } + 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 + 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); + }; + 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`])) { + 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')) { + 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; + }); + } + break; + default: moveToCardWithField( returnTrue); + } // prettier-ignore + }; + /** - * Goes to the next flashcard in the stack and filters - * based on the the currently selected option. + * Goes to the next Doc in the stack subject to the currently selected filter option. */ advance = (e: React.MouseEvent) => { e.stopPropagation(); - this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) + 1) % this.carouselItems.length; - let startInd = this.layoutDoc._carousel_index; - - // if the star filter is selected - if (this.layoutDoc.filterOp === 'star') { - // go to a flashcard that is starred, skip the ones that aren't - while (!this.carouselItems?.[NumCast(startInd)].layout[`${this.fieldKey}_star`] && (startInd + 1) % this.carouselItems.length !== this.layoutDoc._carousel_index) { - startInd = (startInd + 1) % this.carouselItems.length; - } - this.layoutDoc._carousel_index = startInd; - // if there aren't any starred, show all cards - if (!this.carouselItems?.[NumCast(startInd)].layout[`${this.fieldKey}_star`]) { - this.layoutDoc.filterOp = 'all'; - } - } - - // if the practice filter is selected - if (this.layoutDoc.filterOp === 'practice') { - // go to a new index that is missed, skip the ones that are correct - while (this.carouselItems?.[NumCast(startInd)].layout[`${this.fieldKey}_missed`] === 'correct' && (startInd + 1) % this.carouselItems.length !== this.layoutDoc._carousel_index) { - startInd = (startInd + 1) % this.carouselItems.length; - } - this.layoutDoc._carousel_index = startInd; - - // if the user has gone through all of the cards and gotten them all correct, show all cards and exit practice mode - if (this.carouselItems?.[NumCast(startInd)].layout[`${this.fieldKey}_missed`] === 'correct') { - this.layoutDoc.filterOp = 'all'; - - // set all the cards to missed - for (let i = 0; i < this.carouselItems.length; i++) { - const curDoc = this.carouselItems?.[NumCast(i)]; - curDoc.layout[`${this.fieldKey}_missed`] = undefined; - } - } - } + this.move(1); }; /** - * Goes to the previous flashcard in the stack and filters - * based on the the currently selected option. + * Goes to the previous Doc in the stack subject to the currently selected filter option. */ goback = (e: React.MouseEvent) => { e.stopPropagation(); - this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) - 1 + this.carouselItems.length) % this.carouselItems.length; - - let startInd = this.layoutDoc._carousel_index; - - // if the star filter is selected - if (this.layoutDoc.filterOp === 'star') { - // go to a new index that is starred, skip the ones that aren't - while (!this.carouselItems?.[NumCast(startInd)].layout[`${this.fieldKey}_star`] && (startInd - 1 + this.carouselItems.length) % this.carouselItems.length !== this.layoutDoc._carousel_index) { - startInd = (startInd - 1 + this.carouselItems.length) % this.carouselItems.length; - } - this.layoutDoc._carousel_index = startInd; - // if there aren't any starred, show all cards - if (!this.carouselItems?.[NumCast(startInd)].layout[`${this.fieldKey}_star`]) { - this.layoutDoc.filterOp = 'all'; - } - } - - // if the practice filter is selected - if (this.layoutDoc.filterOp === 'practice') { - // go to a new index that is missed, skip the ones that are correct - while (this.carouselItems?.[NumCast(startInd)].layout[`${this.fieldKey}_missed`] === 'correct' && (startInd - 1 + this.carouselItems.length) % this.carouselItems.length !== this.layoutDoc._carousel_index) { - startInd = (startInd - 1 + this.carouselItems.length) % this.carouselItems.length; - } - - this.layoutDoc._carousel_index = startInd; - - // See all flashcards when finish going through practice mode and set all of the flashcards back to - if (this.carouselItems?.[NumCast(startInd)].layout[`${this.fieldKey}_missed`] === 'correct') { - this.layoutDoc.filterOp = 'all'; - - for (let i = 0; i < this.carouselItems.length; i++) { - const curDoc = this.carouselItems?.[NumCast(i)]; - curDoc.layout[`${this.fieldKey}_missed`] = undefined; - } - } - } + this.move(-1); }; /* @@ -134,10 +94,8 @@ export class CollectionCarouselView extends CollectionSubView() { */ star = (e: React.MouseEvent) => { e.stopPropagation(); - const curDoc = this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)]; - if (!curDoc) return; - if (curDoc.layout[`${this.fieldKey}_star`] === undefined) curDoc.layout[`${this.fieldKey}_star`] = true; - else curDoc.layout[`${this.fieldKey}_star`] = !curDoc.layout[`${this.fieldKey}_star`]; + const curDoc = this.carouselItems[NumCast(this.layoutDoc._carousel_index)]; + curDoc.layout[`${this.fieldKey}_star`] = curDoc.layout[`${this.fieldKey}_star`] ? undefined : true; }; /* @@ -228,12 +186,24 @@ export class CollectionCarouselView extends CollectionSubView() { ); } + 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 (
(this.layoutDoc[`filterOp`] = 'all'), icon: 'layer-group' }); - revealItems.push({ description: 'Star', event: () => (this.layoutDoc[`filterOp`] = 'star'), icon: 'star' }); - revealItems.push({ description: 'Practice Mode', event: () => (this.layoutDoc[`filterOp`] = 'practice'), icon: 'check' }); - revealItems.push({ description: 'Quiz Cards', event: () => (this.layoutDoc[`filterOp`] = 'quiz'), icon: 'pencil' }); - - // only show the filter options if it is a collection of type Carousel view - if (this.Document?._type_collection === CollectionViewType.Carousel) { - !revealOptions && cm.addItem({ description: 'Filter Flashcards', addDivider: false, noexpand: true, subitems: revealItems, icon: 'layer-group' }); - } - const options = cm.findByDescription('Options...'); const optionItems = options && 'subitems' in options ? options.subitems : []; !Doc.noviceMode ? optionItems.splice(0, 0, { description: `${this.Document.forceActive ? 'Select' : 'Force'} Contents Active`, event: () => {this.Document.forceActive = !this.Document.forceActive}, icon: 'project-diagram' }) : null; // prettier-ignore diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 110f7816c..be96b914c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -517,6 +517,7 @@ export class CollectionFreeFormView extends CollectionSubView { let isInside = false; if (!isNaN(eraserOutline[0].X) && !isNaN(eraserOutline[0].Y)) { - let minX = eraserOutline[0].X, - maxX = eraserOutline[0].X; - let minY = eraserOutline[0].Y, - maxY = eraserOutline[0].Y; + let [minX, minY] = [eraserOutline[0].X, eraserOutline[0].Y]; + let [maxX, maxY] = [eraserOutline[0].X, eraserOutline[0].Y]; for (let i = 1; i < eraserOutline.length; i++) { const currPoint: { X: number; Y: number } = eraserOutline[i]; minX = Math.min(currPoint.X, minX); @@ -784,7 +783,7 @@ export class CollectionFreeFormView extends CollectionSubView point.Y != eraserOutline[j].Y > point.Y && point.X < ((eraserOutline[j].X - eraserOutline[i].X) * (point.Y - eraserOutline[i].Y)) / (eraserOutline[j].Y - eraserOutline[i].Y) + eraserOutline[i].X) { + if (eraserOutline[i].Y > point.Y !== eraserOutline[j].Y > point.Y && point.X < ((eraserOutline[j].X - eraserOutline[i].X) * (point.Y - eraserOutline[i].Y)) / (eraserOutline[j].Y - eraserOutline[i].Y) + eraserOutline[i].X) { isInside = !isInside; } } @@ -845,7 +844,7 @@ export class CollectionFreeFormView extends CollectionSubView { // set distance of the eraser's bounding box based on the zoom let boundingBoxDist = ActiveEraserWidth() + 5; - this.zoomScaling() < 1 ? (boundingBoxDist = boundingBoxDist / (this.zoomScaling() * 1.5)) : (boundingBoxDist *= this.zoomScaling()); + this.zoomScaling() < 1 ? (boundingBoxDist /= this.zoomScaling() * 1.5) : (boundingBoxDist *= this.zoomScaling()); const eraserMin = { X: Math.min(lastPoint.X, currPoint.X) - boundingBoxDist, Y: Math.min(lastPoint.Y, currPoint.Y) - boundingBoxDist }; const eraserMax = { X: Math.max(lastPoint.X, currPoint.X) + boundingBoxDist, Y: Math.max(lastPoint.Y, currPoint.Y) + boundingBoxDist }; @@ -961,29 +960,25 @@ export class CollectionFreeFormView extends CollectionSubView 0) { - segments.push(currSegment); // ...so we add it to the list and reset currSegment - if (firstSegment.length === 0) { - firstSegment = currSegment; - } - currSegment = []; + // we've reached the end of the part to take out... + continueErasing = false; + if (currSegment.length > 0) { + segments.push(currSegment); // ...so we add it to the list and reset currSegment + if (firstSegment.length === 0) { + firstSegment = currSegment; } - currSegment.push(inkBezier.split(segmentTs[j] - currCurveT, 1)); + currSegment = []; } + currSegment.push(inkBezier.split(segmentTs[j] - currCurveT, 1)); } } - } else { - if (!continueErasing) { - // push the bezier piece if not in the eraser circle - currSegment.push(inkBezier); - } + } else if (!continueErasing) { + // push the bezier piece if not in the eraser circle + currSegment.push(inkBezier); } } @@ -1078,13 +1073,11 @@ export class CollectionFreeFormView extends CollectionSubView= startIndex && tVals[mid - 1] < excludeT) { + return [mid - 1, mid]; } else { - if (mid - 1 >= startIndex && tVals[mid - 1] < excludeT) { - return [mid - 1, mid]; - } else { - return this.getClosestTs(tVals, excludeT, startIndex, mid - 1); - } + return this.getClosestTs(tVals, excludeT, startIndex, mid - 1); } } }; -- cgit v1.2.3-70-g09d2