aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionCarouselView.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-09-17 18:31:09 -0400
committerbobzel <zzzman@gmail.com>2024-09-17 18:31:09 -0400
commit0653464370398188b23bb490c16b5a2ccf0300c3 (patch)
tree3dff6b5a05b6e4f5d3ad489b3e34ece487b836ac /src/client/views/collections/CollectionCarouselView.tsx
parent35d19c29c2f628792a379534df6d5760e49cfb8f (diff)
parent4f2ee4a8642a93fb399b979750078374b317af32 (diff)
merged with master + cleanup of carousel code
Diffstat (limited to 'src/client/views/collections/CollectionCarouselView.tsx')
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx359
1 files changed, 164 insertions, 195 deletions
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index a1c59d238..d9a99f47f 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -1,11 +1,10 @@
/* 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 { IReactionDisposer, action, computed, makeObservable, observable, reaction } 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 { StopEvent, returnOne, returnZero } from '../../../ClientUtils';
import { Doc, Opt } from '../../../fields/Doc';
import { BoolCast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { DocumentType } from '../../documents/DocumentTypes';
@@ -19,15 +18,12 @@ 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',
@@ -36,24 +32,20 @@ enum practiceVal {
@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 sideField() { return "_" + this.fieldKey + "_usePath"; } // prettier-ignore
get starField() { return "star"; } // prettier-ignore
+ _fadeTimer: NodeJS.Timeout | undefined;
+
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);
}
+ @observable _last_index = this.carouselIndex;
+ @observable _last_opacity = 1;
+
componentWillUnmount() {
this._dropDisposer?.();
}
@@ -65,65 +57,42 @@ export class CollectionCarouselView extends CollectionSubView() {
}
};
- @computed get carouselItems() {
- this.childLayoutPairs.map(pair => {
- pair.layout.embedContainer = this.Document;
- });
- return this.childLayoutPairs.filter(pair => pair.layout.type !== DocumentType.LINK);
+ @computed get practiceMode() {
+ return this.childDocs.some(doc => doc._layout_isFlashcard) ? StrCast(this.layoutDoc.practiceMode) : '';
}
- @computed get marginX() {
- return NumCast(this.layoutDoc.caption_xMargin, 50);
+ @computed get practiceMessage() {
+ const cardCount = this.carouselItems.length;
+ if (this.practiceMode) {
+ if (!Doc.hasDocFilter(this.layoutDoc, 'star') && !cardCount) {
+ return 'Finished! Click here to view all flashcards.';
+ }
+ }
+ return '';
}
- @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;
+ @computed get filterMessage() {
+ const cardCount = this.carouselItems.length;
+ if (!this.practiceMessage) {
+ if (Doc.hasDocFilter(this.layoutDoc, 'star') && !cardCount) {
+ return 'No starred items. Click here to view all flash cards.';
}
- if (match(this.carouselItems?.[startInd].layout)) {
- this.layoutDoc._carousel_index = startInd;
- return true;
+ if (this.practiceMode) {
+ if (!cardCount) return 'No flashcards to show! Click here to leave practice mode';
}
- 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);
}
- };
+ return '';
+ }
+ @computed get marginX() { return NumCast(this.layoutDoc.caption_xMargin, 50); } // prettier-ignore
+ @computed get carouselIndex() { return NumCast(this.layoutDoc._carousel_index) % this.carouselItems.length; } // prettier-ignore
+ @computed get carouselItems() { return this.childDocs
+ .filter(doc => doc.type !== DocumentType.LINK)
+ .filter(doc => !this.practiceMode || (BoolCast(doc?._layout_isFlashcard) && doc[this.practiceField] !== practiceVal.CORRECT))// show only cards that aren't marked as correct
+ } // prettier-ignore
+
+ move = action((dir: number) => {
+ this._last_index = this.carouselIndex;
+ this.layoutDoc._carousel_index = this.carouselItems.length ? (this.carouselIndex + dir + this.carouselItems.length) % this.carouselItems.length : 0;
+ });
/**
* Goes to the next Doc in the stack subject to the currently selected filter option.
@@ -146,10 +115,8 @@ export class CollectionCarouselView extends CollectionSubView() {
*/
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;
+ const curDoc = this.carouselItems[this.carouselIndex];
+ curDoc && (curDoc[this.starField] = curDoc[this.starField] ? undefined : true);
};
/*
@@ -157,8 +124,8 @@ export class CollectionCarouselView extends CollectionSubView() {
*/
setPracticeVal = (e: React.MouseEvent, val: string) => {
e.stopPropagation();
- const curDoc = this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)];
- curDoc.layout[this.practiceField] = val;
+ const curDoc = this.carouselItems[this.carouselIndex];
+ curDoc && (curDoc[this.practiceField] = val);
this.advance(e);
};
@@ -172,71 +139,92 @@ export class CollectionCarouselView extends CollectionSubView() {
onContentClick = () => ScriptCast(this.layoutDoc.onChildClick);
captionWidth = () => this._props.PanelWidth() - 2 * this.marginX;
- setPracticeMode = (mode: practiceMode) => {
+ setPracticeMode = (mode: practiceMode | undefined) => {
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;
- }
+ this.carouselItems?.map(doc => (doc[this.practiceField] = undefined));
+ if (mode === practiceMode.QUIZ) this.carouselItems?.map(doc => (doc[this.sideField] = undefined));
};
- 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');
- }
- };
contentScreentToLocalXf = () => this._props.ScreenToLocalTransform().translate(-NumCast(this.layoutDoc.xMargin), -NumCast(this.layoutDoc.yMargin));
contentPanelWidth = () => this._props.PanelWidth() - 2 * NumCast(this.layoutDoc.xMargin);
+
+ isChildContentActive = () =>
+ this._props.isContentActive?.() === false
+ ? false
+ : this._props.isDocumentActive?.() && (this._props.childDocumentsActive?.() || BoolCast(this.Document.childDocumentsActive))
+ ? true
+ : this._props.childDocumentsActive?.() === false || this.Document.childDocumentsActive === false
+ ? false
+ : undefined;
+
+ renderDoc = (doc: Doc, showCaptions: boolean, overlayFunc?: (r: DocumentView | null) => void) => {
+ return (
+ <DocumentView
+ {...this._props}
+ ref={overlayFunc}
+ Document={doc}
+ NativeWidth={returnZero}
+ NativeHeight={returnZero}
+ fitWidth={undefined}
+ containerViewPath={this.childContainerViewPath}
+ setContentViewBox={undefined}
+ onDoubleClickScript={this.onContentDoubleClick}
+ onClickScript={this.onContentClick}
+ isDocumentActive={this._props.childDocumentsActive?.() ? this._props.isDocumentActive : this._props.isContentActive}
+ isContentActive={this.isChildContentActive}
+ hideCaptions={showCaptions}
+ renderDepth={this._props.renderDepth + 1}
+ LayoutTemplate={this._props.childLayoutTemplate}
+ LayoutTemplateString={this._props.childLayoutString}
+ TemplateDataDocument={DocCast(Doc.Layout(doc).resolvedDataDoc)}
+ childFilters={this.childDocFilters}
+ hideDecorations={BoolCast(this.layoutDoc.layout_hideDecorations)}
+ addDocument={this._props.addDocument}
+ ScreenToLocalTransform={this.contentScreentToLocalXf}
+ PanelWidth={this.contentPanelWidth}
+ PanelHeight={this.contentPanelHeight}
+ />
+ );
+ };
+ /**
+ * Display an overlay of the previous card that crossfades to the next card
+ */
+ @computed get overlay() {
+ const fadeTime = 500;
+ const lastDoc = this.carouselItems?.[this._last_index];
+ return !lastDoc || this.carouselIndex === this._last_index ? null : (
+ <div className="collectionCarouselView-image" style={{ opacity: this._last_opacity, position: 'absolute', top: 0, left: 0, transition: `opacity ${fadeTime}ms` }}>
+ {this.renderDoc(
+ lastDoc,
+ false, // hide captions if the carousel is configured to show the captions
+ action((r: DocumentView | null) => {
+ if (r) {
+ this._fadeTimer && clearTimeout(this._fadeTimer);
+ this._last_opacity = 0;
+ this._fadeTimer = setTimeout(
+ action(() => {
+ this._last_index = -1;
+ this._last_opacity = 1;
+ }),
+ fadeTime
+ );
+ }
+ })
+ )}
+ </div>
+ );
+ }
@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 index = this.carouselIndex;
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 : (
+ return !curDoc ? null : (
<>
- <div className="collectionCarouselView-image" style={{ padding: `${NumCast(this.layoutDoc.yMargin)}px ${NumCast(this.layoutDoc.xMargin)}px ${NumCast(this.layoutDoc.yMargin)}px ${NumCast(this.layoutDoc.xMargin)}px` }}>
- <DocumentView
- {...this._props}
- NativeWidth={returnZero}
- NativeHeight={returnZero}
- fitWidth={undefined}
- setContentViewBox={undefined}
- childFilters={this.childDocFilters}
- containerViewPath={this._props.docViewPath}
- onDoubleClickScript={this.onContentDoubleClick}
- onClickScript={this.onContentClick}
- hideDecorations={BoolCast(this.layoutDoc.layout_hideDecorations)}
- isDocumentActive={this._props.childDocumentsActive?.() ? this._props.isDocumentActive : this._props.isContentActive}
- isContentActive={(this._props.childContentsActive ?? this._props.isContentActive() === false) ? returnFalse : emptyFunction}
- addDocument={this._props.addDocument}
- hideCaptions={!!carouselShowsCaptions} // hide captions if the carousel is configured to show the captions
- renderDepth={this._props.renderDepth + 1}
- LayoutTemplate={this._props.childLayoutTemplate}
- LayoutTemplateString={this._props.childLayoutString}
- Document={curDoc.layout}
- TemplateDataDocument={DocCast(curDoc.layout.resolvedDataDoc)}
- ScreenToLocalTransform={this.contentScreentToLocalXf}
- PanelWidth={this.contentPanelWidth}
- PanelHeight={this.contentPanelHeight}
- />
+ <div className="collectionCarouselView-image" key="image">
+ {this.renderDoc(curDoc, !!carouselShowsCaptions)}
+ {this.overlay}
</div>
{!carouselShowsCaptions ? null : (
<div
@@ -249,17 +237,13 @@ export class CollectionCarouselView extends CollectionSubView() {
marginLeft: this.marginX,
width: `calc(100% - ${this.marginX * 2}px)`,
}}>
- <FormattedTextBox key={index} {...captionProps} fieldKey={carouselShowsCaptions} styleProvider={this.captionStyleProvider} Document={curDoc.layout} TemplateDataDocument={undefined} />
+ <FormattedTextBox key={index} xPadding={10} yPadding={10} {...captionProps} fieldKey={carouselShowsCaptions} styleProvider={this.captionStyleProvider} Document={curDoc} TemplateDataDocument={undefined} />
</div>
)}
</>
);
}
- 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);
@@ -275,30 +259,28 @@ export class CollectionCarouselView extends CollectionSubView() {
}
@computed get buttons() {
- if (!this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)]) return null;
+ if (!this.carouselItems?.[this.carouselIndex]) return null;
return (
<>
+ <div>
+ <Tooltip title="star">
+ <div key="star" className="carouselView-star" onClick={this.star}>
+ <FontAwesomeIcon icon="star" color={this.carouselItems[this.carouselIndex]?.[this.starField] ? 'yellow' : 'gray'} size="1x" />
+ </div>
+ </Tooltip>
+ {/* <Tooltip title="add new flashcard to pile">
+ <div key="add" className="carouselView-add" onClick={this.addFlashcard}>
+ <FontAwesomeIcon icon="plus" color={this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout[this.starField] ? 'yellow' : 'gray'} size="1x" />
+ </div>
+ </Tooltip> */}
+ </div>
<div key="back" className="carouselView-back" onClick={this.goback}>
<FontAwesomeIcon icon="chevron-left" size="2x" />
</div>
<div key="fwd" className="carouselView-fwd" onClick={this.advance}>
<FontAwesomeIcon icon="chevron-right" size="2x" />
</div>
- {!this.containsDifTypes() ? (
- <div>
- <Tooltip title="star">
- <div key="star" className="carouselView-star" onClick={this.star}>
- <FontAwesomeIcon icon="star" color={this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout[this.starField] ? 'yellow' : 'gray'} size="1x" />
- </div>
- </Tooltip>
- {/* <Tooltip title="add new flashcard to pile">
- <div key="add" className="carouselView-add" onClick={this.addFlashcard}>
- <FontAwesomeIcon icon="plus" color={this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout[this.starField] ? 'yellow' : 'gray'} size="1x" />
- </div>
- </Tooltip> */}
- </div>
- ) : null}
- {this.layoutDoc.practiceMode === practiceMode.PRACTICE ? (
+ {this.practiceMode ? (
<div>
<Tooltip title="Incorrect. View again later.">
<div key="remove" className="carouselView-remove" onClick={e => this.setPracticeVal(e, practiceVal.MISSED)}>
@@ -316,33 +298,31 @@ export class CollectionCarouselView extends CollectionSubView() {
);
}
- 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
+ togglePracticeMode = (mode: practiceMode) => this.setPracticeMode(mode === this.layoutDoc.practiceMode ? undefined : mode);
+ toggleFilterMode = () => Doc.setDocFilter(this.Document, 'star', true, 'match', true);
setColor = (mode: practiceMode | cardMode, which: string) => { return which === mode ? 'white' : 'light gray'}; //prettier-ignore
@computed get menu() {
+ const curDoc = this.carouselItems?.[this.carouselIndex];
return (
<div className="carouselView-menu">
- <Tooltip title="Practice flashcards using GPT">
- <div key="back" className="carouselView-quiz" onClick={e => this.togglePracticeMode(practiceMode.QUIZ)}>
- <FontAwesomeIcon icon="file-pen" color={this.setColor(practiceMode.QUIZ, StrCast(this.layoutDoc.practiceMode))} size="1x" />
- </div>
- </Tooltip>
- <Tooltip title={this.layoutDoc.practiceMode === practiceMode.PRACTICE ? 'Exit practice mode' : 'Practice flashcards manually'}>
- <div key="back" className="carouselView-practice" onClick={e => this.togglePracticeMode(practiceMode.PRACTICE)}>
- <FontAwesomeIcon icon="check" color={this.setColor(practiceMode.PRACTICE, StrCast(this.layoutDoc.practiceMode))} size="1x" />
- </div>
- </Tooltip>
- <Tooltip title={this.layoutDoc.filterOp === cardMode.STAR ? 'Show all cards' : 'Show only starred cards'}>
+ <Tooltip title={Doc.hasDocFilter(this.Document, 'star') ? 'Show all cards' : 'Show only starred cards'}>
<div key="back" className="carouselView-starFilter" onClick={e => this.toggleFilterMode()}>
- <FontAwesomeIcon icon="filter" color={this.setColor(cardMode.STAR, StrCast(this.layoutDoc.filterOp))} size="1x" />
+ <FontAwesomeIcon icon="filter" color={Doc.hasDocFilter(this.Document, 'star') ? 'white' : 'lightgray'} size="1x" />
</div>
</Tooltip>
+ <div className="carouselView-practiceModes" style={{ display: BoolCast(curDoc?._layout_isFlashcard) ? undefined : 'none' }}>
+ <Tooltip title="Practice flashcards using GPT">
+ <div key="back" className="carouselView-quiz" onClick={e => this.togglePracticeMode(practiceMode.QUIZ)}>
+ <FontAwesomeIcon icon="file-pen" color={this.setColor(practiceMode.QUIZ, StrCast(this.layoutDoc.practiceMode))} size="1x" />
+ </div>
+ </Tooltip>
+ <Tooltip title={this.layoutDoc.practiceMode === practiceMode.PRACTICE ? 'Exit practice mode' : 'Practice flashcards manually'}>
+ <div key="back" className="carouselView-practice" onClick={e => this.togglePracticeMode(practiceMode.PRACTICE)}>
+ <FontAwesomeIcon icon="check" color={this.setColor(practiceMode.PRACTICE, StrCast(this.layoutDoc.practiceMode))} size="1x" />
+ </div>
+ </Tooltip>
+ </div>
</div>
);
}
@@ -356,36 +336,25 @@ export class CollectionCarouselView extends CollectionSubView() {
background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string,
color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string,
}}>
- {!this._practiceMessage && !this._filterMessage ? (
+ {!this.practiceMessage && !this.filterMessage ? (
this.content
) : (
- <p className="message">
- {this._filterMessage}
- {'\n'}
- {this._practiceMessage}
+ <p
+ className="message"
+ onClick={e => {
+ if (this.filterMessage) {
+ this.layoutDoc.practiceMode = undefined;
+ Doc.setDocFilter(this.layoutDoc, 'star', undefined, 'remove');
+ }
+ this.childDocs.forEach(item => {
+ item[this.practiceField] = undefined;
+ });
+ }}>
+ {this.filterMessage || this.practiceMessage}
</p>
)}
- {!this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)] && this.layoutDoc.practiceMode === practiceMode.PRACTICE ? <p className="message">Add flashcards </p> : null}
- <p
- className="missed-message"
- style={{
- color: 'red',
- fontWeight: 'bold',
- zIndex: '999',
- position: 'relative',
- left: '10px',
- top: '10px',
- width: '10px',
- display: this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)]
- ? this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout[this.practiceField] === practiceVal.MISSED && this.layoutDoc.practiceMode === practiceMode.PRACTICE && !this._practiceMessage
- ? 'block'
- : 'none'
- : 'none',
- }}>
- Recently missed!
- </p>
- {!this.containsDifTypes() && this.carouselItems.length !== 0 ? this.menu : null}
- {this.Document._chromeHidden || (!this._filterMessage && !this._practiceMessage) ? this.buttons : null}
+ {!this.Document._chromeHidden ? this.menu : null}
+ {!this.Document._chromeHidden ? this.buttons : null}
</div>
);
}