aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionNoteTakingView.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2022-08-03 13:33:38 -0400
committerbobzel <zzzman@gmail.com>2022-08-03 13:33:38 -0400
commit55bac585fa0b8d6c3f513ccecb22456d1d361040 (patch)
tree3c4886b07ba775e656f264874d8552992f087abd /src/client/views/collections/CollectionNoteTakingView.tsx
parent4ad4936393d11227934fdda2c18bea3446b20795 (diff)
fixes for dragging notes so that they highlight properly and go to the right place when embedded in freeform views.
Diffstat (limited to 'src/client/views/collections/CollectionNoteTakingView.tsx')
-rw-r--r--src/client/views/collections/CollectionNoteTakingView.tsx91
1 files changed, 49 insertions, 42 deletions
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index f442559fb..1854a4213 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -1,6 +1,6 @@
import React = require('react');
import { CursorProperty } from 'csstype';
-import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { DataSym, Doc, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
@@ -21,10 +21,12 @@ import { ContextMenuProps } from '../ContextMenuItem';
import { LightboxView } from '../LightboxView';
import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from '../nodes/DocumentView';
+import { FieldViewProps } from '../nodes/FieldView';
+import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { StyleProp } from '../StyleProvider';
import './CollectionNoteTakingView.scss';
import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn';
-import CollectionNoteTakingViewDivider from './CollectionNoteTakingViewDivider';
+import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider';
import { CollectionSubView } from './CollectionSubView';
const _global = (window /* browser */ || global) /* node */ as any;
@@ -40,7 +42,6 @@ export type collectionNoteTakingViewProps = {
@observer
export class CollectionNoteTakingView extends CollectionSubView<Partial<collectionNoteTakingViewProps>>() {
- _pivotFieldDisposer?: IReactionDisposer;
_autoHeightDisposer?: IReactionDisposer;
_masonryGridRef: HTMLDivElement | null = null;
_draggerRef = React.createRef<HTMLDivElement>();
@@ -54,10 +55,10 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden);
}
@computed get columnHeaders() {
- return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null);
+ return Cast(this.dataDoc.columnHeaders, listSpec(SchemaHeaderField), null);
}
- @computed get pivotField() {
- return 'Col';
+ @computed get notetakingCategoryField() {
+ return 'noteTakingCategory';
}
@computed get filteredChildren() {
return this.childLayoutPairs.filter(pair => pair.layout instanceof Doc && !pair.layout.hidden).map(pair => pair.layout);
@@ -90,7 +91,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
constructor(props: any) {
super(props);
if (this.columnHeaders === undefined) {
- this.layoutDoc._columnHeaders = new List<SchemaHeaderField>([new SchemaHeaderField('New Column')]);
+ this.dataDoc.columnHeaders = new List<SchemaHeaderField>([new SchemaHeaderField('New Column')]);
this.columnStartXCoords = [0];
// add all of the docs that have not been added to a column to this new column
} else {
@@ -126,18 +127,16 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
// filter out the currently dragged docs from the child docs, since we will insert them later
if (rowCol.length && DragManager.docsBeingDragged.length) {
const docIdsToRemove = new Set();
- DragManager.docsBeingDragged.forEach(d => {
- docIdsToRemove.add(d[Id]);
- });
+ DragManager.docsBeingDragged.forEach(d => docIdsToRemove.add(d[Id]));
docs = docs.filter(d => !docIdsToRemove.has(d[Id]));
}
// this will sort the docs into the correct columns (minus the ones you're currently dragging)
docs.map(d => {
- if (!d[this.pivotField]) {
- d[this.pivotField] = columnHeaders.length > 0 ? columnHeaders[0].heading : `New Column`;
+ if (!d[this.notetakingCategoryField]) {
+ d[this.notetakingCategoryField] = columnHeaders.length > 0 ? columnHeaders[0].heading : `New Column`;
}
- const sectionValue = d[this.pivotField] as object;
+ const sectionValue = d[this.notetakingCategoryField] as object;
// look for if header exists already
const existingHeader = columnHeaders.find(sh => sh.heading === sectionValue.toString());
@@ -156,14 +155,15 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
return sections;
}
+ removeDocDragHighlight = () => {
+ setTimeout(
+ action(() => (this.docsDraggedRowCol.length = 0)),
+ 100
+ );
+ };
componentDidMount() {
super.componentDidMount?.();
- // reset section headers when a new filter is inputted
- this._pivotFieldDisposer = reaction(
- () => this.pivotField,
- () => (this.layoutDoc._columnHeaders = new List())
- );
-
+ document.addEventListener('pointerup', this.removeDocDragHighlight, true);
this._autoHeightDisposer = reaction(
() => this.layoutDoc._autoHeight,
autoHeight => autoHeight && this.props.setHeight?.(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), this.headerMargin + Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace('px', ''))))))
@@ -171,8 +171,8 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
}
componentWillUnmount() {
+ document.removeEventListener('pointerup', this.removeDocDragHighlight, true);
super.componentWillUnmount();
- this._pivotFieldDisposer?.();
this._autoHeightDisposer?.();
}
@@ -227,6 +227,9 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
};
styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string) => {
+ if (property === StyleProp.BoxShadow && doc && DragManager.docsBeingDragged.includes(doc)) {
+ return `#9c9396 ${StrCast(doc?.boxShadow, '10px 10px 0.9vw')}`;
+ }
if (property === StyleProp.Opacity && doc) {
if (this.props.childOpacity) {
return this.props.childOpacity();
@@ -258,9 +261,9 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
docViewPath={this.props.docViewPath}
fitWidth={this.props.childFitWidth}
isContentActive={emptyFunction}
- originalBackgroundColor={StrCast(doc.backgroundColor)}
+ onKey={this.onKeyDown}
//TODO: change this from a prop to a parameter passed into a function
- isNoteTakingView={true}
+ dontHideOnDrag={true}
isDocumentActive={this.isContentActive}
LayoutTemplate={this.props.childLayoutTemplate}
LayoutTemplateString={this.props.childLayoutString}
@@ -307,7 +310,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
// how to get the width of a document. Currently returns the width of the column (minus margins)
// if a note doc. Otherwise, returns the normal width (for graphs, images, etc...)
getDocWidth(d: Doc) {
- const heading = d[this.pivotField] as object;
+ const heading = d[this.notetakingCategoryField] as object;
const castedSectionValue = heading.toString();
const existingHeader = this.columnHeaders.find(sh => sh.heading === castedSectionValue);
const colStartXCoords = this.columnStartXCoords;
@@ -364,20 +367,14 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
if (DragManager.docsBeingDragged.length && this.childDocList) {
// get the current docs for the column based on the mouse's x coordinate
// will use again later, which is why we're saving as local
- const xCoord = e.clientX - 2 * this.gridGap;
+ const xCoord = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0] - 2 * this.gridGap;
const colDocs = this.getDocsFromXCoord(xCoord);
// get the index for where you need to insert the doc you are currently dragging
- const clientY = e.clientY;
+ const clientY = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[1];
let dropInd = -1;
- // unsure whether we still want this dropAfter field
- // let dropAfter = 0;
- // manually set to 140, because not sure how to get exact value
- let pos0 = 140;
+ let pos0 = (this.refList.lastElement() as HTMLDivElement).children[0].getBoundingClientRect().height + this.yMargin * 2;
colDocs.forEach((doc, i) => {
- const noteTakingDocTransform = () => this.getDocTransform(doc);
- let pos1 = noteTakingDocTransform()
- .inverse()
- .transformPoint(0, this.getDocHeight(doc) + 2 * this.gridGap)[1];
+ let pos1 = this.getDocHeight(doc) + 2 * this.gridGap;
pos1 += pos0;
// updating drop position based on y coordinates
const yCoordInBetween = clientY > pos0 && (clientY < pos1 || i == colDocs.length - 1);
@@ -393,10 +390,10 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
// we alter the pivot fields of the docs in case they are moved to a new column.
const colIndex = this.getColumnFromXCoord(xCoord);
const colHeader = StrCast(this.columnHeaders[colIndex].heading);
- DragManager.docsBeingDragged.forEach(d => (d[this.pivotField] = colHeader));
+ DragManager.docsBeingDragged.forEach(d => (d[this.notetakingCategoryField] = colHeader));
// used to notify sections to re-render
- // console.log([dropInd, this.getColumnFromXCoord(xCoord)])
- this.docsDraggedRowCol = [dropInd, this.getColumnFromXCoord(xCoord)];
+ this.docsDraggedRowCol.length = 0;
+ this.docsDraggedRowCol.push(dropInd, this.getColumnFromXCoord(xCoord));
}
};
@@ -425,7 +422,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
if (docs) {
docs.map(d => {
if (d instanceof Promise) return;
- const sectionValue = d[this.pivotField] as object;
+ const sectionValue = d[this.notetakingCategoryField] as object;
if (sectionValue.toString() == colHeader) {
docsMatchingHeader.push(d);
}
@@ -436,11 +433,22 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
@undoBatch
@action
+ onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
+ const docView = fieldProps.DocumentView?.();
+ if (docView && (e.ctrlKey || docView.rootDoc._singleLine) && ['Enter'].includes(e.key)) {
+ e.stopPropagation?.();
+ const newDoc = Doc.MakeCopy(docView.rootDoc, true);
+ Doc.GetProto(newDoc).text = undefined;
+ FormattedTextBox.SelectOnLoad = newDoc[Id];
+ return this.addDocument?.(newDoc);
+ }
+ };
+
+ @undoBatch
+ @action
onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
if (de.complete.docDragData) {
if (super.onInternalDrop(e, de)) {
- DragManager.docsBeingDragged = [];
- // this.docsDraggedRowCol = []
// filter out the currently dragged docs from the child docs, since we will insert them later
const rowCol = this.docsDraggedRowCol;
const droppedDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= this.childDocs.length); // if the drop operation adds something to the end of the list, then use that as the new document (may be different than what was dropped e.g., in the case of a button which is dropped but which creates say, a note).
@@ -456,10 +464,9 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
if (rowCol[0] <= 0) {
docs.splice(0, 0, ...newDocs);
} else {
- const colDocs = this.getDocsFromXCoord(de.x);
+ const colDocs = this.getDocsFromXCoord(this.props.ScreenToLocalTransform().transformPoint(de.x, de.y)[0]);
const previousDoc = colDocs[rowCol[0] - 1];
const previousDocIndex = docs.indexOf(previousDoc);
- console.log(`docs: ${previousDocIndex}`);
docs.splice(previousDocIndex + 1, 0, ...newDocs);
}
}
@@ -561,7 +568,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
renderChildren={this.children}
numGroupColumns={this.numGroupColumns}
gridGap={this.gridGap}
- pivotField={this.pivotField}
+ pivotField={this.notetakingCategoryField}
columnStartXCoords={this.columnStartXCoords}
maxColWidth={this.maxColWdith}
PanelWidth={this.PanelWidth}