aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2025-04-08 14:26:56 -0400
committerbobzel <zzzman@gmail.com>2025-04-08 14:26:56 -0400
commitd60734c4cdd8fe64d50e3de32182cc6b04afc747 (patch)
treef40568f613580ebf8a712d4a4ef1674d7edd1b36
parent840d5b3b3a0e907b0ca74abb9ad57e09bfbc0b76 (diff)
fixed gptImageLabel calls and added ImageCastToNameType to deal with filenames with '.'s in them. fixed vertical centered text.
-rw-r--r--src/client/apis/gpt/GPT.ts1
-rw-r--r--src/client/documents/DocUtils.ts4
-rw-r--r--src/client/documents/DocumentTypes.ts19
-rw-r--r--src/client/documents/Documents.ts8
-rw-r--r--src/client/util/CurrentUserUtils.ts87
-rw-r--r--src/client/views/GlobalKeyHandler.ts9
-rw-r--r--src/client/views/MainView.tsx21
-rw-r--r--src/client/views/PropertiesButtons.tsx2
-rw-r--r--src/client/views/collections/CollectionView.tsx1
-rw-r--r--src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx20
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx5
-rw-r--r--src/client/views/nodes/FontIconBox/FontIconBox.tsx4
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx2
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx6
-rw-r--r--src/client/views/search/FaceRecognitionHandler.tsx4
-rw-r--r--src/fields/Doc.ts2
-rw-r--r--src/fields/Types.ts8
18 files changed, 97 insertions, 110 deletions
diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts
index 140aebfe0..9cb47995c 100644
--- a/src/client/apis/gpt/GPT.ts
+++ b/src/client/apis/gpt/GPT.ts
@@ -271,7 +271,6 @@ const gptImageLabel = async (src: string, prompt: string): Promise<string> => {
],
});
if (response.choices[0].message.content) {
- console.log(response.choices[0].message.content);
return response.choices[0].message.content;
}
return 'Missing labels';
diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts
index 69bf4815e..a657b673a 100644
--- a/src/client/documents/DocUtils.ts
+++ b/src/client/documents/DocUtils.ts
@@ -726,12 +726,12 @@ export namespace DocUtils {
: {
_width: width || BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 * 6 : 200,
_height: BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 : 35,
- _layout_centered: BoolCast(Doc.UserDoc()._layout_centered),
_layout_fitWidth: true,
_layout_autoHeight: true,
backgroundColor: StrCast(Doc.UserDoc().textBackgroundColor),
borderColor: Doc.UserDoc().borderColor as string,
borderWidth: Doc.UserDoc().borderWidth as number,
+ text_centered: BoolCast(Doc.UserDoc().textCentered),
text_fitBox: BoolCast(Doc.UserDoc().fitBox),
text_align: StrCast(Doc.UserDoc().textAlign),
text_fontColor: StrCast(Doc.UserDoc().fontColor),
@@ -752,12 +752,12 @@ export namespace DocUtils {
: {
_width: width || BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 * 6 : 200,
_height: BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 : 35,
- _layout_centered: BoolCast(Doc.UserDoc()._layout_centered),
_layout_fitWidth: true,
_layout_autoHeight: true,
backgroundColor: StrCast(Doc.UserDoc().textBackgroundColor),
borderColor: Doc.UserDoc().borderColor as string,
borderWidth: Doc.UserDoc().borderWidth as number,
+ text_centered: BoolCast(Doc.UserDoc().textCentered),
text_fitBox: BoolCast(Doc.UserDoc().fitBox),
text_align: StrCast(Doc.UserDoc().textAlign),
text_fontColor: StrCast(Doc.UserDoc().fontColor),
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 03626107f..dd0985182 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -47,25 +47,30 @@ export enum DocumentType {
JOURNAL = 'journal', // AARAV ADD
}
export enum CollectionViewType {
- Invalid = 'invalid',
+ // general collections
Freeform = 'freeform',
- Calendar = 'calendar',
Card = 'card',
Carousel = 'carousel',
Carousel3D = '3D Carousel',
- Docking = 'docking',
Grid = 'grid',
- Linear = 'linear',
- Map = 'map',
Masonry = 'masonry',
Multicolumn = 'multicolumn',
Multirow = 'multirow',
NoteTaking = 'notetaking',
- Pile = 'pileup',
Pivot = 'pivot',
Schema = 'schema',
Stacking = 'stacking',
- StackedTimeline = 'stacked timeline',
Time = 'time',
Tree = 'tree',
+ // under development
+ Calendar = 'calendar',
+ // special collections
+ Docking = 'docking',
+ Pile = 'pileup',
+ StackedTimeline = 'stacked timeline',
+ Linear = 'linear',
+ Invalid = 'invalid',
}
+
+export const specialCollectionTypes = [CollectionViewType.Docking, CollectionViewType.Pile, CollectionViewType.StackedTimeline, CollectionViewType.Linear, CollectionViewType.Invalid];
+export const standardViewTypes = Object.values(CollectionViewType).filter(key => !specialCollectionTypes.includes(key));
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f1655e3cf..bab9edf0e 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -283,7 +283,6 @@ export class DocumentOptions {
_layout_autoHeightMargins?: NUMt = new NumInfo('Margin heights to be added to the computed auto height of a Doc');
_layout_curPage?: NUMt = new NumInfo('current page of a PDF or other? paginated document', false);
_layout_currentTimecode?: NUMt = new NumInfo('the current timecode of a time-based document (e.g., current time of a video) value is in seconds', false);
- _layout_centered?: BOOLt = new BoolInfo('whether text should be vertically centered in Doc');
_layout_fitWidth?: BOOLt = new BoolInfo('whether document should scale its contents to fit its rendered width or not (e.g., for PDFviews)');
_layout_fieldKey?: STRt = new StrInfo('the field key containing the current layout definition', false);
_layout_enableAltContentUI?: BOOLt = new BoolInfo('whether to show alternate content button');
@@ -309,6 +308,7 @@ export class DocumentOptions {
text_fontSize?: string;
text_fontFamily?: string;
text_fontWeight?: string;
+ text_centered?: BOOLt = new BoolInfo('whether text should be vertically centered in Doc');
text_fitBox?: BOOLt = new BoolInfo("whether text box should be scaled to fit it's containing render box");
text_align?: STRt = new StrInfo('horizontal text alignment default', undefined, undefined, ['left', 'center', 'right']);
title_align?: STRt = new StrInfo('horizontal title alignment in label box', undefined, undefined, ['left', 'center', 'right']);
@@ -840,7 +840,7 @@ export namespace Docs {
return TextDocument(RichTextField.textToRtf(text, img?.[Id]), {
title, //
_layout_autoHeight: true,
- _layout_centered: true,
+ text_centered: true,
text_align: 'center',
_layout_fitWidth: true,
...opts,
@@ -1072,10 +1072,6 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Linear }, id);
}
- export function MapCollectionDocument(documents: Array<Doc>, options: DocumentOptions = {}) {
- return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Map });
- }
-
export function CarouselDocument(documents: Array<Doc>, options: DocumentOptions) {
return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Carousel });
}
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 3ce20fc7b..4c492cae0 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -15,7 +15,7 @@ import { SetCachedGroups, SharingPermissions } from "../../fields/util";
import { Gestures } from "../../pen-gestures/GestureTypes";
import { DocServer } from "../DocServer";
import { DocUtils, FollowLinkScript } from '../documents/DocUtils';
-import { CollectionViewType, DocumentType } from "../documents/DocumentTypes";
+import { CollectionViewType, DocumentType, standardViewTypes } from "../documents/DocumentTypes";
import { Docs, DocumentOptions, FInfo, FInfoFieldType } from "../documents/Documents";
import { DashboardView } from "../views/DashboardView";
import { OverlayView } from "../views/OverlayView";
@@ -481,22 +481,24 @@ pie title Minerals in my tap water
const badgeValue = "((len) => len && len !== '0' ? len: undefined)(docList(this.target?.data).filter(doc => !docList(this.target.viewed).includes(doc)).length.toString())";
const getActiveDashTrails = "Doc.ActiveDashboard?.myTrails";
return [
- { title: "Dashboards", toolTip: "Dashboards", target: this.setupDashboards(doc, "myDashboards"), ignoreClick: true, icon: "desktop", funcs: {hidden: "IsNoviceMode()"} },
- { title: "Search", toolTip: "Search ⌘F", target: this.setupSearcher(doc, "mySearcher"), ignoreClick: true, icon: "search", },
- { title: "Files", toolTip: "Files", target: this.setupFilesystem(doc, "myFilesystem"), ignoreClick: true, icon: "folder-open", },
- { title: "Tools", toolTip: "Tools", target: this.setupToolsBtnPanel(doc, "myTools"), ignoreClick: true, icon: "wrench", },
- { title: "Imports", toolTip: "Imports ⌘I", target: this.setupImportSidebar(doc, "myImports"), ignoreClick:false, icon: "upload", },
- { title: "Closed", toolTip: "Recently Closed", target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), ignoreClick: true, icon: "archive", hidden: true }, // this doc is hidden from the Sidebar, but it's still being used in MyFilesystem which ignores the hidden field
- { title: "Shared", toolTip: "Shared Docs", target: Doc.MySharedDocs, ignoreClick: true, icon: "users", funcs: {badgeValue: badgeValue}},
- { title: "Trails", toolTip: "Trails ⌘R", target: Doc.UserDoc(), ignoreClick: true, icon: "pres-trail", funcs: {target: getActiveDashTrails}},
- { title: "Image Grouper", toolTip: "Image Grouper", target: this.setupImageGrouper(doc, "myImageGrouper"), ignoreClick: true, icon: "folder-open", hidden: false },
- { title: "Faces", toolTip: "Unique Faces", target: this.setupFaceCollection(doc, "myFaceCollection"), ignoreClick: true, icon: "face-smile", hidden: false },
- { title: "User Doc", toolTip: "User Doc", target: this.setupUserDocView(doc, "myUserDocView"), ignoreClick: true, icon: "address-card",funcs: {hidden: "IsNoviceMode()"} },
+ { title: "Dashboards", toolTip: "Dashboards", target: this.setupDashboards(doc, "myDashboards"), icon: "desktop", funcs: {hidden: "IsNoviceMode()"} },
+ { title: "Search", toolTip: "Search ⌘F", target: this.setupSearcher(doc, "mySearcher"), icon: "search", },
+ { title: "Files", toolTip: "Files", target: this.setupFilesystem(doc, "myFilesystem"), icon: "folder-open", },
+ { title: "Tools", toolTip: "Tools", target: this.setupToolsBtnPanel(doc, "myTools"), icon: "wrench", },
+ { title: "Imports", toolTip: "Imports ⌘I", target: this.setupImportSidebar(doc, "myImports"), icon: "upload", },
+ { title: "Closed", toolTip: "Recently Closed", target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), icon: "archive", hidden: true }, // this doc is hidden from the Sidebar, but it's still being used in MyFilesystem which ignores the hidden field
+ { title: "Shared", toolTip: "Shared Docs", target: Doc.MySharedDocs, icon: "users", funcs: {badgeValue: badgeValue}},
+ { title: "Trails", toolTip: "Trails ⌘R", target: Doc.UserDoc(), icon: "pres-trail", funcs: {target: getActiveDashTrails}},
+ { title: "Image Grouper", toolTip: "Image Grouper", target: this.setupImageGrouper(doc, "myImageGrouper"), icon: "folder-open", hidden: false },
+ { title: "Faces", toolTip: "Unique Faces", target: this.setupFaceCollection(doc, "myFaceCollection"), icon: "face-smile", hidden: false },
+ { title: "User Doc", toolTip: "User Doc", target: this.setupUserDocView(doc, "myUserDocView"), icon: "address-card",funcs: {hidden: "IsNoviceMode()"} },
].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(this)'}}));
}
/// the empty panel that is filled with whichever left menu button's panel has been selected
static setupLeftSidebarPanel(doc: Doc, field="myLeftSidebarPanel") {
+ const panel = DocCast(doc[field]);
+ if (panel) panel.proto = undefined;
DocUtils.AssignDocField(doc, field, (opts) => Doc.assign(new Doc(), opts as {[key:string]: FieldType}), {title:"leftSidebarPanel", isSystem:true, undoIgnoreFields: new List<string>(['proto'])});
}
@@ -737,12 +739,12 @@ pie title Minerals in my tap water
}
static viewTools(): Button[] {
return [
- { title: "Tags", icon: "id-card", toolTip: "Toggle Tags display", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"toggle-tags",funcs: { }, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'} },
- { title: "Snap", icon: "th", toolTip: "Show Snap Lines", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"snaplines", funcs: { hidden: `!SelectedDocType("${CollectionViewType.Freeform}", this.expertMode)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
- { title: "Grid", icon: "border-all", toolTip: "Show Grid", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"grid", funcs: { hidden: `!SelectedDocType("${CollectionViewType.Freeform}", this.expertMode)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
- { title: "Fit All", icon: "object-group", toolTip:"Fit Docs to View (double tap to persist)",
- btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"viewAll", funcs: { hidden: `!SelectedDocType("${CollectionViewType.Freeform}", this.expertMode)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}', onDoubleClick: '{ return showFreeform(this.toolType, _readOnly_, true);}'}}, // Only when floating document is selected in freeform
- { title: "Clusters", icon: "braille", toolTip: "Show Doc Clusters", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"clusters", funcs: { hidden: `!SelectedDocType("${CollectionViewType.Freeform}", this.expertMode)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+ { title: "Tags", icon: "id-card", toolTip: "Toggle Tags display", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"toggle-tags",funcs: { }, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'} },
+ { title: "Snap", icon: "th", toolTip: "Show Snap Lines", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"snaplines", funcs: { hidden: `!SelectedDocType("${CollectionViewType.Freeform}", this.expertMode)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+ { title: "Grid", icon: "border-all", toolTip: "Show Grid", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"grid", funcs: { hidden: `!SelectedDocType("${CollectionViewType.Freeform}", this.expertMode)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+ { title: "Fit All", icon: "object-group", toolTip:"Fit Docs to View (double tap to persist)",
+ btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"viewAll", funcs: { hidden: `!SelectedDocType("${CollectionViewType.Freeform}", this.expertMode)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}', onDoubleClick: '{ return showFreeform(this.toolType, _readOnly_, true);}'}}, // Only when floating document is selected in freeform
+ { title: "Clusters", icon: "braille", toolTip: "Show Doc Clusters", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"clusters", funcs: { hidden: `!SelectedDocType("${CollectionViewType.Freeform}", this.expertMode)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
]
}
static textTools():Button[] {
@@ -760,14 +762,14 @@ pie title Minerals in my tap water
{ title: "Vcenter", toolTip: "Vertical center", btnType: ButtonType.ToggleButton, icon: "pallet", toolType:"vcent", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
{ title: "Align", toolTip: "Alignment", btnType: ButtonType.MultiToggleButton, toolType:"alignment",ignoreClick: true,
subMenu: [
- { title: "Left", toolTip: "Left align (Cmd-[)", btnType: ButtonType.ToggleButton, icon: "align-left", toolType:"left", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
- { title: "Center", toolTip: "Center align (Cmd-\\)",btnType: ButtonType.ToggleButton, icon: "align-center",toolType:"center",ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
- { title: "Right", toolTip: "Right align (Cmd-])", btnType: ButtonType.ToggleButton, icon: "align-right", toolType:"right", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
+ { title: "Left", toolTip: "Left align (Cmd-[)", btnType: ButtonType.ToggleButton, icon: "align-left", toolType:"left", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
+ { title: "Center", toolTip: "Center align (Cmd-\\)",btnType: ButtonType.ToggleButton, icon: "align-center",toolType:"center", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
+ { title: "Right", toolTip: "Right align (Cmd-])", btnType: ButtonType.ToggleButton, icon: "align-right", toolType:"right", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
]},
- { title: "Fit Box", toolTip: "Fit text to box", btnType: ButtonType.ToggleButton, icon: "object-group",toolType:"fitBox", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
- { title: "Elide", toolTip: "Elide selection", btnType: ButtonType.ToggleButton, icon: "eye", toolType:"elide", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
- { title: "Dictate", toolTip: "Dictate", btnType: ButtonType.ToggleButton, icon: "microphone", toolType:"dictation", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
- { title: "NoLink", toolTip: "Auto Link", btnType: ButtonType.ToggleButton, icon: "link", toolType:"noAutoLink", expertMode:true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'}, funcs: {hidden: 'IsNoviceMode()'}},
+ { title: "Fit Box", toolTip: "Fit text to box", btnType: ButtonType.ToggleButton, icon: "object-group",toolType:"fitBox", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
+ { title: "Elide", toolTip: "Elide selection", btnType: ButtonType.ToggleButton, icon: "eye", toolType:"elide", ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
+ { title: "Dictate", toolTip: "Dictate", btnType: ButtonType.ToggleButton, icon: "microphone", toolType:"dictation",ignoreClick: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'} },
+ { title: "NoLink", toolTip: "Auto Link", btnType: ButtonType.ToggleButton, icon: "link", toolType:"noAutoLink",expertMode: true, scripts: {onClick: '{ return toggleCharStyle(this.toolType, _readOnly_);}'}, funcs: {hidden: 'IsNoviceMode()'}},
// { title: "Strikethrough", tooltip: "Strikethrough", btnType: ButtonType.ToggleButton, icon: "strikethrough", scripts: {onClick:: 'toggleStrikethrough()'}},
// { title: "Superscript", tooltip: "Superscript", btnType: ButtonType.ToggleButton, icon: "superscript", scripts: {onClick:: 'toggleSuperscript()'}},
// { title: "Subscript", tooltip: "Subscript", btnType: ButtonType.ToggleButton, icon: "subscript", scripts: {onClick:: 'toggleSubscript()'}},
@@ -825,13 +827,9 @@ pie title Minerals in my tap water
{ title: "Rotate",toolTip: "Rotate 90", btnType: ButtonType.ClickButton, icon: "redo-alt", scripts: { onClick: 'imageRotate90();' }},
];
}
- static contextMenuTools(doc:Doc):Button[] {
+ static contextMenuTools():Button[] {
return [
- { btnList: new List<string>([CollectionViewType.Freeform, CollectionViewType.Card, CollectionViewType.Carousel,CollectionViewType.Carousel3D,
- CollectionViewType.Masonry, CollectionViewType.Multicolumn, CollectionViewType.Multirow, CollectionViewType.Linear,
- CollectionViewType.Map, CollectionViewType.NoteTaking, CollectionViewType.Pivot, CollectionViewType.Schema, CollectionViewType.Stacking,
- CollectionViewType.Calendar, CollectionViewType.Grid, CollectionViewType.Tree, CollectionViewType.Time, ]),
- title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: '{ return setView(value, shiftKey, _readOnly_); }'}},
+ { title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, expertMode: false, btnList: new List<string>(standardViewTypes), ignoreClick: true, width: 100, scripts: { script: '{ return setView(value, shiftKey, _readOnly_); }'}},
{ title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, expertMode: false, width: 30, scripts: { onClick: 'pinWithView(altKey)'}, funcs: {hidden: "IsNoneSelected()"}},
{ title: "Header", icon: "heading", toolTip: "Doc Titlebar Color", btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'} },
{ title: "Template",icon: "scroll", toolTip: "Default Note Template",btnType: ButtonType.ToggleButton, expertMode: false, toolType:DocumentType.RTF, scripts: { onClick: '{ return setDefaultTemplate(_readOnly_); }'} },
@@ -843,18 +841,19 @@ pie title Minerals in my tap water
{ title: "Num", icon:"", toolTip: "Frame # (click to toggle edit mode)",btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}},
{ title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)'}, width: 30, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}},
{ title: "Chat", icon: "lightbulb", toolTip: "Toggle Chat Assistant",btnType: ButtonType.ToggleButton, expertMode: false, toolType:"toggle-chat", funcs: {}, width: 30, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'} },
- { title: "Filter", icon: "=", toolTip: "Filter cards by tags", subMenu: CurrentUserUtils.filterTools(), ignoreClick:true, toolType:DocumentType.COL, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)'}, btnType: ButtonType.MultiToggleButton, width: 30, backgroundColor: doc.userVariantColor as string},
- { title: "Sort", icon: "Sort", toolTip: "Sort Documents", subMenu: CurrentUserUtils.sortTools(), expertMode: false, toolType:DocumentType.COL, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
- { title: "Text", icon: "Text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), expertMode: false, toolType:DocumentType.RTF, funcs: { linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
- { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: {hidden: `IsExploreMode()`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available
- { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode, true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
- { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:DocumentType.COL, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
- { title: "Stack", icon: "View", toolTip: "Stacking tools", subMenu: CurrentUserUtils.stackTools(), expertMode: false, toolType:CollectionViewType.Stacking, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
-
- { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when Web is selected
- { title: "Video", icon: "Video", toolTip: "Video functions", subMenu: CurrentUserUtils.videoTools(), expertMode: false, toolType:DocumentType.VID, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when video is selected
- { title: "Image", icon: "Image", toolTip: "Image functions", subMenu: CurrentUserUtils.imageTools(), expertMode: false, toolType:DocumentType.IMG, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when image is selected
- { title: "Schema", icon: "Schema", toolTip: "Schema functions", subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`}, linearBtnWidth:58 }, // Only when Schema is selected
+ { title: "Filter", icon: "=", toolTip: "Filter cards by tags", btnType: ButtonType.MultiToggleButton,
+ subMenu: this.filterTools(), expertMode: false, toolType:DocumentType.COL, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)'},ignoreClick:true, width: 30},
+ { title: "Sort", icon: "Sort", toolTip: "Sort Documents", subMenu: this.sortTools(), expertMode: false, toolType:DocumentType.COL, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "Text", icon: "Text", toolTip: "Text functions", subMenu: this.textTools(), expertMode: false, toolType:DocumentType.RTF, funcs: { linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: this.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: {hidden: `IsExploreMode()`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available
+ { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: this.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode, true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "View", icon: "View", toolTip: "View tools", subMenu: this.viewTools(), expertMode: false, toolType:DocumentType.COL, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "Stack", icon: "View", toolTip: "Stacking tools", subMenu: this.stackTools(), expertMode: false, toolType:CollectionViewType.Stacking, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
+
+ { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: this.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when Web is selected
+ { title: "Video", icon: "Video", toolTip: "Video functions", subMenu: this.videoTools(), expertMode: false, toolType:DocumentType.VID, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when video is selected
+ { title: "Image", icon: "Image", toolTip: "Image functions", subMenu: this.imageTools(), expertMode: false, toolType:DocumentType.IMG, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when image is selected
+ { title: "Schema", icon: "Schema", toolTip: "Schema functions", subMenu: this.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`}, linearBtnWidth:58 }, // Only when Schema is selected
];
}
@@ -900,7 +899,7 @@ pie title Minerals in my tap water
static setupContextMenuButtons(doc: Doc, field="myContextMenuBtns") {
const reqdCtxtOpts:DocumentOptions = { title: "context menu buttons", undoIgnoreFields:new List<string>(['width', "linearView_IsOpen"]), flexGap: 0, childDragAction: dropActionType.embed, childDontRegisterViews: true, linearView_IsOpen: true, ignoreClick: true, linearView_Expandable: false, _height: 35 };
const ctxtMenuBtnsDoc = DocUtils.AssignDocField(doc, field, (opts, items) => this.linearButtonList(opts, items??[]), reqdCtxtOpts, undefined);
- const ctxtMenuBtns = CurrentUserUtils.contextMenuTools(doc).map(params => this.setupContextMenuBtn(params, ctxtMenuBtnsDoc) );
+ const ctxtMenuBtns = CurrentUserUtils.contextMenuTools().map(params => this.setupContextMenuBtn(params, ctxtMenuBtnsDoc) );
return DocUtils.AssignOpts(ctxtMenuBtnsDoc, reqdCtxtOpts, ctxtMenuBtns);
}
/// Initializes all the default buttons for the top bar context menu
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 37060d20c..94c023330 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -11,14 +11,13 @@ import { GroupManager } from '../util/GroupManager';
import { SettingsManager } from '../util/SettingsManager';
import { SharingManager } from '../util/SharingManager';
import { SnappingManager } from '../util/SnappingManager';
-import { UndoManager, undoable } from '../util/UndoManager';
+import { UndoManager } from '../util/UndoManager';
import { ContextMenu } from './ContextMenu';
import { DocumentDecorations } from './DocumentDecorations';
import { InkStrokeProperties } from './InkStrokeProperties';
import { MainView } from './MainView';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
-import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { CollectionFreeFormDocumentView } from './nodes/CollectionFreeFormDocumentView';
import { DocumentLinksButton } from './nodes/DocumentLinksButton';
import { DocumentView } from './nodes/DocumentView';
@@ -242,7 +241,7 @@ export class KeyManager {
{
const importBtn = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MyImports);
if (importBtn) {
- MainView.Instance.selectMenu(importBtn);
+ MainView.Instance.selectLeftSidebarButton(importBtn);
}
}
break;
@@ -250,7 +249,7 @@ export class KeyManager {
{
const trailsBtn = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MyTrails);
if (trailsBtn) {
- MainView.Instance.selectMenu(trailsBtn);
+ MainView.Instance.selectLeftSidebarButton(trailsBtn);
}
}
break;
@@ -260,7 +259,7 @@ export class KeyManager {
} else {
const searchBtn = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MySearcher);
if (searchBtn) {
- MainView.Instance.selectMenu(searchBtn);
+ MainView.Instance.selectLeftSidebarButton(searchBtn);
}
}
break;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 2b2b77384..be6e2fecb 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -848,7 +848,7 @@ export class MainView extends ObservableReactComponent<object> {
}
@action
- selectMenu = (button: Doc) => {
+ selectLeftSidebarButton = (button: Doc) => {
const title = StrCast(button.$title);
const willOpen = !this._leftMenuFlyoutWidth || this._panelContent !== title;
this.closeFlyout();
@@ -860,7 +860,9 @@ export class MainView extends ObservableReactComponent<object> {
case 'Help':
break;
default:
- this.expandFlyout(button);
+ this._leftMenuFlyoutWidth = this._leftMenuFlyoutWidth || 250;
+ this._sidebarContent.proto = DocCast(button.target);
+ SnappingManager.SetLastPressedBtn(button[Id]);
}
}
return true;
@@ -936,19 +938,6 @@ export class MainView extends ObservableReactComponent<object> {
</div>
);
}
-
- expandFlyout = action((button: Doc) => {
- // bcz: What's going on here!? --- may be fixed now, so commenting out ...
- // Chrome(not firefox) seems to have a bug when the flyout expands and there's a zoomed freeform tab. All of the div below the CollectionFreeFormView's main div
- // generate the wrong value from getClientRectangle() -- specifically they return an 'x' that is the flyout's width greater than it should be.
- // interactively adjusting the flyout fixes the problem. So does programmatically changing the value after a timeout to something *fractionally* different (ie, 1.5, not 1);)
- this._leftMenuFlyoutWidth = this._leftMenuFlyoutWidth || 250;
- // setTimeout(action(() => (this._leftMenuFlyoutWidth += 0.5)));
-
- this._sidebarContent.proto = DocCast(button.target);
- SnappingManager.SetLastPressedBtn(button[Id]);
- });
-
closeFlyout = action(() => {
SnappingManager.SetLastPressedBtn('');
this._panelContent = 'none';
@@ -1162,7 +1151,7 @@ export class MainView extends ObservableReactComponent<object> {
// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function selectMainMenu(doc: Doc) {
- MainView.Instance.selectMenu(doc);
+ MainView.Instance.selectLeftSidebarButton(doc);
});
// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function hideUI() {
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index a1e8fe7ba..8f18de33f 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -118,7 +118,7 @@ export class PropertiesButtons extends React.Component {
// select text
return this.propertyToggleBtn(
on => (on ? 'ALIGN TOP' : 'ALIGN CENTER'),
- '_layout_centered',
+ 'text_centered',
on => `${on ? 'Text is aligned with top of document' : 'Text is aligned with center of document'} `,
() => <MdTouchApp /> // 'eye'
);
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 7ba8989ce..6a7336bca 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -130,7 +130,6 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
{ description: 'Calendar', event: () => func(CollectionViewType.Calendar), icon: 'columns' },
{ description: 'Pivot', event: () => func(CollectionViewType.Pivot), icon: 'columns' },
{ description: 'Time', event: () => func(CollectionViewType.Time), icon: 'columns' },
- { description: 'Map', event: () => func(CollectionViewType.Map), icon: 'globe-americas' },
{ description: 'Grid', event: () => func(CollectionViewType.Grid), icon: 'th-list' },
];
diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
index b40189d76..e4d38eb4a 100644
--- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
+++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
@@ -11,7 +11,7 @@ import { emptyFunction } from '../../../../Utils';
import { Doc, DocListCast, Opt } from '../../../../fields/Doc';
import { DocData } from '../../../../fields/DocSymbols';
import { List } from '../../../../fields/List';
-import { DocCast, ImageCast, NumCast, StrCast } from '../../../../fields/Types';
+import { DocCast, ImageCast, ImageCastToNameType, NumCast, StrCast } from '../../../../fields/Types';
import { DocumentType } from '../../../documents/DocumentTypes';
import { Docs } from '../../../documents/Documents';
import { DragManager } from '../../../util/DragManager';
@@ -187,7 +187,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent<FieldViewProps>() {
ele?.addEventListener('wheel', this.onPassiveWheel, { passive: false });
})}>
{FaceRecognitionHandler.UniqueFaceImages(this.Document).map((doc, i) => {
- const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)])?.url.href.split('.') ?? ['-missing-', '.png'];
+ const [name, type] = ImageCastToNameType(doc[Doc.LayoutFieldKey(doc)]) ?? ['-missing-', '.png'];
return (
<div
className="image-wrapper"
diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx
index c983d7c26..7c8ccb92d 100644
--- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx
+++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx
@@ -10,7 +10,7 @@ import { imageUrlToBase64 } from '../../../../ClientUtils';
import { Utils, numberRange } from '../../../../Utils';
import { Doc, NumListCast, Opt } from '../../../../fields/Doc';
import { List } from '../../../../fields/List';
-import { ImageCast } from '../../../../fields/Types';
+import { ImageCastToNameType, ImageCastWithSuffix } from '../../../../fields/Types';
import { gptGetEmbedding, gptImageLabel } from '../../../apis/gpt/GPT';
import { DocumentType } from '../../../documents/DocumentTypes';
import { Docs } from '../../../documents/Documents';
@@ -165,8 +165,8 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
const imageInfos = this._selectedImages.map(async doc => {
if (!doc.$tags_chat) {
- const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.');
- return imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 =>
+ const url = ImageCastWithSuffix(doc[Doc.LayoutFieldKey(doc)], '_o') ?? '';
+ return imageUrlToBase64(url).then(hrefBase64 =>
!hrefBase64 ? undefined :
gptImageLabel(hrefBase64,'Give three labels to describe this image.').then(labels =>
({ doc, labels }))) ; // prettier-ignore
@@ -199,13 +199,11 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
groupImagesInBox = action(async () => {
this.startLoading();
- for (const doc of this._selectedImages) {
- for (let index = 0; index < (doc.$tags_chat as List<string>).length; index++) {
- const label = (doc.$tags_chat as List<string>)[index];
- const embedding = await gptGetEmbedding(label);
- doc[`$tags_embedding_${index + 1}`] = new List<number>(embedding);
- }
- }
+ await Promise.all(
+ this._selectedImages
+ .map(doc => ({ doc, labels: doc.$tags_chat as List<string> }))
+ .map(({ doc, labels }) => labels.map((label, index) => gptGetEmbedding(label).then(embedding => (doc[`$tags_embedding_${index + 1}`] = new List<number>(embedding)))))
+ );
const labelToEmbedding = new Map<string, number[]>();
// Create embeddings for the labels.
@@ -312,7 +310,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
{this._displayImageInformation ? (
<div className="image-information-list">
{this._selectedImages.map(doc => {
- const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.');
+ const [name, type] = ImageCastToNameType(doc[Doc.LayoutFieldKey(doc)]);
return (
<div className="image-information" style={{ borderColor: SettingsManager.userColor }} key={Utils.GenerateGuid()}>
<img
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index ca7e7a311..5fbf72f39 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -8,7 +8,7 @@ import { AclAdmin, AclAugment, AclEdit, DocData } from '../../../../fields/DocSy
import { Id } from '../../../../fields/FieldSymbols';
import { InkData, InkTool } from '../../../../fields/InkField';
import { List } from '../../../../fields/List';
-import { Cast, NumCast, StrCast } from '../../../../fields/Types';
+import { Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
import { ImageField } from '../../../../fields/URLField';
import { GetEffectiveAcl } from '../../../../fields/util';
import { DocUtils } from '../../../documents/DocUtils';
@@ -18,7 +18,6 @@ import { SnappingManager, freeformScrollMode } from '../../../util/SnappingManag
import { Transform } from '../../../util/Transform';
import { UndoManager, undoBatch } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
-import { MainView } from '../../MainView';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { MarqueeViewBounds } from '../../PinFuncs';
import { PreviewCursor } from '../../PreviewCursor';
@@ -442,7 +441,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
if (groupButton) {
this._selectedDocs = this.marqueeSelect(false, DocumentType.IMG);
ImageLabelBoxData.Instance.setData(this._selectedDocs);
- MainView.Instance.expandFlyout(groupButton);
+ ScriptCast(groupButton.onClick)?.script.run({ this: groupButton });
}
};
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index d14def9aa..3190757e2 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -302,7 +302,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
multiSelect={true}
onPointerDown={e => script && !toggleStatus && setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => script.run({ this: this.Document, value: undefined, _readOnly_: false }))}
toggleStatus={toggleStatus}
- showUntilToggle={BoolCast(this.Document.showUntilToggle)} // allow the toggle to be clickable unless ignoreClick is set on the Document
+ showUntilToggle={BoolCast(this.Document.showUntilToggle)}
label={selectedItems.length === 1 ? selectedItems[0] : this.label}
items={items.map(item => ({
icon: <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={StrCast(item.icon) as IconProp} color={color} />,
@@ -413,7 +413,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
case ButtonType.TextButton: return <Button {...btnProps} color={color} background={color}
text={StrCast(this.dataDoc.buttonText)}/>;
case ButtonType.MenuButton: return <IconButton size={Size.LARGE} {...btnProps} color={color} background={color}
- tooltipPlacement='right' onPointerDown={scriptFunc} />;
+ tooltipPlacement='right' onClick={scriptFunc} />;
default:
}
return this.defaultButton;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 2a1ec0881..a7e342063 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -2165,7 +2165,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
onScroll={this.onScroll}
onDrop={this.ondrop}>
<div
- className={`formattedTextBox-inner${rounded} ${this.layoutDoc._layout_centered && this.scrollHeight <= (this._props.fitWidth?.(this.Document) ? this._props.PanelHeight() : NumCast(this.layoutDoc._height)) ? 'centered' : ''} ${this.layoutDoc.hCentering}`}
+ className={`formattedTextBox-inner${rounded} ${this.dataDoc.text_centered && this.scrollHeight <= (this._props.fitWidth?.(this.Document) ? this._props.PanelHeight() : NumCast(this.layoutDoc._height)) ? 'centered' : ''} ${this.layoutDoc.hCentering}`}
ref={this.createDropTarget}
style={{
padding: StrCast(this.layoutDoc._textBoxPadding),
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 10c95f1e1..4fa1fb13b 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -117,7 +117,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
return this._activeAlignment;
}
@computed get textVcenter() {
- return BoolCast(this.dataDoc?._layout_centered, BoolCast(Doc.UserDoc().layout_centered));
+ return BoolCast(this.dataDoc?.text_centered, BoolCast(Doc.UserDoc().textCentered));
}
@action
@@ -426,8 +426,8 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
vcenterToggle = () => {
- if (this.dataDoc) this.dataDoc._layout_centered = !this.dataDoc._layout_centered;
- else Doc.UserDoc()._layout_centered = !Doc.UserDoc()._layout_centered;
+ if (this.dataDoc) this.dataDoc.text_centered = !this.dataDoc.text_centered;
+ else Doc.UserDoc().textCentered = !Doc.UserDoc().textCentered;
};
align = (view: EditorView | undefined, dispatch: undefined | ((tr: Transaction) => void), alignment: 'left' | 'right' | 'center') => {
if (view && dispatch && this.RootSelected) {
diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx
index 841546a04..86e28a768 100644
--- a/src/client/views/search/FaceRecognitionHandler.tsx
+++ b/src/client/views/search/FaceRecognitionHandler.tsx
@@ -4,7 +4,7 @@ import { Doc, DocListCast } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { List } from '../../../fields/List';
import { ComputedField } from '../../../fields/ScriptField';
-import { DocCast, ImageCast, NumCast, StrCast } from '../../../fields/Types';
+import { DocCast, ImageCast, ImageCastToNameType, NumCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
@@ -43,7 +43,7 @@ export class FaceRecognitionHandler {
* Loads an image
*/
private static loadImage = (imgUrl: ImageField): Promise<HTMLImageElement> => {
- const [name, type] = imgUrl.url.href.split('.');
+ const [name, type] = ImageCastToNameType(imgUrl.url.href);
const imageURL = `${name}_o.${type}`;
return new Promise((resolve, reject) => {
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 734af4ccd..e48337651 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1461,7 +1461,7 @@ export namespace Doc {
const docText = (async (tdoc:Doc) => {
switch (tdoc.type) {
case DocumentType.PDF: return curDescription || StrCast(tdoc.text).split(/\s+/).slice(0, 50).join(' '); // first 50 words of pdf text
- case DocumentType.IMG: return curDescription || imageUrlToBase64(ImageCastWithSuffix(Doc.LayoutField(tdoc), '_o') ?? '')
+ case DocumentType.IMG: return curDescription || imageUrlToBase64(ImageCastWithSuffix(tdoc[Doc.LayoutFieldKey(tdoc)], '_o') ?? '')
.then(hrefBase64 => gptImageLabel(hrefBase64, 'Give three to five labels to describe this image.'));
case DocumentType.RTF: return RTFCast(tdoc[Doc.LayoutFieldKey(tdoc)])?.Text ?? StrCast(tdoc[Doc.LayoutFieldKey(tdoc)]);
default: return StrCast(tdoc.title).startsWith("Untitled") ? "" : StrCast(tdoc.title);
diff --git a/src/fields/Types.ts b/src/fields/Types.ts
index af9cb1180..dc7516f38 100644
--- a/src/fields/Types.ts
+++ b/src/fields/Types.ts
@@ -131,9 +131,13 @@ export function PDFCast(field: FieldResult, defaultVal: PdfField | null = null)
export function ImageCast(field: FieldResult, defaultVal: ImageField | null = null) {
return Cast(field, ImageField, defaultVal);
}
-export function ImageCastWithSuffix(field: FieldResult, suffix: string, defaultVal: ImageField | null = null) {
+export function ImageCastToNameType(field: FieldResult, defaultVal: ImageField | null = null) {
const href = ImageCast(field, defaultVal)?.url.href;
- return href ? `${href.split('.')[0]}${suffix}.${href.split('.')[1]}` : null;
+ return href ? [href.replace(/.[^.]*$/, ''), href.split('.').lastElement()] : ["", ""];
+}
+export function ImageCastWithSuffix(field: FieldResult, suffix: string, defaultVal: ImageField | null = null) {
+ const [name, type] = ImageCastToNameType(field, defaultVal);
+ return name ? `${name}${suffix}.${type}` : null;
}
export function FieldValue<T extends FieldType, U extends WithoutList<T>>(field: FieldResult<T>, defaultValue: U): WithoutList<T>;