diff options
author | A.J. Shulman <Shulman.aj@gmail.com> | 2025-05-11 10:46:15 -0400 |
---|---|---|
committer | A.J. Shulman <Shulman.aj@gmail.com> | 2025-05-11 10:46:15 -0400 |
commit | b87b2105e966928518c96c7702b68c12344ffdd7 (patch) | |
tree | 84fd5ecede3af9d773c10d02908cdde27da1a759 /src/client/documents/Documents.ts | |
parent | 0db4583914e43e6efdba3e86a614a19956e73b5e (diff) | |
parent | 0c3f86d57225a2991920adef3a337bc13e408ac0 (diff) |
Merge branch 'master' into agent-web-working
Diffstat (limited to 'src/client/documents/Documents.ts')
-rw-r--r-- | src/client/documents/Documents.ts | 179 |
1 files changed, 100 insertions, 79 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f87bd7092..6371c4e9d 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -4,7 +4,7 @@ import { basename } from 'path'; import { ClientUtils, OmitKeys } from '../../ClientUtils'; import { DateField } from '../../fields/DateField'; import { CreateLinkToActiveAudio, Doc, FieldType, Opt, updateCachedAcls } from '../../fields/Doc'; -import { Initializing } from '../../fields/DocSymbols'; +import { Id } from '../../fields/FieldSymbols'; import { HtmlField } from '../../fields/HtmlField'; import { InkField } from '../../fields/InkField'; import { List } from '../../fields/List'; @@ -18,7 +18,6 @@ import { PointData } from '../../pen-gestures/GestureTypes'; import { DocServer } from '../DocServer'; import { dropActionType } from '../util/DropActionTypes'; import { CollectionViewType, DocumentType } from './DocumentTypes'; -import { Id } from '../../fields/FieldSymbols'; class EmptyBox { public static LayoutString() { @@ -43,7 +42,6 @@ export class FInfo { readOnly: boolean = false; fieldType?: FInfoFieldType; values?: FieldType[]; - onLayout?: boolean; filterable?: boolean = true; // can be used as a Filter in FilterPanel // format?: string; // format to display values (e.g, decimal places, $, etc) // parse?: ScriptField; // parse a value from a string @@ -156,12 +154,16 @@ type DROPt = DAInfo | dropActionType; type DATEt = DateInfo | number; type DTYPEt = DTypeInfo | string; export class DocumentOptions { + [key: string]: FInfo | FieldType | undefined; // coordinate and dimensions depending on view x?: NUMt = new NumInfo('horizontal coordinate in freeform view', false); y?: NUMt = new NumInfo('vertical coordinate in freeform view', false); z?: NUMt = new NumInfo('whether document is in overlay (1) or not (0)', false, false, [1, 0]); + zIndex?: NUMt = new NumInfo('stacking index of documents in freeform view (higher numbers are towards the top'); overlayX?: NUMt = new NumInfo('horizontal coordinate in overlay view', false); overlayY?: NUMt = new NumInfo('vertical coordinate in overlay view', false); + embedContainer?: DOCt = new DocInfo('document that displays (contains) this document', false); + text?: RTFt = new RtfInfo('plain or rich text', true); text_html?: STRt = new StrInfo('plain text or html', true); _dimMagnitude?: NUMt = new NumInfo("magnitude of collectionMulti{row,col} element's width or height", false); @@ -196,7 +198,6 @@ export class DocumentOptions { _height?: NUMt = new NumInfo("height of document in container's coordiantes"); data_nativeWidth?: NUMt = new NumInfo('native width of data field contents (e.g., the pixel width of an image)', false); data_nativeHeight?: NUMt = new NumInfo('native height of data field contents (e.g., the pixel height of an image)', false); - linearBtnWidth?: NUMt = new NumInfo('unexpanded width of a linear menu button (button "width" changes when it expands)', false); _nativeWidth?: NUMt = new NumInfo('Deprecated: use nativeWidth. native width of document contents (e.g., the pixel width of an image)', false); _nativeHeight?: NUMt = new NumInfo('Deprecated: use nativeHeight. native height of document contents (e.g., the pixel height of an image)', false); nativeWidth?: NUMt = new NumInfo('native width of document contents (e.g., the pixel width of an image)', false); @@ -215,8 +216,7 @@ export class DocumentOptions { author?: string; // STRt = new StrInfo('creator of document'); // bcz: don't change this. Otherwise, the userDoc's field Infos will have a FieldInfo assigned to its author field which will render it unreadable author_date?: DATEt = new DateInfo('date the document was created', true); annotationOn?: DOCt = new DocInfo('document annotated by this document', false); - _embedContainer?: DOCt = new DocInfo('document that displays (contains) this document', false); - rootDocument?: DOCt = new DocInfo('document that supplies the information needed for a rendering template (eg, pres slide for PresElement)'); + rootDocument?: DOCt = new DocInfo('document that stores the data for compound template documents.'); color?: STRt = new StrInfo('foreground color data doc', false); hidden?: BOOLt = new BoolInfo('whether the document is not rendered by its collection', false); backgroundColor?: STRt = new StrInfo('background color for data doc', false); @@ -282,9 +282,8 @@ 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_fieldKey?: STRt = new StrInfo('the field key containing the current layout definition', false); _layout_enableAltContentUI?: BOOLt = new BoolInfo('whether to show alternate content button'); _layout_flashcardType?: STRt = new StrInfo('flashcard style to render in ComparisonBox. currently just "flashcard".'); _layout_showTitle?: string; // field name to display in header (:hover is an optional suffix) @@ -295,10 +294,8 @@ export class DocumentOptions { _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'); _gridGap?: NUMt = new NumInfo('gap between items in masonry view', false); - _xMargin?: NUMt = new NumInfo('gap between left edge of document and start of masonry/stacking layouts', false); - _yMargin?: NUMt = new NumInfo('gap between top edge of dcoument and start of masonry/stacking layouts', false); - _xPadding?: NUMt = new NumInfo('x padding', false); - _yPadding?: NUMt = new NumInfo('y padding', false); + _xMargin?: NUMt = new NumInfo('gap between left edge of document and contents of freeform/masonry/stacking layouts', false); + _yMargin?: NUMt = new NumInfo('gap between top edge of dcoument and contents offreeform/masonry/stacking layouts', false); _createDocOnCR?: boolean; // whether carriage returns and tabs create new text documents _columnsHideIfEmpty?: BOOLt = new BoolInfo('whether stacking view column headings should be hidden'); _caption_xMargin?: NUMt = new NumInfo('x margin of caption inside of a carousel collection', false, true); @@ -308,6 +305,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']); @@ -367,7 +365,7 @@ export class DocumentOptions { isGroup?: BOOLt = new BoolInfo('should collection use a grouping UI behavior'); isFolder?: BOOLt = new BoolInfo('is document a tree view folder'); _isTimelineLabel?: BOOLt = new BoolInfo('is document a timeline label'); - _isLightbox?: BOOLt = new BoolInfo('whether a collection acts as a lightbox by opening lightbox links by hiding all other documents in collection besides link target'); + isLightbox?: BOOLt = new BoolInfo('whether a collection acts as a lightbox by opening lightbox links by hiding all other documents in collection besides link target'); cloneOnCopy?: BOOLt = new BoolInfo('if this Doc is a field of another Doc, then it should be copied when the other Doc is copied'); mapPin?: DOCt = new DocInfo('pin associated with a config anchor', false); @@ -427,10 +425,9 @@ export class DocumentOptions { badgeValue?: ScriptField; // LINEAR VIEW - linearView_IsOpen?: BOOLt = new BoolInfo('is linear view open'); - linearView_Expandable?: BOOLt = new BoolInfo('can linear view be expanded'); - linearView_Dropdown?: BOOLt = new BoolInfo('can linear view be opened as a dropdown'); - linearView_SubMenu?: BOOLt = new BoolInfo('is doc a sub menu of more linear views'); + linearView_btnWidth?: NUMt = new NumInfo('unexpanded width of a linear menu button (button "width" changes when it expands)', false); + linearView_isOpen?: BOOLt = new BoolInfo('is linear view open'); + linearView_expandable?: BOOLt = new BoolInfo('can linear view be expanded'); flexGap?: NUMt = new NumInfo('Linear view flex gap'); flexDirection?: 'unset' | 'row' | 'column' | 'row-reverse' | 'column-reverse'; @@ -523,8 +520,19 @@ export class DocumentOptions { card_sort_isDesc?: BOOLt = new BoolInfo('whether the cards are sorted ascending or descending'); ai?: string; // to mark items as ai generated - ai_firefly_seed?: number; - ai_firefly_prompt?: string; + ai_prompt_seed?: NUMt = new NumInfo('seed to GAI engine to make results deterministic'); + ai_prompt?: STRt = new StrInfo('input prompt to GAI engine'); + ai_generatedDocs?: List<Doc>; // list of documents generated by GAI engine + + /** + * JSONāstringified slot configuration for ScrapbookBox + */ + scrapbookConfig?: string; + + /** + * The list of embedded Doc instances in each Scrapbook slot + */ + scrapbookContents?: List<Doc>; } export const DocOptions = new DocumentOptions(); @@ -574,19 +582,6 @@ export namespace Docs { options: { acl: '' }, }, ], - - // AARAV ADD // - [ - DocumentType.JOURNAL, - { - layout: { view: EmptyBox, dataField: 'text' }, - options: { - title: 'Daily Journal', - acl_Guest: SharingPermissions.View, - }, - }, - ], - // AARAV ADD // ]); const suffix = 'Proto'; @@ -677,7 +672,7 @@ export namespace Docs { // whatever options pertain to this specific prototype const options: DocumentOptions = { isSystem: true, - _layout_fieldKey: 'layout', + layout_fieldKey: 'layout', title, type, isBaseProto: true, @@ -687,10 +682,11 @@ export namespace Docs { layout: layout.view?.LayoutString(layout.dataField), }; Object.entries(options) - .filter(pair => typeof pair[1] === 'string' && pair[1].startsWith('@')) - .forEach(pair => { - if (!existing || ScriptCast(existing[pair[0]])?.script.originalScript !== pair[1].substring(1)) { - (options as { [key: string]: unknown })[pair[0]] = ComputedField.MakeFunction(pair[1].substring(1)); + .filter(([, val]) => (val as string)?.startsWith?.('@')) + .map(([key, val]) => [key, val as string]) + .forEach(([key, val]) => { + if (!existing || ScriptCast(existing[key])?.script.originalScript !== val.substring(1)) { + options[key] = ComputedField.MakeFunction(val.substring(1)); } }); return Doc.assign(existing ?? new Doc(prototypeId, true), OmitKeys(options, Object.keys(existing ?? {})).omit as { [key: string]: FieldType }, undefined, true); @@ -723,7 +719,7 @@ export namespace Docs { */ function InstanceFromProto(proto: Doc, data: FieldType | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = 'data', protoId?: string, placeholderDocIn?: Doc, noView?: boolean) { const placeholderDoc = placeholderDocIn; - const viewKeys = ['x', 'y', 'isSystem']; // keys that should be addded to the view document even though they don't begin with an "_" + const viewKeys = ['x', 'y', 'isSystem', 'overlayX', 'overlayY', 'zIndex', 'embedContainer']; // keys that should be addded to the view document even though they don't begin with an "_" const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, '^_') as { omit: { [key: string]: FieldType | undefined }; extract: { [key: string]: FieldType | undefined } }; // dataProps.acl_Override = SharingPermissions.Unset; @@ -838,7 +834,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, @@ -918,25 +914,58 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.RTF), field, options, undefined, fieldKey); } + export function ScrapbookDocument(items: Doc[] = [], options: DocumentOptions = {}, fieldKey: string = 'items') { + return InstanceFromProto( + Prototypes.get(DocumentType.SCRAPBOOK), + new List<Doc>(items), + { + title: + options.title ?? + new Date().toLocaleDateString(undefined, { + year: 'numeric', + month: 'short', + day: 'numeric', + }), + ...options, + }, + undefined, + fieldKey + ); + } + // AARAV ADD // export function DailyJournalDocument(text: string | RichTextField, options: DocumentOptions = {}, fieldKey: string = 'text') { - const styles = { - bold: true, // Make the journal date bold - color: 'blue', // Set the journal date color to blue - fontSize: 18, // Set the font size to 18px for the whole text - }; + // const getFormattedDate = () => { + // const date = new Date().toLocaleDateString(undefined, { + // weekday: 'long', + // year: 'numeric', + // month: 'long', + // day: 'numeric', + // }); + // return date; + // }; + + // const getDailyText = () => { + // const placeholderText = 'Start writing here...'; + // const dateText = `${getFormattedDate()}`; + + // return RichTextField.textToRtfFormat( + // [ + // { text: 'Journal Entry:', styles: { bold: true, color: 'black', fontSize: 20 } }, + // { text: dateText, styles: { italic: true, color: 'gray', fontSize: 15 } }, + // { text: placeholderText, styles: { fontSize: 14, color: 'gray' } }, + // ], + // undefined, + // placeholderText.length + // ); + // }; return InstanceFromProto( Prototypes.get(DocumentType.JOURNAL), - typeof text === 'string' ? RichTextField.textToRtf(text, undefined, styles, undefined) : text, + '', { - title: new Date().toLocaleDateString(undefined, { - weekday: 'long', - year: 'numeric', - month: 'long', - day: 'numeric', - }), + title: '', ...options, }, undefined, @@ -966,26 +995,22 @@ export namespace Docs { export function InkDocument(points: PointData[], options: DocumentOptions = {}, strokeWidth: number, color: string, strokeBezier: string, fillColor: string, arrowStart: string, arrowEnd: string, dash: string, isInkMask: boolean) { const ink = InstanceFromProto(Prototypes.get(DocumentType.INK), '', { title: 'ink', ...options }); - const I = Doc.GetProto(ink); - // I.layout_hideOpenButton = true; // don't show open full screen button when selected - I.color = color; - I.fillColor = fillColor && fillColor !== 'transparent' ? fillColor : undefined; - I.stroke = new InkField(points); - I.stroke_width = strokeWidth; - I.stroke_bezier = strokeBezier; - I.stroke_startMarker = arrowStart; - I.stroke_endMarker = arrowEnd; - I.stroke_dash = dash; - I.stroke_isInkMask = isInkMask; - I.text_align = 'center'; - I.rotation = 0; - I.width_min = 1; - I.height_min = 1; - I.defaultDoubleClick = 'ignore'; - I.author_date = new DateField(); - I.acl_Guest = Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View; - // I.acl_Override = SharingPermissions.Unset; - I[Initializing] = false; + ink.$color = color; + ink.$fillColor = fillColor && fillColor !== 'transparent' ? fillColor : undefined; + ink.$stroke = new InkField(points); + ink.$stroke_width = strokeWidth; + ink.$stroke_bezier = strokeBezier; + ink.$stroke_startMarker = arrowStart; + ink.$stroke_endMarker = arrowEnd; + ink.$stroke_dash = dash; + ink.$stroke_isInkMask = isInkMask; + ink.$text_align = 'center'; + ink.$rotation = 0; + ink.$width_min = 1; + ink.$height_min = 1; + ink.$defaultDoubleClick = 'ignore'; + ink.$author_date = new DateField(); + ink.$acl_Guest = Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View; return ink; } @@ -1005,7 +1030,7 @@ export namespace Docs { const nwid = options._nativeWidth || undefined; const nhght = options._nativeHeight || undefined; if (!nhght && width && height && nwid) options._nativeHeight = (Number(nwid) * Number(height)) / Number(width); - return InstanceFromProto(Prototypes.get(DocumentType.WEB), new WebField(url || 'https://www.wikipedia.org/'), options); + return InstanceFromProto(Prototypes.get(DocumentType.WEB), new WebField(url || 'https://wikipedia.org/'), options); } export function HtmlDocument(html: string, options: DocumentOptions = {}) { @@ -1060,10 +1085,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 }); } @@ -1132,8 +1153,8 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { ...(options || {}) }); } - export function PresElementBoxDocument() { - return Prototypes.get(DocumentType.PRESELEMENT); + export function PresSlideDocument() { + return Prototypes.get(DocumentType.PRESSLIDE); } export function DataVizDocument(url: string, options?: DocumentOptions, overwriteDoc?: Doc) { @@ -1141,7 +1162,7 @@ export namespace Docs { } export function AnnoPaletteDocument(options?: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.ANNOPALETTE), new List([Doc.MyStickers]), { ...(options || {}) }); + return InstanceFromProto(Prototypes.get(DocumentType.ANNOPALETTE), new List([...(Doc.MyStickers ? [Doc.MyStickers] : [])]), { ...(options || {}) }); } export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) { |