aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionFreeForm
diff options
context:
space:
mode:
authorSophie Zhang <sophie_zhang@brown.edu>2023-08-17 17:53:28 -0400
committerSophie Zhang <sophie_zhang@brown.edu>2023-08-17 17:53:28 -0400
commitdef88f33905ae6a1521ca6f36b0863e03effdfba (patch)
treed007f6a1fd0e843879e3cdc8ddd5c3837123e780 /src/client/views/collections/collectionFreeForm
parent592e1a1b1000157db77bd812b8debfbcc45844f9 (diff)
parentbcada17befd639516862163831b9adb823791a93 (diff)
Merge branch 'master' into sophie-ai-images
Diffstat (limited to 'src/client/views/collections/collectionFreeForm')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss7
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx46
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx64
3 files changed, 56 insertions, 61 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index c6419885b..e4ae251c8 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -153,7 +153,12 @@
overflow-y: auto;
overflow-x: hidden;
}
-
+.collectionFreeFormView-brushView {
+ pointer-events: none;
+ position: absolute;
+ transition: opacity 0.5s;
+ z-index: 1000;
+}
.collectionfreeformview-container {
// touch action none means that the browser will handle none of the touch actions. this allows us to implement our own actions.
touch-action: none;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index f353dfab7..91a78c2af 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -319,7 +319,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
// focus on the document in the collection
const didMove = !cantTransform && !anchor.z && (panX !== savedState.panX || panY !== savedState.panY || scale !== savedState.scale);
if (didMove) options.didMove = true;
- // glr: freeform transform speed can be set by adjusting presTransition field - needs a way of knowing when presentation is not active...
+ // glr: freeform transform speed can be set by adjusting presentation_transition field - needs a way of knowing when presentation is not active...
if (didMove) {
const focusTime = options?.instant ? 0 : options.zoomTime ?? 500;
(options.zoomScale ?? options.willZoomCentered) && scale && (this.Document[this.scaleFieldKey] = scale);
@@ -681,6 +681,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
case GestureUtils.Gestures.Stroke:
const points = ge.points;
const B = this.getTransform().transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
+ console.log(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
const inkDoc = Docs.Create.InkDocument(
ActiveInkColor(),
ActiveInkWidth() * this.props.ScreenToLocalTransform().Scale,
@@ -1050,7 +1051,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
onPointerWheel = (e: React.WheelEvent): void => {
if (this.Document._isGroup || !this.isContentActive()) return; // group style collections neither pan nor zoom
PresBox.Instance?.pauseAutoPres();
- if (this.layoutDoc._Transform || this.props.Document.treeViewOutlineMode === TreeViewType.outline) return;
+ if (this.layoutDoc._Transform || this.props.Document.treeView_OutlineMode === TreeViewType.outline) return;
e.stopPropagation();
const docHeight = NumCast(this.rootDoc[Doc.LayoutFieldKey(this.rootDoc) + '_nativeHeight'], this.nativeHeight);
const scrollable = NumCast(this.layoutDoc[this.scaleFieldKey], 1) === 1 && docHeight > this.props.PanelHeight() / this.nativeDimScaling + 1e-4;
@@ -1318,7 +1319,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
layout_showTitle={this.props.childlayout_showTitle}
dontRegisterView={this.props.dontRenderDocuments || this.props.dontRegisterView}
pointerEvents={this.pointerEvents}
- //fitContentsToBox={this.props.fitContentsToBox || BoolCast(this.props.treeViewFreezeChildDimensions)} // bcz: check this
+ //fitContentsToBox={this.props.fitContentsToBox || BoolCast(this.props.treeView_FreezeChildDimensions)} // bcz: check this
/>
);
}
@@ -1537,7 +1538,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
// create an anchor that saves information about the current state of the freeform view (pan, zoom, view type)
- const anchor = Docs.Create.ConfigDocument({ title: 'ViewSpec - ' + StrCast(this.layoutDoc._type_collection), layout_unrendered: true, presTransition: 500, annotationOn: this.rootDoc });
+ const anchor = Docs.Create.ConfigDocument({ title: 'ViewSpec - ' + StrCast(this.layoutDoc._type_collection), layout_unrendered: true, presentation_transition: 500, annotationOn: this.rootDoc });
PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), pannable: !this.Document._isGroup, type_collection: true, filters: true } }, this.rootDoc);
if (addAsAnnotation) {
@@ -1883,6 +1884,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
showPresPaths = () => (CollectionFreeFormView.ShowPresPaths ? PresBox.Instance.getPaths(this.rootDoc) : null);
+ brushedView = () => this._brushedView;
@computed get marqueeView() {
TraceMobx();
return (
@@ -1925,13 +1927,13 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
</div>
) : null}
<CollectionFreeFormViewPannableContents
- brushView={this._brushedView}
+ brushedView={this.brushedView}
isAnnotationOverlay={this.isAnnotationOverlay}
isAnnotationOverlayScrollable={this.props.isAnnotationOverlayScrollable}
transform={this.contentTransform}
zoomScaling={this.zoomScaling}
presPaths={this.showPresPaths}
- presPinView={BoolCast(this.Document.presPinView)}
+ presPinView={BoolCast(this.Document.config_pinView)}
transition={this._panZoomTransition ? `transform ${this._panZoomTransition}ms` : Cast(this.layoutDoc._viewTransition, 'string', Cast(this.props.DocumentView?.()?.rootDoc._viewTransition, 'string', null))}
viewDefDivClick={this.props.viewDefDivClick}>
{this.children}
@@ -1962,19 +1964,19 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
@action
- brushView = (viewport: { width: number; height: number; panX: number; panY: number }) => {
- this._brushedView = { ...viewport, panX: viewport.panX - viewport.width / 2, panY: viewport.panY - viewport.height / 2, opacity: 1 };
+ brushView = (viewport: { width: number; height: number; panX: number; panY: number }, transTime: number) => {
this._brushtimer1 && clearTimeout(this._brushtimer1);
this._brushtimer && clearTimeout(this._brushtimer);
+ this._brushedView = { width: 0, height: 0, panX: 0, panY: 0, opacity: 0 };
this._brushtimer1 = setTimeout(
action(() => {
- this._brushedView.opacity = 0;
+ this._brushedView = { ...viewport, panX: viewport.panX - viewport.width / 2, panY: viewport.panY - viewport.height / 2, opacity: 1 };
this._brushtimer = setTimeout(
- action(() => (this._brushedView = { width: 0, height: 0, panX: 0, panY: 0, opacity: 0 })),
- 500
+ action(() => (this._brushedView.opacity = 0)),
+ 2500
);
}),
- 1000
+ transTime + 1
);
};
lightboxPanelWidth = () => Math.max(0, this.props.PanelWidth() - 30);
@@ -2101,7 +2103,7 @@ interface CollectionFreeFormViewPannableContentsProps {
presPinView?: boolean;
isAnnotationOverlay: boolean | undefined;
isAnnotationOverlayScrollable: boolean | undefined;
- brushView: { panX: number; panY: number; width: number; height: number; opacity: number };
+ brushedView: () => { panX: number; panY: number; width: number; height: number; opacity: number };
}
@observer
@@ -2173,6 +2175,7 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
}
render() {
+ const brushedView = this.props.brushedView();
return (
<div
className={'collectionfreeformview' + (this.props.viewDefDivClick ? '-viewDef' : '-none')}
@@ -2190,21 +2193,18 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
//willChange: "transform"
}}>
{this.props.children}
- {!this.props.brushView.width ? null : (
+ {
<div
className="collectionFreeFormView-brushView"
style={{
- zIndex: 1000,
- opacity: this.props.brushView.opacity,
- border: 'orange solid 2px',
- position: 'absolute',
- transform: `translate(${this.props.brushView.panX}px, ${this.props.brushView.panY}px)`,
- width: this.props.brushView.width,
- height: this.props.brushView.height,
- transition: 'opacity 2s',
+ opacity: brushedView.opacity,
+ transform: `translate(${brushedView.panX}px, ${brushedView.panY}px)`,
+ width: brushedView.width,
+ height: brushedView.height,
+ border: `orange solid ${brushedView.width * 0.005}px`,
}}
/>
- )}
+ }
{this.presPaths}
</div>
);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 7c53bfdbe..1c3da1dc5 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -170,7 +170,15 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
TreeView._editTitleOnLoad = { id: slide[Id], parent: undefined };
this.props.addDocument?.(slide);
e.stopPropagation();
- }*/ else if (!e.ctrlKey && !e.metaKey && SelectionManager.Views().length < 2) {
+ }*/ else if (e.key === 'p' && e.ctrlKey) {
+ e.preventDefault();
+ (async () => {
+ const text: string = await navigator.clipboard.readText();
+ const ns = text.split('\n').filter(t => t.trim() !== '\r' && t.trim() !== '');
+ this.pasteTable(ns, x, y);
+ })();
+ e.stopPropagation();
+ } else if (!e.ctrlKey && !e.metaKey && SelectionManager.Views().length < 2) {
FormattedTextBox.SelectOnLoadChar = Doc.UserDoc().defaultTextLayout && !this.props.childLayoutString ? e.key : '';
FormattedTextBox.LiveTextUndo = UndoManager.StartBatch('type new note');
this.props.addLiveTextDocument(DocUtils.GetNewTextDoc('-typed text-', x, y, 200, 100, this.props.xPadding === 0));
@@ -185,44 +193,26 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
// any row that has only one column is a section header-- this header is then added as a column to subsequent rows until the next header
// assumes each cell is a string or a number
pasteTable(ns: string[], x: number, y: number) {
- while (ns.length > 0 && ns[0].split('\t').length < 2) {
- ns.splice(0, 1);
- }
- if (ns.length > 0) {
- const columns = ns[0].split('\t');
- const docList: Doc[] = [];
- let groupAttr: string | number = '';
- const rowProto = new Doc();
- rowProto.title = rowProto.Id;
- rowProto._width = 200;
- rowProto.isDataDoc = true;
- for (let i = 1; i < ns.length - 1; i++) {
- const values = ns[i].split('\t');
- if (values.length === 1 && columns.length > 1) {
- groupAttr = values[0];
- continue;
- }
- const docDataProto = Doc.MakeDelegate(rowProto);
- docDataProto.isDataDoc = true;
- columns.forEach((col, i) => (docDataProto[columns[i]] = values.length > i ? (values[i].indexOf(Number(values[i]).toString()) !== -1 ? Number(values[i]) : values[i]) : undefined));
- if (groupAttr) {
- docDataProto._group = groupAttr;
- }
- docDataProto.title = i.toString();
- const doc = Doc.MakeDelegate(docDataProto);
- doc._width = 200;
- docList.push(doc);
+ let csvRows = [];
+ const headers = ns[0].split('\t');
+ csvRows.push(headers.join(','));
+ ns[0] = '';
+ const eachCell = ns.join('\t').split('\t')
+ let eachRow = []
+ for (let i=1; i<eachCell.length; i++){
+ eachRow.push(eachCell[i].replace(/\,/g, ''));
+ if (i % headers.length == 0){
+ csvRows.push(eachRow)
+ eachRow = [];
}
- const newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField('_group', '#f1efeb')] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c, '#f1efeb'))], docList, {
- x: x,
- y: y,
- title: 'droppedTable',
- _width: 300,
- _height: 100,
- });
-
- this.props.addDocument?.(newCol);
}
+
+ const blob = new Blob([csvRows.join('\n')], {type: 'text/csv'})
+ const options = { x: x, y: y, title: 'droppedTable', _width: 300, _height: 100, type:'text/csv'}
+ const file = new File([blob], 'droppedTable', options);
+ const loading = Docs.Create.LoadingDocument(file, options);
+ DocUtils.uploadFileToDoc(file, {}, loading);
+ this.props.addDocument?.(loading);
}
@action