From 9e809f8748d1812bb03ec6471aa6f97467f8f75a Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 23 Apr 2024 16:20:08 -0400
Subject: fixes for rich text menu updates and setting parameters on text doc
 vs within in RTF. Lots of lint cleanup.

---
 src/client/views/StyleProvider.tsx | 108 ++++++++++++++++++++++---------------
 1 file changed, 66 insertions(+), 42 deletions(-)

(limited to 'src/client/views/StyleProvider.tsx')

diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 75f1a7d80..3697aa010 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -49,6 +49,7 @@ export enum StyleProp {
     TitleHeight = 'titleHeight', // Height of Title area
     ShowTitle = 'layout_showTitle', // whether to display a title on a Document (optional :hover suffix)
     BorderPath = 'customBorder', // border path for document view
+    FontColor = 'fontColor', // color o tet
     FontSize = 'fontSize', // size of text font
     FontFamily = 'fontFamily', // font family of text
     FontWeight = 'fontWeight', // font weight of text
@@ -109,13 +110,35 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
     const layoutDoc = doc ? Doc.Layout(doc) : doc;
     const isOpen = property.includes(':open');
     const boxBackground = property.includes(':box');
-    const fieldKey = props?.fieldKey ? props.fieldKey + '_' : isCaption ? 'caption_' : '';
-    const isInk = () => layoutDoc?._layout_isSvg && !props?.LayoutTemplateString;
+    const {
+        fieldKey: fieldKeyProp,
+        styleProvider,
+        pointerEvents,
+        isGroupActive,
+        isDocumentActive,
+        containerViewPath,
+        childFilters,
+        hideCaptions,
+        // eslint-disable-next-line camelcase
+        layout_showTitle,
+        childFiltersByRanges,
+        renderDepth,
+        docViewPath,
+        DocumentView,
+        LayoutTemplateString,
+        disableBrushing,
+        NativeDimScaling,
+        PanelWidth,
+        PanelHeight,
+    } = props || {}; // extract props that are not shared between fieldView and documentView props.
+    const fieldKey = fieldKeyProp ? fieldKeyProp + '_' : isCaption ? 'caption_' : '';
+    const isInk = () => layoutDoc?._layout_isSvg && !LayoutTemplateString;
     const lockedPosition = () => doc && BoolCast(doc._lockedPosition);
-    const titleHeight = () => props?.styleProvider?.(doc, props, StyleProp.TitleHeight);
-    const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor + ':nonTransparent' + (isNonTransparentLevel + 1));
-    const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity);
-    const layoutShowTitle = () => props?.styleProvider?.(doc, props, StyleProp.ShowTitle);
+    const titleHeight = () => styleProvider?.(doc, props, StyleProp.TitleHeight);
+    const backgroundCol = () => styleProvider?.(doc, props, StyleProp.BackgroundColor + ':nonTransparent' + (isNonTransparentLevel + 1));
+    const color = () => styleProvider?.(doc, props, StyleProp.Color);
+    const opacity = () => styleProvider?.(doc, props, StyleProp.Opacity);
+    const layoutShowTitle = () => styleProvider?.(doc, props, StyleProp.ShowTitle);
     // prettier-ignore
     switch (property.split(':')[0]) {
         case StyleProp.TreeViewIcon: {
@@ -137,7 +160,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
         }
         case StyleProp.Highlighting:
             if (doc && (Doc.IsSystem(doc) || doc.type === DocumentType.FONTICON)) return undefined;            
-            if (doc && !doc.layout_disableBrushing && !props?.disableBrushing) {
+            if (doc && !doc.layout_disableBrushing && !disableBrushing) {
                 const selected = Array.from(doc?.[DocViews]??[]).filter(dv => dv.IsSelected).length;
                 const highlightIndex = Doc.GetBrushHighlightStatus(doc) || (selected ? Doc.DocBrushStatus.selfBrushed : 0);
                 const highlightColor = ['transparent', 'rgb(68, 118, 247)', selected ? "black" : 'rgb(68, 118, 247)', 'orange', 'lightBlue'][highlightIndex];
@@ -152,26 +175,27 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
                 }
             }
             return  undefined;
-        case StyleProp.DocContents:return undefined;
-        case StyleProp.WidgetColor:return isAnnotated ? Colors.LIGHT_BLUE : 'dimgrey';
-        case StyleProp.Opacity:    return props?.LayoutTemplateString?.includes(KeyValueBox.name) ? 1 : doc?.text_inlineAnnotations ? 0 :  Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
-        case StyleProp.FontSize:   return StrCast(doc?.[fieldKey + 'fontSize'],   StrCast(Doc.UserDoc().fontSize));
-        case StyleProp.FontFamily: return StrCast(doc?.[fieldKey + 'fontFamily'], StrCast(Doc.UserDoc().fontFamily));
-        case StyleProp.FontWeight: return StrCast(doc?.[fieldKey + 'fontWeight'],  StrCast(Doc.UserDoc().fontWeight));
-        case StyleProp.FillColor:  return StrCast(doc?._fillColor, StrCast(doc?.fillColor, StrCast(doc?.backgroundColor, 'transparent')));
-        case StyleProp.ShowCaption:return props?.hideCaptions || doc?._type_collection === CollectionViewType.Carousel ? undefined: StrCast(doc?._layout_showCaption);
-        case StyleProp.TitleHeight:return Math.min(4,(props?.DocumentView?.().screenToViewTransform().Scale ?? 1)) * NumCast(Doc.UserDoc().headerHeight,30);
+        case StyleProp.DocContents:  return undefined;
+        case StyleProp.WidgetColor:  return isAnnotated ? Colors.LIGHT_BLUE : 'dimgrey';
+        case StyleProp.Opacity:      return LayoutTemplateString?.includes(KeyValueBox.name) ? 1 : doc?.text_inlineAnnotations ? 0 :  Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
+        case StyleProp.FontColor:    return StrCast(doc?.[fieldKey + 'fontColor'],  StrCast(Doc.UserDoc().fontColor, color()));
+        case StyleProp.FontSize:     return StrCast(doc?.[fieldKey + 'fontSize'],   StrCast(Doc.UserDoc().fontSize));
+        case StyleProp.FontFamily:   return StrCast(doc?.[fieldKey + 'fontFamily'], StrCast(Doc.UserDoc().fontFamily));
+        case StyleProp.FontWeight:   return StrCast(doc?.[fieldKey + 'fontWeight'], StrCast(Doc.UserDoc().fontWeight));
+        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,(DocumentView?.().screenToViewTransform().Scale ?? 1)) * NumCast(Doc.UserDoc().headerHeight,30);
         case StyleProp.ShowTitle:
             return (
                 (doc &&
-                    !(props?.DocumentView?.().ComponentView instanceof CollectionSchemaView) &&
-                    !props?.LayoutTemplateString &&
+                    !(DocumentView?.().ComponentView instanceof CollectionSchemaView) &&
+                    !LayoutTemplateString &&
                     !doc.presentation_targetDoc &&
-                    !props?.LayoutTemplateString?.includes(KeyValueBox.name) &&
-                    props?.layout_showTitle?.() !== '' &&
+                    !LayoutTemplateString?.includes(KeyValueBox.name) &&
+                    layout_showTitle?.() !== '' &&
                     StrCast(
                         doc._layout_showTitle,
-                        props?.layout_showTitle?.() ||
+                        layout_showTitle?.() ||
                             (!Doc.IsSystem(doc) && [DocumentType.COL, DocumentType.FUNCPLOT, DocumentType.LABEL, DocumentType.RTF, DocumentType.IMG, DocumentType.VID].includes(doc.type as any)
                                 ? doc.author === ClientUtils.CurrentUserEmail()
                                     ? StrCast(Doc.UserDoc().layout_showTitle)
@@ -195,15 +219,15 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
         }
         case StyleProp.BorderPath: {
             const borderPath = Doc.IsComicStyle(doc) &&
-                props?.renderDepth &&
-                !doc?.layout_isSvg && { path: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0), fill: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0, 0.08), width: 3 };
+                renderDepth &&
+                !doc?.layout_isSvg && { path: wavyBorderPath(PanelWidth?.() || 0, PanelHeight?.() || 0), fill: wavyBorderPath(PanelWidth?.() || 0, PanelHeight?.() || 0, 0.08), width: 3 };
                 return !borderPath
                     ? null
                     : {
                         clipPath: `path('${borderPath.path}')`,
                         jsx: (
                             <div key="border2" className="documentView-customBorder" style={{ pointerEvents: 'none' }}>
-                                <svg style={{ overflow: 'visible', height: '100%' }} viewBox={`0 0 ${props.PanelWidth()} ${props.PanelHeight()}`}>
+                                <svg style={{ overflow: 'visible', height: '100%' }} viewBox={`0 0 ${PanelWidth?.()} ${PanelHeight?.()}`}>
                                     <path d={borderPath.path} style={{ stroke: 'black', fill: 'transparent', strokeWidth: borderPath.width }} />
                                 </svg>
                             </div>
@@ -251,13 +275,13 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
                             ? undefined
                             : doc?._type_collection === CollectionViewType.Stacking ?
                             (Colors.DARK_GRAY)
-                            : Cast((props?.renderDepth || 0) > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (Colors.MEDIUM_GRAY));
+                            : Cast((renderDepth || 0) > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (Colors.MEDIUM_GRAY));
                     break;
                 // if (doc._type_collection !== CollectionViewType.Freeform && doc._type_collection !== CollectionViewType.Time) return "rgb(62,62,62)";
                 default: docColor = docColor || (Colors.WHITE);
             }
-            if (isNonTransparent && isNonTransparentLevel < 9 && (!docColor || docColor === 'transparent') && doc?.embedContainer && props?.styleProvider) {
-                return props.styleProvider(DocCast(doc.embedContainer), props, StyleProp.BackgroundColor+":nonTransparent"+(isNonTransparentLevel+1));
+            if (isNonTransparent && isNonTransparentLevel < 9 && (!docColor || docColor === 'transparent') && doc?.embedContainer && styleProvider) {
+                return styleProvider(DocCast(doc.embedContainer), props, StyleProp.BackgroundColor+":nonTransparent"+(isNonTransparentLevel+1));
             }
             return (docColor && !doc) ? DashColor(docColor).fade(0.5).toString() : docColor;
         }
@@ -271,7 +295,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
                         doc?.layout_boxShadow,
                         doc?._type_collection === CollectionViewType.Pile
                             ? '4px 4px 10px 2px'
-                            : lockedPosition() || doc?.isGroup || props?.LayoutTemplateString
+                            : lockedPosition() || doc?.isGroup || LayoutTemplateString
                             ? undefined // groups have no drop shadow -- they're supposed to be "invisible".  LayoutString's imply collection is being rendered as something else (e.g., title of a Slide)
                             : `${Colors.DARK_GRAY} ${StrCast(doc.layout_boxShadow, '0.2vw 0.2vw 0.8vw')}`
                     );
@@ -282,10 +306,10 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
                 default:
                     return doc.z
                         ? `#9c9396  ${StrCast(doc?.layout_boxShadow, '10px 10px 0.9vw')}` // if it's a floating doc, give it a big shadow
-                        : props?.containerViewPath?.().lastElement()?.Document._freeform_useClusters
-                        ? `${backgroundCol()} ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (props?.NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
+                        : containerViewPath?.().lastElement()?.Document._freeform_useClusters
+                        ? `${backgroundCol()} ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
                         : NumCast(doc.group, -1) !== -1
-                        ? `gray ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (props?.NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
+                        ? `gray ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
                         : lockedPosition()
                         ? undefined // if it's a background & has a cluster color, make the shadow spread really big
                         : fieldKey.includes('_inline')  // if doc is an inline document in a text box
@@ -296,14 +320,14 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
             }
         }
         case StyleProp.PointerEvents:
-            if (StrCast(doc?.pointerEvents) && !props?.LayoutTemplateString?.includes(KeyValueBox.name)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
-            if (props?.LayoutTemplateString?.includes(KeyValueBox.name)) return 'all';
+            if (StrCast(doc?.pointerEvents) && !LayoutTemplateString?.includes(KeyValueBox.name)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
+            if (LayoutTemplateString?.includes(KeyValueBox.name)) return 'all';
             if (SnappingManager.ExploreMode || doc?.layout_unrendered) return isInk() ? 'visiblePainted' : 'all';
-            if (props?.pointerEvents?.() === 'none') return 'none';
+            if (pointerEvents?.() === 'none') return 'none';
             if (opacity() === 0) return 'none';
-            if (props?.isGroupActive?.() ) return isInk()  ? 'visiblePainted':  (doc?.
+            if (isGroupActive?.() ) return isInk()  ? 'visiblePainted':  (doc?.
                 isGroup )? undefined: 'all' 
-            if (props?.isDocumentActive?.()) return isInk() ? 'visiblePainted' : 'all';
+            if (isDocumentActive?.()) return isInk() ? 'visiblePainted' : 'all';
             return undefined; // fixes problem with tree view elements getting pointer events when the tree view is not active
         case StyleProp.Decorations: {
             const lock = () => doc?.pointerEvents !== 'none' ? null : (
@@ -312,7 +336,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
                         </div>
                     );
             const paint = () => !doc?.onPaint ? null : (
-                        <div className={`styleProvider-paint${props?.DocumentView?.().IsSelected ? "-selected":""}`} onClick={e => togglePaintView(e, doc, props)}>
+                        <div className={`styleProvider-paint${DocumentView?.().IsSelected ? "-selected":""}`} onClick={e => togglePaintView(e, doc, props)}>
                             <FontAwesomeIcon icon='pen' size="lg" />
                         </div>
                     );
@@ -321,7 +345,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
                 const showFilterIcon =
                     StrListCast(doc?._childFilters).length || StrListCast(doc?._childFiltersByRanges).length
                         ? 'green' // #18c718bd' //'hasFilter'
-                        : props?.childFilters?.().filter(f => ClientUtils.IsRecursiveFilter(f) && f !== ClientUtils.noDragDocsFilter).length || props?.childFiltersByRanges().length
+                        : childFilters?.().filter(f => ClientUtils.IsRecursiveFilter(f) && f !== ClientUtils.noDragDocsFilter).length || childFiltersByRanges?.().length
                         ? 'orange' // 'inheritsFilter'
                         : undefined;
                 return !showFilterIcon ? null : (
@@ -353,7 +377,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
                                 "this view inherits filters from one of its parents"}
                             color={SettingsManager.userColor}
                             background={showFilterIcon}
-                            items={[ ...(dashView ? [dashView]: []), ...(props?.docViewPath?.()??[])]
+                            items={[ ...(dashView ? [dashView]: []), ...(docViewPath?.()??[])]
                                     .filter(dv => StrListCast(dv?.Document.childFilters).length || StrListCast(dv?.Document.childRangeFilters).length)
                                     .map(dv => ({
                                 text: StrCast(dv?.Document.title),
@@ -365,9 +389,9 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
                 );
             };
             const audio = () => {
-                const audioAnnoState = (doc: Doc) => StrCast(doc.audioAnnoState, AudioAnnoState.stopped);
-                const audioAnnosCount = (doc: Doc) => StrListCast(doc[fieldKey + 'audioAnnotations']).length;
-                if (!doc || props?.renderDepth === -1 || !audioAnnosCount(doc)) return null;
+                const audioAnnoState = (audioDoc: Doc) => StrCast(audioDoc.audioAnnoState, AudioAnnoState.stopped);
+                const audioAnnosCount = (audioDoc: Doc) => StrListCast(audioDoc[fieldKey + 'audioAnnotations']).length;
+                if (!doc || renderDepth === -1 || !audioAnnosCount(doc)) return null;
                 const audioIconColors: { [key: string]: string } = { playing: 'green', stopped: 'blue' };
                 return (
                     <Tooltip title={<div>{StrListCast(doc[fieldKey + 'audioAnnotations_text']).lastElement()}</div>}>
-- 
cgit v1.2.3-70-g09d2

