aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/ProsemirrorKeymap.ts4
-rw-r--r--src/client/util/RichTextSchema.tsx103
-rw-r--r--src/client/util/TooltipTextMenu.scss76
-rw-r--r--src/client/util/TooltipTextMenu.tsx89
-rw-r--r--src/client/views/InkingControl.scss4
-rw-r--r--src/client/views/MainView.tsx27
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx16
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx32
8 files changed, 236 insertions, 115 deletions
diff --git a/src/client/util/ProsemirrorKeymap.ts b/src/client/util/ProsemirrorKeymap.ts
index 00d086b97..cf656dc17 100644
--- a/src/client/util/ProsemirrorKeymap.ts
+++ b/src/client/util/ProsemirrorKeymap.ts
@@ -1,4 +1,4 @@
-import { Schema } from "prosemirror-model";
+import { Schema, NodeType } from "prosemirror-model";
import {
wrapIn, setBlockType, chainCommands, toggleMark, exitCode,
joinUp, joinDown, lift, selectParentNode
@@ -50,7 +50,7 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?:
}
if (type = schema.nodes.bullet_list) {
- bind("Ctrl-b", wrapInList(type));
+ bind("Ctrl-.", wrapInList(type));
}
if (type = schema.nodes.ordered_list) {
bind("Ctrl-n", wrapInList(type));
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 3e3e98206..61ca4af5e 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -1,9 +1,9 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Schema, NodeSpec, MarkSpec, DOMOutputSpecArray, NodeType } from "prosemirror-model";
-import { joinUp, lift, setBlockType, toggleMark, wrapIn } from 'prosemirror-commands';
+import { Schema, NodeSpec, MarkSpec, DOMOutputSpecArray, NodeType, Slice } from "prosemirror-model";
+import { joinUp, lift, setBlockType, toggleMark, wrapIn, selectNodeForward, deleteSelection } from 'prosemirror-commands';
import { redo, undo } from 'prosemirror-history';
import { orderedList, bulletList, listItem, } from 'prosemirror-schema-list';
-import { EditorState, Transaction, NodeSelection, } from "prosemirror-state";
+import { EditorState, Transaction, NodeSelection, TextSelection, Selection, } from "prosemirror-state";
import { EditorView, } from "prosemirror-view";
const pDOM: DOMOutputSpecArray = ["p", 0], blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"],
@@ -26,6 +26,14 @@ export const nodes: { [index: string]: NodeSpec } = {
toDOM() { return pDOM; }
},
+ // starmine: {
+ // inline: true,
+ // attrs: { oldtext: { default: "" } },
+ // group: "inline",
+ // toDOM() { return ["star", "㊉"]; },
+ // parseDOM: [{ tag: "star" }]
+ // },
+
// :: NodeSpec A blockquote (`<blockquote>`) wrapping one or more blocks.
blockquote: {
content: "block+",
@@ -77,6 +85,30 @@ export const nodes: { [index: string]: NodeSpec } = {
group: "inline"
},
+ star: {
+ inline: true,
+ attrs: {
+ visibility: { default: false },
+ oldtext: { default: undefined },
+ oldtextslice: { default: undefined },
+ oldtextlen: { default: 0 }
+
+ },
+ group: "inline",
+ toDOM(node) {
+ const attrs = { style: `width: 40px` };
+ return ["span", { ...node.attrs, ...attrs }];
+ },
+ // parseDOM: [{
+ // tag: "star", getAttrs(dom: any) {
+ // return {
+ // visibility: dom.getAttribute("visibility"),
+ // oldtext: dom.getAttribute("oldtext"),
+ // oldtextlen: dom.getAttribute("oldtextlen"),
+ // }
+ // }
+ // }]
+ },
// :: NodeSpec An inline image (`<img>`) node. Supports `src`,
// `alt`, and `href` attributes. The latter two default to the empty
// string.
@@ -222,6 +254,15 @@ export const marks: { [index: string]: MarkSpec } = {
toDOM: () => ['sup']
},
+ collapse: {
+ parseDOM: [{ style: 'color: blue' }],
+ toDOM() {
+ return ['span', {
+ style: 'color: blue'
+ }]
+ }
+ },
+
// :: MarkSpec Code font mark. Represented as a `<code>` element.
code: {
@@ -280,6 +321,7 @@ export const marks: { [index: string]: MarkSpec } = {
}]
},
+
/** FONT SIZES */
p10: {
@@ -407,6 +449,49 @@ export class ImageResizeView {
this._handle.style.display = "none";
}
}
+
+export class SummarizedView {
+ // TODO: highlight text that is summarized. to find end of region, walk along mark
+ _collapsed: HTMLElement;
+ constructor(node: any, view: any, getPos: any) {
+ this._collapsed = document.createElement("span");
+ this._collapsed.textContent = "㊉";
+ this._collapsed.style.opacity = "0.5";
+ // this._collapsed.style.background = "yellow";
+ this._collapsed.style.position = "relative";
+ this._collapsed.style.width = "40px";
+ this._collapsed.style.height = "20px";
+ this._collapsed.onpointerdown = function (e: any) {
+ console.log("star pressed!");
+ if (node.attrs.visibility) {
+ node.attrs.visibility = !node.attrs.visibility;
+ console.log("content is visible");
+ let y = getPos();
+ view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, y + 1, y + 1 + node.attrs.oldtextlen)));
+ view.dispatch(view.state.tr.deleteSelection(view.state, () => { }));
+ //this._collapsed.textContent = "㊀";
+ } else {
+ node.attrs.visibility = !node.attrs.visibility;
+ console.log("content is invisible");
+ let y = getPos();
+ let mark = view.state.schema.mark(view.state.schema.marks.underline);
+ console.log("PASTING " + node.attrs.oldtext.toString());
+ view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, y + 1, y + 1)));
+ view.dispatch(view.state.tr.replaceSelection(node.attrs.oldtext).addMark(view.state.selection.from, view.state.selection.from + node.attrs.oldtextlen, mark));
+ //this._collapsed.textContent = "㊉";
+ }
+ e.preventDefault();
+ e.stopPropagation();
+ };
+ (this as any).dom = this._collapsed;
+
+ }
+ selectNode() {
+ }
+
+ deselectNode() {
+ }
+}
// :: Schema
// This schema rougly corresponds to the document schema used by
// [CommonMark](http://commonmark.org/), minus the list elements,
@@ -415,4 +500,14 @@ export class ImageResizeView {
//
// To reuse elements from this schema, extend or read from its
// `spec.nodes` and `spec.marks` [properties](#model.Schema.spec).
-export const schema = new Schema({ nodes, marks }); \ No newline at end of file
+export const schema = new Schema({ nodes, marks });
+
+const fromJson = schema.nodeFromJSON;
+
+schema.nodeFromJSON = (json: any) => {
+ let node = fromJson(json);
+ if (json.type === "star") {
+ node.attrs.oldtext = Slice.fromJSON(schema, node.attrs.oldtextslice);
+ }
+ return node;
+} \ No newline at end of file
diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss
index 437da0d63..4d4eb386d 100644
--- a/src/client/util/TooltipTextMenu.scss
+++ b/src/client/util/TooltipTextMenu.scss
@@ -36,7 +36,7 @@
position: relative;
padding-right: 15px;
margin: 3px;
- background: #333333;
+ background: white;
border-radius: 3px;
text-align: center;
}
@@ -69,6 +69,7 @@
.ProseMirror-menu-dropdown-menu {
z-index: 15;
min-width: 6em;
+ background: white;
}
.linking {
@@ -82,7 +83,7 @@
}
.ProseMirror-menu-dropdown-item:hover {
- background: #2e2b2b;
+ background: white;
}
.ProseMirror-menu-submenu-wrap {
@@ -132,7 +133,7 @@
position: relative;
min-height: 1em;
color: white;
- padding: 1px 6px;
+ padding: 10px 10px;
top: 0; left: 0; right: 0;
border-bottom: 1px solid silver;
background:$dark-color;
@@ -155,7 +156,7 @@
}
.ProseMirror-icon svg {
- fill: currentColor;
+ fill:white;
height: 1em;
}
@@ -184,7 +185,7 @@
position: fixed;
border-radius: 3px;
z-index: 11;
- box-shadow: -.5px 2px 5px rgba(0, 0, 0, .2);
+ box-shadow: -.5px 2px 5px white(255, 255, 255, 0.2);
}
.ProseMirror-prompt h5 {
@@ -196,7 +197,7 @@
.ProseMirror-prompt input[type="text"],
.ProseMirror-prompt textarea {
- background: #eee;
+ background: white;
border: none;
outline: none;
}
@@ -233,15 +234,18 @@
.tooltipMenu {
position: absolute;
- z-index: 200;
- background: $dark-color;
+ z-index: 50;
+ background: whitesmoke;
border: 1px solid silver;
- border-radius: 4px;
+ border-radius: 15px;
padding: 2px 10px;
- margin-bottom: 7px;
- -webkit-transform: translateX(-50%);
- transform: translateX(-50%);
+ //margin-bottom: 100px;
+ //-webkit-transform: translateX(-50%);
+ //transform: translateX(-50%);
+ transform: translateY(-50%);
pointer-events: all;
+ height: auto;
+ width:inherit;
.ProseMirror-example-setup-style hr {
padding: 2px 10px;
border: none;
@@ -257,34 +261,34 @@
}
}
-.tooltipMenu:before {
- content: "";
- height: 0; width: 0;
- position: absolute;
- left: 50%;
- margin-left: -5px;
- bottom: -6px;
- border: 5px solid transparent;
- border-bottom-width: 0;
- border-top-color: silver;
- }
- .tooltipMenu:after {
- content: "";
- height: 0; width: 0;
- position: absolute;
- left: 50%;
- margin-left: -5px;
- bottom: -4.5px;
- border: 5px solid transparent;
- border-bottom-width: 0;
- border-top-color: $dark-color;
- }
+// .tooltipMenu:before {
+// content: "";
+// height: 0; width: 0;
+// position: absolute;
+// left: 50%;
+// margin-left: -5px;
+// bottom: -6px;
+// border: 5px solid transparent;
+// border-bottom-width: 0;
+// border-top-color: silver;
+// }
+// .tooltipMenu:after {
+// content: "";
+// height: 0; width: 0;
+// position: absolute;
+// left: 50%;
+// margin-left: -5px;
+// bottom: -4.5px;
+// border: 5px solid transparent;
+// border-bottom-width: 0;
+// border-top-color: $dark-color;
+// }
.menuicon {
display: inline-block;
- border-right: 1px solid rgba(0, 0, 0, 0.2);
+ border-right: 1px solid white(0, 0, 0, 0.2);
//color: rgb(19, 18, 18);
- color: white;
+ color: rgb(226, 21, 21);
line-height: 1;
padding: 0px 2px;
margin: 1px;
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index f517f757a..e12d4ed3c 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -1,6 +1,6 @@
import { action, IReactionDisposer, reaction } from "mobx";
import { Dropdown, DropdownSubmenu, MenuItem, MenuItemSpec, renderGrouped, icons, } from "prosemirror-menu"; //no import css
-import { baseKeymap, lift } from "prosemirror-commands";
+import { baseKeymap, lift, deleteSelection } from "prosemirror-commands";
import { history, redo, undo } from "prosemirror-history";
import { keymap } from "prosemirror-keymap";
import { EditorState, Transaction, NodeSelection, TextSelection } from "prosemirror-state";
@@ -22,12 +22,13 @@ import { throwStatement } from "babel-types";
import { View } from "@react-pdf/renderer";
import { DragManager } from "./DragManager";
import { Doc, Opt, Field } from "../../new_fields/Doc";
-import { Utils } from "../northstar/utils/Utils";
import { DocServer } from "../DocServer";
import { CollectionFreeFormDocumentView } from "../views/nodes/CollectionFreeFormDocumentView";
import { CollectionDockingView } from "../views/collections/CollectionDockingView";
import { DocumentManager } from "./DocumentManager";
import { Id } from "../../new_fields/FieldSymbols";
+import { Utils } from "../../Utils";
+// import { wrap } from "module";
const SVG = "http://www.w3.org/2000/svg";
@@ -68,12 +69,13 @@ export class TooltipTextMenu {
library.add(faListUl);
//add the buttons to the tooltip
let items = [
- { command: toggleMark(schema.marks.strong), dom: this.icon("B", "strong") },
- { command: toggleMark(schema.marks.em), dom: this.icon("i", "em") },
- { command: toggleMark(schema.marks.underline), dom: this.icon("U", "underline") },
- { command: toggleMark(schema.marks.strikethrough), dom: this.icon("S", "strikethrough") },
- { command: toggleMark(schema.marks.superscript), dom: this.icon("s", "superscript") },
- { command: toggleMark(schema.marks.subscript), dom: this.icon("s", "subscript") },
+ { command: toggleMark(schema.marks.strong), dom: this.icon("B", "strong", "Bold") },
+ { command: toggleMark(schema.marks.em), dom: this.icon("i", "em", "Italic") },
+ { command: toggleMark(schema.marks.underline), dom: this.icon("U", "underline", "Underline") },
+ { command: toggleMark(schema.marks.strikethrough), dom: this.icon("S", "strikethrough", "Strikethrough") },
+ { command: toggleMark(schema.marks.superscript), dom: this.icon("s", "superscript", "Superscript") },
+ { command: toggleMark(schema.marks.subscript), dom: this.icon("s", "subscript", "Subscript") },
+ { command: deleteSelection, dom: this.icon("C", 'collapse', 'Collapse') }
// { command: wrapInList(schema.nodes.bullet_list), dom: this.icon(":", "bullets") },
// { command: wrapInList(schema.nodes.ordered_list), dom: this.icon("1)", "bullets") },
// { command: lift, dom: this.icon("<", "lift") },
@@ -86,7 +88,10 @@ export class TooltipTextMenu {
dom.addEventListener("pointerdown", e => {
e.preventDefault();
view.focus();
- command(view.state, view.dispatch, view);
+ if (dom.contains(e.target as Node)) {
+ e.stopPropagation();
+ command(view.state, view.dispatch, view);
+ }
});
});
@@ -131,13 +136,13 @@ export class TooltipTextMenu {
//font SIZES
let fontSizeBtns: MenuItem[] = [];
this.fontSizeToNum.forEach((number, mark) => {
- fontSizeBtns.push(this.dropdownMarkBtn(String(number), "width: 50px;", mark, this.view, this.changeToMarkInGroup, this.fontSizes));
+ fontSizeBtns.push(this.dropdownMarkBtn(String(number), "color: black; width: 50px;", mark, this.view, this.changeToMarkInGroup, this.fontSizes));
});
if (this.fontSizeDom) { this.tooltip.removeChild(this.fontSizeDom); }
this.fontSizeDom = (new Dropdown(cut(fontSizeBtns), {
label: label,
- css: "color:white; min-width: 60px; padding-left: 5px; margin-right: 0;"
+ css: "color:black; min-width: 60px; padding-left: 5px; margin-right: 0;"
}) as MenuItem).render(this.view).dom;
this.tooltip.appendChild(this.fontSizeDom);
}
@@ -150,13 +155,13 @@ export class TooltipTextMenu {
//font STYLES
let fontBtns: MenuItem[] = [];
this.fontStylesToName.forEach((name, mark) => {
- fontBtns.push(this.dropdownMarkBtn(name, "font-family: " + name + ", sans-serif; width: 125px;", mark, this.view, this.changeToMarkInGroup, this.fontStyles));
+ fontBtns.push(this.dropdownMarkBtn(name, "color: black; font-family: " + name + ", sans-serif; width: 125px;", mark, this.view, this.changeToMarkInGroup, this.fontStyles));
});
if (this.fontStyleDom) { this.tooltip.removeChild(this.fontStyleDom); }
this.fontStyleDom = (new Dropdown(cut(fontBtns), {
label: label,
- css: "color:white; width: 125px; margin-left: -3px; padding-left: 2px;"
+ css: "color:black; width: 125px; margin-left: -3px; padding-left: 2px;"
}) as MenuItem).render(this.view).dom;
this.tooltip.appendChild(this.fontStyleDom);
@@ -165,7 +170,7 @@ export class TooltipTextMenu {
updateLinkMenu() {
if (!this.linkEditor || !this.linkText) {
this.linkEditor = document.createElement("div");
- this.linkEditor.style.color = "white";
+ this.linkEditor.style.color = "black";
this.linkText = document.createElement("div");
this.linkText.style.cssFloat = "left";
this.linkText.style.marginRight = "5px";
@@ -174,13 +179,13 @@ export class TooltipTextMenu {
this.linkText.style.whiteSpace = "nowrap";
this.linkText.style.width = "150px";
this.linkText.style.overflow = "hidden";
- this.linkText.style.color = "white";
+ this.linkText.style.color = "black";
this.linkText.onpointerdown = (e: PointerEvent) => { e.stopPropagation(); };
let linkBtn = document.createElement("div");
linkBtn.textContent = ">>";
- linkBtn.style.width = "20px";
- linkBtn.style.height = "20px";
- linkBtn.style.color = "white";
+ linkBtn.style.width = "10px";
+ linkBtn.style.height = "10px";
+ linkBtn.style.color = "black";
linkBtn.style.cssFloat = "left";
linkBtn.onpointerdown = (e: PointerEvent) => {
let node = this.view.state.selection.$from.nodeAfter;
@@ -207,7 +212,7 @@ export class TooltipTextMenu {
this.linkDrag.src = "https://seogurusnyc.com/wp-content/uploads/2016/12/link-1.png";
this.linkDrag.style.width = "20px";
this.linkDrag.style.height = "20px";
- this.linkDrag.style.color = "white";
+ this.linkDrag.style.color = "black";
this.linkDrag.style.background = "black";
this.linkDrag.style.cssFloat = "left";
this.linkDrag.onpointerdown = (e: PointerEvent) => {
@@ -228,6 +233,22 @@ export class TooltipTextMenu {
this.linkEditor.appendChild(this.linkText);
this.linkEditor.appendChild(linkBtn);
this.tooltip.appendChild(this.linkEditor);
+
+ let starButton = document.createElement("span");
+ // starButton.style.width = '10px';
+ // starButton.style.height = '10px';
+ starButton.style.marginLeft = '10px';
+ starButton.textContent = "Summarize";
+ starButton.style.color = 'black';
+ starButton.style.height = '20px';
+ starButton.style.backgroundColor = 'white';
+ starButton.style.textAlign = 'center';
+ starButton.onclick = () => {
+ let state = this.view.state;
+ this.insertStar(state, this.view.dispatch);
+ }
+
+ this.tooltip.appendChild(starButton);
}
let node = this.view.state.selection.$from.nodeAfter;
@@ -253,6 +274,16 @@ export class TooltipTextMenu {
link = node && node.marks.find(m => m.type.name === "link");
}
+ insertStar(state: EditorState<any>, dispatch: any) {
+ console.log("creating star...");
+ let newNode = schema.nodes.star.create({ visibility: false, oldtext: state.selection.content(), oldtextslice: state.selection.content().toJSON(), oldtextlen: state.selection.to - state.selection.from });
+ if (dispatch) {
+ console.log(newNode.attrs.oldtext.toString());
+ dispatch(state.tr.replaceSelectionWith(newNode));
+ }
+ return true;
+ }
+
//will display a remove-list-type button if selection is in list, otherwise will show list type dropdown
updateListItemDropdown(label: string, listTypeBtn: Node) {
//remove old btn
@@ -261,14 +292,14 @@ export class TooltipTextMenu {
//Make a dropdown of all list types
let toAdd: MenuItem[] = [];
this.listTypeToIcon.forEach((icon, type) => {
- toAdd.push(this.dropdownNodeBtn(icon, "width: 40px;", type, this.view, this.listTypes, this.changeToNodeType));
+ toAdd.push(this.dropdownNodeBtn(icon, "color: black; width: 40px;", type, this.view, this.listTypes, this.changeToNodeType));
});
//option to remove the list formatting
- toAdd.push(this.dropdownNodeBtn("X", "width: 40px;", undefined, this.view, this.listTypes, this.changeToNodeType));
+ toAdd.push(this.dropdownNodeBtn("X", "color: black; width: 40px;", undefined, this.view, this.listTypes, this.changeToNodeType));
listTypeBtn = (new Dropdown(toAdd, {
label: label,
- css: "color:white; width: 40px;"
+ css: "color:black; width: 40px;"
}) as MenuItem).render(this.view).dom;
//add this new button and return it
@@ -349,12 +380,12 @@ export class TooltipTextMenu {
}
// Helper function to create menu icons
- icon(text: string, name: string) {
+ icon(text: string, name: string, title: string = name) {
let span = document.createElement("span");
span.className = name + " menuicon";
- span.title = name;
+ span.title = title;
span.textContent = text;
- span.style.color = "white";
+ span.style.color = "black";
return span;
}
@@ -421,8 +452,14 @@ export class TooltipTextMenu {
let width = Math.abs(start.left - end.left) / 2 * this.editorProps.ScreenToLocalTransform().Scale;
let mid = Math.min(start.left, end.left) + width;
- this.tooltip.style.width = 225 + "px";
+ //this.tooltip.style.width = 225 + "px";
this.tooltip.style.bottom = (box.bottom - start.top) * this.editorProps.ScreenToLocalTransform().Scale + "px";
+ this.tooltip.style.top = "-100px";
+ //this.tooltip.style.height = "100px";
+
+ // let transform = this.editorProps.ScreenToLocalTransform();
+ // this.tooltip.style.width = `${225 / transform.Scale}px`;
+ // Utils
//UPDATE LIST ITEM DROPDOWN
this.listTypeBtnDom = this.updateListItemDropdown(":", this.listTypeBtnDom!);
diff --git a/src/client/views/InkingControl.scss b/src/client/views/InkingControl.scss
index ba4ec41af..2c53dc031 100644
--- a/src/client/views/InkingControl.scss
+++ b/src/client/views/InkingControl.scss
@@ -1,8 +1,8 @@
@import "globalCssVariables";
.inking-control {
position: absolute;
- left: 70px;
- bottom: 70px;
+ right: 0px;
+ bottom: 20px;
margin: 0;
padding: 0;
display: flex;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 42d5929bf..4b328f286 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -221,33 +221,15 @@ export class MainView extends React.Component {
nodesMenu() {
let imgurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg";
- let pdfurl = "http://www.adobe.com/support/products/enterprise/knowledgecenter/media/c27211_sample_explain.pdf";
- let weburl = "https://cs.brown.edu/courses/cs166/";
- let audiourl = "http://techslides.com/demos/samples/sample.mp3";
- let videourl = "http://techslides.com/demos/sample-videos/small.mp4";
- let addTextNode = action(() => Docs.TextDocument({ borderRounding: -1, width: 200, height: 200, title: "a text note" }));
let addColNode = action(() => Docs.FreeformDocument([], { width: this.pwidth * .7, height: this.pheight, title: "a freeform collection" }));
- let addSchemaNode = action(() => Docs.SchemaDocument(["title"], [], { width: 200, height: 200, title: "a schema collection" }));
let addTreeNode = action(() => CurrentUserUtils.UserDocument);
- //let addTreeNode = action(() => Docs.TreeDocument([CurrentUserUtils.UserDocument], { width: 250, height: 400, title: "Library:" + CurrentUserUtils.email, dropAction: "alias" }));
- // let addTreeNode = action(() => Docs.TreeDocument(this._northstarSchemas, { width: 250, height: 400, title: "northstar schemas", dropAction: "copy" }));
- let addVideoNode = action(() => Docs.VideoDocument(videourl, { width: 200, title: "video node" }));
- let addPDFNode = action(() => Docs.PdfDocument(pdfurl, { width: 200, height: 200, title: "a pdf doc" }));
let addImageNode = action(() => Docs.ImageDocument(imgurl, { width: 200, title: "an image of a cat" }));
- let addWebNode = action(() => Docs.WebDocument(weburl, { width: 200, height: 200, title: "a sample web page" }));
- let addAudioNode = action(() => Docs.AudioDocument(audiourl, { width: 200, height: 200, title: "audio node" }));
let btns: [React.RefObject<HTMLDivElement>, IconName, string, () => Doc][] = [
- [React.createRef<HTMLDivElement>(), "font", "Add Textbox", addTextNode],
[React.createRef<HTMLDivElement>(), "image", "Add Image", addImageNode],
- [React.createRef<HTMLDivElement>(), "file-pdf", "Add PDF", addPDFNode],
- [React.createRef<HTMLDivElement>(), "film", "Add Video", addVideoNode],
- [React.createRef<HTMLDivElement>(), "music", "Add Audio", addAudioNode],
- [React.createRef<HTMLDivElement>(), "globe-asia", "Add Web Clipping", addWebNode],
[React.createRef<HTMLDivElement>(), "object-group", "Add Collection", addColNode],
[React.createRef<HTMLDivElement>(), "tree", "Add Tree", addTreeNode],
- [React.createRef<HTMLDivElement>(), "table", "Add Schema", addSchemaNode],
];
return < div id="add-nodes-menu" >
@@ -256,12 +238,16 @@ export class MainView extends React.Component {
<div id="add-options-content">
<ul id="add-options-list">
+ <li key="search"><button className="add-button round-button" title="Search" onClick={this.toggleSearch}><FontAwesomeIcon icon="search" size="sm" /></button></li>
+ <li key="undo"><button className="add-button round-button" title="Undo" onClick={() => UndoManager.Undo()}><FontAwesomeIcon icon="undo-alt" size="sm" /></button></li>
+ <li key="redo"><button className="add-button round-button" title="Redo" onClick={() => UndoManager.Redo()}><FontAwesomeIcon icon="redo-alt" size="sm" /></button></li>
{btns.map(btn =>
<li key={btn[1]} ><div ref={btn[0]}>
<button className="round-button add-button" title={btn[2]} onPointerDown={SetupDrag(btn[0], btn[3])}>
<FontAwesomeIcon icon={btn[1]} size="sm" />
</button>
</div></li>)}
+ <li key="ink"><button className="toolbar-button round-button" title="Ink" onClick={() => InkingControl.Instance.toggleDisplay()}><FontAwesomeIcon icon="pen-nib" size="sm" /></button></li>
</ul>
</div>
</div >;
@@ -276,7 +262,6 @@ export class MainView extends React.Component {
let logoutRef = React.createRef<HTMLDivElement>();
return [
- <button className="clear-db-button" key="clear-db" onClick={e => e.shiftKey && e.altKey && DocServer.DeleteDatabase()}>Clear Database</button>,
<div id="toolbar" key="toolbar">
<div ref={notifsRef}>
<button className="toolbar-button round-button" title="Notifs"
@@ -287,10 +272,6 @@ export class MainView extends React.Component {
{length}
</div>
</div>
- <button className="toolbar-button round-button" title="Search" onClick={this.toggleSearch}><FontAwesomeIcon icon="search" size="sm" /></button>
- <button className="toolbar-button round-button" title="Undo" onClick={() => UndoManager.Undo()}><FontAwesomeIcon icon="undo-alt" size="sm" /></button>
- <button className="toolbar-button round-button" title="Redo" onClick={() => UndoManager.Redo()}><FontAwesomeIcon icon="redo-alt" size="sm" /></button>
- <button className="toolbar-button round-button" title="Ink" onClick={() => InkingControl.Instance.toggleDisplay()}><FontAwesomeIcon icon="pen-nib" size="sm" /></button>
</div >,
this.isSearchVisible ? <div className="main-searchDiv" key="search" style={{ top: '34px', right: '1px', position: 'absolute' }} > <SearchBox /> </div> : null,
<div className="main-buttonDiv" key="logout" style={{ bottom: '0px', right: '1px', position: 'absolute' }} ref={logoutRef}>
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 01bbbba4c..5f2a732b9 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -45,12 +45,14 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
_commandExecuted = false;
@action
- cleanupInteractions = (all: boolean = false) => {
+ cleanupInteractions = (all: boolean = false, rem_keydown: boolean = true) => {
if (all) {
document.removeEventListener("pointerup", this.onPointerUp, true);
document.removeEventListener("pointermove", this.onPointerMove, true);
}
- document.removeEventListener("keydown", this.marqueeCommand, true);
+ if (rem_keydown) {
+ document.removeEventListener("keydown", this.marqueeCommand, true);
+ }
this._visible = false;
}
@@ -146,6 +148,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
this._downY = this._lastY = e.pageY;
this._commandExecuted = false;
PreviewCursor.Visible = false;
+ this.cleanupInteractions(true);
if (e.button === 2 || (e.button === 0 && e.altKey)) {
if (!this.props.container.props.active()) this.props.selectDocuments([this.props.container.props.Document]);
document.addEventListener("pointermove", this.onPointerMove, true);
@@ -181,14 +184,21 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
@action
onPointerUp = (e: PointerEvent): void => {
+ console.log("pointer up!");
if (this._visible) {
+ console.log("visible");
let mselect = this.marqueeSelect();
if (!e.shiftKey) {
SelectionManager.DeselectAll(mselect.length ? undefined : this.props.container.props.Document);
}
this.props.selectDocuments(mselect.length ? mselect : [this.props.container.props.Document]);
+ mselect.length ? this.cleanupInteractions(true, false) : this.cleanupInteractions(true);
}
- this.cleanupInteractions(true);
+ else {
+ console.log("invisible");
+ this.cleanupInteractions(true);
+ }
+
if (e.altKey) {
e.preventDefault();
}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 6a51db4ac..6a490109f 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -7,7 +7,7 @@ import { history } from "prosemirror-history";
import { keymap } from "prosemirror-keymap";
import { EditorState, Plugin, Transaction } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
-import { Doc, Opt } from "../../../new_fields/Doc";
+import { Doc, Field, Opt, WidthSym, HeightSym } from "../../../new_fields/Doc";
import { Id } from '../../../new_fields/FieldSymbols';
import { RichTextField } from "../../../new_fields/RichTextField";
import { createSchema, makeInterface } from "../../../new_fields/Schema";
@@ -18,18 +18,21 @@ import { DocumentManager } from "../../util/DocumentManager";
import { DragManager } from "../../util/DragManager";
import buildKeymap from "../../util/ProsemirrorKeymap";
import { inpRules } from "../../util/RichTextRules";
-import { ImageResizeView, schema } from "../../util/RichTextSchema";
+import { SummarizedView, ImageResizeView, schema } from "../../util/RichTextSchema";
import { SelectionManager } from "../../util/SelectionManager";
import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu";
import { TooltipTextMenu } from "../../util/TooltipTextMenu";
-import { UndoManager } from "../../util/UndoManager";
-import { ContextMenu } from '../ContextMenu';
-import { ContextMenuProps } from '../ContextMenuItem';
+import { undoBatch, UndoManager } from "../../util/UndoManager";
+import { ContextMenu } from "../../views/ContextMenu";
+import { CollectionDockingView } from "../collections/CollectionDockingView";
import { DocComponent } from "../DocComponent";
import { InkingControl } from "../InkingControl";
import { FieldView, FieldViewProps } from "./FieldView";
import "./FormattedTextBox.scss";
import React = require("react");
+import { DocUtils } from '../../documents/Documents';
+import { start } from 'repl';
+import { ContextMenuProps } from '../ContextMenuItem';
library.add(faEdit);
library.add(faSmile);
@@ -174,7 +177,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
state: field && field.Data ? EditorState.fromJSON(config, JSON.parse(field.Data)) : EditorState.create(config),
dispatchTransaction: this.dispatchTransaction,
nodeViews: {
- image(node, view, getPos) { return new ImageResizeView(node, view, getPos); }
+ image(node, view, getPos) { return new ImageResizeView(node, view, getPos); },
+ star(node, view, getPos) { return new SummarizedView(node, view, getPos); }
}
});
if (startup) {
@@ -208,7 +212,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
this._toolTipTextMenu.tooltip.style.opacity = "0";
}
}
- this._linkClicked = "";
+ let ctrlKey = e.ctrlKey;
if (e.button === 0 && ((!this.props.isSelected() && !e.ctrlKey) || (this.props.isSelected() && e.ctrlKey)) && !e.metaKey && e.target) {
let href = (e.target as any).href;
for (let parent = (e.target as any).parentNode; !href && parent; parent = parent.parentNode) {
@@ -225,6 +229,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
e.stopPropagation();
e.preventDefault();
}
+
}
if (e.button === 2 || (e.button === 0 && e.ctrlKey)) {
e.preventDefault();
@@ -234,14 +239,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
if (this._toolTipTextMenu && this._toolTipTextMenu.tooltip) {
this._toolTipTextMenu.tooltip.style.opacity = "1";
}
- let ctrlKey = e.ctrlKey;
- if (this._linkClicked) {
- DocServer.GetRefField(this._linkClicked).then(f => {
- (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, document => this.props.addDocTab(document, "inTab"));
- });
- e.stopPropagation();
- e.preventDefault();
- }
if (e.buttons === 1 && this.props.isSelected() && !e.altKey) {
e.stopPropagation();
}
@@ -265,10 +262,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
onClick = (e: React.MouseEvent): void => {
this._proseRef.current!.focus();
- if (this._linkClicked) {
- e.preventDefault();
- e.stopPropagation();
- }
}
onMouseDown = (e: React.MouseEvent): void => {
if (!this.props.isSelected()) { // preventing default allows the onClick to be generated instead of being swallowed by the text box itself
@@ -368,6 +361,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
onPointerUp={this.onPointerUp}
onPointerDown={this.onPointerDown}
onMouseDown={this.onMouseDown}
+ // tfs: do we need this event handler
onWheel={this.onPointerWheel}
onPointerEnter={this.onPointerEnter}
onPointerLeave={this.onPointerLeave}