From 2c565fd81daca02cabb9598c699cedb7611c3841 Mon Sep 17 00:00:00 2001
From: ljungster <parkerljung@gmail.com>
Date: Sat, 12 Mar 2022 07:44:01 -0500
Subject: attempting to add note-taking

I think this has something to do with the view not being rendered in novice mode. Assuming this is an issue in CollectionMenu.tsx.

Essentially what I did was add a note-taking view wherever I found a stacking view (via global search)
---
 src/client/views/collections/CollectionMenu.tsx | 125 +++++++++++++++++++++++-
 1 file changed, 124 insertions(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 131f5ba46..1ab4e9207 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -278,6 +278,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
 
     @computed get _freeform_commands() { return Doc.UserDoc().noviceMode ? [this._viewCommand, this._saveFilterCommand] : [this._viewCommand, this._saveFilterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; }
     @computed get _stacking_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._contentCommand, this._templateCommand]; }
+    @computed get _notetaking_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._contentCommand, this._templateCommand]; }
     @computed get _masonry_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._contentCommand, this._templateCommand]; }
     @computed get _schema_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._templateCommand, this._narrativeCommand]; }
     @computed get _doc_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._openLinkInCommand, this._onClickCommand]; }
@@ -289,6 +290,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
             case CollectionViewType.Tree: return this._tree_commands;
             case CollectionViewType.Schema: return this._schema_commands;
             case CollectionViewType.Stacking: return this._stacking_commands;
+            case CollectionViewType.NoteTaking: return this._notetaking_commands;
             case CollectionViewType.Masonry: return this._stacking_commands;
             case CollectionViewType.Time: return this._freeform_commands;
             case CollectionViewType.Carousel: return this._freeform_commands;
@@ -326,6 +328,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
             case CollectionViewType.Invalid:
             case CollectionViewType.Freeform: return (<CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={this.props.type === CollectionViewType.Invalid} />);
             case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" {...this.props} />);
+            case CollectionViewType.NoteTaking: return (<CollectionNoteTakingViewChrome key="collchrome" {...this.props} />);
             case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" {...this.props} />);
             case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" {...this.props} />);
             case CollectionViewType.Masonry: return (<CollectionStackingViewChrome key="collchrome" {...this.props} />);
@@ -496,7 +499,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
             const size: number = PresBox.Instance?._selectedArray.size;
             const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined;
             const activeDoc = presSelected ? PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.indexOf(presSelected) + 1] : PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.length - 1];
-            if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) {
+            if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking || targetDoc._viewType === CollectionViewType.NoteTaking) {
                 const scroll = targetDoc._scrollTop;
                 activeDoc.presPinView = true;
                 activeDoc.presPinViewScroll = scroll;
@@ -987,6 +990,126 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
     }
 }
 
+@observer
+export class CollectionNoteTakingViewChrome extends React.Component<CollectionViewMenuProps> {
+    @observable private _currentKey: string = "";
+    @observable private suggestions: string[] = [];
+
+    get document() { return this.props.docView.props.Document; }
+
+    @computed private get descending() { return StrCast(this.document._columnsSort) === "descending"; }
+    @computed get pivotField() { return StrCast(this.document._pivotField); }
+
+    getKeySuggestions = async (value: string): Promise<string[]> => {
+        const val = value.toLowerCase();
+        const docs = DocListCast(this.document[this.props.fieldKey]);
+
+        if (Doc.UserDoc().noviceMode) {
+            if (docs instanceof Doc) {
+                const keys = Object.keys(docs).filter(key => key.indexOf("title") >= 0 || key.indexOf("author") >= 0 ||
+                    key.indexOf("creationDate") >= 0 || key.indexOf("lastModified") >= 0 ||
+                    (key[0].toUpperCase() === key[0] && key[0] !== "_"));
+                return keys.filter(key => key.toLowerCase().indexOf(val) > -1);
+            } else {
+                const keys = new Set<string>();
+                docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
+                const noviceKeys = Array.from(keys).filter(key => key.indexOf("title") >= 0 || key.indexOf("author") >= 0 ||
+                    key.indexOf("creationDate") >= 0 || key.indexOf("lastModified") >= 0 ||
+                    (key[0]?.toUpperCase() === key[0] && key[0] !== "_"));
+                return noviceKeys.filter(key => key.toLowerCase().indexOf(val) > -1);
+            }
+        }
+
+        if (docs instanceof Doc) {
+            return Object.keys(docs).filter(key => key.toLowerCase().indexOf(val) > -1);
+        } else {
+            const keys = new Set<string>();
+            docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
+            return Array.from(keys).filter(key => key.toLowerCase().indexOf(val) > -1);
+        }
+    }
+
+    @action
+    onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => {
+        this._currentKey = newValue;
+    }
+
+    getSuggestionValue = (suggestion: string) => suggestion;
+
+    renderSuggestion = (suggestion: string) => {
+        return <p>{suggestion}</p>;
+    }
+
+    onSuggestionFetch = async ({ value }: { value: string }) => {
+        const sugg = await this.getKeySuggestions(value);
+        runInAction(() => {
+            this.suggestions = sugg;
+        });
+    }
+
+    @action
+    onSuggestionClear = () => {
+        this.suggestions = [];
+    }
+
+    @action
+    setValue = (value: string) => {
+        this.document._pivotField = value;
+        return true;
+    }
+
+    @action toggleSort = () => {
+        this.document._columnsSort =
+            this.document._columnsSort === "descending" ? "ascending" :
+                this.document._columnsSort === "ascending" ? undefined : "descending";
+    }
+    @action resetValue = () => { this._currentKey = this.pivotField; };
+
+    render() {
+        const doctype = this.props.docView.Document.type;
+        const isPres: boolean = (doctype === DocumentType.PRES);
+        return (
+            isPres ? (null) : <div className="collectionStackingViewChrome-cont">
+                <div className="collectionStackingViewChrome-pivotField-cont">
+                    <div className="collectionStackingViewChrome-pivotField-label">
+                        GROUP BY:
+                    </div>
+                    <div className="collectionStackingViewChrome-sortIcon" onClick={this.toggleSort} style={{ transform: `rotate(${this.descending ? "180" : "0"}deg)` }}>
+                        <FontAwesomeIcon icon="caret-up" size="2x" color="white" />
+                    </div>
+                    <div className="collectionStackingViewChrome-pivotField">
+                        <EditableView
+                            GetValue={() => this.pivotField}
+                            autosuggestProps={
+                                {
+                                    resetValue: this.resetValue,
+                                    value: this._currentKey,
+                                    onChange: this.onKeyChange,
+                                    autosuggestProps: {
+                                        inputProps:
+                                        {
+                                            value: this._currentKey,
+                                            onChange: this.onKeyChange
+                                        },
+                                        getSuggestionValue: this.getSuggestionValue,
+                                        suggestions: this.suggestions,
+                                        alwaysRenderSuggestions: true,
+                                        renderSuggestion: this.renderSuggestion,
+                                        onSuggestionsFetchRequested: this.onSuggestionFetch,
+                                        onSuggestionsClearRequested: this.onSuggestionClear
+                                    }
+                                }}
+                            oneLine
+                            SetValue={this.setValue}
+                            contents={this.pivotField ? this.pivotField : "N/A"}
+                        />
+                    </div>
+                </div>
+            </div>
+        );
+    }
+}
+
 
 @observer
 export class CollectionSchemaViewChrome extends React.Component<CollectionViewMenuProps> {
-- 
cgit v1.2.3-70-g09d2


From b8bef1149b057d59076fe2c5e46d4b42c1f2ecdd Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 3 Aug 2022 09:19:09 -0400
Subject: fixing styles on parker branch

---
 .prettierrc                                     |   4 -
 src/client/documents/Documents.ts               |  80 +++++------
 src/client/views/collections/CollectionMenu.tsx | 173 ++++++++++++++----------
 3 files changed, 143 insertions(+), 114 deletions(-)
 delete mode 100644 .prettierrc

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

diff --git a/.prettierrc b/.prettierrc
deleted file mode 100644
index 222861c34..000000000
--- a/.prettierrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "tabWidth": 2,
-  "useTabs": false
-}
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 31cb0678a..32d7152fd 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1036,8 +1036,8 @@ export namespace Docs {
         }
 
         export function NoteTakingDocument(documents: Array<Doc>, options: DocumentOptions, id?: string, protoId?: string) {
-          return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.NoteTaking }, id, undefined, protoId);
-      }
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.NoteTaking }, id, undefined, protoId);
+        }
 
         export function MulticolumnDocument(documents: Array<Doc>, options: DocumentOptions) {
             return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Multicolumn });
@@ -1490,48 +1490,52 @@ export namespace DocUtils {
     }
 
     export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false, pivotField?: string, pivotValue?: string): void {
-        !simpleMenu && ContextMenu.Instance.addItem({
-            description: "Quick Notes",
-            subitems: DocListCast((Doc.UserDoc()["template-notes"] as Doc).data).map((note, i) => ({
-                description: ":" + StrCast(note.title),
-                event: undoBatch((args: { x: number, y: number }) => {
-                    const textDoc = Docs.Create.TextDocument("", {
-                        _width: 200, x, y, _autoHeight: note._autoHeight !== false,
-                        title: StrCast(note.title) + "#" + (note.aliasCount = NumCast(note.aliasCount) + 1),
-                    });
-                    textDoc.layoutKey = "layout_" + note.title;
-                    textDoc[textDoc.layoutKey] = note;
-                    if (pivotField) {
-                      textDoc[pivotField] = pivotValue;
-                    }
-                    docTextAdder(textDoc);
-                }),
-                icon: StrCast(note.icon) as IconProp
-            })) as ContextMenuProps[],
-            icon: "sticky-note"
-        });
+        !simpleMenu &&
+            ContextMenu.Instance.addItem({
+                description: 'Quick Notes',
+                subitems: DocListCast((Doc.UserDoc()['template-notes'] as Doc).data).map((note, i) => ({
+                    description: ':' + StrCast(note.title),
+                    event: undoBatch((args: { x: number; y: number }) => {
+                        const textDoc = Docs.Create.TextDocument('', {
+                            _width: 200,
+                            x,
+                            y,
+                            _autoHeight: note._autoHeight !== false,
+                            title: StrCast(note.title) + '#' + (note.aliasCount = NumCast(note.aliasCount) + 1),
+                        });
+                        textDoc.layoutKey = 'layout_' + note.title;
+                        textDoc[textDoc.layoutKey] = note;
+                        if (pivotField) {
+                            textDoc[pivotField] = pivotValue;
+                        }
+                        docTextAdder(textDoc);
+                    }),
+                    icon: StrCast(note.icon) as IconProp,
+                })) as ContextMenuProps[],
+                icon: 'sticky-note',
+            });
         const documentList: ContextMenuProps[] = DocListCast(DocListCast(Doc.MyTools?.data)[0]?.data)
             .filter(btnDoc => !btnDoc.hidden)
             .map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null))
             .filter(doc => doc && doc !== Doc.UserDoc().emptyPresentation)
             .map((dragDoc, i) => ({
-            description: ":" + StrCast(dragDoc.title).replace("Untitled ",""),
-            event: undoBatch((args: { x: number, y: number }) => {
-                const newDoc = DocUtils.copyDragFactory(dragDoc);
-                if (newDoc) {
-                    newDoc.author = Doc.CurrentUserEmail;
-                    newDoc.x = x;
-                    newDoc.y = y;
-                    EquationBox.SelectOnLoad = newDoc[Id];
-                    if (newDoc.type === DocumentType.RTF) FormattedTextBox.SelectOnLoad = newDoc[Id];
-                    if (pivotField) {
-                      newDoc[pivotField] = pivotValue;
+                description: ':' + StrCast(dragDoc.title).replace('Untitled ', ''),
+                event: undoBatch((args: { x: number; y: number }) => {
+                    const newDoc = DocUtils.copyDragFactory(dragDoc);
+                    if (newDoc) {
+                        newDoc.author = Doc.CurrentUserEmail;
+                        newDoc.x = x;
+                        newDoc.y = y;
+                        EquationBox.SelectOnLoad = newDoc[Id];
+                        if (newDoc.type === DocumentType.RTF) FormattedTextBox.SelectOnLoad = newDoc[Id];
+                        if (pivotField) {
+                            newDoc[pivotField] = pivotValue;
+                        }
+                        docAdder?.(newDoc);
                     }
-                    docAdder?.(newDoc);
-                }
-            }),
-            icon: Doc.toIcon(dragDoc),
-        })) as ContextMenuProps[];
+                }),
+                icon: Doc.toIcon(dragDoc),
+            })) as ContextMenuProps[];
         ContextMenu.Instance.addItem({
             description: 'Create document',
             subitems: documentList,
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index aa1765c14..cfbcec2d6 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -311,25 +311,49 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
         },
     };
 
-    @computed get _freeform_commands() { return Doc.noviceMode ? [this._viewCommand, this._saveFilterCommand] : [this._viewCommand, this._saveFilterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; }
-    @computed get _stacking_commands() { return Doc.noviceMode ? undefined : [this._contentCommand, this._templateCommand]; }
-    @computed get _notetaking_commands() { return Doc.noviceMode ? undefined : [this._contentCommand, this._templateCommand]; }
-    @computed get _masonry_commands() { return Doc.noviceMode ? undefined : [this._contentCommand, this._templateCommand]; }
-    @computed get _schema_commands() { return Doc.noviceMode ? undefined : [this._templateCommand, this._narrativeCommand]; }
-    @computed get _doc_commands() { return Doc.noviceMode ? undefined : [this._openLinkInCommand, this._onClickCommand]; }
-    @computed get _tree_commands() { return undefined; }
+    @computed get _freeform_commands() {
+        return Doc.noviceMode ? [this._viewCommand, this._saveFilterCommand] : [this._viewCommand, this._saveFilterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand];
+    }
+    @computed get _stacking_commands() {
+        return Doc.noviceMode ? undefined : [this._contentCommand, this._templateCommand];
+    }
+    @computed get _notetaking_commands() {
+        return Doc.noviceMode ? undefined : [this._contentCommand, this._templateCommand];
+    }
+    @computed get _masonry_commands() {
+        return Doc.noviceMode ? undefined : [this._contentCommand, this._templateCommand];
+    }
+    @computed get _schema_commands() {
+        return Doc.noviceMode ? undefined : [this._templateCommand, this._narrativeCommand];
+    }
+    @computed get _doc_commands() {
+        return Doc.noviceMode ? undefined : [this._openLinkInCommand, this._onClickCommand];
+    }
+    @computed get _tree_commands() {
+        return undefined;
+    }
     private get _buttonizableCommands() {
         switch (this.props.type) {
-            default: return this._doc_commands;
-            case CollectionViewType.Freeform: return this._freeform_commands;
-            case CollectionViewType.Tree: return this._tree_commands;
-            case CollectionViewType.Schema: return this._schema_commands;
-            case CollectionViewType.Stacking: return this._stacking_commands;
-            case CollectionViewType.NoteTaking: return this._notetaking_commands;
-            case CollectionViewType.Masonry: return this._stacking_commands;
-            case CollectionViewType.Time: return this._freeform_commands;
-            case CollectionViewType.Carousel: return this._freeform_commands;
-            case CollectionViewType.Carousel3D: return this._freeform_commands;
+            default:
+                return this._doc_commands;
+            case CollectionViewType.Freeform:
+                return this._freeform_commands;
+            case CollectionViewType.Tree:
+                return this._tree_commands;
+            case CollectionViewType.Schema:
+                return this._schema_commands;
+            case CollectionViewType.Stacking:
+                return this._stacking_commands;
+            case CollectionViewType.NoteTaking:
+                return this._notetaking_commands;
+            case CollectionViewType.Masonry:
+                return this._stacking_commands;
+            case CollectionViewType.Time:
+                return this._freeform_commands;
+            case CollectionViewType.Carousel:
+                return this._freeform_commands;
+            case CollectionViewType.Carousel3D:
+                return this._freeform_commands;
         }
     }
     private _commandRef = React.createRef<HTMLInputElement>();
@@ -363,12 +387,18 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
             default:
                 return this.otherSubChrome;
             case CollectionViewType.Invalid:
-            case CollectionViewType.Freeform: return (<CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={this.props.type === CollectionViewType.Invalid} />);
-            case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" {...this.props} />);
-            case CollectionViewType.NoteTaking: return (<CollectionNoteTakingViewChrome key="collchrome" {...this.props} />);
-            case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" {...this.props} />);
-            case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" {...this.props} />);
-            case CollectionViewType.Masonry: return (<CollectionStackingViewChrome key="collchrome" {...this.props} />);
+            case CollectionViewType.Freeform:
+                return <CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={this.props.type === CollectionViewType.Invalid} />;
+            case CollectionViewType.Stacking:
+                return <CollectionStackingViewChrome key="collchrome" {...this.props} />;
+            case CollectionViewType.NoteTaking:
+                return <CollectionNoteTakingViewChrome key="collchrome" {...this.props} />;
+            case CollectionViewType.Schema:
+                return <CollectionSchemaViewChrome key="collchrome" {...this.props} />;
+            case CollectionViewType.Tree:
+                return <CollectionTreeViewChrome key="collchrome" {...this.props} />;
+            case CollectionViewType.Masonry:
+                return <CollectionStackingViewChrome key="collchrome" {...this.props} />;
             case CollectionViewType.Carousel:
             case CollectionViewType.Carousel3D:
                 return <Collection3DCarouselViewChrome key="collchrome" {...this.props} />;
@@ -1124,13 +1154,19 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
 
 @observer
 export class CollectionNoteTakingViewChrome extends React.Component<CollectionViewMenuProps> {
-    @observable private _currentKey: string = "";
+    @observable private _currentKey: string = '';
     @observable private suggestions: string[] = [];
 
-    get document() { return this.props.docView.props.Document; }
+    get document() {
+        return this.props.docView.props.Document;
+    }
 
-    @computed private get descending() { return StrCast(this.document._columnsSort) === "descending"; }
-    @computed get pivotField() { return StrCast(this.document._pivotField); }
+    @computed private get descending() {
+        return StrCast(this.document._columnsSort) === 'descending';
+    }
+    @computed get pivotField() {
+        return StrCast(this.document._pivotField);
+    }
 
     getKeySuggestions = async (value: string): Promise<string[]> => {
         const val = value.toLowerCase();
@@ -1138,16 +1174,14 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi
 
         if (Doc.UserDoc().noviceMode) {
             if (docs instanceof Doc) {
-                const keys = Object.keys(docs).filter(key => key.indexOf("title") >= 0 || key.indexOf("author") >= 0 ||
-                    key.indexOf("creationDate") >= 0 || key.indexOf("lastModified") >= 0 ||
-                    (key[0].toUpperCase() === key[0] && key[0] !== "_"));
+                const keys = Object.keys(docs).filter(key => key.indexOf('title') >= 0 || key.indexOf('author') >= 0 || key.indexOf('creationDate') >= 0 || key.indexOf('lastModified') >= 0 || (key[0].toUpperCase() === key[0] && key[0] !== '_'));
                 return keys.filter(key => key.toLowerCase().indexOf(val) > -1);
             } else {
                 const keys = new Set<string>();
                 docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
-                const noviceKeys = Array.from(keys).filter(key => key.indexOf("title") >= 0 || key.indexOf("author") >= 0 ||
-                    key.indexOf("creationDate") >= 0 || key.indexOf("lastModified") >= 0 ||
-                    (key[0]?.toUpperCase() === key[0] && key[0] !== "_"));
+                const noviceKeys = Array.from(keys).filter(
+                    key => key.indexOf('title') >= 0 || key.indexOf('author') >= 0 || key.indexOf('creationDate') >= 0 || key.indexOf('lastModified') >= 0 || (key[0]?.toUpperCase() === key[0] && key[0] !== '_')
+                );
                 return noviceKeys.filter(key => key.toLowerCase().indexOf(val) > -1);
             }
         }
@@ -1159,81 +1193,77 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi
             docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
             return Array.from(keys).filter(key => key.toLowerCase().indexOf(val) > -1);
         }
-    }
+    };
 
     @action
     onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => {
         this._currentKey = newValue;
-    }
+    };
 
     getSuggestionValue = (suggestion: string) => suggestion;
 
     renderSuggestion = (suggestion: string) => {
         return <p>{suggestion}</p>;
-    }
+    };
 
     onSuggestionFetch = async ({ value }: { value: string }) => {
         const sugg = await this.getKeySuggestions(value);
         runInAction(() => {
             this.suggestions = sugg;
         });
-    }
+    };
 
     @action
     onSuggestionClear = () => {
         this.suggestions = [];
-    }
+    };
 
     @action
     setValue = (value: string) => {
         this.document._pivotField = value;
         return true;
-    }
+    };
 
     @action toggleSort = () => {
-        this.document._columnsSort =
-            this.document._columnsSort === "descending" ? "ascending" :
-                this.document._columnsSort === "ascending" ? undefined : "descending";
-    }
-    @action resetValue = () => { this._currentKey = this.pivotField; };
+        this.document._columnsSort = this.document._columnsSort === 'descending' ? 'ascending' : this.document._columnsSort === 'ascending' ? undefined : 'descending';
+    };
+    @action resetValue = () => {
+        this._currentKey = this.pivotField;
+    };
 
     render() {
         const doctype = this.props.docView.Document.type;
-        const isPres: boolean = (doctype === DocumentType.PRES);
-        return (
-            isPres ? (null) : <div className="collectionStackingViewChrome-cont">
+        const isPres: boolean = doctype === DocumentType.PRES;
+        return isPres ? null : (
+            <div className="collectionStackingViewChrome-cont">
                 <div className="collectionStackingViewChrome-pivotField-cont">
-                    <div className="collectionStackingViewChrome-pivotField-label">
-                        GROUP BY:
-                    </div>
-                    <div className="collectionStackingViewChrome-sortIcon" onClick={this.toggleSort} style={{ transform: `rotate(${this.descending ? "180" : "0"}deg)` }}>
+                    <div className="collectionStackingViewChrome-pivotField-label">GROUP BY:</div>
+                    <div className="collectionStackingViewChrome-sortIcon" onClick={this.toggleSort} style={{ transform: `rotate(${this.descending ? '180' : '0'}deg)` }}>
                         <FontAwesomeIcon icon="caret-up" size="2x" color="white" />
                     </div>
                     <div className="collectionStackingViewChrome-pivotField">
                         <EditableView
                             GetValue={() => this.pivotField}
-                            autosuggestProps={
-                                {
-                                    resetValue: this.resetValue,
-                                    value: this._currentKey,
-                                    onChange: this.onKeyChange,
-                                    autosuggestProps: {
-                                        inputProps:
-                                        {
-                                            value: this._currentKey,
-                                            onChange: this.onKeyChange
-                                        },
-                                        getSuggestionValue: this.getSuggestionValue,
-                                        suggestions: this.suggestions,
-                                        alwaysRenderSuggestions: true,
-                                        renderSuggestion: this.renderSuggestion,
-                                        onSuggestionsFetchRequested: this.onSuggestionFetch,
-                                        onSuggestionsClearRequested: this.onSuggestionClear
-                                    }
-                                }}
+                            autosuggestProps={{
+                                resetValue: this.resetValue,
+                                value: this._currentKey,
+                                onChange: this.onKeyChange,
+                                autosuggestProps: {
+                                    inputProps: {
+                                        value: this._currentKey,
+                                        onChange: this.onKeyChange,
+                                    },
+                                    getSuggestionValue: this.getSuggestionValue,
+                                    suggestions: this.suggestions,
+                                    alwaysRenderSuggestions: true,
+                                    renderSuggestion: this.renderSuggestion,
+                                    onSuggestionsFetchRequested: this.onSuggestionFetch,
+                                    onSuggestionsClearRequested: this.onSuggestionClear,
+                                },
+                            }}
                             oneLine
                             SetValue={this.setValue}
-                            contents={this.pivotField ? this.pivotField : "N/A"}
+                            contents={this.pivotField ? this.pivotField : 'N/A'}
                         />
                     </div>
                 </div>
@@ -1242,7 +1272,6 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi
     }
 }
 
-
 @observer
 export class CollectionSchemaViewChrome extends React.Component<CollectionViewMenuProps> {
     // private _textwrapAllRows: boolean = Cast(this.document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
-- 
cgit v1.2.3-70-g09d2


From 513dcaa2d8c86f1cb5236ce89062cace6f418d1b Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 10 Aug 2022 14:52:04 -0400
Subject: cleaned up pinning documents with an activeFrame index (and special
 case of isInkMask).  removed text-color from pres boxes which was breaking
 opacity when docs had an appearFrame > 0.

---
 src/client/views/DocumentButtonBar.tsx             |  18 +-
 src/client/views/collections/CollectionMenu.tsx    |  25 ++-
 src/client/views/collections/TabDocView.tsx        |  15 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx | 208 ++++++++++++---------
 src/client/views/nodes/DocumentView.tsx            |   4 +-
 src/client/views/nodes/trails/PresBox.tsx          |  23 +--
 6 files changed, 163 insertions(+), 130 deletions(-)

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

diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 1f8550ad6..40fc8dae6 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -5,7 +5,7 @@ import { action, computed, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { Doc } from '../../fields/Doc';
 import { RichTextField } from '../../fields/RichTextField';
-import { Cast, NumCast } from '../../fields/Types';
+import { Cast, DocCast, NumCast } from '../../fields/Types';
 import { emptyFunction, returnFalse, setupMoveUpEvents, simulateMouseClick } from '../../Utils';
 import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
 import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
@@ -238,15 +238,13 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
                 <div
                     className="documentButtonBar-icon"
                     style={{ color: 'white' }}
-                    onClick={e =>
-                        TabDocView.PinDoc(
-                            this.props
-                                .views()
-                                .filter(v => v)
-                                .map(dv => dv!.rootDoc),
-                            { pinDocView: true }
-                        )
-                    }>
+                    onClick={e => {
+                        const docs = this.props
+                            .views()
+                            .filter(v => v)
+                            .map(dv => dv!.rootDoc);
+                        TabDocView.PinDoc(docs, { pinDocView: true, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) });
+                    }}>
                     <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
                 </div>
             </Tooltip>
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index cfbcec2d6..8432619de 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -769,6 +769,21 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionView
         return this.selectedDoc?.type === DocumentType.RTF || (RichTextMenu.Instance?.view as any) ? true : false;
     }
 
+    public static gotoKeyFrame(doc: Doc, newFrame: number) {
+        if (!doc) {
+            return;
+        }
+        const dataField = doc[Doc.LayoutFieldKey(doc)];
+        const childDocs = DocListCast(dataField);
+        const currentFrame = Cast(doc._currentFrame, 'number', null);
+        if (currentFrame === undefined) {
+            doc._currentFrame = 0;
+            CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
+        }
+        CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
+        doc._currentFrame = newFrame === undefined ? 0 : Math.max(0, newFrame);
+    }
+
     @undoBatch
     @action
     nextKeyframe = (): void => {
@@ -1569,13 +1584,5 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
     }
 }
 ScriptingGlobals.add(function gotoFrame(doc: any, newFrame: any) {
-    const dataField = doc[Doc.LayoutFieldKey(doc)];
-    const childDocs = DocListCast(dataField);
-    const currentFrame = Cast(doc._currentFrame, 'number', null);
-    if (currentFrame === undefined) {
-        doc._currentFrame = 0;
-        CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
-    }
-    CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
-    doc._currentFrame = newFrame === undefined ? 0 : Math.max(0, newFrame);
+    CollectionFreeFormViewChrome.gotoKeyFrame(doc, newFrame);
 });
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index ec291e72c..f30faab79 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -288,14 +288,15 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                     pinDoc.presEndTime = NumCast(doc.clipEnd, duration);
                 }
                 //save position
-                if (pinProps?.setPosition || pinDoc.isInkMask) {
-                    pinDoc.setPosition = true;
-                    pinDoc.y = doc.y;
-                    pinDoc.x = doc.x;
-                    pinDoc.presHideAfter = true;
-                    pinDoc.presHideBefore = true;
+                if (pinProps?.activeFrame !== undefined) {
+                    pinDoc.presActiveFrame = pinProps?.activeFrame;
                     pinDoc.title = doc.title + ' (move)';
-                    pinDoc.presMovement = PresMovement.None;
+                    pinDoc.presMovement = PresMovement.Pan;
+                    if (pinDoc.isInkMask) {
+                        pinDoc.presHideAfter = true;
+                        pinDoc.presHideBefore = true;
+                        pinDoc.presMovement = PresMovement.None;
+                    }
                 }
                 if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
                 PresBox.Instance?._selectedArray.clear();
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 284584a3d..e154e8445 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,26 +1,26 @@
-import { action, computed, observable, trace } from "mobx";
-import { observer } from "mobx-react";
-import { Doc, Opt } from "../../../fields/Doc";
-import { List } from "../../../fields/List";
-import { listSpec } from "../../../fields/Schema";
-import { ComputedField } from "../../../fields/ScriptField";
-import { Cast, NumCast, StrCast } from "../../../fields/Types";
-import { TraceMobx } from "../../../fields/util";
-import { DashColor, numberRange, OmitKeys } from "../../../Utils";
-import { DocumentManager } from "../../util/DocumentManager";
-import { SelectionManager } from "../../util/SelectionManager";
-import { Transform } from "../../util/Transform";
-import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
-import { DocComponent } from "../DocComponent";
-import { InkingStroke } from "../InkingStroke";
-import { StyleProp } from "../StyleProvider";
-import "./CollectionFreeFormDocumentView.scss";
-import { DocumentView, DocumentViewProps } from "./DocumentView";
-import React = require("react");
+import { action, computed, observable, trace } from 'mobx';
+import { observer } from 'mobx-react';
+import { Doc, Opt } from '../../../fields/Doc';
+import { List } from '../../../fields/List';
+import { listSpec } from '../../../fields/Schema';
+import { ComputedField } from '../../../fields/ScriptField';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { TraceMobx } from '../../../fields/util';
+import { DashColor, numberRange, OmitKeys } from '../../../Utils';
+import { DocumentManager } from '../../util/DocumentManager';
+import { SelectionManager } from '../../util/SelectionManager';
+import { Transform } from '../../util/Transform';
+import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
+import { DocComponent } from '../DocComponent';
+import { InkingStroke } from '../InkingStroke';
+import { StyleProp } from '../StyleProvider';
+import './CollectionFreeFormDocumentView.scss';
+import { DocumentView, DocumentViewProps } from './DocumentView';
+import React = require('react');
 
 export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
-    dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
-    sizeProvider?: (doc: Doc, replica: string) => { width: number, height: number } | undefined;
+    dataProvider?: (doc: Doc, replica: string) => { x: number; y: number; zIndex?: number; opacity?: number; highlight?: boolean; z: number; transition?: string } | undefined;
+    sizeProvider?: (doc: Doc, replica: string) => { width: number; height: number } | undefined;
     renderCutoffProvider: (doc: Doc) => boolean;
     zIndex?: number;
     highlight?: boolean;
@@ -32,29 +32,51 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
 
 @observer
 export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps>() {
-    public static animFields = ["_height", "_width", "x", "y", "_scrollTop", "opacity"];  // fields that are configured to be animatable using animation frames
+    public static animFields = ['_height', '_width', 'x', 'y', '_scrollTop', 'opacity']; // fields that are configured to be animatable using animation frames
     @observable _animPos: number[] | undefined = undefined;
     @observable _contentView: DocumentView | undefined | null;
-    get displayName() { return "CollectionFreeFormDocumentView(" + this.rootDoc.title + ")"; } // this makes mobx trace() statements more descriptive
-    get maskCentering() { return this.props.Document.isInkMask ? InkingStroke.MaskDim / 2 : 0; }
-    get transform() { return `translate(${this.X - this.maskCentering}px, ${this.Y - this.maskCentering}px) rotate(${NumCast(this.Document.jitterRotation, this.props.jitterRotation)}deg)`; }
-    get X() { return this.dataProvider ? this.dataProvider.x : NumCast(this.Document.x); }
-    get Y() { return this.dataProvider ? this.dataProvider.y : NumCast(this.Document.y); }
-    get ZInd() { return this.dataProvider ? this.dataProvider.zIndex : NumCast(this.Document.zIndex); }
-    get Opacity() { return this.dataProvider ? this.dataProvider.opacity : undefined; }
-    get Highlight() { return this.dataProvider?.highlight; }
-    @computed get ShowTitle() { return this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.ShowTitle) as (Opt<string>); }
-    @computed get dataProvider() { return this.props.dataProvider?.(this.props.Document, this.props.replica); }
-    @computed get sizeProvider() { return this.props.sizeProvider?.(this.props.Document, this.props.replica); }
+    get displayName() {
+        return 'CollectionFreeFormDocumentView(' + this.rootDoc.title + ')';
+    } // this makes mobx trace() statements more descriptive
+    get maskCentering() {
+        return this.props.Document.isInkMask ? InkingStroke.MaskDim / 2 : 0;
+    }
+    get transform() {
+        return `translate(${this.X - this.maskCentering}px, ${this.Y - this.maskCentering}px) rotate(${NumCast(this.Document.jitterRotation, this.props.jitterRotation)}deg)`;
+    }
+    get X() {
+        return this.dataProvider ? this.dataProvider.x : NumCast(this.Document.x);
+    }
+    get Y() {
+        return this.dataProvider ? this.dataProvider.y : NumCast(this.Document.y);
+    }
+    get ZInd() {
+        return this.dataProvider ? this.dataProvider.zIndex : NumCast(this.Document.zIndex);
+    }
+    get Opacity() {
+        return this.dataProvider ? this.dataProvider.opacity : undefined;
+    }
+    get Highlight() {
+        return this.dataProvider?.highlight;
+    }
+    @computed get ShowTitle() {
+        return this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.ShowTitle) as Opt<string>;
+    }
+    @computed get dataProvider() {
+        return this.props.dataProvider?.(this.props.Document, this.props.replica);
+    }
+    @computed get sizeProvider() {
+        return this.props.sizeProvider?.(this.props.Document, this.props.replica);
+    }
 
     styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string) => {
         if (property === StyleProp.Opacity && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children
         return this.props.styleProvider?.(doc, props, property);
-    }
+    };
 
     public static getValues(doc: Doc, time: number) {
         return CollectionFreeFormDocumentView.animFields.reduce((p, val) => {
-            p[val] = Cast(`${val}-indexed`, listSpec("number"), [NumCast(doc[val])]).reduce((p, v, i) => (i <= Math.round(time) && v !== undefined) || p === undefined ? v : p, undefined as any as number);
+            p[val] = Cast(`${val}-indexed`, listSpec('number'), [NumCast(doc[val])]).reduce((p, v, i) => ((i <= Math.round(time) && v !== undefined) || p === undefined ? v : p), undefined as any as number);
             return p;
         }, {} as { [val: string]: Opt<number> });
     }
@@ -62,35 +84,43 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     public static setValues(time: number, d: Doc, vals: { [val: string]: Opt<number> }) {
         const timecode = Math.round(time);
         Object.keys(vals).forEach(val => {
-            const findexed = Cast(d[`${val}-indexed`], listSpec("number"), []).slice();
+            const findexed = Cast(d[`${val}-indexed`], listSpec('number'), []).slice();
             findexed[timecode] = vals[val] as any as number;
             d[`${val}-indexed`] = new List<number>(findexed);
         });
-        d.appearFrame && (d["text-color"] =
-            d.appearFrame === timecode + 1 ? "red" :
-                d.appearFrame < timecode + 1 ? "grey" : "black");
     }
 
     public static updateKeyframe(docs: Doc[], time: number, targetDoc?: Doc) {
         const timecode = Math.round(time);
-        docs.forEach(action(doc => {
-            doc._viewTransition = doc.dataTransition = "all 1s";
-            doc["text-color"] =
-                !doc.appearFrame || !targetDoc ? "black" :
-                    doc.appearFrame === timecode + 1 ? StrCast(targetDoc["pres-text-color"]) :
-                        doc.appearFrame < timecode + 1 ? StrCast(targetDoc["pres-text-viewed-color"]) :
-                            "black";
-            CollectionFreeFormDocumentView.animFields.forEach(val => {
-                const findexed = Cast(doc[`${val}-indexed`], listSpec("number"), null);
-                findexed?.length <= timecode + 1 && findexed.push(undefined as any as number);
-            });
-        }));
-        setTimeout(() => docs.forEach(doc => { doc._viewTransition = undefined; doc.dataTransition = "inherit"; }), 1010);
+        docs.forEach(
+            action(doc => {
+                doc._viewTransition = doc.dataTransition = 'all 1s';
+                CollectionFreeFormDocumentView.animFields.forEach(val => {
+                    const findexed = Cast(doc[`${val}-indexed`], listSpec('number'), null);
+                    findexed?.length <= timecode + 1 && findexed.push(undefined as any as number);
+                });
+            })
+        );
+        setTimeout(
+            () =>
+                docs.forEach(doc => {
+                    doc._viewTransition = undefined;
+                    doc.dataTransition = 'inherit';
+                }),
+            1010
+        );
     }
 
     public static gotoKeyframe(docs: Doc[]) {
-        docs.forEach(doc => doc._viewTransition = doc.dataTransition = "all 1s");
-        setTimeout(() => docs.forEach(doc => { doc._viewTransition = undefined; doc.dataTransition = "inherit"; }), 1010);
+        docs.forEach(doc => (doc._viewTransition = doc.dataTransition = 'all 1s'));
+        setTimeout(
+            () =>
+                docs.forEach(doc => {
+                    doc._viewTransition = undefined;
+                    doc.dataTransition = 'inherit';
+                }),
+            1010
+        );
     }
 
     public static setupZoom(doc: Doc, targDoc: Doc) {
@@ -102,21 +132,22 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         height.push(NumCast(targDoc._height));
         top.push(NumCast(targDoc._height) / -2);
         left.push(NumCast(targDoc._width) / -2);
-        doc["viewfinder-width-indexed"] = width;
-        doc["viewfinder-height-indexed"] = height;
-        doc["viewfinder-top-indexed"] = top;
-        doc["viewfinder-left-indexed"] = left;
+        doc['viewfinder-width-indexed'] = width;
+        doc['viewfinder-height-indexed'] = height;
+        doc['viewfinder-top-indexed'] = top;
+        doc['viewfinder-left-indexed'] = left;
     }
 
     public static setupKeyframes(docs: Doc[], currTimecode: number, makeAppear: boolean = false) {
         docs.forEach(doc => {
             if (doc.appearFrame === undefined) doc.appearFrame = currTimecode;
-            if (!doc["opacity-indexed"]) { // opacity is unlike other fields because it's value should not be undefined before it appears to enable it to fade-in
-                doc["opacity-indexed"] = new List<number>(numberRange(currTimecode + 1).map(t => !doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1));
+            if (!doc['opacity-indexed']) {
+                // opacity is unlike other fields because it's value should not be undefined before it appears to enable it to fade-in
+                doc['opacity-indexed'] = new List<number>(numberRange(currTimecode + 1).map(t => (!doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1)));
             }
-            CollectionFreeFormDocumentView.animFields.forEach(val => doc[val] = ComputedField.MakeInterpolated(val, "activeFrame", doc, currTimecode));
-            doc.activeFrame = ComputedField.MakeFunction("self.context?._currentFrame||0");
-            doc.dataTransition = "inherit";
+            CollectionFreeFormDocumentView.animFields.forEach(val => (doc[val] = ComputedField.MakeInterpolated(val, 'activeFrame', doc, currTimecode)));
+            doc.activeFrame = ComputedField.MakeFunction('self.context?._currentFrame||0');
+            doc.dataTransition = 'inherit';
         });
     }
 
@@ -131,7 +162,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 topDoc.x = spt[0];
                 topDoc.y = spt[1];
                 this.props.removeDocument?.(topDoc);
-                this.props.addDocTab(topDoc, "inParent");
+                this.props.addDocTab(topDoc, 'inParent');
             } else {
                 const spt = this.screenToLocalTransform().inverse().transformPoint(0, 0);
                 const fpt = screenXf.transformPoint(spt[0], spt[1]);
@@ -141,14 +172,14 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             }
             setTimeout(() => SelectionManager.SelectView(DocumentManager.Instance.getDocumentView(topDoc, container)!, false), 0);
         }
-    }
+    };
 
     nudge = (x: number, y: number) => {
         this.props.Document.x = NumCast(this.props.Document.x) + x;
         this.props.Document.y = NumCast(this.props.Document.y) + y;
-    }
-    panelWidth = () => (this.sizeProvider?.width || this.props.PanelWidth?.());
-    panelHeight = () => (this.sizeProvider?.height || this.props.PanelHeight?.());
+    };
+    panelWidth = () => this.sizeProvider?.width || this.props.PanelWidth?.();
+    panelHeight = () => this.sizeProvider?.height || this.props.PanelHeight?.();
     screenToLocalTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y);
     focusDoc = (doc: Doc) => this.props.focus(doc);
     returnThis = () => this;
@@ -163,24 +194,27 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             PanelHeight: this.panelHeight,
         };
         const background = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-        const mixBlendMode = StrCast(this.layoutDoc.mixBlendMode) as any || (typeof background === "string" && background && (!background.startsWith("linear") && DashColor(background).alpha() !== 1) ? "multiply" : undefined);
-        return <div className={"collectionFreeFormDocumentView-container"}
-            style={{
-                outline: this.Highlight ? "orange solid 2px" : "",
-                width: this.panelWidth(),
-                height: this.panelHeight(),
-                transform: this.transform,
-                transformOrigin: '50% 50%',
-                transition: this.dataProvider?.transition ?? (this.props.dataTransition ? this.props.dataTransition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.dataTransition)),
-                zIndex: this.ZInd,
-                mixBlendMode: mixBlendMode,
-                display: this.ZInd === -99 ? "none" : undefined
-            }} >
-            {this.props.renderCutoffProvider(this.props.Document) ?
-                <div style={{ position: "absolute", width: this.panelWidth(), height: this.panelHeight(), background: "lightGreen" }} />
-                :
-                <DocumentView {...divProps} ref={action((r: DocumentView | null) => this._contentView = r)} />
-            }
-        </div>;
+        const mixBlendMode = (StrCast(this.layoutDoc.mixBlendMode) as any) || (typeof background === 'string' && background && !background.startsWith('linear') && DashColor(background).alpha() !== 1 ? 'multiply' : undefined);
+        return (
+            <div
+                className={'collectionFreeFormDocumentView-container'}
+                style={{
+                    outline: this.Highlight ? 'orange solid 2px' : '',
+                    width: this.panelWidth(),
+                    height: this.panelHeight(),
+                    transform: this.transform,
+                    transformOrigin: '50% 50%',
+                    transition: this.dataProvider?.transition ?? (this.props.dataTransition ? this.props.dataTransition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.dataTransition)),
+                    zIndex: this.ZInd,
+                    mixBlendMode: mixBlendMode,
+                    display: this.ZInd === -99 ? 'none' : undefined,
+                }}>
+                {this.props.renderCutoffProvider(this.props.Document) ? (
+                    <div style={{ position: 'absolute', width: this.panelWidth(), height: this.panelHeight(), background: 'lightGreen' }} />
+                ) : (
+                    <DocumentView {...divProps} ref={action((r: DocumentView | null) => (this._contentView = r))} />
+                )}
+            </div>
+        );
     }
 }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index f87581875..f9ef85595 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1640,8 +1640,8 @@ export class DocumentView extends React.Component<DocumentViewProps> {
 
     render() {
         TraceMobx();
-        const xshift = () => (this.props.Document.isInkMask ? InkingStroke.MaskDim : Math.abs(this.Xshift) <= 0.001 ? this.props.PanelWidth() : undefined);
-        const yshift = () => (this.props.Document.isInkMask ? InkingStroke.MaskDim : Math.abs(this.Yshift) <= 0.001 ? this.props.PanelHeight() : undefined);
+        const xshift = () => (this.props.Document.isInkMask && !this.props.LayoutTemplateString && !this.props.LayoutTemplate?.() ? InkingStroke.MaskDim : Math.abs(this.Xshift) <= 0.001 ? this.props.PanelWidth() : undefined);
+        const yshift = () => (this.props.Document.isInkMask && !this.props.LayoutTemplateString && !this.props.LayoutTemplate?.() ? InkingStroke.MaskDim : Math.abs(this.Yshift) <= 0.001 ? this.props.PanelHeight() : undefined);
         const isPresTreeElement: boolean = this.props.treeViewDoc?.type === DocumentType.PRES;
         const isButton: boolean = this.props.Document.type === DocumentType.FONTICON || this.props.Document._viewType === CollectionViewType.Linear;
         return (
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 6e5eb3300..3bbdce1e4 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -29,10 +29,11 @@ import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentVie
 import { FieldView, FieldViewProps } from '../FieldView';
 import './PresBox.scss';
 import { PresEffect, PresMovement, PresStatus } from './PresEnums';
+import { CollectionFreeFormViewChrome } from '../../collections/CollectionMenu';
 
 export interface PinProps {
     audioRange?: boolean;
-    setPosition?: boolean;
+    activeFrame?: number;
     hidePresBox?: boolean;
     pinWithView?: PinViewProps;
     pinDocView?: boolean; // whether the current view specs of the document should be saved the pinned document
@@ -509,7 +510,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         this.childDocs.forEach((doc, index) => {
             const curDoc = Cast(doc, Doc, null);
             const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
-            if (tagDoc) tagDoc.opacity = 1;
+            //if (tagDoc) tagDoc.opacity = 1;
             const itemIndexes: number[] = this.getAllIndexes(this.tagDocs, tagDoc);
             const curInd: number = itemIndexes.indexOf(index);
             if (tagDoc === this.layoutDoc.presCollection) {
@@ -519,7 +520,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 } else if (curDoc.presHideBefore) {
                     if (index > this.itemIndex) {
                         tagDoc.opacity = 0;
-                    } else if (!curDoc.presHideAfter) {
+                    } else if (index === this.itemIndex || !curDoc.presHideAfter) {
                         tagDoc.opacity = 1;
                     }
                 }
@@ -527,7 +528,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 } else if (curDoc.presHideAfter) {
                     if (index < this.itemIndex) {
                         tagDoc.opacity = 0;
-                    } else if (!curDoc.presHideBefore) {
+                    } else if (index === this.itemIndex || !curDoc.presHideBefore) {
                         tagDoc.opacity = 1;
                     }
                 }
@@ -821,17 +822,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         if (doc.presPinView || doc.presentationTargetDoc === this.layoutDoc.presCollection) setTimeout(() => this.updateCurrentPresentation(context), 0);
         else this.updateCurrentPresentation(context);
 
-        if (this.activeItem.setPosition && this.activeItem.y !== undefined && this.activeItem.x !== undefined && this.targetDoc.x !== undefined && this.targetDoc.y !== undefined) {
-            const timer = (ms: number) => new Promise(res => (this._presTimer = setTimeout(res, ms)));
-            const time = 10;
-            const ydiff = NumCast(this.activeItem.y) - NumCast(this.targetDoc.y);
-            const xdiff = NumCast(this.activeItem.x) - NumCast(this.targetDoc.x);
-
-            for (let i = 0; i < time; i++) {
-                this.targetDoc.x = NumCast(this.targetDoc.x) + xdiff / time;
-                this.targetDoc.y = NumCast(this.targetDoc.y) + ydiff / time;
-                await timer(0.1);
-            }
+        if (this.activeItem.presActiveFrame !== undefined) {
+            const context = DocCast(DocCast(this.activeItem.presentationTargetDoc).context);
+            context && CollectionFreeFormViewChrome.gotoKeyFrame(context, NumCast(this.activeItem.presActiveFrame));
         }
     };
 
-- 
cgit v1.2.3-70-g09d2

