From 01db98ebdd02729729222bdd20ab65b57cbbe94c Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 9 Oct 2024 13:27:56 -0400
Subject: more refactoring to of collection flashcards into CollectioSubView to
 simplify using it in diferent collection views.

---
 src/client/views/collections/CollectionSubView.tsx | 51 ++++++++++++++++++++--
 1 file changed, 48 insertions(+), 3 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 581201a20..c057d2402 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -9,7 +9,7 @@ import { Id } from '../../../fields/FieldSymbols';
 import { List } from '../../../fields/List';
 import { listSpec } from '../../../fields/Schema';
 import { ScriptField } from '../../../fields/ScriptField';
-import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types';
+import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { WebField } from '../../../fields/URLField';
 import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
 import { GestureUtils } from '../../../pen-gestures/GestureUtils';
@@ -25,7 +25,8 @@ import { SnappingManager } from '../../util/SnappingManager';
 import { UndoManager } from '../../util/UndoManager';
 import { ViewBoxBaseComponent } from '../DocComponent';
 import { FieldViewProps } from '../nodes/FieldView';
-import { DocumentView } from '../nodes/DocumentView';
+import { DocumentView, DocumentViewProps } from '../nodes/DocumentView';
+import { FlashcardPracticeUI } from './FlashcardPracticeUI';
 
 export interface CollectionViewProps extends React.PropsWithChildren<FieldViewProps> {
     isAnnotationOverlay?: boolean; // is the collection an annotation overlay (eg an overlay on an image/video/etc)
@@ -119,7 +120,8 @@ export function CollectionSubView<X>() {
                     pair =>
                         // filter out any documents that have a proto that we don't have permissions to
                         !pair.layout?.hidden && pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate))
-                );
+                )
+                .filter(pair => !this._filterFunc?.(pair.layout!));
             return validPairs.map(({ data, layout }) => ({ data: data as Doc, layout: layout! })); // this mapping is a bit of a hack to coerce types
         }
         /**
@@ -515,6 +517,49 @@ export function CollectionSubView<X>() {
                 alert('Document upload failed - possibly an unsupported file type.');
             }
         };
+
+        protected _sideBtnWidth = 35;
+        @observable _filterFunc: ((doc: Doc) => boolean) | undefined = undefined;
+        /**
+         * How much the content of the collection is being scaled based on its nesting and its fit-to-width settings
+         */
+        @computed get contentScaling() { return this.ScreenToLocalBoxXf().Scale * (this._props.NativeDimScaling?.() ?? 1); } // prettier-ignore
+        /**
+         * The maximum size a UI widget can be in collection coordinates based on not wanting the widget to visually obscure too much of the collection
+         * This takes the desired screen space size and converts into collection coordinates.  It then returns the smaller of the converted
+         * size or a fraction of the collection view.
+         */
+        @computed get maxWidgetSize() { return Math.min(this._sideBtnWidth * this.contentScaling, 0.25 * NumCast(this.layoutDoc.width, 1));  } // prettier-ignore
+        /**
+         * This computes a scale factor for UI elements so that they shrink and grow as the collection does in screen space.
+         * Note, the scale factor does not allow for elements to grow larger than their native screen space size.
+         */
+        @computed get uiBtnScaling() { return this.maxWidgetSize / this._sideBtnWidth; } // prettier-ignore
+
+        screenXPadding = () => (this.uiBtnScaling * this._sideBtnWidth - NumCast(this.layoutDoc.xMargin)) / this._props.ScreenToLocalTransform().Scale;
+        filteredChildDocs = () => this.childLayoutPairs.map(pair => pair.layout);
+        childDocsFunc = () => this.childDocs;
+        @action setFilterFunc = (func?: (doc: Doc) => boolean) => { this._filterFunc = func; }; // prettier-ignore
+
+        public flashCardUI = (curDoc: () => Doc | undefined, docViewProps: () => DocumentViewProps, answered?: (correct: boolean) => void) => {
+            return (
+                <FlashcardPracticeUI
+                    setFilterFunc={this.setFilterFunc}
+                    fieldKey={this.fieldKey}
+                    sideBtnWidth={this._sideBtnWidth}
+                    allChildDocs={this.childDocsFunc}
+                    filteredChildDocs={this.filteredChildDocs}
+                    advance={answered}
+                    curDoc={curDoc}
+                    practiceBtnOffset={this._sideBtnWidth * 4}
+                    layoutDoc={this.layoutDoc}
+                    uiBtnScaling={this.uiBtnScaling}
+                    ScreenToLocalBoxXf={this.ScreenToLocalBoxXf}
+                    renderDepth={this._props.renderDepth}
+                    docViewProps={docViewProps}
+                />
+            );
+        };
     }
 
     return CollectionSubViewInternal;
-- 
cgit v1.2.3-70-g09d2

