aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionCarouselView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/CollectionCarouselView.tsx')
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx137
1 files changed, 135 insertions, 2 deletions
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 45b64d3e6..b736c7ced 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -42,14 +42,114 @@ export class CollectionCarouselView extends CollectionSubView() {
return this.childLayoutPairs.filter(pair => pair.layout.type !== DocumentType.LINK);
}
+ /**
+ * Goes to the next flashcard in the stack and filters
+ * based on the the currently selected option.
+ */
advance = (e: React.MouseEvent) => {
e.stopPropagation();
- this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) + 1) % this.carouselItems.length;
+ this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) + 1) % this.childLayoutPairs.length;
+ var 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.childLayoutPairs?.[NumCast(startInd)].layout[`${this.fieldKey}_star`] && (startInd + 1) % this.childLayoutPairs.length != this.layoutDoc._carousel_index) {
+ startInd = (startInd + 1) % this.childLayoutPairs.length;
+ }
+ this.layoutDoc._carousel_index = startInd;
+ // if there aren't any starred, show all cards
+ if (!this.childLayoutPairs?.[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.childLayoutPairs?.[NumCast(startInd)].layout[`${this.fieldKey}_missed`] == 'correct' && (startInd + 1) % this.childLayoutPairs.length != this.layoutDoc._carousel_index) {
+ startInd = (startInd + 1) % this.childLayoutPairs.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.childLayoutPairs?.[NumCast(startInd)].layout[`${this.fieldKey}_missed`] == 'correct') {
+ this.layoutDoc[`filterOp`] = 'all';
+
+ // set all the cards to missed
+ for (var i = 0; i < this.childLayoutPairs.length; i++) {
+ const curDoc = this.childLayoutPairs?.[NumCast(i)];
+ curDoc.layout[`${this.fieldKey}_missed`] = undefined;
+ }
+ }
+ }
};
+
+ /**
+ * Goes to the previous flashcard in the stack and filters
+ * based on the the currently selected option.
+ */
goback = (e: React.MouseEvent) => {
e.stopPropagation();
- this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) - 1 + this.carouselItems.length) % this.carouselItems.length;
+ this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.length;
+
+ var 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.childLayoutPairs?.[NumCast(startInd)].layout[`${this.fieldKey}_star`] && (startInd - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.length != this.layoutDoc._carousel_index) {
+ startInd = (startInd - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.length;
+ }
+ this.layoutDoc._carousel_index = startInd;
+ // if there aren't any starred, show all cards
+ if (!this.childLayoutPairs?.[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.childLayoutPairs?.[NumCast(startInd)].layout[`${this.fieldKey}_missed`] == 'correct' && (startInd - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.length != this.layoutDoc._carousel_index) {
+ startInd = (startInd - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.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.childLayoutPairs?.[NumCast(startInd)].layout[`${this.fieldKey}_missed`] == 'correct') {
+ this.layoutDoc[`filterOp`] = 'all';
+
+ for (var i = 0; i < this.childLayoutPairs.length; i++) {
+ const curDoc = this.childLayoutPairs?.[NumCast(i)];
+ curDoc.layout[`${this.fieldKey}_missed`] = undefined;
+ }
+ }
+ }
+ };
+
+ /*
+ * Stars the document when the star button is pressed.
+ */
+ star = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ const curDoc = this.childLayoutPairs?.[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`];
+ };
+
+ /*
+ * 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) => {
+ e.stopPropagation();
+ const curDoc = this.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)];
+ curDoc.layout[`${this.fieldKey}_missed`] = val;
+ this.advance(e);
};
+
captionStyleProvider = (doc: Doc | undefined, captionProps: Opt<FieldViewProps>, property: string): any => {
// 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;
@@ -107,6 +207,7 @@ export class CollectionCarouselView extends CollectionSubView() {
);
}
@computed get buttons() {
+ if (!this.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)]) return;
return (
<>
<div key="back" className="carouselView-back" onClick={this.goback}>
@@ -115,6 +216,15 @@ export class CollectionCarouselView extends CollectionSubView() {
<div key="fwd" className="carouselView-fwd" onClick={this.advance}>
<FontAwesomeIcon icon="chevron-right" size="2x" />
</div>
+ <div key="star" className="carouselView-star" onClick={this.star}>
+ <FontAwesomeIcon icon={'star'} color={this.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)].layout[`${this.fieldKey}_star`] ? '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' }}>
+ <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' }}>
+ <FontAwesomeIcon icon={'check'} color={'green'} size={'1x'} />
+ </div>
</>
);
}
@@ -129,6 +239,29 @@ export class CollectionCarouselView extends CollectionSubView() {
color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color),
}}>
{this.content}
+ {/* 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.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)] && this.layoutDoc[`filterOp`] == 'practice' ? 'flex' : 'none',
+ justifyContent: 'center',
+ alignItems: 'center',
+ height: '100%',
+ zIndex: '-1',
+ }}>
+ Add flashcards!
+ </p>
+ {/* Displays a message to the user that a flashcard was recently missed if they had previously gotten it wrong. */}
+ <p
+ style={{
+ color: 'red',
+ zIndex: '999',
+ position: 'relative',
+ left: '10px',
+ top: '10px',
+ display: this.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)] ? (this.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)].layout[`${this.fieldKey}_missed`] == 'missed' ? 'block' : 'none') : 'none',
+ }}>
+ Recently missed!
+ </p>
{this.Document._chromeHidden ? null : this.buttons}
</div>
);