aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/documents/DocumentTypes.ts1
-rw-r--r--src/client/documents/Documents.ts44
-rw-r--r--src/client/util/CurrentUserUtils.ts3
-rw-r--r--src/client/views/Main.tsx2
-rw-r--r--src/client/views/nodes/scrapbook/ScrapbookBox.tsx106
-rw-r--r--src/client/views/nodes/scrapbook/ScrapbookContent.tsx23
-rw-r--r--src/client/views/nodes/scrapbook/ScrapbookSlot.tsx26
-rw-r--r--src/client/views/nodes/scrapbook/ScrapbookSlotTypes.ts25
8 files changed, 230 insertions, 0 deletions
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 5c6559836..cef44e999 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -44,6 +44,7 @@ export enum DocumentType {
SCRIPTDB = 'scriptdb', // database of scripts
GROUPDB = 'groupdb', // database of groups
+ SCRAPBOOK = 'scrapbook',
JOURNAL = 'journal', // AARAV ADD
}
export enum CollectionViewType {
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index be857da6d..2a2f9d342 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -526,6 +526,16 @@ export class DocumentOptions {
ai_firefly_seed?: number;
ai_firefly_prompt?: string;
+ /**
+ * JSON‐stringified slot configuration for ScrapbookBox
+ */
+ scrapbookConfig?: string;
+
+ /**
+ * The list of embedded Doc instances in each Scrapbook slot
+ */
+ scrapbookContents?: List<Doc>;
+
_outpaintingMetadata?: STRt = new StrInfo('serialized JSON metadata needed for image outpainting', false);
}
@@ -590,6 +600,18 @@ export namespace Docs {
},
],
// AARAV ADD //
+
+ [
+ DocumentType.SCRAPBOOK,
+ {
+ layout: { view: EmptyBox, dataField: 'text' },
+ options: {
+ title: 'Scrapbook',
+ acl_Guest: SharingPermissions.View,
+ },
+
+ },
+ ],
]);
const suffix = 'Proto';
@@ -922,6 +944,26 @@ 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') {
@@ -964,6 +1006,8 @@ export namespace Docs {
// AARAV ADD //
+
+
export function LinkDocument(source: Doc, target: Doc, options: DocumentOptions = {}, id?: string) {
const linkDoc = InstanceFromProto(
Prototypes.get(DocumentType.LINK),
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 99a67ebb2..8f4d568ab 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -407,6 +407,8 @@ pie title Minerals in my tap water
{key: "DataViz", creator: opts => Docs.Create.DataVizDocument("", opts), opts: { _width: 300, _height: 300, }},
// AARAV ADD //
{key: "DailyJournal",creator:opts => Docs.Create.DailyJournalDocument("", opts),opts: { _width: 300, _height: 300, }},
+ {key: "Scrapbook",creator:opts => Docs.Create.ScrapbookDocument([], opts),opts:{ _width: 300, _height: 300}},
+ //{key: "Scrapbook",creator:opts => Docs.Create.ScrapbookDocument([], opts),opts:{ _width: 300, _height: 300}},
{key: "Chat", creator: Docs.Create.ChatDocument, opts: { _width: 500, _height: 500, _layout_fitWidth: true, }},
{key: "MetaNote", creator: metaNoteTemplate, opts: { _width: 300, _height: 120, _header_pointerEvents: "all", _header_height: 50, _header_fontSize: 9,_layout_autoHeightMargins: 50, _layout_autoHeight: true, treeView_HideUnrendered: true}},
{key: "ViewSlide", creator: slideView, opts: { _width: 400, _height: 300, _xMargin: 3, _yMargin: 3,}},
@@ -449,6 +451,7 @@ pie title Minerals in my tap water
{ toolTip: "Tap or drag to create a button", title: "Button", icon: "circle", dragFactory: doc.emptyButton as Doc, clickFactory: DocCast(doc.emptyButton)},
{ toolTip: "Tap or drag to create a scripting box", title: "Script", icon: "terminal", dragFactory: doc.emptyScript as Doc, clickFactory: DocCast(doc.emptyScript), funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a data viz node", title: "DataViz", icon: "chart-bar", dragFactory: doc.emptyDataViz as Doc, clickFactory: DocCast(doc.emptyDataViz)},
+ { toolTip: "Tap or drag to create a scrapbook template", title: "Scrapbook", icon: "palette", dragFactory: doc.emptyScrapbook as Doc,clickFactory:DocCast(doc.emptyScrapbook), },
{ toolTip: "Tap or drag to create a journal entry", title: "Journal", icon: "book", dragFactory:doc.emptyDailyJournal as Doc,clickFactory: DocCast(doc.emptyDataJournal), },
{ toolTip: "Tap or drag to create a bullet slide", title: "PPT Slide", icon:"person-chalkboard",dragFactory: doc.emptySlide as Doc, clickFactory: DocCast(doc.emptySlide), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a view slide", title: "View Slide", icon: "address-card", dragFactory: doc.emptyViewSlide as Doc, clickFactory: DocCast(doc.emptyViewSlide), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index e4bbb1c0f..7992ed412 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -53,6 +53,7 @@ import { WebBox } from './nodes/WebBox';
import { CalendarBox } from './nodes/calendarBox/CalendarBox';
import { ChatBox } from './nodes/chatbot/chatboxcomponents/ChatBox';
import { DailyJournal } from './nodes/formattedText/DailyJournal';
+import { ScrapbookVersionTwo } from './nodes/scrapbook/ScrapbookVersionTwo';
import { DashDocCommentView } from './nodes/formattedText/DashDocCommentView';
import { DashDocView } from './nodes/formattedText/DashDocView';
import { DashFieldView } from './nodes/formattedText/DashFieldView';
@@ -120,6 +121,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' };
FormattedTextBox,
DailyJournal, // AARAV
ImageBox,
+ ScrapbookVersionTwo,
FontIconBox,
LabelBox,
EquationBox,
diff --git a/src/client/views/nodes/scrapbook/ScrapbookBox.tsx b/src/client/views/nodes/scrapbook/ScrapbookBox.tsx
new file mode 100644
index 000000000..56cfcda70
--- /dev/null
+++ b/src/client/views/nodes/scrapbook/ScrapbookBox.tsx
@@ -0,0 +1,106 @@
+import { makeObservable } from 'mobx';
+import * as React from 'react';
+import { ViewBoxAnnotatableComponent } from '../../DocComponent';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { Docs } from '../../../documents/Documents';
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { action, observable } from 'mobx';
+import { DocListCast } from '../../../../fields/Doc';
+import { Doc } from '../../../../fields/Doc';
+import { DocumentView } from '../DocumentView';
+import { FormattedTextBox } from '../formattedText/FormattedTextBox';
+import { List } from '../../../../fields/List';
+// Scrapbook view: a container that lays out its child items in a grid/template
+export class ScrapbookBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
+ @observable createdDate: string;
+
+ constructor(props: FieldViewProps) {
+ super(props);
+ makeObservable(this);
+ this.createdDate = this.getFormattedDate();
+
+ // ensure we always have a List<Doc> in dataDoc['items']
+ if (!this.dataDoc[this.fieldKey]) {
+ this.dataDoc[this.fieldKey] = new List<Doc>();
+ }
+ this.createdDate = this.getFormattedDate();
+ this.setTitle();
+ }
+
+ public static LayoutString(fieldStr: string) {
+ return FieldView.LayoutString(ScrapbookBox, fieldStr);
+ }
+
+
+
+
+
+
+
+ getFormattedDate(): string {
+ return new Date().toLocaleDateString(undefined, {
+ year: 'numeric',
+ month: 'short',
+ day: 'numeric',
+ });
+ }
+
+ @action
+ setTitle() {
+ const title = `Scrapbook - ${this.createdDate}`;
+ if (this.dataDoc.title !== title) {
+ this.dataDoc.title = title;
+ }
+ }
+
+ componentDidMount() {
+ this.setTitle();
+ if (!this.dataDoc[this.fieldKey]) {
+ this.dataDoc[this.fieldKey] = new List<Doc>();
+ }
+ }
+
+ render() {
+ // cast into an array even if empty
+ const items: Doc[] = DocListCast(this.dataDoc[this.fieldKey]);
+
+ return (
+ <div style={{ background: 'beige', width: '100%', height: '100%' }}>
+
+ </div>
+
+ // <div
+ // style={{
+ // }}
+ // >
+ // {items.length === 0
+ // ? <div style={{color:'#888',fontStyle:'italic'}}>Drop docs here</div>
+ // : items.map((childDoc, idx) => (
+ // <DocumentView
+ // key={String(childDoc.id ?? idx)}
+ // {...this._props}
+ // Document={childDoc}
+ // />
+ // ))
+ // }
+ // </div>
+ );
+ }
+}
+
+
+// Register scrapbook
+Docs.Prototypes.TemplateMap.set(DocumentType.SCRAPBOOK, {
+ layout: { view: ScrapbookBox, dataField: 'items' },
+ options: {
+ acl: '',
+ _height: 200,
+ _xMargin: 10,
+ _yMargin: 10,
+ _layout_autoHeight: true,
+ _layout_reflowVertical: true,
+ _layout_reflowHorizontal: true,
+ defaultDoubleClick: 'ignore',
+ systemIcon: 'BsImages',
+ },
+});
diff --git a/src/client/views/nodes/scrapbook/ScrapbookContent.tsx b/src/client/views/nodes/scrapbook/ScrapbookContent.tsx
new file mode 100644
index 000000000..ad1d308e8
--- /dev/null
+++ b/src/client/views/nodes/scrapbook/ScrapbookContent.tsx
@@ -0,0 +1,23 @@
+import React from "react";
+import { observer } from "mobx-react-lite";
+// Import the Doc type from your actual module.
+import { Doc } from "../../../../fields/Doc";
+
+export interface ScrapbookContentProps {
+ doc: Doc;
+}
+
+// A simple view that displays a document's title and content.
+// Adjust how you extract the text if your Doc fields are objects.
+export const ScrapbookContent: React.FC<ScrapbookContentProps> = observer(({ doc }) => {
+ // If doc.title or doc.content are not plain strings, convert them.
+ const titleText = doc.title ? doc.title.toString() : "Untitled";
+ const contentText = doc.content ? doc.content.toString() : "No content available.";
+
+ return (
+ <div className="scrapbook-content">
+ <h3>{titleText}</h3>
+ <p>{contentText}</p>
+ </div>
+ );
+});
diff --git a/src/client/views/nodes/scrapbook/ScrapbookSlot.tsx b/src/client/views/nodes/scrapbook/ScrapbookSlot.tsx
new file mode 100644
index 000000000..05215d3e5
--- /dev/null
+++ b/src/client/views/nodes/scrapbook/ScrapbookSlot.tsx
@@ -0,0 +1,26 @@
+export interface SlotDefinition {
+ id: string;
+ x: number; y: number;
+ defaultWidth: number;
+ defaultHeight: number;
+ }
+
+ export interface SlotContentMap {
+ slotId: string;
+ docId?: string;
+ }
+
+ export interface ScrapbookConfig {
+ slots: SlotDefinition[];
+ contents?: SlotContentMap[];
+ }
+
+ export const DEFAULT_SCRAPBOOK_CONFIG: ScrapbookConfig = {
+ slots: [
+ { id: "slot1", x: 10, y: 10, defaultWidth: 180, defaultHeight: 120 },
+ { id: "slot2", x: 200, y: 10, defaultWidth: 180, defaultHeight: 120 },
+ // …etc
+ ],
+ contents: []
+ };
+ \ No newline at end of file
diff --git a/src/client/views/nodes/scrapbook/ScrapbookSlotTypes.ts b/src/client/views/nodes/scrapbook/ScrapbookSlotTypes.ts
new file mode 100644
index 000000000..686917d9a
--- /dev/null
+++ b/src/client/views/nodes/scrapbook/ScrapbookSlotTypes.ts
@@ -0,0 +1,25 @@
+// ScrapbookSlotTypes.ts
+export interface SlotDefinition {
+ id: string;
+ title: string;
+ x: number;
+ y: number;
+ defaultWidth: number;
+ defaultHeight: number;
+ }
+
+ export interface ScrapbookConfig {
+ slots: SlotDefinition[];
+ contents?: { slotId: string; docId: string }[];
+ }
+
+ // give it three slots by default:
+ export const DEFAULT_SCRAPBOOK_CONFIG: ScrapbookConfig = {
+ slots: [
+ { id: "main", title: "Main Content", x: 20, y: 20, defaultWidth: 360, defaultHeight: 200 },
+ { id: "notes", title: "Notes", x: 20, y: 240, defaultWidth: 360, defaultHeight: 160 },
+ { id: "resources", title: "Resources", x: 400, y: 20, defaultWidth: 320, defaultHeight: 380 },
+ ],
+ contents: [],
+ };
+ \ No newline at end of file