aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoreleanor-park <eleanor_park@brown.edu>2024-07-24 16:52:50 -0400
committereleanor-park <eleanor_park@brown.edu>2024-07-24 16:52:50 -0400
commita763c4e80cec6aef5219a8c9fcfa2ddccbc10b0a (patch)
tree87bbbe2f9360525b8196f1864abc97e569d1ea97 /src
parent9e2f51dc5a1c82e9293e04c71f4430fd67ff3378 (diff)
bug and render fixes
Diffstat (limited to 'src')
-rw-r--r--src/client/apis/gpt/GPT.ts2
-rw-r--r--src/client/util/CurrentUserUtils.ts26
-rw-r--r--src/client/util/DropConverter.ts22
-rw-r--r--src/client/util/bezierFit.ts13
-rw-r--r--src/client/views/DocumentButtonBar.tsx2
-rw-r--r--src/client/views/DocumentDecorations.tsx7
-rw-r--r--src/client/views/LightboxView.tsx20
-rw-r--r--src/client/views/MainView.tsx1
-rw-r--r--src/client/views/collections/CollectionCarousel3DView.tsx2
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx11
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx10
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx13
-rw-r--r--src/client/views/smartdraw/AnnotationPalette.tsx203
-rw-r--r--src/client/views/smartdraw/SmartDrawHandler.tsx9
-rw-r--r--src/fields/Doc.ts1
15 files changed, 132 insertions, 210 deletions
diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts
index cbe2f0582..a780596fa 100644
--- a/src/client/apis/gpt/GPT.ts
+++ b/src/client/apis/gpt/GPT.ts
@@ -58,7 +58,7 @@ const callTypeMap: { [type: string]: GPTCallOpts } = {
model: 'gpt-4o',
maxTokens: 1024,
temp: 0.5,
- prompt: 'Given an item, a level of complexity from 1-10, and a size in pixels, generate a detailed and colored line drawing representation of it. Make sure every element has the stroke field filled out. More complex drawings will have much more detail and strokes. The drawing should be in SVG format with no additional text or comments. For path coordinates, make sure you format with a comma between numbers, like M100,200 C150,250 etc. The only supported commands are line, ellipse, circle, rect, and path with M, Q, C, and L so only use those.',
+ prompt: 'Given an item, a level of complexity from 1-10, and a size in pixels, generate a detailed and colored line drawing representation of it. Make sure every element has the stroke field filled out. More complex drawings will have much more detail and strokes. The drawing should be in SVG format with no additional text or comments. For path coordinates, make sure you format with a comma between numbers, like M100,200 C150,250 etc. The only supported commands are line, ellipse, circle, rect, polygon, and path with M, Q, C, and L so only use those.',
},
};
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 98a54d4d0..6b59828eb 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -165,7 +165,7 @@ export class CurrentUserUtils {
static setupAnnoPalette(doc: Doc, field="myAnnos") {
const reqdOpts:DocumentOptions = {
- title: "Saved Annotations", _xMargin: 0, _layout_showTitle: "title", _chromeHidden: true, hidden: false,
+ title: "Saved Annotations", _xMargin: 0, _layout_showTitle: "title", hidden: false,
_dragOnlyWithinContainer: true, layout_hideContextMenu: true, isSystem: true, _forceActive: true,
_layout_autoHeight: true, _width: 500, _height: 300, _layout_fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true,
};
@@ -174,21 +174,14 @@ export class CurrentUserUtils {
return DocUtils.AssignDocField(doc, field, (opts,items) => Docs.Create.MasonryDocument(items??[], opts), reqdOpts, DocListCast(savedAnnos?.data), reqdScripts);
}
- // static setupNoteTemplates(doc: Doc, field="template_notes") {
- // const tempNotes = DocCast(doc[field]);
- // const reqdTempOpts:DocumentOptions[] = [
- // { title: "Postit", backgroundColor: "yellow", icon: "sticky-note", _layout_showTitle: "title", layout_borderRounding: "5px"},
- // { title: "Idea", backgroundColor: "pink", icon: "lightbulb" , _layout_showTitle: "title"},
- // { title: "Topic", backgroundColor: "lightblue", icon: "book-open" , _layout_showTitle: "title"}];
- // const reqdNoteList = [...reqdTempOpts.map(opts => {
- // const reqdOpts = {...opts, isSystem:true, width:200, layout_autoHeight: true, layout_fitWidth: true};
- // const noteTemp = tempNotes ? DocListCast(tempNotes.data).find(fdoc => fdoc.title === opts.title): undefined;
- // return DocUtils.AssignOpts(noteTemp, reqdOpts) ?? MakeTemplate(Docs.Create.TextDocument("",reqdOpts));
- // }), ... DocListCast(tempNotes?.data).filter(note => !reqdTempOpts.find(reqd => reqd.title === note.title))];
-
- // const reqdOpts:DocumentOptions = { title: "Note Layouts", _height: 75, isSystem: true };
- // // eslint-disable-next-line no-return-assign
- // r
+ static setupLightboxDrawingPreviews(doc: Doc, field="myLightboxDrawings") {
+ const reqdOpts:DocumentOptions = {
+ title: "Preview", _layout_fitWidth: true, childLayoutFitWidth: true,
+ };
+ const reqdScripts = {};
+ const drawings = DocCast(doc[field]);
+ return DocUtils.AssignDocField(doc, field, (opts,items) => Docs.Create.CarouselDocument(items??[], opts), reqdOpts, DocListCast(drawings?.data), reqdScripts);
+ }
// setup templates for different document types when they are iconified from Document Decorations
static setupDefaultIconTemplates(doc: Doc, field="template_icons") {
@@ -1015,6 +1008,7 @@ pie title Minerals in my tap water
this.setupDockedButtons(doc); // the bottom bar of font icons
this.setupLeftSidebarMenu(doc); // the left-side column of buttons that open their contents in a flyout panel on the left
this.setupAnnoPalette(doc);
+ this.setupLightboxDrawingPreviews(doc);
this.setupDocTemplates(doc); // sets up the template menu of templates
// sthis.setupFieldInfos(doc); // sets up the collection of field info descriptions for each possible DocumentOption
DocUtils.AssignDocField(doc, "globalScriptDatabase", () => Docs.Prototypes.MainScriptDocument(), {});
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 0314af06b..3e26fefad 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -86,6 +86,28 @@ export function makeUserTemplateButton(doc: Doc) {
dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory)');
return dbox;
}
+
+export function makeUserTemplateImage(doc: Doc, image: ImageField) {
+ const layoutDoc = doc; // doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc;
+ if (layoutDoc.type !== DocumentType.FONTICON) {
+ !layoutDoc.isTemplateDoc && makeTemplate(layoutDoc);
+ }
+ layoutDoc.isTemplateDoc = true;
+ const dbox = Docs.Create.ImageDocument(image, {
+ _nativeWidth: 100,
+ _nativeHeight: 100,
+ _width: 100,
+ _height: 100,
+ title: StrCast(layoutDoc.title),
+ isSystem: false,
+ });
+ dbox.title = ComputedField.MakeFunction('this.dragFactory.title');
+ dbox.dragFactory = layoutDoc;
+ dbox.dropPropertiesToRemove = doc.dropPropertiesToRemove instanceof ObjectField ? ObjectField.MakeCopy(doc.dropPropertiesToRemove) : undefined;
+ dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory)');
+ return dbox;
+}
+
export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
data?.draggedDocuments.forEach((doc, i) => {
let dbox = doc;
diff --git a/src/client/util/bezierFit.ts b/src/client/util/bezierFit.ts
index 98a6feea0..6a4577506 100644
--- a/src/client/util/bezierFit.ts
+++ b/src/client/util/bezierFit.ts
@@ -694,7 +694,7 @@ export function SVGToBezier(name: SVGType, attributes: any): Point[] {
const matches: RegExpMatchArray[] = Array.from(
attributes.d.matchAll(/Q(-?\d+\.?\d*),(-?\d+\.?\d*) (-?\d+\.?\d*),(-?\d+\.?\d*)|C(-?\d+\.?\d*),(-?\d+\.?\d*) (-?\d+\.?\d*),(-?\d+\.?\d*) (-?\d+\.?\d*),(-?\d+\.?\d*)|L(-?\d+\.?\d*),(-?\d+\.?\d*)/g)
);
- let lastPt: Point;
+ let lastPt: Point = { X: 0, Y: 0 };
matches.forEach(match => {
if (match[0].startsWith('Q')) {
coordList.push({ X: parseInt(match[1]), Y: parseInt(match[2]) });
@@ -726,6 +726,17 @@ export function SVGToBezier(name: SVGType, attributes: any): Point[] {
}
return coordList;
case 'polygon':
+ const coords: RegExpMatchArray[] = Array.from(attributes.points.matchAll(/(-?\d+\.?\d*),(-?\d+\.?\d*)/g));
+ let list: Point[] = [];
+ coords.forEach(coord => {
+ list.push({ X: parseInt(coord[1]), Y: parseInt(coord[2]) });
+ list.push({ X: parseInt(coord[1]), Y: parseInt(coord[2]) });
+ list.push({ X: parseInt(coord[1]), Y: parseInt(coord[2]) });
+ list.push({ X: parseInt(coord[1]), Y: parseInt(coord[2]) });
+ });
+ const firstPts = list.splice(0, 2);
+ list = list.concat(firstPts);
+ return list;
default:
return [];
}
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index eb0b00472..6950bec14 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -249,7 +249,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
saveAnno = action((targetDoc: Doc) => {
// targetDoc.savedAsAnno = true;
this._annoSaved = true;
- AnnotationPalette.Instance.addToPalette(targetDoc);
+ // AnnotationPalette.addToPalette(targetDoc);
});
@computed
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index a229b15db..ae4f5b98b 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -229,6 +229,11 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
if (iconViewDoc.activeFrame) {
iconViewDoc.opacity = 0; // bcz: hacky ... allows inkMasks and other documents to be "turned off" without removing them from the animated collection which allows them to function properly in a presenation.
} else {
+ // to mark annotations as no longer saved if they're deleted from the palette
+ const dragFactory: Doc = DocCast(iconView.Document.dragFactory);
+ if (dragFactory && DocCast(dragFactory.cloneOf).savedAsAnno) {
+ DocCast(dragFactory.cloneOf).savedAsAnno = undefined;
+ }
iconView._props.removeDocument?.(iconView.Document);
}
});
@@ -872,4 +877,4 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
</div>
);
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 4fcb7ec9c..b0d469674 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -12,7 +12,7 @@ import { emptyFunction } from '../../Utils';
import { CreateLinkToActiveAudio, Doc, DocListCast, FieldResult, Opt } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { InkTool } from '../../fields/InkField';
-import { Cast, NumCast, toList } from '../../fields/Types';
+import { Cast, DocCast, NumCast, toList } from '../../fields/Types';
import { SnappingManager } from '../util/SnappingManager';
import { Transform } from '../util/Transform';
import { GestureOverlay } from './GestureOverlay';
@@ -43,13 +43,11 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
* @returns true if a DocumentView is descendant of the lightbox view
*/
public static Contains(view?: DocumentView) {
- return true;
- }
- // return (
- // (view && LightboxView.Instance?._docView && (view.containerViewPath?.() ?? []).concat(view).includes(LightboxView.Instance?._docView)) ||
- // view?.Document === AnnotationPalette.Instance.FreeformCanvas ||
- // view?.Document.embedContainer === AnnotationPalette.Instance.DrawingCarousel
- // ); } // prettier-ignore
+ return (
+ (view && LightboxView.Instance?._docView && (view.containerViewPath?.() ?? []).concat(view).includes(LightboxView.Instance?._docView)) ||
+ (view && LightboxView.Instance?._annoPaletteView?.Contains(view))
+ );
+ } // prettier-ignore
public static LightboxDoc = () => LightboxView.Instance?._doc;
// eslint-disable-next-line no-use-before-define
static Instance: LightboxView;
@@ -69,6 +67,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
@observable private _docTarget: Opt<Doc> = undefined;
@observable private _docView: Opt<DocumentView> = undefined;
@observable private _showPalette: boolean = false;
+ private _annoPaletteView: AnnotationPalette | null = null;
@computed get leftBorder() { return Math.min(this._props.PanelWidth / 4, this._props.maxBorder[0]); } // prettier-ignore
@computed get topBorder() { return Math.min(this._props.PanelHeight / 4, this._props.maxBorder[1]); } // prettier-ignore
@@ -114,7 +113,6 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
this._history = [];
Doc.ActiveTool = InkTool.None;
SnappingManager.SetExploreMode(false);
- AnnotationPalette.Instance.displayPalette(false);
this._showPalette = false;
}
DocumentView.DeselectAll();
@@ -217,8 +215,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
};
togglePalette = () => {
this._showPalette = !this._showPalette;
- AnnotationPalette.Instance.displayPalette(this._showPalette);
- if (this._showPalette === false) AnnotationPalette.Instance.resetPalette(true);
+ // if (this._showPalette === false) AnnotationPalette.Instance.resetPalette(true);
};
togglePen = () => {
Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen;
@@ -324,6 +321,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
</GestureOverlay>
</div>
+ {this._showPalette && <AnnotationPalette ref={r => (this._annoPaletteView = r)} Document={DocCast(Doc.UserDoc().myLightboxDrawings)} />}
{this.renderNavBtn(0, undefined, this._props.PanelHeight / 2 - 12.5, 'chevron-left', this._doc && this._history.length, this.previous)}
{this.renderNavBtn(
this._props.PanelWidth - Math.min(this._props.PanelWidth / 4, this._props.maxBorder[0]),
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index fd1af7547..757fc3fe2 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1119,7 +1119,6 @@ export class MainView extends ObservableReactComponent<{}> {
<GPTPopup key="gptpopup" />
<SchemaCSVPopUp key="schemacsvpopup" />
<GenerativeFill imageEditorOpen={ImageEditor.Open} imageEditorSource={ImageEditor.Source} imageRootDoc={ImageEditor.RootDoc} addDoc={ImageEditor.AddDoc} />
- <AnnotationPalette />
</div>
);
}
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx
index 27c85533f..241087fd2 100644
--- a/src/client/views/collections/CollectionCarousel3DView.tsx
+++ b/src/client/views/collections/CollectionCarousel3DView.tsx
@@ -78,7 +78,7 @@ export class CollectionCarousel3DView extends CollectionSubView() {
// suppressSetHeight={true}
NativeWidth={returnZero}
NativeHeight={returnZero}
- fitWidth={undefined}
+ fitWidth={this._props.childLayoutFitWidth}
onDoubleClickScript={this.onChildDoubleClick}
renderDepth={this._props.renderDepth + 1}
LayoutTemplate={this._props.childLayoutTemplate}
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 2adad68e0..8b083de15 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -8,7 +8,7 @@ import * as React from 'react';
import { StopEvent, returnFalse, returnOne, returnTrue, returnZero } from '../../../ClientUtils';
import { emptyFunction } from '../../../Utils';
import { Doc, Opt } from '../../../fields/Doc';
-import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { DocumentType } from '../../documents/DocumentTypes';
import { DragManager } from '../../util/DragManager';
import { ContextMenu } from '../ContextMenu';
@@ -144,6 +144,7 @@ export class CollectionCarouselView extends CollectionSubView() {
revealItems.push({description: 'Quiz Cards', event: () => {this.layoutDoc.filterOp = cardMode.QUIZ;}, icon: 'pencil',}); // prettier-ignore
!revealOptions && cm.addItem({ description: 'Filter Flashcards', addDivider: false, noexpand: true, subitems: revealItems, icon: 'layer-group' });
};
+ childFitWidth = (doc: Doc) => Cast(this.Document.childLayoutFitWidth, 'boolean', this._props.childLayoutFitWidth?.(doc) ?? Cast(doc.layout_fitWidth, 'boolean', null));
@computed get content() {
const index = NumCast(this.layoutDoc._carousel_index);
const curDoc = this.carouselItems?.[index];
@@ -154,10 +155,11 @@ export class CollectionCarouselView extends CollectionSubView() {
<div className="collectionCarouselView-image" key="image">
<DocumentView
{...this._props}
- NativeWidth={returnZero}
- NativeHeight={returnZero}
- fitWidth={undefined}
+ // NativeWidth={returnZero}
+ // NativeHeight={returnZero}
+ fitWidth={returnTrue}
setContentViewBox={undefined}
+ containerViewPath={this.DocumentView?.().docViewPath}
onDoubleClickScript={this.onContentDoubleClick}
onClickScript={this.onContentClick}
isDocumentActive={this._props.childDocumentsActive?.() ? this._props.isDocumentActive : this._props.isContentActive}
@@ -169,6 +171,7 @@ export class CollectionCarouselView extends CollectionSubView() {
Document={curDoc.layout}
TemplateDataDocument={DocCast(curDoc.layout.resolvedDataDoc)}
PanelHeight={this.panelHeight}
+ PanelWidth={this._props.PanelWidth}
/>
</div>
{!carouselShowsCaptions ? null : (
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d0f65866b..f2b94fabc 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1312,7 +1312,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._drawing.push(inkDoc);
this.addDocument(inkDoc);
});
- const collection = containerDoc || this._marqueeViewRef.current?.collection(undefined, true, this._drawing);
+ const collection = this._marqueeViewRef.current?.collection(undefined, true, this._drawing);
if (collection) {
const docData = collection[DocData];
docData.title = opts.text.match(/^(.*?)~~~.*$/)?.[1] || opts.text;
@@ -1329,14 +1329,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
removeDrawing = (doc?: Doc) => {
this._batch = UndoManager.StartBatch('regenerateDrawing');
if (doc) {
- const docData = DocCast(doc[DocData]);
+ const docData = doc[DocData];
const children = DocListCast(docData.data);
+ this._props.removeDocument?.(doc);
this._props.removeDocument?.(children);
- // this._props.removeDocument?.(doc);
} else {
- this._props.removeDocument?.(this._drawing);
- // if (this._drawingContainer) this._props.removeDocument?.(this._drawingContainer);
+ if (this._drawingContainer) this._props.removeDocument?.(this._drawingContainer);
}
+ this._drawing = [];
};
@action
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 5aff3ed6f..8560323c9 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -363,7 +363,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
this.hideMarquee();
});
- getCollection = action((selected: Doc[], creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, makeGroup: Opt<boolean>) => {
+ public static getCollection = action((selected: Doc[], creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, makeGroup: Opt<boolean>, bounds: MarqueeViewBounds) => {
const newCollection = creator
? creator(selected, { title: 'nested stack' })
: ((doc: Doc) => {
@@ -375,14 +375,13 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
return doc;
})(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true));
newCollection.isSystem = undefined;
- newCollection._width = this.Bounds.width || 1; // if width/height are unset/0, then groups won't autoexpand to contain their children
- newCollection._height = this.Bounds.height || 1;
+ newCollection._width = bounds.width || 1; // if width/height are unset/0, then groups won't autoexpand to contain their children
+ newCollection._height = bounds.height || 1;
newCollection._dragWhenActive = makeGroup;
- newCollection.x = this.Bounds.left;
- newCollection.y = this.Bounds.top;
+ newCollection.x = bounds.left;
+ newCollection.y = bounds.top;
newCollection.layout_fitWidth = true;
selected.forEach(d => Doc.SetContainer(d, newCollection));
- this.hideMarquee();
return newCollection;
});
@@ -419,7 +418,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
this._props.removeDocument?.(selected);
}
- const newCollection = this.getCollection(selected, (e as KeyboardEvent)?.key === 't' ? Docs.Create.StackingDocument : undefined, group);
+ const newCollection = MarqueeView.getCollection(selected, (e as KeyboardEvent)?.key === 't' ? Docs.Create.StackingDocument : undefined, group, this.Bounds);
newCollection._freeform_panX = this.Bounds.left + this.Bounds.width / 2;
newCollection._freeform_panY = this.Bounds.top + this.Bounds.height / 2;
newCollection._currentFrame = activeFrame;
diff --git a/src/client/views/smartdraw/AnnotationPalette.tsx b/src/client/views/smartdraw/AnnotationPalette.tsx
index c8ce9e653..83f173fcb 100644
--- a/src/client/views/smartdraw/AnnotationPalette.tsx
+++ b/src/client/views/smartdraw/AnnotationPalette.tsx
@@ -8,13 +8,13 @@ import * as React from 'react';
import { AiOutlineSend } from 'react-icons/ai';
import ReactLoading from 'react-loading';
import { returnAll, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero } from '../../../ClientUtils';
-import { ActiveInkWidth, Doc, DocListCast, StrListCast } from '../../../fields/Doc';
+import { ActiveInkWidth, Doc, DocListCast, Opt, StrListCast } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { InkData, InkField } from '../../../fields/InkField';
import { BoolCast, DocCast, ImageCast, NumCast } from '../../../fields/Types';
import { emptyFunction, unimplementedFunction } from '../../../Utils';
import { Docs } from '../../documents/Documents';
-import { makeUserTemplateButton } from '../../util/DropConverter';
+import { makeUserTemplateButton, makeUserTemplateImage } from '../../util/DropConverter';
import { SettingsManager } from '../../util/SettingsManager';
import { Transform } from '../../util/Transform';
import { undoable, undoBatch } from '../../util/UndoManager';
@@ -28,20 +28,18 @@ import { DrawingOptions, SmartDrawHandler } from './SmartDrawHandler';
import { DocumentType } from '../../documents/DocumentTypes';
import { ImageField } from '../../../fields/URLField';
import { CollectionCarousel3DView } from '../collections/CollectionCarousel3DView';
+import { Copy } from '../../../fields/FieldSymbols';
@observer
-export class AnnotationPalette extends ObservableReactComponent<{}> {
+export class AnnotationPalette extends ObservableReactComponent<{ Document: Doc }> {
static Instance: AnnotationPalette;
- @observable private _display: boolean = false;
@observable private _paletteMode: 'create' | 'view' = 'view';
@observable private _userInput: string = '';
@observable private _isLoading: boolean = false;
@observable private _canInteract: boolean = true;
@observable private _showRegenerate: boolean = false;
- @observable private _freeFormCanvas = Docs.Create.FreeformDocument([], {});
- @observable private _drawingCarousel = Docs.Create.CarouselDocument([], {});
- @observable private _drawings: Doc[] = [];
- private _drawing: Doc[] = [];
+ @observable private _docView: DocumentView | null = null;
+ @observable private _docCarouselView: DocumentView | null = null;
@observable private _opts: DrawingOptions = { text: '', complexity: 5, size: 200, autoColor: true, x: 0, y: 0 };
private _gptRes: string[] = [];
@@ -55,33 +53,16 @@ export class AnnotationPalette extends ObservableReactComponent<{}> {
return FieldView.LayoutString(AnnotationPalette, fieldKey);
}
- public get FreeformCanvas() {
- return this._freeFormCanvas;
- }
-
- public get DrawingCarousel() {
- return this._drawingCarousel;
- }
-
- // componentDidUpdate(prevProps: Readonly<{}>) {
- // const docView = DocumentView.getDocumentView(this._freeFormCanvas);
- // const componentView = docView?.ComponentView as CollectionFreeFormView;
- // if (componentView) {
- // componentView.fitContentOnce();
- // }
- // this._freeFormCanvas._freeform_fitContentsToBox = false;
- // }
+ Contains = (view: DocumentView) => {
+ return (this._docView && (view.containerViewPath?.() ?? []).concat(view).includes(this._docView)) || (this._docCarouselView && (view.containerViewPath?.() ?? []).concat(view).includes(this._docCarouselView));
+ };
return170 = () => 170;
@action
handleKeyPress = async (event: React.KeyboardEvent) => {
if (event.key === 'Enter') {
- // if (this._showRegenerate) {
- // this.regenerate();
- // } else {
await this.generateDrawing();
- // }
}
};
@@ -117,42 +98,34 @@ export class AnnotationPalette extends ObservableReactComponent<{}> {
this.setDetail(5);
this.setColor(true);
this.setSize(200);
- this._freeFormCanvas = Docs.Create.FreeformDocument([], {});
- this._drawingCarousel = Docs.Create.CarouselDocument([], {});
this._showRegenerate = false;
this._canInteract = true;
- this._drawing = [];
- this._drawings = [];
this._opts = { text: '', complexity: 5, size: 200, autoColor: true, x: 0, y: 0 };
this._gptRes = [];
};
- addToPalette = async (doc: Doc) => {
- if (!doc.savedAsAnno) {
- const clone = await Doc.MakeClone(doc);
- clone.clone.title = doc.title;
- const image = await this.getIcon(doc);
- if (image) {
- const imageDoc = Docs.Create.ImageDocument(image);
- Doc.AddDocToList(Doc.MyAnnos, 'data', imageDoc);
- }
- doc.savedAsAnno = true;
- // const templateBtn = makeUserTemplateButton(clone.clone);
- // Doc.AddDocToList(Doc.MyAnnos, 'data', templateBtn);
- // this.resetPalette(true);
- }
+ public static addToPalette = async (doc: Doc) => {
+ // if (!doc.savedAsAnno) {
+ // const clone = await Doc.MakeClone(doc);
+ // clone.clone.title = doc.title;
+ // const image = (await this.getIcon(doc))?.[Copy]();
+ // if (image) {
+ // const imageTemplate = makeUserTemplateImage(clone.clone, image);
+ // Doc.AddDocToList(Doc.MyAnnos, 'data', imageTemplate);
+ // doc.savedAsAnno = true;
+ // }
+ // this.resetPalette(true);
+ // }
};
- @action
- displayPalette = (display: boolean) => {
- this._display = display;
- };
+ // @action
+ // displayPalette = (display: boolean) => {
+ // this._display = display;
+ // };
@undoBatch
generateDrawing = action(async () => {
this._isLoading = true;
- this._drawings = [];
- this._drawing = [];
for (var i = 0; i < 3; i++) {
try {
SmartDrawHandler.Instance._addFunc = this.createDrawing;
@@ -177,8 +150,8 @@ export class AnnotationPalette extends ObservableReactComponent<{}> {
createDrawing = (strokeList: [InkData, string, string][], opts: DrawingOptions, gptRes: string) => {
this._opts = opts;
this._gptRes.push(gptRes);
- this._drawing = [];
- // const childDocs = DocListCast(this._drawing1[DocData].data);
+ const drawing: Doc[] = [];
+
strokeList.forEach((stroke: [InkData, string, string]) => {
const bounds = InkField.getBounds(stroke[0]);
const inkWidth = ActiveInkWidth();
@@ -199,51 +172,27 @@ export class AnnotationPalette extends ObservableReactComponent<{}> {
ActiveDash(),
ActiveIsInkMask()
);
- this._drawing.push(inkDoc);
- // childDocs.push(inkDoc);
+ drawing.push(inkDoc);
});
- const cv = DocumentView.getDocumentView(this._freeFormCanvas)?.ComponentView as CollectionFreeFormView;
- const collection = cv._marqueeViewRef.current?.collection(undefined, true, this._drawing);
+ const collection = MarqueeView.getCollection(drawing, undefined, true, { left: 1, top: 1, width: 1, height: 1 });
if (collection) {
- this._drawings.push(collection);
- cv.fitContentOnce();
+ Doc.AddDocToList(this._props.Document, 'data', collection);
}
- this._drawingCarousel = Docs.Create.CarouselDocument(this._drawings, { childLayoutFitWidth: true, _layout_fitWidth: true, _freeform_fitContentsToBox: true });
- this._freeFormCanvas = Docs.Create.FreeformDocument(this._drawing, { _freeform_fitContentsToBox: true });
};
saveDrawing = async () => {
- // const cv = DocumentView.getDocumentView(this._freeFormCanvas)?.ComponentView as CollectionFreeFormView;
- // if (cv) {
- // const collection = cv._marqueeViewRef.current?.collection(undefined, true, this._drawing);
- const cIndex: number = this._drawingCarousel.carousel_index as number;
- const focusedDrawing = this._drawings[cIndex];
-
- const docData = focusedDrawing[DocData];
- docData.title = this._opts.text.match(/^(.*?)~~~.*$/)?.[1] || this._opts.text;
- docData.drawingInput = this._opts.text;
- docData.drawingComplexity = this._opts.complexity;
- docData.drawingColored = this._opts.autoColor;
- docData.drawingSize = this._opts.size;
- docData.drawingData = this._gptRes[cIndex];
- docData.width = this._opts.size;
- // const image = await this.getIcon(collection);
- await this.addToPalette(focusedDrawing);
-
- // if (collection) {
- // const docData = collection[DocData];
- // docData.title = this._opts.text.match(/^(.*?)~~~.*$/)?.[1] || this._opts.text;
- // docData.drawingInput = this._opts.text;
- // docData.drawingComplexity = this._opts.complexity;
- // docData.drawingColored = this._opts.autoColor;
- // docData.drawingSize = this._opts.size;
- // docData.drawingData = this._gptRes;
- // docData.width = this._opts.size;
- // // const image = await this.getIcon(collection);
- // await this.addToPalette(collection);
- // }
- // }
+ // const cIndex: number = this._drawingCarousel.carousel_index as number;
+ // const focusedDrawing = this._drawings[cIndex];
+ // const docData = focusedDrawing[DocData];
+ // docData.title = this._opts.text.match(/^(.*?)~~~.*$/)?.[1] || this._opts.text;
+ // docData.drawingInput = this._opts.text;
+ // docData.drawingComplexity = this._opts.complexity;
+ // docData.drawingColored = this._opts.autoColor;
+ // docData.drawingSize = this._opts.size;
+ // docData.drawingData = this._gptRes[cIndex];
+ // docData.width = this._opts.size;
+ // await AnnotationPalette.addToPalette(focusedDrawing);
};
async getIcon(group: Doc) {
@@ -255,36 +204,13 @@ export class AnnotationPalette extends ObservableReactComponent<{}> {
return undefined;
}
- @computed get drawingCreator() {
- return (
- <DocumentView
- Document={this._freeFormCanvas}
- addDocument={undefined}
- addDocTab={DocumentViewInternal.addDocTabFunc}
- pinToPres={DocumentView.PinDoc}
- containerViewPath={returnEmptyDoclist}
- styleProvider={DefaultStyleProvider}
- removeDocument={returnFalse}
- ScreenToLocalTransform={Transform.Identity}
- PanelWidth={this.return170}
- PanelHeight={this.return170}
- renderDepth={1}
- isContentActive={returnTrue}
- focus={emptyFunction}
- whenChildContentsActiveChanged={emptyFunction}
- childFilters={returnEmptyFilter}
- childFiltersByRanges={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- />
- );
- }
-
render() {
- return !this._display ? null : (
+ return (
<div className="annotation-palette" style={{ zIndex: 1000 }}>
{this._paletteMode === 'view' && (
<>
<DocumentView
+ ref={r => (this._docView = r)}
Document={Doc.MyAnnos}
addDocument={undefined}
addDocTab={DocumentViewInternal.addDocTabFunc}
@@ -303,34 +229,19 @@ export class AnnotationPalette extends ObservableReactComponent<{}> {
childFiltersByRanges={returnEmptyFilter}
searchFilterDocs={returnEmptyDoclist}
/>
- <Button
- // style={{ alignSelf: 'center' }}
- text="Add"
- icon={<FontAwesomeIcon icon="square-plus" />}
- // iconPlacement=""
- color={SettingsManager.userColor}
- onClick={() => this.setPaletteMode('create')}
- />
+ <Button text="Add" icon={<FontAwesomeIcon icon="square-plus" />} color={SettingsManager.userColor} onClick={() => this.setPaletteMode('create')} />
</>
)}
{this._paletteMode === 'create' && (
<>
<div style={{ display: 'flex', flexDirection: 'row', width: '170px' }}>
- {/* <IconButton
- tooltip="Advanced Options"
- icon={<FontAwesomeIcon icon="caret-right" />}
- color={SettingsManager.userColor}
- style={{ width: '14px' }}
- // onClick={() => {
- // this._showOptions = !this._showOptions;
- // }}
- /> */}
<input
aria-label="label-input"
id="new-label"
type="text"
style={{ color: 'black', width: '170px' }}
value={this._userInput}
+ onClick={e => e.stopPropagation()}
onChange={e => {
this.setUserInput(e.target.value);
}}
@@ -423,29 +334,9 @@ export class AnnotationPalette extends ObservableReactComponent<{}> {
/>
</div>
</div>
- <div style={{ display: 'none' }}>
- <DocumentView
- Document={this._freeFormCanvas}
- addDocument={undefined}
- addDocTab={DocumentViewInternal.addDocTabFunc}
- pinToPres={DocumentView.PinDoc}
- containerViewPath={returnEmptyDoclist}
- styleProvider={DefaultStyleProvider}
- removeDocument={returnFalse}
- ScreenToLocalTransform={Transform.Identity}
- PanelWidth={this.return170}
- PanelHeight={this.return170}
- renderDepth={1}
- isContentActive={returnTrue}
- focus={emptyFunction}
- whenChildContentsActiveChanged={emptyFunction}
- childFilters={returnEmptyFilter}
- childFiltersByRanges={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- />
- </div>
<DocumentView
- Document={this._drawingCarousel}
+ ref={r => (this._docCarouselView = r)}
+ Document={this._props.Document}
addDocument={undefined}
addDocTab={DocumentViewInternal.addDocTabFunc}
pinToPres={DocumentView.PinDoc}
diff --git a/src/client/views/smartdraw/SmartDrawHandler.tsx b/src/client/views/smartdraw/SmartDrawHandler.tsx
index 489f6f92b..ca65ea388 100644
--- a/src/client/views/smartdraw/SmartDrawHandler.tsx
+++ b/src/client/views/smartdraw/SmartDrawHandler.tsx
@@ -99,7 +99,7 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
@action
displayRegenerate = (x: number, y: number, addFunc: (strokeData: [InkData, string, string][], opts: DrawingOptions, gptRes: string, containerDoc?: Doc) => void, deleteFunc: (doc?: Doc) => void) => {
- this._selectedDoc = DocumentView.SelectedDocs().lastElement();
+ this._selectedDoc = DocumentView.SelectedDocs()?.lastElement();
const docData = this._selectedDoc[DocData];
this._addFunc = addFunc;
this._deleteFunc = deleteFunc;
@@ -123,7 +123,6 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
this._size = 350;
this._autoColor = true;
Doc.ActiveTool = InkTool.None;
- this._lastInput = { text: '', complexity: 5, size: 350, autoColor: true, x: 0, y: 0 };
};
@action
@@ -154,8 +153,6 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
} else {
this._showOptions = false;
await this.drawWithGPT({ X: this._pageX, Y: this._pageY }, this._userInput, this._complexity, this._size, this._autoColor);
- this.hideSmartDrawHandler();
- this._showRegenerate = true;
}
this._isLoading = false;
this._canInteract = true;
@@ -176,6 +173,8 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
console.log(res);
const strokeData = await this.parseResponse(res, startPt, false, autoColor);
this._errorOccurredOnce = false;
+ this.hideSmartDrawHandler();
+ this._showRegenerate = true;
return strokeData;
} catch (err) {
if (this._errorOccurredOnce) {
@@ -239,7 +238,7 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
});
if (regenerate) {
if (this._deleteFunc !== unimplementedFunction) this._deleteFunc(this._selectedDoc);
- this._addFunc(strokeData, this._lastInput, svg[0], this._selectedDoc);
+ this._addFunc(strokeData, this._lastInput, svg[0]);
} else {
this._addFunc(strokeData, this._lastInput, svg[0]);
}
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index c86342870..c3e96ab49 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -277,6 +277,7 @@ export class Doc extends RefField {
public static get MyDashboards() { return DocCast(Doc.UserDoc().myDashboards); } // prettier-ignore
public static get MyTemplates() { return DocCast(Doc.UserDoc().myTemplates); } // prettier-ignore
public static get MyAnnos() { return DocCast(Doc.UserDoc().myAnnos); } // prettier-ignore
+ public static get MyLightboxDrawings() { return DocCast(Doc.UserDoc().myLightboxDrawings); } // prettier-ignore
public static get MyImports() { return DocCast(Doc.UserDoc().myImports); } // prettier-ignore
public static get MyFilesystem() { return DocCast(Doc.UserDoc().myFilesystem); } // prettier-ignore
public static get MyTools() { return DocCast(Doc.UserDoc().myTools); } // prettier-ignore