From 484e85d4448cd56d096a1b234d2a98a638e08c77 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 12 Sep 2024 13:40:10 -0400
Subject: fixed removing a face image from a face doc

---
 src/client/views/search/FaceRecognitionHandler.tsx | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'src/client/views/search/FaceRecognitionHandler.tsx')

diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx
index 4f6f5d314..636a44984 100644
--- a/src/client/views/search/FaceRecognitionHandler.tsx
+++ b/src/client/views/search/FaceRecognitionHandler.tsx
@@ -119,8 +119,7 @@ export class FaceRecognitionHandler {
      * @param faceDoc - unique face Doc
      */
     public static UniqueFaceRemoveFaceImage = (faceAnno: Doc, faceDoc: Doc) => {
-        Doc.RemoveDocFromList(faceDoc[DocData], 'face_annos', faceAnno);
-        faceAnno.face = undefined;
+        FaceRecognitionHandler.ImageDocFaceAnnos(faceAnno).forEach(face => Doc.RemoveDocFromList(faceDoc[DocData], 'face_annos', face) && (face.face = undefined));
     };
 
     constructor() {
-- 
cgit v1.2.3-70-g09d2


From bb1f4c62071987cc59461a8ce53522fa7a9036cc Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 12 Sep 2024 14:42:10 -0400
Subject: changed closing of face rectangles to hide them.  added Shift+click
 of tags button to show face rectangles.

---
 src/client/documents/Documents.ts                          |  1 +
 src/client/views/DocumentButtonBar.tsx                     | 14 +++++++++-----
 src/client/views/DocumentDecorations.tsx                   |  7 ++++---
 src/client/views/TagsView.tsx                              |  6 +++---
 .../views/collections/collectionFreeForm/ImageLabelBox.tsx |  4 ++--
 src/client/views/nodes/formattedText/RichTextRules.ts      |  2 +-
 src/client/views/search/FaceRecognitionHandler.tsx         |  3 +++
 7 files changed, 23 insertions(+), 14 deletions(-)

(limited to 'src/client/views/search/FaceRecognitionHandler.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index fbdf361dd..89356072a 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -273,6 +273,7 @@ export class DocumentOptions {
     _layout_showTitle?: string; // field name to display in header (:hover is an optional suffix)
     _layout_showSidebar?: BOOLt = new BoolInfo('whether an annotationsidebar should be displayed for text docuemnts');
     _layout_showCaption?: string; // which field to display in the caption area.  leave empty to have no caption
+    _layout_showTags?: BOOLt = new BoolInfo('whether to show the list of document tags at the bottom of a DocView');
 
     _chromeHidden?: BOOLt = new BoolInfo('whether the editing chrome for a document is hidden');
     hideClickBehaviors?: BOOLt = new BoolInfo('whether to hide click behaviors in context menu');
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 785e69f84..f14fd033b 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -9,7 +9,7 @@ import * as React from 'react';
 import { FaEdit } from 'react-icons/fa';
 import { returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../ClientUtils';
 import { emptyFunction } from '../../Utils';
-import { Doc } from '../../fields/Doc';
+import { Doc, DocListCast } from '../../fields/Doc';
 import { Cast, DocCast } from '../../fields/Types';
 import { DocUtils, IsFollowLinkScript } from '../documents/DocUtils';
 import { CalendarManager } from '../util/CalendarManager';
@@ -270,12 +270,16 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
                 <div
                     className="documentButtonBar-icon"
                     style={{ color: 'white' }}
-                    onClick={() => {
-                        const showing = DocumentView.Selected().some(dv => dv.dataDoc.showTags);
+                    onClick={undoable(e => {
+                        const showing = DocumentView.Selected().some(dv => dv.layoutDoc._layout_showTags);
                         DocumentView.Selected().forEach(dv => {
-                            dv.dataDoc.showTags = !showing;
+                            dv.layoutDoc._layout_showTags = !showing;
+                            if (e.shiftKey)
+                                DocListCast(dv.Document[Doc.LayoutFieldKey(dv.Document) + '_annotations']).forEach(doc => {
+                                    if (doc.face) doc.hidden = showing;
+                                });
                         });
-                    }}>
+                    }, 'show Doc tags')}>
                     <FontAwesomeIcon className="documentdecorations-icon" icon="tag" />
                 </div>
             </Tooltip>
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 118a5bd3d..907bb2614 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -232,7 +232,8 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
                         if (iconViewDoc.activeFrame) {
                             iconViewDoc.opacity = 0; // bcz: hacky ... allows inkMasks and other documents to be "turned off" without removing them from the animated collection which allows them to function properly in a presenation.
                         } else {
-                            iconView._props.removeDocument?.(iconView.Document);
+                            if (iconView.Document.annotationOn && iconView.Document.face) iconView.Document.hidden = true;
+                            else iconView._props.removeDocument?.(iconView.Document);
                         }
                     });
                     views.forEach(DocumentView.DeselectView);
@@ -836,7 +837,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
                                 <div
                                     className="link-button-container"
                                     style={{
-                                        top: DocumentView.Selected().length > 1 ? 0 : `${doc[DocData].showTags ? 4 + seldocview.TagPanelHeight : 4}px`,
+                                        top: DocumentView.Selected().length > 1 ? 0 : `${doc._layout_showTags ? 4 + seldocview.TagPanelHeight : 4}px`,
                                         transform: `translate(${-this._resizeBorderWidth / 2 + 10}px, ${this._resizeBorderWidth + bounds.b - bounds.y + this._titleHeight}px) `,
                                     }}>
                                     <DocumentButtonBar views={() => DocumentView.Selected()} />
@@ -845,7 +846,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
                             <div
                                 className="documentDecorations-tagsView"
                                 style={{
-                                    top: `${doc[DocData].showTags ? 4 + seldocview.TagPanelHeight : 4}px`,
+                                    top: `${doc._layout_showTags ? 4 + seldocview.TagPanelHeight : 4}px`,
                                     transform: `translate(${-this._resizeBorderWidth / 2 + 10}px, ${this._resizeBorderWidth + bounds.b - bounds.y + this._titleHeight}px) `,
                                 }}>
                                 {DocumentView.Selected().length > 1 ? <TagsView Views={DocumentView.Selected()} /> : null}
diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx
index ae9d42749..0b303f6f5 100644
--- a/src/client/views/TagsView.tsx
+++ b/src/client/views/TagsView.tsx
@@ -172,12 +172,12 @@ export class TagItem extends ObservableReactComponent<TagItemProps> {
             docData.data = new List<Doc>(newEmbeddings);
             docData.title = this._props.tag;
             docData.tags = new List<string>([this._props.tag]);
-            docData.showTags = true;
             docData.freeform_fitContentsToBox = true;
             doc._freeform_panX = doc._freeform_panY = 0;
             doc._width = 900;
             doc._height = 900;
             doc.layout_fitWidth = true;
+            doc._layout_showTags = true;
             return doc;
         })(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true));
         newEmbeddings.forEach(embed => Doc.SetContainer(embed, newCollection));
@@ -322,7 +322,7 @@ export class TagsView extends ObservableReactComponent<TagViewProps> {
     );
 
     /**
-     * When 'showTags' is set on a Doc, this displays a wrapping panel of tagItemViews corresponding to all the tags set on the Doc).
+     * When 'layout_showTags' is set on a Doc, this displays a wrapping panel of tagItemViews corresponding to all the tags set on the Doc).
      * When the dropdown is clicked, this will toggle an extended UI that allows additional tags to be added/removed.
      */
     render() {
@@ -336,7 +336,7 @@ export class TagsView extends ObservableReactComponent<TagViewProps> {
         );
         this._panelHeightDirty;
 
-        return !this.View.Document.showTags && this._props.Views.length === 1 ? null : (
+        return !this.View.Document._layout_showTags && this._props.Views.length === 1 ? null : (
             <div
                 className="tagsView-container"
                 ref={r => r && new ResizeObserver(action(() => this._props.Views.length === 1 && (this.View.TagPanelHeight = Math.max(0, (r?.getBoundingClientRect().height ?? 0) - this.InsetDist)))).observe(r)}
diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx
index e419e522c..033d1590d 100644
--- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx
+++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx
@@ -139,9 +139,9 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
     toggleDisplayInformation = () => {
         this._displayImageInformation = !this._displayImageInformation;
         if (this._displayImageInformation) {
-            this._selectedImages.forEach(doc => (doc[DocData].showTags = true));
+            this._selectedImages.forEach(doc => (doc._layout_showTags = true));
         } else {
-            this._selectedImages.forEach(doc => (doc[DocData].showTags = false));
+            this._selectedImages.forEach(doc => (doc._layout_showTags = false));
         }
     };
 
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index e0d6c7c05..0ef67b4be 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -404,7 +404,7 @@ export class RichTextRules {
                 if (!tags.includes(tag)) {
                     tags.push(tag);
                     this.Document[DocData].tags = new List<string>(tags);
-                    this.Document[DocData].showTags = true;
+                    this.Document._layout_showTags = true;
                 }
                 const fieldView = state.schema.nodes.dashField.create({ fieldKey: '#' + tag });
                 return state.tr
diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx
index 636a44984..c507e54b6 100644
--- a/src/client/views/search/FaceRecognitionHandler.tsx
+++ b/src/client/views/search/FaceRecognitionHandler.tsx
@@ -220,6 +220,7 @@ export class FaceRecognitionHandler {
                             .then(imgDocFaceDescriptions => {  // For each face detected, find a match.
                                 const annos = [] as Doc[];
                                 const scale = NumCast(imgDoc.data_nativeWidth) / img.width;
+                                const showTags= imgDocFaceDescriptions.length > 1;
                                 imgDocFaceDescriptions.forEach((fd, i) => {
                                     const faceDescriptor = new List<number>(Array.from(fd.descriptor));
                                     const matchedUniqueFace = this.findMatchingFaceDoc(fd.descriptor) ?? this.createUniqueFaceDoc(activeDashboard);
@@ -233,12 +234,14 @@ export class FaceRecognitionHandler {
                                         y: fd.alignedRect.box.top * scale,
                                         _width: fd.alignedRect.box.width * scale,
                                         _height: fd.alignedRect.box.height * scale,
+                                        _layout_showTags: showTags
                                     })
                                     FaceRecognitionHandler.UniqueFaceAddFaceImage(faceAnno, matchedUniqueFace); // add image/faceDescriptor to matched unique face
                                     annos.push(faceAnno);
                                 });
 
                                 imgDoc[DocData].data_annotations = new List<Doc>(annos);
+                                imgDoc._layout_showTags = annos.length > 0;
                                 return imgDocFaceDescriptions;
                             })
                 ); // prettier-ignore
-- 
cgit v1.2.3-70-g09d2

