From 41e47a7b7789e8c192fb31188cf549178ec71a22 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 16 May 2024 11:28:10 -0400
Subject: moved isHovering to DocumentView as instance variable instead from
 FormattedText as a Document field.  cleaned up cluster style provider.  fixed
 freeformView to not trigger as many updates when a doc is dropped, and fixed
 layoutEngines to not return a background or color unless actually set by the
 engine.

---
 src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

(limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx')

diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 62c4cc61a..d65e2d65e 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -126,15 +126,16 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     PanelHeight = ()       => this._props.autoDim ? this._props.PanelHeight?.() : this.Height; // prettier-ignore
 
     styleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => {
-        if (doc === this.layoutDoc) {
+        const overrideProp = () => {
             switch (property.split(':')[0]) {
-                case StyleProp.Opacity:         return this.Opacity; // only change the opacity for this specific document, not its children
+                case StyleProp.Opacity:         return this.Opacity; 
                 case StyleProp.BackgroundColor: return this.BackgroundColor;
                 case StyleProp.Color:           return this.Color;
-                default:
-            } // prettier-ignore
-        }
-        return this._props.styleProvider?.(doc, props, property);
+                default:                        return undefined;
+            }}; // prettier-ignore
+
+        // only override values for this specific document, not any children
+        return (doc === this.layoutDoc && overrideProp()) ?? this._props.styleProvider?.(doc, props, property);
     };
 
     public static getValues(doc: Doc, time: number, fillIn: boolean = true) {
-- 
cgit v1.2.3-70-g09d2


From 56917559cf47bba35740571e97845295dd63b424 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 16 May 2024 12:04:49 -0400
Subject: cleaned up and fixed feeformdocview styleprovider.

---
 src/client/views/StyleProvider.tsx                               | 8 ++++----
 .../collections/collectionFreeForm/CollectionFreeFormClusters.ts | 2 +-
 src/client/views/nodes/CollectionFreeFormDocumentView.tsx        | 2 +-
 src/client/views/nodes/DocumentView.tsx                          | 9 +++++----
 4 files changed, 11 insertions(+), 10 deletions(-)

(limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx')

diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 557f7db37..b7f8a3170 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -16,6 +16,7 @@ import { Id } from '../../fields/FieldSymbols';
 import { ScriptField } from '../../fields/ScriptField';
 import { BoolCast, Cast, DocCast, ImageCast, NumCast, ScriptCast, StrCast } from '../../fields/Types';
 import { AudioAnnoState } from '../../server/SharedMediaTypes';
+import { emptyPath } from '../../Utils';
 import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
 import { IsFollowLinkScript } from '../documents/DocUtils';
 import { SnappingManager } from '../util/SnappingManager';
@@ -26,7 +27,6 @@ import { DocumentView, DocumentViewProps } from './nodes/DocumentView';
 import { FieldViewProps } from './nodes/FieldView';
 import { StyleProp } from './StyleProp';
 import './StyleProvider.scss';
-import { emptyPath } from '../../Utils';
 
 function toggleLockedPosition(doc: Doc) {
     UndoManager.RunInBatch(() => Doc.toggleLockedPosition(doc), 'toggleBackground');
@@ -102,6 +102,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
         PanelWidth,
         PanelHeight,
         isSelected,
+        isHovering,
     } = props || {}; // extract props that are not shared between fieldView and documentView props.
     const componentView = docView?.()?.ComponentView;
     const fieldKey = fieldKeyProp ? fieldKeyProp + '_' : isCaption ? 'caption_' : '';
@@ -158,8 +159,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
         case StyleProp.FillColor:    return StrCast(doc?._fillColor, StrCast(doc?.fillColor, StrCast(doc?.backgroundColor, 'transparent')));
         case StyleProp.ShowCaption:  return hideCaptions || doc?._type_collection === CollectionViewType.Carousel ? undefined: StrCast(doc?._layout_showCaption);
         case StyleProp.TitleHeight:  return Math.min(4,(docView?.().screenToViewTransform().Scale ?? 1)) * NumCast(Doc.UserDoc().headerHeight,30);
-        case StyleProp.ShowTitle:
-            return (
+        case StyleProp.ShowTitle:    return (
                 (doc &&
                     !componentView?.isUnstyledView?.() &&
                     !LayoutTemplateString &&
@@ -218,7 +218,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
             if (SnappingManager.LastPressedBtn === doc?.[Id]) return SnappingManager.userColor; // hack to indicate active menu panel item
             const dataKey = doc ? Doc.LayoutFieldKey(doc) : "";
             const usePath = StrCast(doc?.[dataKey + "_usePath"]);
-            const alternate = usePath.includes(":hover") ? ( props?.isHovering?.() ? '_' + usePath.replace(":hover","") : "") : usePath ? "_" +usePath:usePath;
+            const alternate = usePath.includes(":hover") ? ( isHovering?.() ? '_' + usePath.replace(":hover","") : "") : usePath ? "_" +usePath:usePath;
             let docColor: Opt<string> = StrCast(doc?.[fieldKey+alternate], StrCast(doc?.['backgroundColor' +alternate], isCaption ? 'rgba(0,0,0,0.4)' : ''));
             if (doc?.[StrCast(doc?.layout_fieldKey)] instanceof Doc) docColor = StrCast(doc._backgroundColor,docColor)
             // prettier-ignore
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts b/src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts
index 6415d5225..6ad67a864 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts
@@ -2,7 +2,7 @@ import { action, observable } from 'mobx';
 import { CollectionFreeFormView } from '.';
 import { intersectRect } from '../../../../Utils';
 import { Doc, Opt } from '../../../../fields/Doc';
-import { Cast, NumCast, StrCast } from '../../../../fields/Types';
+import { NumCast, StrCast } from '../../../../fields/Types';
 import { DocumentType } from '../../../documents/DocumentTypes';
 import { DragManager } from '../../../util/DragManager';
 import { dropActionType } from '../../../util/DropActionTypes';
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index d65e2d65e..0bcaa06de 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -135,7 +135,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             }}; // prettier-ignore
 
         // only override values for this specific document, not any children
-        return (doc === this.layoutDoc && overrideProp()) ?? this._props.styleProvider?.(doc, props, property);
+        return (doc === this.layoutDoc ? overrideProp() : undefined) ?? this._props.styleProvider?.(doc, props, property);
     };
 
     public static getValues(doc: Doc, time: number, fillIn: boolean = true) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 66540678d..6f9e14c1b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -52,6 +52,7 @@ import { FormattedTextBox } from './formattedText/FormattedTextBox';
 import { PresEffect, PresEffectDirection } from './trails/PresEnums';
 import SpringAnimation from './trails/SlideEffect';
 import { SpringSettings, SpringType, springMappings } from './trails/SpringUtils';
+
 interface Window {
     MediaRecorder: MediaRecorder;
 }
@@ -957,7 +958,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
             duration: Cast(presEffectDoc?.presentation_transition, 'number', Cast(presEffectDoc?.followLinkTransitionTime, 'number', null)),
         };
 
-        let timing = StrCast(presEffectDoc?.presEffectTiming);
+        const timing = StrCast(presEffectDoc?.presEffectTiming);
         let timingConfig: SpringSettings | undefined;
         if (timing) {
             timingConfig = JSON.parse(timing);
@@ -966,7 +967,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
         if (!timingConfig) {
             timingConfig = {
                 type: SpringType.GENTLE,
-                ...springMappings['gentle'],
+                ...springMappings.gentle,
             };
         }
 
@@ -975,8 +976,6 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
         }
 
         switch (StrCast(presEffectDoc?.presentation_effect, StrCast(presEffectDoc?.followLinkAnimEffect))) {
-            default:
-            case PresEffect.None:       return renderDoc;
             case PresEffect.Zoom:       return <SpringAnimation doc={root} dir={dir} presEffect={PresEffect.Zoom} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SpringAnimation>
             // case PresEffect.Fade:        return <SlideEffect doc={root} dir={dir} presEffect={PresEffect.Fade} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect>
             case PresEffect.Fade:       return <Fade {...effectProps}>{renderDoc}</Fade>
@@ -986,6 +985,8 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
             case PresEffect.Roll:       return <SpringAnimation doc={root} dir={dir} presEffect={PresEffect.Roll} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SpringAnimation>
             // keep as preset, doesn't really make sense with spring config
             case PresEffect.Lightspeed: return <JackInTheBox {...effectProps}>{renderDoc}</JackInTheBox>;
+            case PresEffect.None:       
+            default:                    return renderDoc;
         } // prettier-ignore
     }
 }
-- 
cgit v1.2.3-70-g09d2


From deb55ee338269d51d001f1120cd8d0d6a2c4bc6a Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 20 May 2024 14:18:41 -0400
Subject: lint fixes

---
 package-lock.json                                  |  3 +-
 src/client/apis/gpt/GPT.ts                         |  2 +-
 .../views/collections/CollectionCarouselView.tsx   | 54 +++++++++++-----------
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  6 +--
 4 files changed, 31 insertions(+), 34 deletions(-)

(limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx')

diff --git a/package-lock.json b/package-lock.json
index 9500b1488..3a4ca6668 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -39228,8 +39228,7 @@
         "node_modules/text-table": {
             "version": "0.2.0",
             "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-            "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
-            "dev": true
+            "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="
         },
         "node_modules/textarea-caret": {
             "version": "3.1.0",
diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts
index 9efe4ec39..cca9d58f3 100644
--- a/src/client/apis/gpt/GPT.ts
+++ b/src/client/apis/gpt/GPT.ts
@@ -64,7 +64,7 @@ let lastResp = '';
  * @returns AI Output
  */
 const gptAPICall = async (inputTextIn: string, callType: GPTCallType, prompt?: any) => {
-    const inputText = callType === GPTCallType.SUMMARY || callType == GPTCallType.FLASHCARD || GPTCallType.QUIZ ? inputTextIn + '.' : inputTextIn;
+    const inputText = [GPTCallType.SUMMARY, GPTCallType.FLASHCARD, GPTCallType.QUIZ].includes(callType) ? inputTextIn + '.' : inputTextIn;
     const opts: GPTCallOpts = callTypeMap[callType];
     if (lastCall === inputText) return lastResp;
     try {
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index b736c7ced..95425a217 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -49,35 +49,35 @@ export class CollectionCarouselView extends CollectionSubView() {
     advance = (e: React.MouseEvent) => {
         e.stopPropagation();
         this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) + 1) % this.childLayoutPairs.length;
-        var startInd = this.layoutDoc._carousel_index;
+        let startInd = this.layoutDoc._carousel_index;
 
         // if the star filter is selected
-        if (this.layoutDoc[`filterOp`] == 'star') {
+        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) {
+            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';
+                this.layoutDoc.filterOp = 'all';
             }
         }
 
         // if the practice filter is selected
-        if (this.layoutDoc[`filterOp`] == 'practice') {
+        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) {
+            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';
+            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++) {
+                for (let i = 0; i < this.childLayoutPairs.length; i++) {
                     const curDoc = this.childLayoutPairs?.[NumCast(i)];
                     curDoc.layout[`${this.fieldKey}_missed`] = undefined;
                 }
@@ -93,35 +93,35 @@ export class CollectionCarouselView extends CollectionSubView() {
         e.stopPropagation();
         this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.length;
 
-        var startInd = this.layoutDoc._carousel_index;
+        let startInd = this.layoutDoc._carousel_index;
 
         // if the star filter is selected
-        if (this.layoutDoc[`filterOp`] == 'star') {
+        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) {
+            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';
+                this.layoutDoc.filterOp = 'all';
             }
         }
 
         // if the practice filter is selected
-        if (this.layoutDoc[`filterOp`] == 'practice') {
+        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) {
+            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';
+            if (this.childLayoutPairs?.[NumCast(startInd)].layout[`${this.fieldKey}_missed`] === 'correct') {
+                this.layoutDoc.filterOp = 'all';
 
-                for (var i = 0; i < this.childLayoutPairs.length; i++) {
+                for (let i = 0; i < this.childLayoutPairs.length; i++) {
                     const curDoc = this.childLayoutPairs?.[NumCast(i)];
                     curDoc.layout[`${this.fieldKey}_missed`] = undefined;
                 }
@@ -136,7 +136,7 @@ export class CollectionCarouselView extends CollectionSubView() {
         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;
+        if (curDoc.layout[`${this.fieldKey}_star`] === undefined) curDoc.layout[`${this.fieldKey}_star`] = true;
         else curDoc.layout[`${this.fieldKey}_star`] = !curDoc.layout[`${this.fieldKey}_star`];
     };
 
@@ -207,7 +207,7 @@ export class CollectionCarouselView extends CollectionSubView() {
         );
     }
     @computed get buttons() {
-        if (!this.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)]) return;
+        if (!this.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)]) return null;
         return (
             <>
                 <div key="back" className="carouselView-back" onClick={this.goback}>
@@ -217,13 +217,13 @@ 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.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)].layout[`${this.fieldKey}_star`] ? 'yellow' : 'gray'} size={'1x'} />
+                    <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 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 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>
             </>
         );
@@ -242,7 +242,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.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)] && this.layoutDoc[`filterOp`] == 'practice' ? 'flex' : 'none',
+                        display: !this.childLayoutPairs?.[NumCast(this.layoutDoc._carousel_index)] && this.layoutDoc.filterOp === 'practice' ? 'flex' : 'none',
                         justifyContent: 'center',
                         alignItems: 'center',
                         height: '100%',
@@ -258,7 +258,7 @@ export class CollectionCarouselView extends CollectionSubView() {
                         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',
+                        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>
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 0bcaa06de..034a38e9c 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -240,16 +240,14 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         if (screenXf) {
             DocumentView.DeselectAll();
             if (topDoc.z) {
-                const spt = screenXf.inverse().transformPoint(NumCast(topDoc.x), NumCast(topDoc.y));
+                [topDoc.x, topDoc.y] = screenXf.inverse().transformPoint(NumCast(topDoc.x), NumCast(topDoc.y));
                 topDoc.z = 0;
-                [topDoc.x, topDoc.y] = spt;
                 this._props.removeDocument?.(topDoc);
                 this._props.addDocTab(topDoc, OpenWhere.inParentFromScreen);
             } else {
                 const spt = this.screenToLocalTransform().inverse().transformPoint(0, 0);
-                const fpt = screenXf.transformPoint(spt[0], spt[1]);
+                [topDoc.x, topDoc.y] = screenXf.transformPoint(spt[0], spt[1]);
                 topDoc.z = 1;
-                [topDoc.x, topDoc.y] = fpt;
             }
             setTimeout(() => DocumentView.SelectView(DocumentView.getDocumentView(topDoc, containerDocView), false), 0);
         }
-- 
cgit v1.2.3-70-g09d2

