aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2020-07-03 20:46:59 -0400
committerGitHub <noreply@github.com>2020-07-03 20:46:59 -0400
commitdf00289aad1c35e3811c02aada6479a5490e9650 (patch)
tree09cb1933ad5805c2df8fa32db2dadd8f85f24f51
parenta979ebce6cf3b3aaa0fb6ea3870988b6edc6a889 (diff)
parent397f9811b6675dce5e770082ee68435b7e560f7f (diff)
Merge pull request #432 from browngraphicslab/anika_linking
Initial Linking Changes
-rw-r--r--package-lock.json385
-rw-r--r--package.json3
-rw-r--r--src/client/documents/Documents.ts4
-rw-r--r--src/client/views/DocumentButtonBar.tsx2
-rw-r--r--src/client/views/GlobalKeyHandler.ts8
-rw-r--r--src/client/views/MainView.tsx8
-rw-r--r--src/client/views/collections/CollectionLinearView.scss64
-rw-r--r--src/client/views/collections/CollectionLinearView.tsx34
-rw-r--r--src/client/views/collections/CollectionView.tsx11
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx34
-rw-r--r--src/client/views/linking/LinkMenu.scss9
-rw-r--r--src/client/views/linking/LinkMenu.tsx11
-rw-r--r--src/client/views/linking/LinkMenuGroup.tsx4
-rw-r--r--src/client/views/linking/LinkMenuItem.scss11
-rw-r--r--src/client/views/linking/LinkMenuItem.tsx47
-rw-r--r--src/client/views/nodes/DocumentLinksButton.scss2
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx84
-rw-r--r--src/client/views/nodes/DocumentView.tsx22
-rw-r--r--src/client/views/nodes/LinkAnchorBox.scss7
-rw-r--r--src/client/views/nodes/LinkCreatedBox.scss21
-rw-r--r--src/client/views/nodes/LinkCreatedBox.tsx31
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx54
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx40
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.scss86
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx154
-rw-r--r--src/fields/Doc.ts2
26 files changed, 1000 insertions, 138 deletions
diff --git a/package-lock.json b/package-lock.json
index f03a39df0..ad181758c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -372,6 +372,101 @@
"resolved": "https://registry.npmjs.org/@log4js-node/log4js-api/-/log4js-api-1.0.2.tgz",
"integrity": "sha512-6SJfx949YEWooh/CUPpJ+F491y4BYJmknz4hUN1+RHvKoUEynKbRmhnwbk/VLmh4OthLLDNCyWXfbh4DG1cTXA=="
},
+ "@material-ui/core": {
+ "version": "4.11.0",
+ "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.0.tgz",
+ "integrity": "sha512-bYo9uIub8wGhZySHqLQ833zi4ZML+XCBE1XwJ8EuUVSpTWWG57Pm+YugQToJNFsEyiKFhPh8DPD0bgupz8n01g==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "@material-ui/styles": "^4.10.0",
+ "@material-ui/system": "^4.9.14",
+ "@material-ui/types": "^5.1.0",
+ "@material-ui/utils": "^4.10.2",
+ "@types/react-transition-group": "^4.2.0",
+ "clsx": "^1.0.4",
+ "hoist-non-react-statics": "^3.3.2",
+ "popper.js": "1.16.1-lts",
+ "prop-types": "^15.7.2",
+ "react-is": "^16.8.0",
+ "react-transition-group": "^4.4.0"
+ },
+ "dependencies": {
+ "dom-helpers": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
+ "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
+ "requires": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^2.6.7"
+ }
+ },
+ "popper.js": {
+ "version": "1.16.1-lts",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
+ "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
+ },
+ "react-transition-group": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
+ "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==",
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ }
+ }
+ }
+ },
+ "@material-ui/styles": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz",
+ "integrity": "sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "@emotion/hash": "^0.8.0",
+ "@material-ui/types": "^5.1.0",
+ "@material-ui/utils": "^4.9.6",
+ "clsx": "^1.0.4",
+ "csstype": "^2.5.2",
+ "hoist-non-react-statics": "^3.3.2",
+ "jss": "^10.0.3",
+ "jss-plugin-camel-case": "^10.0.3",
+ "jss-plugin-default-unit": "^10.0.3",
+ "jss-plugin-global": "^10.0.3",
+ "jss-plugin-nested": "^10.0.3",
+ "jss-plugin-props-sort": "^10.0.3",
+ "jss-plugin-rule-value-function": "^10.0.3",
+ "jss-plugin-vendor-prefixer": "^10.0.3",
+ "prop-types": "^15.7.2"
+ }
+ },
+ "@material-ui/system": {
+ "version": "4.9.14",
+ "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz",
+ "integrity": "sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "@material-ui/utils": "^4.9.6",
+ "csstype": "^2.5.2",
+ "prop-types": "^15.7.2"
+ }
+ },
+ "@material-ui/types": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
+ "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A=="
+ },
+ "@material-ui/utils": {
+ "version": "4.10.2",
+ "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.10.2.tgz",
+ "integrity": "sha512-eg29v74P7W5r6a4tWWDAAfZldXIzfyO1am2fIsC39hdUUHm/33k6pGOKPbgDjg/U/4ifmgAePy/1OjkKN6rFRw==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "prop-types": "^15.7.2",
+ "react-is": "^16.8.0"
+ }
+ },
"@rkusa/linebreak": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@rkusa/linebreak/-/linebreak-1.0.0.tgz",
@@ -853,6 +948,16 @@
"@types/prosemirror-view": "*"
}
},
+ "@types/prosemirror-dev-tools": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/prosemirror-dev-tools/-/prosemirror-dev-tools-2.1.0.tgz",
+ "integrity": "sha512-OhnSaC4yrrEMLPRUkEWcHAIPVqgKlLkE4kISqL3cHeAYxASouSPvPMLqhBIbWkGwaozy43DjjVC1OXkxTo+y5Q==",
+ "dev": true,
+ "requires": {
+ "@types/prosemirror-state": "*",
+ "@types/prosemirror-view": "*"
+ }
+ },
"@types/prosemirror-history": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/prosemirror-history/-/prosemirror-history-1.0.1.tgz",
@@ -1065,7 +1170,6 @@
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz",
"integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==",
- "dev": true,
"requires": {
"@types/react": "*"
}
@@ -2468,6 +2572,11 @@
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.0.tgz",
"integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA=="
},
+ "bowser": {
+ "version": "1.9.4",
+ "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz",
+ "integrity": "sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ=="
+ },
"boxen": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
@@ -2868,6 +2977,11 @@
"type-detect": "^4.0.5"
}
},
+ "chain-function": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.1.tgz",
+ "integrity": "sha512-SxltgMwL9uCko5/ZCLiyG2B7R9fY4pDZUw7hJ4MhirdjBLosoDqkWABi3XMucddHdLiFJMb7PD2MZifZriuMTg=="
+ },
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -2878,6 +2992,11 @@
"supports-color": "^5.3.0"
}
},
+ "change-emitter": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz",
+ "integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU="
+ },
"character-parser": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
@@ -2966,7 +3085,8 @@
},
"ansi-regex": {
"version": "2.1.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -2984,11 +3104,13 @@
},
"balanced-match": {
"version": "1.0.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -3001,15 +3123,18 @@
},
"code-point-at": {
"version": "1.1.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -3112,7 +3237,8 @@
},
"inherits": {
"version": "2.0.4",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -3122,6 +3248,7 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -3134,17 +3261,20 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.5",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"minipass": {
"version": "2.9.0",
"bundled": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -3161,6 +3291,7 @@
"mkdirp": {
"version": "0.5.3",
"bundled": true,
+ "optional": true,
"requires": {
"minimist": "^1.2.5"
}
@@ -3216,7 +3347,8 @@
},
"npm-normalize-package-bin": {
"version": "1.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"npm-packlist": {
"version": "1.4.8",
@@ -3241,7 +3373,8 @@
},
"number-is-nan": {
"version": "1.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -3251,6 +3384,7 @@
"once": {
"version": "1.4.0",
"bundled": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -3319,7 +3453,8 @@
},
"safe-buffer": {
"version": "5.1.2",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -3349,6 +3484,7 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -3366,6 +3502,7 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -3404,11 +3541,13 @@
},
"wrappy": {
"version": "1.0.2",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"yallist": {
"version": "3.1.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
}
}
}
@@ -3584,6 +3723,11 @@
"shallow-clone": "^3.0.0"
}
},
+ "clsx": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
+ "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA=="
+ },
"code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
@@ -4233,6 +4377,15 @@
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
"integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4="
},
+ "css-in-js-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz",
+ "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==",
+ "requires": {
+ "hyphenate-style-name": "^1.0.2",
+ "isobject": "^3.0.1"
+ }
+ },
"css-loader": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz",
@@ -4287,6 +4440,15 @@
}
}
},
+ "css-vendor": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
+ "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
+ "requires": {
+ "@babel/runtime": "^7.8.3",
+ "is-in-browser": "^1.0.2"
+ }
+ },
"css-what": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
@@ -7002,6 +7164,11 @@
}
}
},
+ "hyphenate-style-name": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz",
+ "integrity": "sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ=="
+ },
"i": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz",
@@ -7217,6 +7384,15 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
+ "inline-style-prefixer": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz",
+ "integrity": "sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=",
+ "requires": {
+ "bowser": "^1.7.3",
+ "css-in-js-utils": "^2.0.0"
+ }
+ },
"inspect-function": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.2.2.tgz",
@@ -7525,6 +7701,11 @@
"is-extglob": "^2.1.1"
}
},
+ "is-in-browser": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
+ "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU="
+ },
"is-installed-globally": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
@@ -7892,6 +8073,84 @@
"verror": "1.10.0"
}
},
+ "jss": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.3.0.tgz",
+ "integrity": "sha512-B5sTRW9B6uHaUVzSo9YiMEOEp3UX8lWevU0Fsv+xtRnsShmgCfIYX44bTH8bPJe6LQKqEXku3ulKuHLbxBS97Q==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "csstype": "^2.6.5",
+ "is-in-browser": "^1.1.3",
+ "tiny-warning": "^1.0.2"
+ }
+ },
+ "jss-plugin-camel-case": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.3.0.tgz",
+ "integrity": "sha512-tadWRi/SLWqLK3EUZEdDNJL71F3ST93Zrl9JYMjV0QDqKPAl0Liue81q7m/nFUpnSTXczbKDy4wq8rI8o7WFqA==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "hyphenate-style-name": "^1.0.3",
+ "jss": "^10.3.0"
+ }
+ },
+ "jss-plugin-default-unit": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.3.0.tgz",
+ "integrity": "sha512-tT5KkIXAsZOSS9WDSe8m8lEHIjoEOj4Pr0WrG0WZZsMXZ1mVLFCSsD2jdWarQWDaRNyMj/I4d7czRRObhOxSuw==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "^10.3.0"
+ }
+ },
+ "jss-plugin-global": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.3.0.tgz",
+ "integrity": "sha512-etYTG/y3qIR/vxZnKY+J3wXwObyBDNhBiB3l/EW9/pE3WHE//BZdK8LFvQcrCO48sZW1Z6paHo6klxUPP7WbzA==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "^10.3.0"
+ }
+ },
+ "jss-plugin-nested": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.3.0.tgz",
+ "integrity": "sha512-qWiEkoXNEkkZ+FZrWmUGpf+zBsnEOmKXhkjNX85/ZfWhH9dfGxUCKuJFuOWFM+rjQfxV4csfesq4hY0jk8Qt0w==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "^10.3.0",
+ "tiny-warning": "^1.0.2"
+ }
+ },
+ "jss-plugin-props-sort": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.3.0.tgz",
+ "integrity": "sha512-boetORqL/lfd7BWeFD3K+IyPqyIC+l3CRrdZr+NPq7Noqp+xyg/0MR7QisgzpxCEulk+j2CRcEUoZsvgPC4nTg==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "^10.3.0"
+ }
+ },
+ "jss-plugin-rule-value-function": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.3.0.tgz",
+ "integrity": "sha512-7WiMrKIHH3rwxTuJki9+7nY11r1UXqaUZRhHvqTD4/ZE+SVhvtD5Tx21ivNxotwUSleucA/8boX+NF21oXzr5Q==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "^10.3.0",
+ "tiny-warning": "^1.0.2"
+ }
+ },
+ "jss-plugin-vendor-prefixer": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.3.0.tgz",
+ "integrity": "sha512-sZQbrcZyP5V0ADjCLwUA1spVWoaZvM7XZ+2fSeieZFBj31cRsnV7X70FFDerMHeiHAXKWzYek+67nMDjhrZAVQ==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "css-vendor": "^2.0.8",
+ "jss": "^10.3.0"
+ }
+ },
"jstransformer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
@@ -7925,6 +8184,11 @@
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
"integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw=="
},
+ "keycode": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
+ "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ="
+ },
"keygrip": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
@@ -8171,6 +8435,11 @@
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
},
+ "lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+ },
"lodash.padend": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
@@ -8182,6 +8451,11 @@
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
"dev": true
},
+ "lodash.throttle": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+ "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
+ },
"lodash.union": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
@@ -8341,6 +8615,38 @@
"resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
"integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg=="
},
+ "material-ui": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/material-ui/-/material-ui-0.20.2.tgz",
+ "integrity": "sha512-VeqgQkdvtK193w+FFvXDEwlVxI4rWk83eWbpYLeOIHDPWr3rbB9B075JRnJt/8IsI2X8q5Aia5W3+7m4KkleDg==",
+ "requires": {
+ "babel-runtime": "^6.23.0",
+ "inline-style-prefixer": "^3.0.8",
+ "keycode": "^2.1.8",
+ "lodash.merge": "^4.6.0",
+ "lodash.throttle": "^4.1.1",
+ "prop-types": "^15.5.7",
+ "react-event-listener": "^0.6.2",
+ "react-transition-group": "^1.2.1",
+ "recompose": "^0.26.0",
+ "simple-assign": "^0.1.0",
+ "warning": "^3.0.0"
+ },
+ "dependencies": {
+ "react-transition-group": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-1.2.1.tgz",
+ "integrity": "sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q==",
+ "requires": {
+ "chain-function": "^1.0.0",
+ "dom-helpers": "^3.2.0",
+ "loose-envify": "^1.3.1",
+ "prop-types": "^15.5.6",
+ "warning": "^3.0.0"
+ }
+ }
+ }
+ },
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -13858,6 +14164,26 @@
"prop-types": "^15.6.0"
}
},
+ "react-event-listener": {
+ "version": "0.6.6",
+ "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.6.6.tgz",
+ "integrity": "sha512-+hCNqfy7o9wvO6UgjqFmBzARJS7qrNoda0VqzvOuioEpoEXKutiKuv92dSz6kP7rYLmyHPyYNLesi5t/aH1gfw==",
+ "requires": {
+ "@babel/runtime": "^7.2.0",
+ "prop-types": "^15.6.0",
+ "warning": "^4.0.1"
+ },
+ "dependencies": {
+ "warning": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+ "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ }
+ }
+ },
"react-grid-layout": {
"version": "0.18.3",
"resolved": "https://registry.npmjs.org/react-grid-layout/-/react-grid-layout-0.18.3.tgz",
@@ -14194,6 +14520,24 @@
"resolve": "^1.1.6"
}
},
+ "recompose": {
+ "version": "0.26.0",
+ "resolved": "https://registry.npmjs.org/recompose/-/recompose-0.26.0.tgz",
+ "integrity": "sha512-KwOu6ztO0mN5vy3+zDcc45lgnaUoaQse/a5yLVqtzTK13czSWnFGmXbQVmnoMgDkI5POd1EwIKSbjU1V7xdZog==",
+ "requires": {
+ "change-emitter": "^0.1.2",
+ "fbjs": "^0.8.1",
+ "hoist-non-react-statics": "^2.3.1",
+ "symbol-observable": "^1.0.4"
+ },
+ "dependencies": {
+ "hoist-non-react-statics": {
+ "version": "2.5.5",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
+ "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
+ }
+ }
+ },
"redent": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
@@ -14958,6 +15302,11 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
},
+ "simple-assign": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/simple-assign/-/simple-assign-0.1.0.tgz",
+ "integrity": "sha1-F/0wZqXz13OPUDIbsPFMooHMS6o="
+ },
"simple-concat": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
@@ -15797,6 +16146,11 @@
"has-flag": "^3.0.0"
}
},
+ "symbol-observable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
+ },
"symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -16092,6 +16446,11 @@
"resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
"integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
},
+ "tiny-warning": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
+ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
+ },
"tinycolor2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
diff --git a/package.json b/package.json
index 2a08a6bf1..75dc817f5 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,7 @@
"@types/passport-local": "^1.0.33",
"@types/pdfjs-dist": "^2.1.4",
"@types/prosemirror-commands": "^1.0.1",
+ "@types/prosemirror-dev-tools": "^2.1.0",
"@types/prosemirror-history": "^1.0.1",
"@types/prosemirror-inputrules": "^1.0.2",
"@types/prosemirror-keymap": "^1.0.2",
@@ -120,6 +121,7 @@
"@hig/flyout": "^1.2.1",
"@hig/theme-context": "^2.1.3",
"@hig/theme-data": "^2.16.1",
+ "@material-ui/core": "^4.11.0",
"@types/google-maps": "^3.2.2",
"@types/webscopeio__react-textarea-autocomplete": "^4.6.1",
"@webscopeio/react-textarea-autocomplete": "^4.7.0",
@@ -171,6 +173,7 @@
"jsonschema": "^1.2.5",
"libxmljs": "^0.19.7",
"lodash": "^4.17.15",
+ "material-ui": "^0.20.2",
"mobile-detect": "^1.4.4",
"mobx": "^5.15.3",
"mobx-react": "^5.3.5",
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 85da621e0..f81c25bab 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,4 +1,4 @@
-import { runInAction } from "mobx";
+import { runInAction, action } from "mobx";
import { extname, basename } from "path";
import { DateField } from "../../fields/DateField";
import { Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym } from "../../fields/Doc";
@@ -866,6 +866,7 @@ export namespace DocUtils {
export function MakeLinkToActiveAudio(doc: Doc) {
DocUtils.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: doc }, { doc: d }, "audio link", "audio timeline"));
}
+
export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", id?: string) {
const sv = DocumentManager.Instance.getDocumentView(source.doc);
if (sv && sv.props.ContainingCollectionDoc === target.doc) return;
@@ -877,6 +878,7 @@ export namespace DocUtils {
Doc.GetProto(source.doc).links = ComputedField.MakeFunction("links(self)");
Doc.GetProto(target.doc).links = ComputedField.MakeFunction("links(self)");
+
return linkDoc;
}
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 40a9d0c45..1667b2f65 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -271,7 +271,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
const considerPush = isText && this.considerGoogleDocsPush;
return <div className="documentButtonBar">
<div className="documentButtonBar-button">
- <DocumentLinksButton View={this.view0} AlwaysOn={true} />
+ <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} />
</div>
<div className="documentButtonBar-button">
{this.templateButton}
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index ff8380965..34f666f62 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -79,7 +79,15 @@ export default class KeyManager {
// MarqueeView.DragMarquee = !MarqueeView.DragMarquee; // bcz: this needs a better disclosure UI
break;
case "escape":
+ // if (DocumentLinksButton.StartLink) {
+ // if (DocumentLinksButton.StartLink.Document) {
+ // action((e: React.PointerEvent<HTMLDivElement>) => {
+ // Doc.UnBrushDoc(DocumentLinksButton.StartLink?.Document as Doc);
+ // });
+ // }
+ // }
DocumentLinksButton.StartLink = undefined;
+
const main = MainView.Instance;
Doc.SetSelectedTool(InkTool.None);
var doDeselect = true;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index fab1798e2..15f818d1f 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -4,7 +4,7 @@ import {
faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
- faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote,
+ faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTimesCircle,
faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight
} from '@fortawesome/free-solid-svg-icons';
import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
@@ -59,6 +59,8 @@ import { DocumentManager } from '../util/DocumentManager';
import { DocumentLinksButton } from './nodes/DocumentLinksButton';
import { LinkMenu } from './linking/LinkMenu';
import { LinkDocPreview } from './nodes/LinkDocPreview';
+import { Fade } from '@material-ui/core';
+import { LinkCreatedBox } from './nodes/LinkCreatedBox';
@observer
export class MainView extends React.Component {
@@ -82,7 +84,6 @@ export class MainView extends React.Component {
public isPointerDown = false;
-
componentDidMount() {
DocServer.setPlaygroundFields(["dataTransition", "_viewTransition", "_panX", "_panY", "_viewScale", "_viewType"]); // can play with these fields on someone else's
@@ -138,7 +139,7 @@ export class MainView extends React.Component {
}
library.add(faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
- faTerminal, faToggleOn, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard, fileSolid,
+ faTerminal, faToggleOn, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faTimesCircle, faWindowMaximize, faAddressCard, fileSolid,
faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTrashAlt, faAngleRight, faBell,
@@ -606,6 +607,7 @@ export class MainView extends React.Component {
{this.mainContent}
</GestureOverlay>
<PreviewCursor />
+ <LinkCreatedBox />
{DocumentLinksButton.EditLink ? <LinkMenu location={DocumentLinksButton.EditLinkLoc} docView={DocumentLinksButton.EditLink} addDocTab={DocumentLinksButton.EditLink.props.addDocTab} changeFlyout={emptyFunction} /> : (null)}
{LinkDocPreview.LinkInfo ? <LinkDocPreview location={LinkDocPreview.LinkInfo.Location} backgroundColor={this.defaultBackgroundColors}
linkDoc={LinkDocPreview.LinkInfo.linkDoc} linkSrc={LinkDocPreview.LinkInfo.linkSrc} href={LinkDocPreview.LinkInfo.href}
diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/CollectionLinearView.scss
index 123a27deb..5ada79a28 100644
--- a/src/client/views/collections/CollectionLinearView.scss
+++ b/src/client/views/collections/CollectionLinearView.scss
@@ -1,12 +1,51 @@
@import "../globalCssVariables";
@import "../_nodeModuleOverrides";
-.collectionLinearView-outer{
+.collectionLinearView-outer {
overflow: hidden;
- height:100%;
+ height: 100%;
+
.collectionLinearView {
- display:flex;
+ display: flex;
height: 100%;
+
+ >span {
+ background: $dark-color;
+ color: $light-color;
+ border-radius: 18px;
+ margin-right: 6px;
+ cursor: pointer;
+ }
+
+ .bottomPopup-background {
+ padding-right: 14px;
+ height: 35;
+ transform: translate3d(6px, 5px, 0px);
+ padding-top: 6.5px;
+ padding-bottom: 7px;
+ padding-left: 5px;
+ }
+
+ .bottomPopup-text {
+ display: inline;
+ white-space: nowrap;
+ padding-left: 8px;
+ padding-right: 4px;
+ vertical-align: middle;
+ font-size: 12.5px;
+ }
+
+ .bottomPopup-exit {
+ display: inline;
+ white-space: nowrap;
+ padding-left: 8px;
+ padding-right: 8px;
+ vertical-align: middle;
+ background-color: lightgrey;
+ border-radius: 5.5px;
+ color: black;
+ }
+
>label {
margin-top: "auto";
margin-bottom: "auto";
@@ -17,15 +56,15 @@
font-size: 12.5px;
width: 18px;
height: 18px;
- margin-top:auto;
- margin-bottom:auto;
+ margin-top: auto;
+ margin-bottom: auto;
margin-right: 3px;
cursor: pointer;
transition: transform 0.2s;
}
label p {
- padding-left:5px;
+ padding-left: 5px;
}
label:hover {
@@ -36,6 +75,7 @@
>input {
display: none;
}
+
>input:not(:checked)~.collectionLinearView-content {
display: none;
}
@@ -52,12 +92,14 @@
position: relative;
margin-top: auto;
- .collectionLinearView-docBtn, .collectionLinearView-docBtn-scalable {
- position:relative;
- margin:auto;
+ .collectionLinearView-docBtn,
+ .collectionLinearView-docBtn-scalable {
+ position: relative;
+ margin: auto;
margin-left: 3px;
transform-origin: center 80%;
}
+
.collectionLinearView-docBtn-scalable:hover {
transform: scale(1.15);
}
@@ -68,10 +110,10 @@
border-radius: 18px;
font-size: 15px;
}
-
+
.collectionLinearView-round-button:hover {
transform: scale(1.15);
}
}
}
-}
+} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index f38eeaf41..7cbe5c19d 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -13,6 +13,8 @@ import { CollectionSubView } from './CollectionSubView';
import { DocumentView } from '../nodes/DocumentView';
import { documentSchema } from '../../../fields/documentSchemas';
import { Id } from '../../../fields/FieldSymbols';
+import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
type LinearDocument = makeInterface<[typeof documentSchema,]>;
@@ -75,6 +77,18 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
return new Transform(-translateX, -translateY, 1);
}
+ @action
+ exitLongLinks = () => {
+ if (DocumentLinksButton.StartLink) {
+ if (DocumentLinksButton.StartLink.Document) {
+ action((e: React.PointerEvent<HTMLDivElement>) => {
+ Doc.UnBrushDoc(DocumentLinksButton.StartLink?.Document as Doc);
+ });
+ }
+ }
+ DocumentLinksButton.StartLink = undefined;
+ }
+
render() {
const guid = Utils.GenerateGuid();
const flexDir: any = StrCast(this.Document.flexDirection);
@@ -82,7 +96,12 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
const color = StrCast(this.props.Document.color, "white");
return <div className="collectionLinearView-outer">
<div className="collectionLinearView" ref={this.createDashEventsTarget} >
- <label htmlFor={`${guid}`} title="Close Menu" style={{ background: backgroundColor === color ? "black" : backgroundColor }}
+ <label htmlFor={`${guid}`} title="Close Menu" style={{
+ background: backgroundColor === color ? "black" : backgroundColor,
+ // width: "18px", height: "18px", fontSize: "12.5px",
+ // transition: this.props.Document.linearViewIsExpanded ? "transform 0.2s" : "transform 0.5s",
+ // transform: this.props.Document.linearViewIsExpanded ? "" : "rotate(45deg)"
+ }}
onPointerDown={e => e.stopPropagation()} >
<p>+</p>
</label>
@@ -130,6 +149,19 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
</div>;
})}
</div>
+ {DocumentLinksButton.StartLink ? <span className="bottomPopup-background" style={{
+ background: backgroundColor === color ? "black" : backgroundColor
+ }}
+ onPointerDown={e => e.stopPropagation()} >
+ <span className="bottomPopup-text" >
+ Creating link from: {DocumentLinksButton.StartLink.title} </span>
+ <span className="bottomPopup-exit" onClick={this.exitLongLinks}
+ >Exit</span>
+
+ {/* <FontAwesomeIcon icon="times-circle" size="lg" style={{ color: "red" }}
+ onClick={this.exitLongLinks} /> */}
+
+ </span> : null}
</div>
</div>;
}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 10ebe571b..26abd2529 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -12,26 +12,29 @@ import { AclAddonly, AclReadonly, AclSym, DataSym, Doc, DocListCast, Field, Opt
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
+import { RichTextField } from '../../../fields/RichTextField';
import { listSpec } from '../../../fields/Schema';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils, returnEmptyFilter } from '../../../Utils';
+import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
import { CurrentUserUtils } from '../../util/CurrentUserUtils';
import { ImageUtils } from '../../util/Import & Export/ImageUtils';
import { InteractionUtils } from '../../util/InteractionUtils';
+import { UndoManager } from '../../util/UndoManager';
import { ContextMenu } from "../ContextMenu";
import { FieldView, FieldViewProps } from '../nodes/FieldView';
import { ScriptBox } from '../ScriptBox';
import { Touchable } from '../Touchable';
-import { CollectionCarouselView } from './CollectionCarouselView';
import { CollectionCarousel3DView } from './CollectionCarousel3DView';
+import { CollectionCarouselView } from './CollectionCarouselView';
import { CollectionDockingView } from "./CollectionDockingView";
import { AddCustomFreeFormLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
+import { CollectionGridView } from './collectionGrid/CollectionGridView';
import { CollectionLinearView } from './CollectionLinearView';
import CollectionMapView from './CollectionMapView';
import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView';
@@ -43,12 +46,8 @@ import { CollectionStaffView } from './CollectionStaffView';
import { SubCollectionViewProps } from './CollectionSubView';
import { CollectionTimeView } from './CollectionTimeView';
import { CollectionTreeView } from "./CollectionTreeView";
-import { CollectionGridView } from './collectionGrid/CollectionGridView';
import './CollectionView.scss';
import { CollectionViewBaseChrome } from './CollectionViewChromes';
-import { UndoManager } from '../../util/UndoManager';
-import { RichTextField } from '../../../fields/RichTextField';
-import { TextField } from '../../util/ProsemirrorCopy/prompt';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 21b0473c9..b81e400b3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,53 +1,51 @@
import { library } from "@fortawesome/fontawesome-svg-core";
-import { faEye, faEyeSlash } from "@fortawesome/free-regular-svg-icons";
+import { faEye } from "@fortawesome/free-regular-svg-icons";
import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrowsAlt, faFileUpload, faPaintBrush, faTable, faUpload } from "@fortawesome/free-solid-svg-icons";
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, _allowStateChangesInsideComputed, trace } from "mobx";
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
import { computedFn } from "mobx-utils";
-import { Doc, HeightSym, Opt, WidthSym, DocListCast } from "../../../../fields/Doc";
-import { documentSchema, collectionSchema } from "../../../../fields/documentSchemas";
+import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../fields/Doc";
+import { collectionSchema, documentSchema } from "../../../../fields/documentSchemas";
import { Id } from "../../../../fields/FieldSymbols";
-import { InkData, InkField, InkTool, PointData } from "../../../../fields/InkField";
+import { InkData, InkField, InkTool } from "../../../../fields/InkField";
import { List } from "../../../../fields/List";
import { RichTextField } from "../../../../fields/RichTextField";
-import { createSchema, listSpec, makeInterface } from "../../../../fields/Schema";
-import { ScriptField, ComputedField } from "../../../../fields/ScriptField";
+import { createSchema, makeInterface } from "../../../../fields/Schema";
+import { ScriptField } from "../../../../fields/ScriptField";
import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
import { TraceMobx } from "../../../../fields/util";
import { GestureUtils } from "../../../../pen-gestures/GestureUtils";
-import { aggregateBounds, intersectRect, returnOne, Utils, returnZero, returnFalse, numberRange } from "../../../../Utils";
+import { aggregateBounds, intersectRect, returnFalse, returnOne, returnZero, Utils } from "../../../../Utils";
import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
import { DocServer } from "../../../DocServer";
import { Docs, DocUtils } from "../../../documents/Documents";
+import { DocumentType } from "../../../documents/DocumentTypes";
import { DocumentManager } from "../../../util/DocumentManager";
import { DragManager, dropActionType } from "../../../util/DragManager";
import { HistoryUtil } from "../../../util/History";
import { InteractionUtils } from "../../../util/InteractionUtils";
import { SelectionManager } from "../../../util/SelectionManager";
+import { SnappingManager } from "../../../util/SnappingManager";
import { Transform } from "../../../util/Transform";
import { undoBatch, UndoManager } from "../../../util/UndoManager";
import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss";
+import { Timeline } from "../../animationtimeline/Timeline";
import { ContextMenu } from "../../ContextMenu";
-import { ContextMenuProps } from "../../ContextMenuItem";
+import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth } from "../../InkingStroke";
import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView";
-import { DocumentViewProps, DocumentView } from "../../nodes/DocumentView";
+import { DocumentLinksButton } from "../../nodes/DocumentLinksButton";
+import { DocumentViewProps } from "../../nodes/DocumentView";
import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox";
import { pageSchema } from "../../nodes/ImageBox";
-import PDFMenu from "../../pdf/PDFMenu";
import { CollectionDockingView } from "../CollectionDockingView";
import { CollectionSubView } from "../CollectionSubView";
-import { computePivotLayout, computeTimelineLayout, PoolData, ViewDefBounds, ViewDefResult, computerStarburstLayout, computerPassLayout } from "./CollectionFreeFormLayoutEngines";
+import { CollectionViewType } from "../CollectionView";
+import { computePivotLayout, computerPassLayout, computerStarburstLayout, computeTimelineLayout, PoolData, ViewDefBounds, ViewDefResult } from "./CollectionFreeFormLayoutEngines";
import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCursors";
import "./CollectionFreeFormView.scss";
import MarqueeOptionsMenu from "./MarqueeOptionsMenu";
import { MarqueeView } from "./MarqueeView";
import React = require("react");
-import { CollectionViewType } from "../CollectionView";
-import { Timeline } from "../../animationtimeline/Timeline";
-import { SnappingManager } from "../../../util/SnappingManager";
-import { InkingStroke, ActiveArrowStart, ActiveArrowEnd, ActiveInkColor, ActiveFillColor, ActiveInkWidth, ActiveInkBezierApprox, ActiveDash } from "../../InkingStroke";
-import { DocumentType } from "../../../documents/DocumentTypes";
-import { DocumentLinksButton } from "../../nodes/DocumentLinksButton";
library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss
index c372e7098..6468ccd3d 100644
--- a/src/client/views/linking/LinkMenu.scss
+++ b/src/client/views/linking/LinkMenu.scss
@@ -15,7 +15,7 @@
}
.linkMenu-group {
- border-bottom: 0.5px solid lightgray;
+ border-bottom: 0.5px solid lightgray;
padding: 5px 0;
@@ -30,9 +30,11 @@
p {
background-color: lightgray;
}
+
p.expand-one {
width: calc(100% - 26px);
}
+
.linkEditor-tableButton {
display: block;
}
@@ -50,7 +52,4 @@
display: none;
}
}
-}
-
-
-
+} \ No newline at end of file
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index de1d60a09..c672511ac 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -10,6 +10,7 @@ import { LinkMenuGroup } from "./LinkMenuGroup";
import { faTrash } from '@fortawesome/free-solid-svg-icons';
import { library } from "@fortawesome/fontawesome-svg-core";
import { DocumentLinksButton } from "../nodes/DocumentLinksButton";
+import { LinkDocPreview } from "../nodes/LinkDocPreview";
library.add(faTrash);
@@ -28,9 +29,16 @@ export class LinkMenu extends React.Component<Props> {
@action
onClick = (e: PointerEvent) => {
+
+ LinkDocPreview.LinkInfo = undefined;
+
if (this._linkMenuRef?.contains(e.target as any)) {
DocumentLinksButton.EditLink = undefined;
}
+
+ if (this._linkMenuRef && !this._linkMenuRef.contains(e.target as any)) {
+ DocumentLinksButton.EditLink = undefined;
+ }
}
@action
componentDidMount() {
@@ -70,7 +78,8 @@ export class LinkMenu extends React.Component<Props> {
render() {
const sourceDoc = this.props.docView.props.Document;
const groups: Map<string, Doc[]> = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc);
- return <div className="linkMenu-list" ref={(r) => this._linkMenuRef = r} style={{ left: this.props.location[0], top: this.props.location[1] }}>
+ return <div className="linkMenu-list"
+ ref={(r) => this._linkMenuRef = r} style={{ left: this.props.location[0], top: this.props.location[1] }}>
{!this._editingLink ?
this.renderAllGroups(groups) :
<LinkEditor sourceDoc={this.props.docView.props.Document} linkDoc={this._editingLink} showLinks={action(() => this._editingLink = undefined)} />
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index 89deb3a55..7892d381b 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -80,11 +80,11 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
return (
<div className="linkMenu-group">
- <div className="linkMenu-group-name">
+ {/* <div className="linkMenu-group-name">
<p ref={this._drag} onPointerDown={this.onLinkButtonDown}
className={this.props.groupType === "*" || this.props.groupType === "" ? "" : "expand-one"} > {this.props.groupType}:</p>
{this.props.groupType === "*" || this.props.groupType === "" ? <></> : this.viewGroupAsTable(this.props.groupType)}
- </div>
+ </div> */}
<div className="linkMenu-group-wrapper">
{groupItems}
</div>
diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss
index fd0954f65..e3ce69cd7 100644
--- a/src/client/views/linking/LinkMenuItem.scss
+++ b/src/client/views/linking/LinkMenuItem.scss
@@ -5,7 +5,7 @@
position: relative;
display: flex;
font-size: 12px;
-
+
.linkMenu-name {
position: relative;
@@ -22,7 +22,7 @@
.linkMenu-item-content {
width: 100%;
}
-
+
.link-metadata {
padding: 0 10px 0 16px;
margin-bottom: 4px;
@@ -35,11 +35,13 @@
.linkMenu-item-buttons {
display: flex;
}
+
.linkMenu-item-content {
&.expand-two p {
width: calc(100% - 52px);
background-color: lightgray;
}
+
&.expand-three p {
width: calc(100% - 84px);
background-color: lightgray;
@@ -49,11 +51,11 @@
}
.linkMenu-item-buttons {
- display: none;
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
+ display: none;
.button {
width: 20px;
@@ -61,7 +63,6 @@
margin: 0;
margin-right: 6px;
border-radius: 50%;
- cursor: pointer;
pointer-events: auto;
background-color: $dark-color;
color: $light-color;
@@ -80,8 +81,10 @@
&:last-child {
margin-right: 0;
}
+
&:hover {
background: $main-accent;
+ cursor: grab;
}
}
} \ No newline at end of file
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index edc18b6a9..04cd83ee0 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -1,5 +1,5 @@
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faArrowRight, faChevronDown, faChevronUp, faEdit, faEye, faTimes } from '@fortawesome/free-solid-svg-icons';
+import { faArrowRight, faChevronDown, faChevronUp, faEdit, faEye, faTimes, faPencilAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, observable } from 'mobx';
import { observer } from "mobx-react";
@@ -13,7 +13,9 @@ import React = require("react");
import { DocumentManager } from '../../util/DocumentManager';
import { setupMoveUpEvents, emptyFunction } from '../../../Utils';
import { DocumentView } from '../nodes/DocumentView';
-library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp);
+import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
+import { LinkDocPreview } from '../nodes/LinkDocPreview';
+library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt);
interface LinkMenuItemProps {
@@ -69,6 +71,8 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
private _eleClone: any;
_editRef = React.createRef<HTMLDivElement>();
+ _buttonRef = React.createRef<HTMLDivElement>();
+
@observable private _showMore: boolean = false;
@action toggleShowMore(e: React.PointerEvent) { e.stopPropagation(); this._showMore = !this._showMore; }
@@ -95,6 +99,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
return (<div className="link-metadata">{mdRows}</div>);
}
+ @action
onLinkButtonDown = (e: React.PointerEvent): void => {
this._downX = e.clientX;
this._downY = e.clientY;
@@ -104,6 +109,10 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
document.addEventListener("pointermove", this.onLinkButtonMoved);
document.removeEventListener("pointerup", this.onLinkButtonUp);
document.addEventListener("pointerup", this.onLinkButtonUp);
+
+ if (this._buttonRef && this._buttonRef.current?.contains(e.target as any)) {
+ LinkDocPreview.LinkInfo = undefined;
+ }
}
onLinkButtonUp = (e: PointerEvent): void => {
@@ -124,7 +133,10 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
e.stopPropagation();
}
+ @action
onContextMenu = (e: React.MouseEvent) => {
+ DocumentLinksButton.EditLink = undefined;
+ LinkDocPreview.LinkInfo = undefined;
e.preventDefault();
ContextMenu.Instance.addItem({ description: "Follow Default Link", event: () => this.followDefault(), icon: "arrow-right" });
ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
@@ -132,9 +144,20 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
@action.bound
async followDefault() {
+ console.log("FOLLOWWW");
+ DocumentLinksButton.EditLink = undefined;
+ LinkDocPreview.LinkInfo = undefined;
DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false);
}
+ @action
+ deleteLink = (): void => {
+ LinkManager.Instance.deleteLink(this.props.linkDoc);
+ //this.props.showLinks();
+ LinkDocPreview.LinkInfo = undefined;
+ DocumentLinksButton.EditLink = undefined;
+ }
+
render() {
const keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType);
const canExpand = keys ? keys.length > 0 : false;
@@ -142,13 +165,25 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
return (
<div className="linkMenu-item">
<div className={canExpand ? "linkMenu-item-content expand-three" : "linkMenu-item-content expand-two"}>
- <div ref={this._drag} className="linkMenu-name" title="drag to view target. click to customize." onPointerDown={this.onLinkButtonDown}>
+ <div ref={this._drag} className="linkMenu-name" //title="drag to view target. click to customize."
+ onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
+ onPointerEnter={action(e => this.props.linkDoc && (LinkDocPreview.LinkInfo = {
+ addDocTab: this.props.addDocTab,
+ linkSrc: this.props.sourceDoc,
+ linkDoc: this.props.linkDoc,
+ Location: [e.clientX, e.clientY + 20]
+ }))}
+ onPointerDown={this.onLinkButtonDown}>
<p >{StrCast(this.props.destinationDoc.title)}</p>
- <div className="linkMenu-item-buttons">
+ <div className="linkMenu-item-buttons" ref={this._buttonRef} >
{canExpand ? <div title="Show more" className="button" onPointerDown={e => this.toggleShowMore(e)}>
<FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>}
- <div title="Edit link" className="button" ref={this._editRef} onPointerDown={this.onEdit}><FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
- <div title="Follow link" className="button" onClick={this.followDefault} onContextMenu={this.onContextMenu}>
+
+ {/* <div title="Edit link" className="button" ref={this._editRef} onPointerDown={this.onEdit}>
+ <FontAwesomeIcon className="fa-icon" icon="pencil-alt" size="sm" /></div> */}
+ <div title="Delete link" className="button" onPointerDown={this.deleteLink}>
+ <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
+ <div title="Follow link" className="button" onPointerDown={this.followDefault} onContextMenu={this.onContextMenu}>
<FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" />
</div>
</div>
diff --git a/src/client/views/nodes/DocumentLinksButton.scss b/src/client/views/nodes/DocumentLinksButton.scss
index 484f8c469..b58603978 100644
--- a/src/client/views/nodes/DocumentLinksButton.scss
+++ b/src/client/views/nodes/DocumentLinksButton.scss
@@ -23,7 +23,7 @@
&:hover {
background: deepskyblue;
transform: scale(1.05);
- cursor: default;
+ cursor: grab;
}
}
.documentLinksButton {
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 3940b7a98..bfd860f65 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -10,6 +10,7 @@ import React = require("react");
import { DocUtils } from "../../documents/Documents";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { LinkDocPreview } from "./LinkDocPreview";
+import { LinkCreatedBox } from "./LinkCreatedBox";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -18,11 +19,14 @@ interface DocumentLinksButtonProps {
View: DocumentView;
Offset?: number[];
AlwaysOn?: boolean;
+ InMenu?: boolean;
}
@observer
export class DocumentLinksButton extends React.Component<DocumentLinksButtonProps, {}> {
private _linkButton = React.createRef<HTMLDivElement>();
+ @observable public static StartLink: DocumentView | undefined;
+
@action
onLinkButtonMoved = (e: PointerEvent) => {
if (this._linkButton.current !== null) {
@@ -50,30 +54,73 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
return false;
}
- @observable static StartLink: DocumentView | undefined;
onLinkButtonDown = (e: React.PointerEvent): void => {
setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => {
- if (doubleTap) {
+ if (doubleTap && this.props.InMenu) {
+ //action(() => Doc.BrushDoc(this.props.View.Document));
DocumentLinksButton.StartLink = this.props.View;
- } else {
+ } else if (!!!this.props.InMenu) {
DocumentLinksButton.EditLink = this.props.View;
DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY];
}
}));
}
+
+ @action
+ onLinkClick = (e: React.MouseEvent): void => {
+ if (this.props.InMenu) {
+ DocumentLinksButton.StartLink = this.props.View;
+ //action(() => Doc.BrushDoc(this.props.View.Document));
+ } else if (!!!this.props.InMenu) {
+ DocumentLinksButton.EditLink = this.props.View;
+ DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY];
+ }
+ }
+
+ @action
completeLink = (e: React.PointerEvent): void => {
setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e, doubleTap) => {
if (doubleTap) {
if (DocumentLinksButton.StartLink === this.props.View) {
DocumentLinksButton.StartLink = undefined;
+ // action((e: React.PointerEvent<HTMLDivElement>) => {
+ // Doc.UnBrushDoc(this.props.View.Document);
+ // });
} else {
DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
+
+ runInAction(() => {
+ LinkCreatedBox.popupX = e.screenX;
+ LinkCreatedBox.popupY = e.screenY - 120;
+ LinkCreatedBox.linkCreated = true;
+ setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+ });
}
}
}));
}
+ @action
+ finishLinkClick = (e: React.MouseEvent) => {
+ if (DocumentLinksButton.StartLink === this.props.View) {
+ DocumentLinksButton.StartLink = undefined;
+ // action((e: React.PointerEvent<HTMLDivElement>) => {
+ // Doc.UnBrushDoc(this.props.View.Document);
+ // });
+ } else {
+ DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
+ DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
+
+ runInAction(() => {
+ LinkCreatedBox.popupX = e.screenX;
+ LinkCreatedBox.popupY = e.screenY - 120;
+ LinkCreatedBox.linkCreated = true;
+ setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+ });
+ }
+ }
+
@observable
public static EditLink: DocumentView | undefined;
public static EditLinkLoc: number[] = [0, 0];
@@ -83,19 +130,26 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
const links = DocListCast(this.props.View.props.Document.links);
return (!links.length || links[0].hidden) && !this.props.AlwaysOn ? (null) :
<div title="Drag(create link) Tap(view links)" ref={this._linkButton} style={{ minWidth: 20, minHeight: 20, position: "absolute", left: this.props.Offset?.[0] }}>
- <div className={"documentLinksButton"} style={{ backgroundColor: DocumentLinksButton.StartLink ? "transparent" : "" }}
- onPointerDown={this.onLinkButtonDown}
- onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
- onPointerEnter={action(e => links.length && (LinkDocPreview.LinkInfo = {
- addDocTab: this.props.View.props.addDocTab,
- linkSrc: this.props.View.props.Document,
- linkDoc: links[0],
- Location: [e.clientX, e.clientY + 20]
- }))} >
- {links.length ? links.length : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />}
+ <div className={"documentLinksButton"} style={{
+ backgroundColor: DocumentLinksButton.StartLink ? "transparent" : "",
+ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px", fontWeight: "bold"
+ }}
+ onPointerDown={this.onLinkButtonDown} onClick={this.onLinkClick}
+ // onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
+ // onPointerEnter={action(e => links.length && (LinkDocPreview.LinkInfo = {
+ // addDocTab: this.props.View.props.addDocTab,
+ // linkSrc: this.props.View.props.Document,
+ // linkDoc: links[0],
+ // Location: [e.clientX, e.clientY + 20]
+ // }))}
+ >
+ {links.length && !!!this.props.InMenu ? links.length : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />}
</div>
- {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"} onPointerDown={this.completeLink} /> : (null)}
- {DocumentLinksButton.StartLink === this.props.View ? <div className={"documentLinksButton-startLink"} /> : (null)}
+ {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"}
+ style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }}
+ onPointerDown={this.completeLink} onClick={e => this.finishLinkClick(e)} /> : (null)}
+ {DocumentLinksButton.StartLink === this.props.View ? <div className={"documentLinksButton-startLink"}
+ style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }} /> : (null)}
</div>;
}
render() {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 98adab5fa..b38db9a1e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -42,6 +42,7 @@ import { RadialMenu } from './RadialMenu';
import React = require("react");
import { DocumentLinksButton } from './DocumentLinksButton';
import { MobileInterface } from '../../../mobile/MobileInterface';
+import { LinkCreatedBox } from './LinkCreatedBox';
library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
@@ -116,6 +117,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
private holdDisposer?: InteractionUtils.MultiTouchEventDisposer;
+ public get title() { return this.props.Document.title; }
public get displayName() { return "DocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
public get ContentDiv() { return this._mainCont.current; }
get active() { return SelectionManager.IsSelected(this, true) || this.props.parentActive(true); }
@@ -640,12 +642,27 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
e.stopPropagation();
de.complete.annoDragData.linkedToDoc = true;
+ runInAction(() => {
+ LinkCreatedBox.popupX = de.x;
+ LinkCreatedBox.popupY = de.y;
+ LinkCreatedBox.linkCreated = true;
+ setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+ });
+
DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document }, "link");
}
if (de.complete.linkDragData) {
e.stopPropagation();
// const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true);
// const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
+
+ runInAction(() => {
+ LinkCreatedBox.popupX = de.x;
+ LinkCreatedBox.popupY = de.y;
+ LinkCreatedBox.linkCreated = true;
+ setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+ });
+
de.complete.linkDragData.linkSourceDocument !== this.props.Document &&
(de.complete.linkDragData.linkDocument = DocUtils.MakeLink({ doc: de.complete.linkDragData.linkSourceDocument },
{ doc: this.props.Document }, `link`)); // TODODO this is where in text links get passed
@@ -1192,7 +1209,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
id={this.props.Document[Id]}
ref={this._mainCont} onKeyDown={this.onKeyDown}
onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
- onPointerEnter={action(() => Doc.BrushDoc(this.props.Document))}
+ onPointerEnter={action(() => { Doc.BrushDoc(this.props.Document); })}
onPointerLeave={action((e: React.PointerEvent<HTMLDivElement>) => {
let entered = false;
const target = document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y);
@@ -1201,7 +1218,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
entered = true;
}
}
+ // if (this.props.Document !== DocumentLinksButton.StartLink?.Document) {
!entered && Doc.UnBrushDoc(this.props.Document);
+ //}
+
})}
style={{
transformOrigin: this._animateScalingTo ? "center center" : undefined,
diff --git a/src/client/views/nodes/LinkAnchorBox.scss b/src/client/views/nodes/LinkAnchorBox.scss
index 710f2178b..42ef2958e 100644
--- a/src/client/views/nodes/LinkAnchorBox.scss
+++ b/src/client/views/nodes/LinkAnchorBox.scss
@@ -1,4 +1,5 @@
-.linkAnchorBox-cont, .linkAnchorBox-cont-small {
+.linkAnchorBox-cont,
+.linkAnchorBox-cont-small {
cursor: default;
position: absolute;
width: 15;
@@ -24,6 +25,6 @@
}
.linkAnchorBox-cont-small {
- width:5px;
- height:5px;
+ width: 5px;
+ height: 5px;
} \ No newline at end of file
diff --git a/src/client/views/nodes/LinkCreatedBox.scss b/src/client/views/nodes/LinkCreatedBox.scss
new file mode 100644
index 000000000..3cbd38b55
--- /dev/null
+++ b/src/client/views/nodes/LinkCreatedBox.scss
@@ -0,0 +1,21 @@
+.linkCreatedBox-fade {
+ border: 1px solid rgb(100, 100, 100);
+
+
+ width: auto;
+ position: absolute;
+
+ height: auto;
+ z-index: 10000;
+ border-radius: 13px;
+ font-size: 13px;
+ white-space: nowrap;
+
+ color: rgb(100, 100, 100);
+ background-color: rgba(250, 250, 250, 0.85);
+ padding-top: 6.5px;
+ padding-bottom: 6.5px;
+ font-weight: bold;
+ padding-left: 9px;
+ padding-right: 9px;
+} \ No newline at end of file
diff --git a/src/client/views/nodes/LinkCreatedBox.tsx b/src/client/views/nodes/LinkCreatedBox.tsx
new file mode 100644
index 000000000..d157d3fca
--- /dev/null
+++ b/src/client/views/nodes/LinkCreatedBox.tsx
@@ -0,0 +1,31 @@
+import React = require("react");
+import { observer } from "mobx-react";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface } from "../../../fields/Schema";
+import "./LinkCreatedBox.scss";
+import { observable, action } from "mobx";
+import { Fade } from "@material-ui/core";
+
+
+@observer
+export class LinkCreatedBox extends React.Component<{}> {
+
+ @observable public static linkCreated: boolean = false;
+ @observable public static popupX: number = 600;
+ @observable public static popupY: number = 250;
+
+ @action
+ public static changeLinkCreated = () => {
+ LinkCreatedBox.linkCreated = !LinkCreatedBox.linkCreated;
+ }
+
+ render() {
+ return <Fade in={LinkCreatedBox.linkCreated}>
+ <div className="linkCreatedBox-fade"
+ style={{
+ left: LinkCreatedBox.popupX ? LinkCreatedBox.popupX : 600,
+ top: LinkCreatedBox.popupY ? LinkCreatedBox.popupY : 250,
+ }}>Link Created</div>
+ </Fade>;
+ }
+} \ No newline at end of file
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index e8a08abb5..197dc8df4 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -10,6 +10,11 @@ import { Transform } from "../../util/Transform";
import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
import React = require("react");
import { DocumentView } from './DocumentView';
+import { sortAndDeduplicateDiagnostics } from 'typescript';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { LinkManager } from '../../util/LinkManager';
+import { DocumentLinksButton } from './DocumentLinksButton';
+import { ContextMenu } from '../ContextMenu';
interface Props {
linkDoc?: Doc;
@@ -24,6 +29,31 @@ export class LinkDocPreview extends React.Component<Props> {
@observable public static LinkInfo: Opt<{ linkDoc?: Doc; addDocTab: (document: Doc, where: string) => boolean, linkSrc: Doc; href?: string; Location: number[] }>;
@observable _targetDoc: Opt<Doc>;
@observable _toolTipText = "";
+ _editRef = React.createRef<HTMLDivElement>();
+
+ @action
+ deleteLink = (): void => {
+ this.props.linkDoc ? LinkManager.Instance.deleteLink(this.props.linkDoc) : null;
+ //this.props.showLinks();
+ LinkDocPreview.LinkInfo = undefined;
+ DocumentLinksButton.EditLink = undefined;
+ }
+
+ @action
+ onContextMenu = (e: React.MouseEvent) => {
+ DocumentLinksButton.EditLink = undefined;
+ LinkDocPreview.LinkInfo = undefined;
+ e.preventDefault();
+ ContextMenu.Instance.addItem({ description: "Follow Default Link", event: () => this.followDefault(), icon: "arrow-right" });
+ ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
+ }
+
+ @action.bound
+ async followDefault() {
+ DocumentLinksButton.EditLink = undefined;
+ LinkDocPreview.LinkInfo = undefined;
+ this._targetDoc ? DocumentManager.Instance.FollowLink(this.props.linkDoc, this._targetDoc, doc => this.props.addDocTab(doc, "onRight"), false) : null;
+ }
componentDidUpdate() { this.updatePreview(); }
componentDidMount() { this.updatePreview(); }
@@ -56,15 +86,30 @@ export class LinkDocPreview extends React.Component<Props> {
this.props.addDocTab(Docs.Create.WebDocument(this.props.href, { title: this.props.href, _width: 200, _height: 400, UseCors: true }), "onRight");
}
}
- width = () => Math.min(350, NumCast(this._targetDoc?.[WidthSym](), 350));
- height = () => Math.min(350, NumCast(this._targetDoc?.[HeightSym](), 350));
+ width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225));
+ height = () => Math.min(225, NumCast(this._targetDoc?.[HeightSym](), 225));
@computed get targetDocView() {
return !this._targetDoc ?
- <div style={{ pointerEvents: "all", maxWidth: 350, maxHeight: 250, width: "100%", height: "100%", overflow: "hidden" }}>
+ <div style={{
+ pointerEvents: "all", maxWidth: 225, maxHeight: 225, width: "100%", height: "100%",
+ overflow: "hidden"
+ }}>
<div style={{ width: "100%", height: "100%", textOverflow: "ellipsis", }} onPointerDown={this.pointerDown}>
{this._toolTipText}
</div>
</div> :
+ // <div style={{
+ // border: "6px solid white",
+ // }}>
+ // <div style={{ backgroundColor: "white" }}> {this._targetDoc.title}
+ // <div className="wrapper" style={{ float: "right" }}>
+ // <div title="Delete link" className="button" style={{ display: "inline" }} ref={this._editRef} onPointerDown={this.deleteLink}>
+ // <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
+ // <div title="Follow link" className="button" style={{ display: "inline" }} onClick={this.followDefault} onContextMenu={this.onContextMenu}>
+ // <FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" />
+ // </div>
+ // </div>
+ // </div>
<ContentFittingDocumentView
Document={this._targetDoc}
LibraryPath={emptyPath}
@@ -92,6 +137,7 @@ export class LinkDocPreview extends React.Component<Props> {
NativeWidth={returnZero}
NativeHeight={returnZero}
/>;
+ //</div>;
}
render() {
@@ -99,7 +145,7 @@ export class LinkDocPreview extends React.Component<Props> {
style={{
position: "absolute", left: this.props.location[0],
top: this.props.location[1], width: this.width(), height: this.height(),
- boxShadow: "black 2px 2px 1em"
+ boxShadow: "black 2px 2px 1em", zIndex: 1000
}}>
{this.targetDocView}
</div>;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 69708e7a0..167ba782f 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -59,6 +59,7 @@ import { FieldView, FieldViewProps } from "../FieldView";
import "./FormattedTextBox.scss";
import { FormattedTextBoxComment, formattedTextBoxCommentPlugin, findLinkMark } from './FormattedTextBoxComment';
import React = require("react");
+import { DocumentManager } from '../../../util/DocumentManager';
library.add(faEdit);
library.add(faSmile, faTextHeight, faUpload);
@@ -1079,7 +1080,42 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
@action
+ onDoubleClick = (e: React.MouseEvent): void => {
+
+ this.doLinkOnDeselect();
+ FormattedTextBox._downEvent = true;
+ FormattedTextBoxComment.textBox = this;
+ if (this.props.onClick && e.button === 0 && !this.props.isSelected(false)) {
+ e.preventDefault();
+ }
+ if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) {
+ if (e.clientX < this.ProseRef!.getBoundingClientRect().right) { // stop propagation if not in sidebar
+ e.stopPropagation(); // if the text box is selected, then it consumes all down events
+ }
+ }
+ if (e.button === 2 || (e.button === 0 && e.ctrlKey)) {
+ e.preventDefault();
+ }
+ FormattedTextBoxComment.Hide();
+ if (FormattedTextBoxComment.linkDoc) {
+ if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+ this.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+ } else {
+ DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, this.props.Document,
+ (doc: Doc, followLinkLocation: string) => this.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+ }
+ }
+
+ (e.nativeEvent as any).formattedHandled = true;
+
+ if (e.buttons === 1 && this.props.isSelected(true) && !e.altKey) {
+ e.stopPropagation();
+ }
+ }
+
+ @action
onFocused = (e: React.FocusEvent): void => {
+ console.log("FOUCSS");
FormattedTextBox.FocusedBox = this;
this.tryUpdateHeight();
@@ -1211,6 +1247,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
public static HadSelection: boolean = false;
onBlur = (e: any) => {
+ console.log("BLURRR");
FormattedTextBox.HadSelection = window.getSelection()?.toString() !== "";
//DictationManager.Controls.stop(false);
this.endUndoTypingBatch();
@@ -1347,6 +1384,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
}
})}
+ onDoubleClick={this.onDoubleClick}
>
<div className={`formattedTextBox-outer`} ref={this._scrollRef}
style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !this.props.isSelected() ? "none" : undefined }}
@@ -1393,7 +1431,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
setTimeout(() => this._editorView!.focus(), 500);
e.stopPropagation();
}} >
- <FontAwesomeIcon className="formattedTExtBox-audioFont"
+ <FontAwesomeIcon className="formattedTextBox-audioFont"
style={{ color: this._recording ? "red" : "blue", opacity: this._recording ? 1 : 0.5, display: this.props.isSelected() ? "" : "none" }} icon={"microphone"} size="sm" />
</div>}
</div>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
index 2dd63ec21..9089e7039 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
@@ -8,10 +8,12 @@
margin-bottom: 7px;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
- }
- .FormattedTextBox-tooltip:before {
+}
+
+.FormattedTextBox-tooltip:before {
content: "";
- height: 0; width: 0;
+ height: 0;
+ width: 0;
position: absolute;
left: 50%;
margin-left: -5px;
@@ -19,10 +21,12 @@
border: 5px solid transparent;
border-bottom-width: 0;
border-top-color: silver;
- }
- .FormattedTextBox-tooltip:after {
+}
+
+.FormattedTextBox-tooltip:after {
content: "";
- height: 0; width: 0;
+ height: 0;
+ width: 0;
position: absolute;
left: 50%;
margin-left: -5px;
@@ -30,4 +34,72 @@
border: 5px solid transparent;
border-bottom-width: 0;
border-top-color: white;
- } \ No newline at end of file
+}
+
+.FormattedTextBoxComment-buttons {
+ display: none;
+ position: absolute;
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+
+ .FormattedTextBoxComment-button {
+ width: 20px;
+ height: 20px;
+ margin: 0;
+ margin-right: 6px;
+ border-radius: 50%;
+ pointer-events: auto;
+ background-color: rgb(38, 40, 41);
+ color: rgb(178, 181, 184);
+ font-size: 65%;
+ transition: transform 0.2s;
+ text-align: center;
+ position: relative;
+
+ // margin-top: "auto";
+ // margin-bottom: "auto";
+ // background: black;
+ // color: white;
+ // display: inline-block;
+ // border-radius: 18px;
+ // font-size: 12.5px;
+ // width: 18px;
+ // height: 18px;
+ // margin-top: auto;
+ // margin-bottom: auto;
+ // margin-right: 3px;
+ // cursor: pointer;
+ // transition: transform 0.2s;
+
+ .FormattedTextBoxComment-fa-icon {
+ margin-top: "auto";
+ margin-bottom: "auto";
+ background: black;
+ color: white;
+ display: inline-block;
+ border-radius: 18px;
+ font-size: 12.5px;
+ width: 18px;
+ height: 18px;
+ margin-top: auto;
+ margin-bottom: auto;
+ margin-right: 3px;
+ cursor: pointer;
+ transition: transform 0.2s;
+ // position: absolute;
+ // top: 50%;
+ // left: 50%;
+ // transform: translate(-50%, -50%);
+ }
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ &:hover {
+ background: rgb(53, 146, 199);
+ ;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 4c90b6afd..56826e5c7 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -2,7 +2,7 @@ import { Mark, ResolvedPos } from "prosemirror-model";
import { EditorState, Plugin } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import * as ReactDOM from 'react-dom';
-import { Doc, DocCastAsync } from "../../../../fields/Doc";
+import { Doc, DocCastAsync, Opt } from "../../../../fields/Doc";
import { Cast, FieldValue, NumCast } from "../../../../fields/Types";
import { emptyFunction, returnEmptyString, returnFalse, Utils, emptyPath, returnZero, returnOne, returnEmptyFilter } from "../../../../Utils";
import { DocServer } from "../../../DocServer";
@@ -16,6 +16,11 @@ import React = require("react");
import { Docs } from "../../../documents/Documents";
import wiki from "wikijs";
import { DocumentType } from "../../../documents/DocumentTypes";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action } from "mobx";
+import { LinkManager } from "../../../util/LinkManager";
+import { LinkDocPreview } from "../LinkDocPreview";
+import { DocumentLinksButton } from "../DocumentLinksButton";
export let formattedTextBoxCommentPlugin = new Plugin({
view(editorView) { return new FormattedTextBoxComment(editorView); }
@@ -62,6 +67,10 @@ export class FormattedTextBoxComment {
static mark: Mark;
static textBox: FormattedTextBox | undefined;
static linkDoc: Doc | undefined;
+
+ static _deleteRef: Opt<HTMLDivElement | null>;
+ static _followRef: Opt<HTMLDivElement | null>;
+
constructor(view: any) {
if (!FormattedTextBoxComment.tooltip) {
const root = document.getElementById("root");
@@ -75,8 +84,8 @@ export class FormattedTextBoxComment {
FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
FormattedTextBoxComment.tooltip.className = "FormattedTextBox-tooltip";
FormattedTextBoxComment.tooltip.style.pointerEvents = "all";
- FormattedTextBoxComment.tooltip.style.maxWidth = "350px";
- FormattedTextBoxComment.tooltip.style.maxHeight = "250px";
+ FormattedTextBoxComment.tooltip.style.maxWidth = "200px";
+ FormattedTextBoxComment.tooltip.style.maxHeight = "206px";
FormattedTextBoxComment.tooltip.style.width = "100%";
FormattedTextBoxComment.tooltip.style.height = "100%";
FormattedTextBoxComment.tooltip.style.overflow = "hidden";
@@ -87,12 +96,25 @@ export class FormattedTextBoxComment {
const textBox = FormattedTextBoxComment.textBox;
if (FormattedTextBoxComment.linkDoc && !keep && textBox) {
if (FormattedTextBoxComment.linkDoc.author) {
- if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
- textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+
+ if (FormattedTextBoxComment._deleteRef && FormattedTextBoxComment._deleteRef.contains(e.target as any)) {
+ this.deleteLink();
+ } else if (FormattedTextBoxComment._followRef && FormattedTextBoxComment._followRef.contains(e.target as any)) {
+ if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+ textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+ } else {
+ DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
+ (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+ }
} else {
- DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
- (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+ if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+ textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+ } else {
+ DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
+ (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+ }
}
+
}
} else if (textBox && (FormattedTextBoxComment.tooltipText as any).href) {
textBox.props.addDocTab(Docs.Create.WebDocument((FormattedTextBoxComment.tooltipText as any).href, { title: (FormattedTextBoxComment.tooltipText as any).href, _width: 200, _height: 400, UseCors: true }), "onRight");
@@ -106,6 +128,15 @@ export class FormattedTextBoxComment {
}
}
+ @action
+ deleteLink = () => {
+ FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null;
+ LinkDocPreview.LinkInfo = undefined;
+ DocumentLinksButton.EditLink = undefined;
+ //FormattedTextBoxComment.tooltipText = undefined;
+ FormattedTextBoxComment.Hide();
+ }
+
public static Hide() {
FormattedTextBoxComment.textBox = undefined;
FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
@@ -210,32 +241,87 @@ export class FormattedTextBoxComment {
}
if (target?.author) {
FormattedTextBoxComment.showCommentbox("", view, nbef);
- ReactDOM.render(<ContentFittingDocumentView
- Document={target}
- LibraryPath={emptyPath}
- fitToBox={true}
- moveDocument={returnFalse}
- rootSelected={returnFalse}
- ScreenToLocalTransform={Transform.Identity}
- parentActive={returnFalse}
- addDocument={returnFalse}
- removeDocument={returnFalse}
- addDocTab={returnFalse}
- pinToPres={returnFalse}
- dontRegisterView={true}
- docFilters={returnEmptyFilter}
- ContainingCollectionDoc={undefined}
- ContainingCollectionView={undefined}
- renderDepth={0}
- PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
- PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
- focus={emptyFunction}
- whenActiveChanged={returnFalse}
- bringToFront={returnFalse}
- ContentScaling={returnOne}
- NativeWidth={returnZero}
- NativeHeight={returnZero}
- />, FormattedTextBoxComment.tooltipText);
+ const docPreview = <div style={{ backgroundColor: "white", border: "8px solid white" }}>
+ {target.title}
+ <div className="wrapper" style={{ float: "right" }}>
+ <div title="Delete link" className="FormattedTextBoxComment-button" style={{
+ display: "inline",
+ paddingLeft: "6px",
+ paddingRight: "6px",
+ paddingTop: "2.5px",
+ paddingBottom: "2.5px",
+ width: "20px",
+ height: "20px",
+ margin: 0,
+ marginRight: "6px",
+ borderRadius: "50%",
+ pointerEvents: "auto",
+ backgroundColor: "rgb(38, 40, 41)",
+ color: "rgb(178, 181, 184)",
+ transition: "transform 0.2s",
+ textAlign: "center",
+ position: "relative"
+ }} ref={(r) => this._deleteRef = r}>
+ <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="trash"
+ size="sm" /></div>
+ <div title="Follow link" className="FormattedTextBoxComment-button" style={{
+ display: "inline",
+ paddingLeft: "6px",
+ paddingRight: "6px",
+ paddingTop: "2.5px",
+ paddingBottom: "2.5px",
+ width: "20px",
+ height: "20px",
+ margin: 0,
+ marginRight: "6px",
+ borderRadius: "50%",
+ pointerEvents: "auto",
+ backgroundColor: "rgb(38, 40, 41)",
+ color: "rgb(178, 181, 184)",
+ transition: "transform 0.2s",
+ textAlign: "center",
+ position: "relative"
+ }} ref={(r) => this._followRef = r}>
+ <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="arrow-right"
+ size="sm" />
+ </div>
+ </div>
+ <div className="wrapper" style={{
+ maxWidth: "180px", maxHeight: "168px", overflow: "hidden",
+ overflowY: "hidden", paddingTop: "5px"
+ }}>
+ <ContentFittingDocumentView
+ Document={target}
+ LibraryPath={emptyPath}
+ fitToBox={true}
+ moveDocument={returnFalse}
+ rootSelected={returnFalse}
+ ScreenToLocalTransform={Transform.Identity}
+ parentActive={returnFalse}
+ addDocument={returnFalse}
+ removeDocument={returnFalse}
+ addDocTab={returnFalse}
+ pinToPres={returnFalse}
+ dontRegisterView={true}
+ docFilters={returnEmptyFilter}
+ ContainingCollectionDoc={undefined}
+ ContainingCollectionView={undefined}
+ renderDepth={0}
+ PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
+ PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
+ focus={emptyFunction}
+ whenActiveChanged={returnFalse}
+ bringToFront={returnFalse}
+ ContentScaling={returnOne}
+ NativeWidth={returnZero}
+ NativeHeight={returnZero}
+ />
+ </div>
+ </div>;
+ FormattedTextBoxComment.showCommentbox("", view, nbef);
+
+ ReactDOM.render(docPreview, FormattedTextBoxComment.tooltipText);
+
FormattedTextBoxComment.tooltip.style.width = NumCast(target._width) ? `${NumCast(target._width)}` : "100%";
FormattedTextBoxComment.tooltip.style.height = NumCast(target._height) ? `${NumCast(target._height)}` : "100%";
}
@@ -249,4 +335,4 @@ export class FormattedTextBoxComment {
}
destroy() { }
-}
+} \ No newline at end of file
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 4a35ef018..7aa1d528d 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -832,12 +832,14 @@ export namespace Doc {
})(doc);
}
export function BrushDoc(doc: Doc) {
+
if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return doc;
brushManager.BrushedDoc.set(doc, true);
brushManager.BrushedDoc.set(Doc.GetProto(doc), true);
return doc;
}
export function UnBrushDoc(doc: Doc) {
+
if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return doc;
brushManager.BrushedDoc.delete(doc);
brushManager.BrushedDoc.delete(Doc.GetProto(doc));