aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package-lock.json207
-rw-r--r--package.json3
-rw-r--r--src/client/apis/gpt/Summarization.ts48
-rw-r--r--src/client/views/MainView.tsx3
-rw-r--r--src/client/views/MarqueeAnnotator.tsx2
-rw-r--r--src/client/views/collections/CollectionView.tsx2
-rw-r--r--src/client/views/nodes/ImageBox.tsx2
-rw-r--r--src/client/views/nodes/PDFBox.tsx1
-rw-r--r--src/client/views/nodes/WebBox.tsx9
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.scss4
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx81
-rw-r--r--src/client/views/pdf/AnchorMenu.tsx86
-rw-r--r--src/client/views/pdf/GPTPopup.scss123
-rw-r--r--src/client/views/pdf/GPTPopup.tsx131
-rw-r--r--src/client/views/pdf/PDFViewer.tsx12
15 files changed, 629 insertions, 85 deletions
diff --git a/package-lock.json b/package-lock.json
index cc51ad9e0..343fa32c2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2119,6 +2119,15 @@
"@types/react": "*"
}
},
+ "@types/react-typist": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/react-typist/-/react-typist-2.0.3.tgz",
+ "integrity": "sha512-5eDrikVNJ73qR5XEV+ZNApoYarzYUD5OOPdNwnNY5RtqituZl9haq0OdZUaac2R751QSOe3zDwnqYhBmdFhG7g==",
+ "dev": true,
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/reactcss": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.6.tgz",
@@ -13664,7 +13673,7 @@
"dependencies": {
"@iarna/cli": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@iarna/cli/-/cli-2.1.0.tgz",
+ "resolved": false,
"integrity": "sha512-rvVVqDa2g860niRbqs3D5RhL4la3dc1vwk+NlpKPZxKaMSHtE2se6C2x8NeveN+rcjp3/686X+u+09CZ+7lmAQ==",
"requires": {
"glob": "^7.1.2",
@@ -13767,7 +13776,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -13782,7 +13791,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -13791,12 +13800,12 @@
},
"asap": {
"version": "2.0.6",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "resolved": false,
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
},
"asn1": {
"version": "0.2.6",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+ "resolved": false,
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
"requires": {
"safer-buffer": "~2.1.0"
@@ -13804,7 +13813,7 @@
},
"assert-plus": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "resolved": false,
"integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw=="
},
"asynckit": {
@@ -13814,22 +13823,22 @@
},
"aws-sign2": {
"version": "0.7.0",
- "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "resolved": false,
"integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA=="
},
"aws4": {
"version": "1.11.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+ "resolved": false,
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
},
"balanced-match": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "resolved": false,
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"bcrypt-pbkdf": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "resolved": false,
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
"requires": {
"tweetnacl": "^0.14.3"
@@ -13850,7 +13859,7 @@
},
"bluebird": {
"version": "3.7.2",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "resolved": false,
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
},
"boxen": {
@@ -13898,7 +13907,7 @@
},
"cacache": {
"version": "12.0.4",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz",
+ "resolved": false,
"integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==",
"requires": {
"bluebird": "^3.5.5",
@@ -13935,7 +13944,7 @@
},
"caseless": {
"version": "0.12.0",
- "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "resolved": false,
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
},
"chalk": {
@@ -14079,7 +14088,7 @@
},
"combined-stream": {
"version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "resolved": false,
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
@@ -14087,7 +14096,7 @@
},
"concat-map": {
"version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "resolved": false,
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"concat-stream": {
@@ -14117,7 +14126,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -14132,7 +14141,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -14141,7 +14150,7 @@
},
"config-chain": {
"version": "1.1.13",
- "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "resolved": false,
"integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
"requires": {
"ini": "^1.3.4",
@@ -14242,7 +14251,7 @@
},
"dashdash": {
"version": "1.14.1",
- "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "resolved": false,
"integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
"requires": {
"assert-plus": "^1.0.0"
@@ -14275,7 +14284,7 @@
},
"decode-uri-component": {
"version": "0.2.2",
- "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+ "resolved": false,
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="
},
"deep-extend": {
@@ -14321,7 +14330,7 @@
},
"dezalgo": {
"version": "1.0.4",
- "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
+ "resolved": false,
"integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
"requires": {
"asap": "^2.0.0",
@@ -14373,7 +14382,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -14388,7 +14397,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -14397,7 +14406,7 @@
},
"ecc-jsbn": {
"version": "0.1.2",
- "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
"requires": {
"jsbn": "~0.1.0",
@@ -14432,7 +14441,7 @@
},
"env-paths": {
"version": "2.2.1",
- "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "resolved": false,
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="
},
"err-code": {
@@ -14516,7 +14525,7 @@
},
"extsprintf": {
"version": "1.3.0",
- "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "resolved": false,
"integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g=="
},
"fast-json-stable-stringify": {
@@ -14526,12 +14535,12 @@
},
"figgy-pudding": {
"version": "3.5.2",
- "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
+ "resolved": false,
"integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw=="
},
"filter-obj": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
+ "resolved": false,
"integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ=="
},
"find-npm-prefix": {
@@ -14564,7 +14573,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -14579,7 +14588,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -14588,12 +14597,12 @@
},
"forever-agent": {
"version": "0.6.1",
- "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "resolved": false,
"integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw=="
},
"form-data": {
"version": "2.3.3",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "resolved": false,
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
"requires": {
"asynckit": "^0.4.0",
@@ -14626,7 +14635,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -14641,7 +14650,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -14709,7 +14718,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -14724,7 +14733,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -14733,7 +14742,7 @@
},
"fs.realpath": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "resolved": false,
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"function-bind": {
@@ -14823,7 +14832,7 @@
},
"getpass": {
"version": "0.1.7",
- "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "resolved": false,
"integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
"requires": {
"assert-plus": "^1.0.0"
@@ -14831,7 +14840,7 @@
},
"glob": {
"version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "resolved": false,
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"requires": {
"fs.realpath": "^1.0.0",
@@ -14844,7 +14853,7 @@
"dependencies": {
"minimatch": {
"version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"requires": {
"brace-expansion": "^1.1.7"
@@ -14887,12 +14896,12 @@
},
"graceful-fs": {
"version": "4.2.10",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "resolved": false,
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
},
"har-schema": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "resolved": false,
"integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q=="
},
"har-validator": {
@@ -14971,7 +14980,7 @@
},
"http-signature": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "resolved": false,
"integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
"requires": {
"assert-plus": "^1.0.0",
@@ -15098,7 +15107,7 @@
},
"is-cidr": {
"version": "3.1.1",
- "resolved": "https://registry.npmjs.org/is-cidr/-/is-cidr-3.1.1.tgz",
+ "resolved": false,
"integrity": "sha512-Gx+oErgq1j2jAKCR2Kbq0b3wbH0vQKqZ0wOlHxm0o56nq51Cs/DZA8oz9dMDhbHyHEGgJ86eTeVudtgMMOx3Mw==",
"requires": {
"cidr-regex": "^2.0.10"
@@ -15177,7 +15186,7 @@
},
"is-typedarray": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "resolved": false,
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
},
"isarray": {
@@ -15192,12 +15201,12 @@
},
"isstream": {
"version": "0.1.2",
- "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
},
"jsbn": {
"version": "0.1.1",
- "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "resolved": false,
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
},
"json-parse-better-errors": {
@@ -15207,7 +15216,7 @@
},
"json-parse-even-better-errors": {
"version": "2.3.1",
- "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "resolved": false,
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
},
"json-schema": {
@@ -15217,7 +15226,7 @@
},
"json-stringify-safe": {
"version": "5.0.1",
- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "resolved": false,
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
},
"jsonparse": {
@@ -15435,7 +15444,7 @@
},
"lock-verify": {
"version": "2.2.2",
- "resolved": "https://registry.npmjs.org/lock-verify/-/lock-verify-2.2.2.tgz",
+ "resolved": false,
"integrity": "sha512-2CUNtr1ZSVKJHcYP8uEzafmmuyauCB5zZimj8TvQd/Lflt9kXVZs+8S+EbAzZLaVUDn8CYGmeC3DFGdYfnCzeQ==",
"requires": {
"@iarna/cli": "^2.1.0",
@@ -15564,7 +15573,7 @@
},
"meant": {
"version": "1.0.3",
- "resolved": "https://registry.npmjs.org/meant/-/meant-1.0.3.tgz",
+ "resolved": false,
"integrity": "sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw=="
},
"mime-db": {
@@ -15582,7 +15591,7 @@
},
"minimatch": {
"version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"requires": {
"brace-expansion": "^1.1.7"
@@ -15631,7 +15640,7 @@
},
"mkdirp": {
"version": "0.5.6",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "resolved": false,
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"requires": {
"minimist": "^1.2.6"
@@ -15679,7 +15688,7 @@
},
"node-gyp": {
"version": "5.1.1",
- "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz",
+ "resolved": false,
"integrity": "sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==",
"requires": {
"env-paths": "^2.2.0",
@@ -16017,7 +16026,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -16032,7 +16041,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -16046,7 +16055,7 @@
},
"path-is-absolute": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "resolved": false,
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
},
"path-is-inside": {
@@ -16066,7 +16075,7 @@
},
"performance-now": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "resolved": false,
"integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
},
"pify": {
@@ -16115,7 +16124,7 @@
},
"proto-list": {
"version": "1.2.4",
- "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "resolved": false,
"integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="
},
"protoduck": {
@@ -16138,7 +16147,7 @@
},
"psl": {
"version": "1.9.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+ "resolved": false,
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
},
"pump": {
@@ -16178,12 +16187,12 @@
},
"qs": {
"version": "6.5.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+ "resolved": false,
"integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA=="
},
"query-string": {
"version": "6.14.1",
- "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz",
+ "resolved": false,
"integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==",
"requires": {
"decode-uri-component": "^0.2.0",
@@ -16194,7 +16203,7 @@
},
"qw": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/qw/-/qw-1.0.2.tgz",
+ "resolved": false,
"integrity": "sha512-1PhZ/iLKwlVNq45dnerTMKFjMof49uqli7/0QsvPNbX5OJ3IZ8msa9lUpvPheVdP+IYYPrf6cOaVil7S35joVA=="
},
"rc": {
@@ -16240,7 +16249,7 @@
},
"read-package-json": {
"version": "2.1.2",
- "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==",
"requires": {
"glob": "^7.1.1",
@@ -16299,7 +16308,7 @@
},
"request": {
"version": "2.88.2",
- "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+ "resolved": false,
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
"requires": {
"aws-sign2": "~0.7.0",
@@ -16369,7 +16378,7 @@
},
"safe-buffer": {
"version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "resolved": false,
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"safer-buffer": {
@@ -16540,7 +16549,7 @@
},
"sshpk": {
"version": "1.17.0",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
+ "resolved": false,
"integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
"requires": {
"asn1": "~0.2.3",
@@ -16596,7 +16605,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -16611,7 +16620,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -16625,7 +16634,7 @@
},
"strict-uri-encode": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+ "resolved": false,
"integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ=="
},
"string-width": {
@@ -16781,7 +16790,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -16796,7 +16805,7 @@
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
@@ -16815,7 +16824,7 @@
},
"tough-cookie": {
"version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "resolved": false,
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"requires": {
"psl": "^1.1.28",
@@ -16824,7 +16833,7 @@
"dependencies": {
"punycode": {
"version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "resolved": false,
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
}
}
@@ -16839,7 +16848,7 @@
},
"tweetnacl": {
"version": "0.14.5",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "resolved": false,
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
},
"typedarray": {
@@ -16910,7 +16919,7 @@
},
"uri-js": {
"version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "resolved": false,
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"requires": {
"punycode": "^2.1.0"
@@ -16951,7 +16960,7 @@
},
"uuid": {
"version": "3.4.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "resolved": false,
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
},
"validate-npm-package-license": {
@@ -16973,7 +16982,7 @@
},
"verror": {
"version": "1.10.0",
- "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "resolved": false,
"integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
"requires": {
"assert-plus": "^1.0.0",
@@ -17480,6 +17489,40 @@
"mimic-fn": "^2.1.0"
}
},
+ "openai": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/openai/-/openai-3.1.0.tgz",
+ "integrity": "sha512-v5kKFH5o+8ld+t0arudj833Mgm3GcgBnbyN9946bj6u7bvel4Yg6YFz2A4HLIYDzmMjIo0s6vSG9x73kOwvdCg==",
+ "requires": {
+ "axios": "^0.26.0",
+ "form-data": "^4.0.0"
+ },
+ "dependencies": {
+ "axios": {
+ "version": "0.26.1",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
+ "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
+ "requires": {
+ "follow-redirects": "^1.14.8"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
+ },
+ "form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ }
+ }
+ }
+ },
"opentype.js": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz",
@@ -19307,6 +19350,14 @@
}
}
},
+ "react-typist": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/react-typist/-/react-typist-2.0.5.tgz",
+ "integrity": "sha512-iZCkeqeegO0TlkTMiH2JD1tvMtY9RrXkRylnAI6m8aCVAUUwNzoWTVF7CKLij6THeOMcUDCznLDDvNp55s+YZA==",
+ "requires": {
+ "prop-types": "^15.5.10"
+ }
+ },
"react-use-measure": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz",
diff --git a/package.json b/package.json
index 2c4c41917..1d94e5780 100644
--- a/package.json
+++ b/package.json
@@ -77,6 +77,7 @@
"@types/react-select": "^3.1.2",
"@types/react-table": "^6.8.9",
"@types/react-transition-group": "^4.4.5",
+ "@types/react-typist": "^2.0.3",
"@types/request": "^2.48.8",
"@types/request-promise": "^4.1.48",
"@types/rimraf": "^2.0.5",
@@ -240,6 +241,7 @@
"nodemon": "^1.19.4",
"normalize.css": "^8.0.1",
"npm": "^6.14.18",
+ "openai": "^3.1.0",
"p-limit": "^2.2.0",
"passport": "^0.4.0",
"passport-google-oauth20": "^2.0.0",
@@ -287,6 +289,7 @@
"react-select": "^3.2.0",
"react-table": "^6.11.5",
"react-transition-group": "^4.4.2",
+ "react-typist": "^2.0.5",
"readline": "^1.3.0",
"rehype-raw": "^6.1.1",
"remark-gfm": "^3.0.1",
diff --git a/src/client/apis/gpt/Summarization.ts b/src/client/apis/gpt/Summarization.ts
new file mode 100644
index 000000000..0d9b5dfcd
--- /dev/null
+++ b/src/client/apis/gpt/Summarization.ts
@@ -0,0 +1,48 @@
+import { Configuration, OpenAIApi } from 'openai';
+
+enum GPTCallType {
+ SUMMARY = 'summary',
+ COMPLETION = 'completion',
+}
+
+type GPTCallOpts = {
+ model: string;
+ maxTokens: number;
+ temp: number;
+ prompt: string;
+};
+
+const callTypeMap: { [type: string]: GPTCallOpts } = {
+ summary: { model: 'text-davinci-003', maxTokens: 100, temp: 0.5, prompt: 'Summarize this text: ' },
+ completion: { model: 'text-davinci-003', maxTokens: 256, temp: 0.5, prompt: '' },
+};
+
+/**
+ * Calls the OpenAI API.
+ *
+ * @param inputText Text to process
+ * @returns AI Output
+ */
+const gptAPICall = async (inputText: string, callType: GPTCallType) => {
+ if (callType === GPTCallType.SUMMARY) inputText += '.';
+ const opts: GPTCallOpts = callTypeMap[callType];
+ try {
+ const configuration = new Configuration({
+ apiKey: process.env.OPENAI_KEY,
+ });
+ const openai = new OpenAIApi(configuration);
+ const response = await openai.createCompletion({
+ model: opts.model,
+ max_tokens: opts.maxTokens,
+ temperature: opts.temp,
+ prompt: `${opts.prompt}${inputText}`,
+ });
+ return response.data.choices[0].text;
+ } catch (err) {
+ console.log(err);
+ return 'Error connecting with API.';
+ }
+};
+
+
+export { gptAPICall, GPTCallType};
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 2e04ca3dd..31888cbb4 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -242,6 +242,7 @@ export class MainView extends React.Component {
library.add(
...[
+ fa.faExclamationCircle,
fa.faEdit,
fa.faTrash,
fa.faTrashAlt,
@@ -272,6 +273,7 @@ export class MainView extends React.Component {
fa.faHandPointRight,
fa.faCompass,
fa.faSnowflake,
+ fa.faStar,
fa.faMicrophone,
fa.faKeyboard,
fa.faQuestion,
@@ -319,6 +321,7 @@ export class MainView extends React.Component {
fa.faClone,
fa.faCloudUploadAlt,
fa.faCommentAlt,
+ fa.faCommentDots,
fa.faCompressArrowsAlt,
fa.faCut,
fa.faEllipsisV,
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index 30867a774..c02435518 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -199,7 +199,7 @@ export class MarqueeAnnotator extends React.Component<MarqueeAnnotatorProps> {
return textRegionAnno;
};
@action
- highlight = (color: string, isLinkButton: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => {
+ highlight = (color: string, isLinkButton: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean, summarize?: boolean) => {
// creates annotation documents for current highlights
const effectiveAcl = GetEffectiveAcl(this.props.rootDoc[DataSym]);
const annotationDoc = [AclAugment, AclSelfEdit, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color, isLinkButton, savedAnnotations);
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index aed88aa1a..24f77ec0e 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -67,6 +67,8 @@ interface CollectionViewProps_ extends FieldViewProps {
AddToMap?: (treeViewDoc: Doc, index: number[]) => void;
RemFromMap?: (treeViewDoc: Doc, index: number[]) => void;
hierarchyIndex?: number[]; // hierarchical index of a document up to the rendering root (primarily used for tree views)
+ // for animation trail in-between selection
+ isTrailBox?: boolean;
}
export interface CollectionViewProps extends React.PropsWithChildren<CollectionViewProps_> {}
@observer
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index e60a03190..643ad6734 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -352,7 +352,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
@computed get nativeSize() {
TraceMobx();
const nativeWidth = NumCast(this.dataDoc[this.fieldKey + '-nativeWidth'], NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth'], 500));
- const nativeHeight = NumCast(this.dataDoc[this.fieldKey + '-nativeHeight'], NumCast(this.layoutDoc[this.fieldKey + '-nativeHeight'], 1));
+ const nativeHeight = NumCast(this.dataDoc[this.fieldKey + '-nativeHeight'], NumCast(this.layoutDoc[this.fieldKey + '-nativeHeight'], 500));
const nativeOrientation = NumCast(this.dataDoc[this.fieldKey + '-nativeOrientation'], 1);
return { nativeWidth, nativeHeight, nativeOrientation };
}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 5f207cc0d..7e0b5c4d3 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -492,6 +492,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}}>
<PDFViewer
{...this.props}
+ sidebarAddDoc={this.sidebarAddDocument}
rootDoc={this.rootDoc}
addDocTab={this.sidebarAddDocTab}
layoutDoc={this.layoutDoc}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index f7425b26a..e5ef85b5a 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -14,7 +14,6 @@ import { TraceMobx } from '../../../fields/util';
import { emptyFunction, getWordAtPoint, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, smoothScroll, StopEvent, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentManager } from '../../util/DocumentManager';
-import { DragManager } from '../../util/DragManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SnappingManager } from '../../util/SnappingManager';
import { undoBatch, UndoManager } from '../../util/UndoManager';
@@ -36,6 +35,8 @@ import { LinkDocPreview } from './LinkDocPreview';
import { PinProps, PresBox } from './trails';
import './WebBox.scss';
import React = require('react');
+import { DragManager } from '../../util/DragManager';
+import { GPTPopup } from '../pdf/GPTPopup';
const { CreateImage } = require('./WebBoxRenderer');
const _global = (window /* browser */ || global) /* node */ as any;
const htmlToText = require('html-to-text');
@@ -365,8 +366,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const scale = (this.props.NativeDimScaling?.() || 1) * mainContBounds.scale;
const sel = this._iframe.contentWindow.getSelection();
if (sel) {
+ this._selectionText = sel.toString();
+ AnchorMenu.Instance.setSelectedText(sel.toString());
this._textAnnotationCreator = () => this.createTextAnnotation(sel, !sel.isCollapsed ? sel.getRangeAt(0) : undefined);
AnchorMenu.Instance.jumpTo(e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._scrollTop) * scale);
+ // Changing which document to add the annotation to (the currently selected WebBox)
+ GPTPopup.Instance.setSidebarId(`${this.props.fieldKey}-${this._urlHash}-sidebar`);
+ GPTPopup.Instance.addDoc = this.sidebarAddDocument;
}
}
};
@@ -784,6 +790,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => {
+ console.log(annotationKey);
(doc instanceof Doc ? [doc] : doc).forEach(doc => (doc.webUrl = this._url));
return this.addDocument(doc, annotationKey);
};
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index cbe0a465d..fd7fbb333 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -149,6 +149,10 @@ audiotag:hover {
}
}
+.gpt-typing-wrapper {
+ padding: 10px;
+}
+
// .menuicon {
// display: inline-block;
// border-right: 1px solid rgba(0, 0, 0, 0.2);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index a76f9623a..4ad1f73b0 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -3,6 +3,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { isEqual } from 'lodash';
import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
+import { Configuration, OpenAIApi } from 'openai';
import { baseKeymap, selectAll } from 'prosemirror-commands';
import { history } from 'prosemirror-history';
import { inputRules } from 'prosemirror-inputrules';
@@ -22,9 +23,11 @@ import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } fro
import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util';
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, unimplementedFunction, Utils } from '../../../../Utils';
import { GoogleApiClientUtils, Pulls, Pushes } from '../../../apis/google_docs/GoogleApiClientUtils';
+import { gptAPICall, GPTCallType } from '../../../apis/gpt/Summarization';
import { DocServer } from '../../../DocServer';
import { Docs, DocUtils } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
+import { Networking } from '../../../Network';
import { DictationManager } from '../../../util/DictationManager';
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager } from '../../../util/DragManager';
@@ -65,9 +68,7 @@ import { SummaryView } from './SummaryView';
import applyDevTools = require('prosemirror-dev-tools');
import React = require('react');
const translateGoogleApi = require('translate-google-api');
-
export const GoogleRef = 'googleDocId';
-
type PullHandler = (exportState: Opt<GoogleApiClientUtils.Docs.ImportResult>, dataDoc: Doc) => void;
@observer
@@ -170,6 +171,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
};
}
+ // State for GPT
+ @observable
+ private gptRes: string = '';
+
public static PasteOnLoad: ClipboardEvent | undefined;
public static SelectOnLoad = '';
public static DontSelectInitialText = false; // whether initial text should be selected or not
@@ -844,12 +849,84 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
const options = cm.findByDescription('Options...');
const optionItems = options && 'subitems' in options ? options.subitems : [];
+ optionItems.push({ description: `Generate Dall-E Image`, event: () => this.generateImage(), icon: 'star' });
+ optionItems.push({ description: `Ask GPT-3`, event: () => this.askGPT(), icon: 'lightbulb' });
optionItems.push({ description: !this.Document._singleLine ? 'Make Single Line' : 'Make Multi Line', event: () => (this.layoutDoc._singleLine = !this.layoutDoc._singleLine), icon: !this.Document._singleLine ? 'grip-lines' : 'bars' });
optionItems.push({ description: `${this.Document._autoHeight ? 'Lock' : 'Auto'} Height`, event: () => (this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight), icon: this.Document._autoHeight ? 'lock' : 'unlock' });
!options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'eye' });
this._downX = this._downY = Number.NaN;
};
+ mockGPT = async (): Promise<string> => {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ resolve('Mock GPT Call.');
+ }, 2000);
+ });
+ };
+
+ animateRes = (resIndex: number) => {
+ if (resIndex < this.gptRes.length) {
+ this.dataDoc.text = (this.dataDoc.text as RichTextField)?.Text + this.gptRes[resIndex];
+ setTimeout(() => {
+ this.animateRes(resIndex + 1);
+ }, 20);
+ }
+ };
+
+ askGPT = action(async () => {
+ try {
+ let res = await gptAPICall((this.dataDoc.text as RichTextField)?.Text, GPTCallType.COMPLETION);
+ // let res = await this.mockGPT();
+ if (res) {
+ this.gptRes = res;
+ this.animateRes(0);
+ }
+ } catch (err) {
+ console.log(err);
+ this.dataDoc.text = (this.dataDoc.text as RichTextField)?.Text + 'Something went wrong';
+ }
+ });
+
+ generateImage = async () => {
+ console.log('Generate image from text: ', (this.dataDoc.text as RichTextField)?.Text);
+ try {
+ const configuration = new Configuration({
+ apiKey: process.env.OPENAI_KEY,
+ });
+ const openai = new OpenAIApi(configuration);
+ const response = await openai.createImage({
+ prompt: (this.dataDoc.text as RichTextField)?.Text,
+ n: 1,
+ size: '1024x1024',
+ });
+ let image_url = response.data.data[0].url;
+ console.log(image_url);
+ if (image_url) {
+ const [{ accessPaths }] = await Networking.PostToServer('/uploadRemoteImage', { sources: [image_url] });
+ const source = Utils.prepend(accessPaths.agnostic.client);
+ const newDoc = Docs.Create.ImageDocument(source, {
+ x: NumCast(this.rootDoc.x) + NumCast(this.layoutDoc._width) + 10,
+ y: NumCast(this.rootDoc.y),
+ _height: 200,
+ _width: 200,
+ })
+ if (DocListCast(Doc.MyOverlayDocs?.data).includes(this.rootDoc)) {
+ newDoc.overlayX = this.rootDoc.x;
+ newDoc.overlayY = NumCast(this.rootDoc.y) + NumCast(this.rootDoc._height);
+ Doc.AddDocToList(Doc.MyOverlayDocs, undefined, newDoc);
+ } else {
+ this.props.addDocument?.(newDoc);
+ }
+ // Create link between prompt and image
+ DocUtils.MakeLink({doc: this.rootDoc}, {doc: newDoc}, "Image Prompt");
+ }
+ } catch (err) {
+ console.log(err);
+ return '';
+ }
+ };
+
breakupDictation = () => {
if (this._editorView && this._recording) {
this.stopDictation(true);
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index fc8f1da49..1b30e1f68 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -10,6 +10,8 @@ import { SelectionManager } from '../../util/SelectionManager';
import { AntimodeMenu, AntimodeMenuProps } from '../AntimodeMenu';
import { LinkPopup } from '../linking/LinkPopup';
import { ButtonDropdown } from '../nodes/formattedText/RichTextMenu';
+import { gptAPICall, GPTCallType } from '../../apis/gpt/Summarization';
+import { GPTPopup } from './GPTPopup';
import './AnchorMenu.scss';
import { LightboxView } from '../LightboxView';
@@ -43,6 +45,28 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
@observable public Status: 'marquee' | 'annotation' | '' = '';
+ // GPT additions
+ @observable private summarizedText: string = '';
+ @observable private loadingSummary: boolean = false;
+ @observable private showGPTPopup: boolean = false;
+ @action
+ setGPTPopupVis = (vis: boolean) => {
+ this.showGPTPopup = vis;
+ };
+ @action
+ setSummarizedText = (txt: string) => {
+ this.summarizedText = txt;
+ };
+ @action
+ setLoading = (loading: boolean) => {
+ this.loadingSummary = loading;
+ };
+
+ private selectedText: string = '';
+ public setSelectedText = (txt: string) => {
+ this.selectedText = txt;
+ };
+
public onMakeAnchor: () => Opt<Doc> = () => undefined; // Method to get anchor from text search
public OnCrop: (e: PointerEvent) => void = unimplementedFunction;
@@ -76,18 +100,56 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
componentDidMount() {
this._disposer2 = reaction(
() => this._opacity,
- opacity => !opacity && (this._showLinkPopup = false),
+ opacity => {
+ if (!opacity) {
+ this._showLinkPopup = false;
+ this.setGPTPopupVis(false);
+ this.setSummarizedText('');
+ }
+ },
{ fireImmediately: true }
);
this._disposer = reaction(
() => SelectionManager.Views(),
selected => {
this._showLinkPopup = false;
+ this.setGPTPopupVis(false);
+ this.setSummarizedText('');
AnchorMenu.Instance.fadeOut(true);
}
);
}
+ /**
+ * Returns a mock summary simulating an API call.
+ * @returns A Promise that resolves into a string
+ */
+ mockSummarize = async (): Promise<string> => {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ resolve('Mock summary. This is a summary of the highlighted text.');
+ }, 1000);
+ });
+ };
+
+ /**
+ * Invokes the API with the selected text and stores it in the summarized text.
+ * @param e pointer down event
+ */
+ gptSummarize = async (e: React.PointerEvent) => {
+ this.setGPTPopupVis(true);
+ this.setLoading(true);
+ const res = await gptAPICall(this.selectedText, GPTCallType.SUMMARY);
+ // const res = await this.mockSummarize();
+ if (res) {
+ this.setSummarizedText(res);
+ } else {
+ this.setSummarizedText('Something went wrong.');
+ }
+
+ this.setLoading(false);
+ };
+
pointerDown = (e: React.PointerEvent) => {
setupMoveUpEvents(
this,
@@ -180,6 +242,19 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
this.highlightColor = Utils.colorString(col);
};
+ /**
+ * Returns whether the selected text can be summarized. The goal is to have
+ * all selected text available to summarize but its only supported for pdf and web ATM.
+ * @returns Whether the GPT icon for summarization should appear
+ */
+ canSummarize = (): boolean => {
+ const docs = SelectionManager.Docs();
+ if (docs.length > 0) {
+ return docs[0].type === 'pdf' || docs[0].type === 'web';
+ }
+ return false;
+ };
+
render() {
const buttons =
this.Status === 'marquee' ? (
@@ -190,6 +265,15 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
<FontAwesomeIcon icon="comment-alt" size="lg" />
</button>
</Tooltip>
+ {/* GPT Summarize icon only shows up when text is highlighted, not on marquee selection*/}
+ {AnchorMenu.Instance.StartCropDrag === unimplementedFunction && this.canSummarize() && (
+ <Tooltip key="gpt" title={<div className="dash-tooltip">Summarize with AI</div>}>
+ <button className="antimodeMenu-button annotate" onPointerDown={this.gptSummarize} style={{ cursor: 'grab' }}>
+ <FontAwesomeIcon icon="comment-dots" size="lg" />
+ </button>
+ </Tooltip>
+ )}
+ <GPTPopup key="gptpopup" visible={this.showGPTPopup} text={this.summarizedText} loadingSummary={this.loadingSummary} callApi={this.gptSummarize} />
{AnchorMenu.Instance.OnAudio === unimplementedFunction ? null : (
<Tooltip key="annoaudiotate" title={<div className="dash-tooltip">Click to Record Annotation</div>}>
<button className="antimodeMenu-button annotate" onPointerDown={this.audioDown} style={{ cursor: 'grab' }}>
diff --git a/src/client/views/pdf/GPTPopup.scss b/src/client/views/pdf/GPTPopup.scss
new file mode 100644
index 000000000..7b7d2e3f7
--- /dev/null
+++ b/src/client/views/pdf/GPTPopup.scss
@@ -0,0 +1,123 @@
+$textgrey: #707070;
+$lighttextgrey: #a3a3a3;
+$greyborder: #d3d3d3;
+$lightgrey: #ececec;
+$button: #5b97ff;
+
+.summary-box {
+ display: flex;
+ flex-direction: column;
+ background-color: #ffffff;
+ box-shadow: 0 2px 5px #7474748d;
+ color: $textgrey;
+ position: absolute;
+ bottom: 40px;
+ width: 250px;
+ border-radius: 15px;
+ padding: 15px;
+ padding-bottom: 0px;
+
+ .summary-heading {
+ display: flex;
+ align-items: center;
+ border-bottom: 1px solid $greyborder;
+ padding-bottom: 5px;
+
+ .summary-text {
+ font-size: 12px;
+ font-weight: 500;
+ }
+ }
+
+ label {
+ color: $textgrey;
+ font-size: 12px;
+ font-weight: 400;
+ letter-spacing: 1px;
+ margin: 0;
+ padding-right: 5px;
+ }
+
+ a {
+ cursor: pointer;
+ }
+
+ .content-wrapper {
+ padding-top: 10px;
+ min-height: 50px;
+ max-height: 150px;
+ overflow-y: auto;
+ }
+
+ .btns-wrapper {
+ height: 50px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ .summarizing {
+ display: flex;
+ align-items: center;
+ }
+ }
+
+ button {
+ font-size: 9px;
+ padding: 10px;
+ color: #ffffff;
+ background-color: $button;
+ border-radius: 5px;
+ }
+
+ .text-btn {
+ &:hover {
+ background-color: $button;
+ }
+ }
+
+ .btn-secondary {
+ font-size: 8px;
+ padding: 10px 5px;
+ background-color: $lightgrey;
+ color: $textgrey;
+ &:hover {
+ background-color: $lightgrey;
+ }
+ }
+
+ .icon-btn {
+ background-color: #ffffff;
+ padding: 10px;
+ border-radius: 50%;
+ color: $button;
+ border: 1px solid $button;
+ }
+
+ .ai-warning {
+ padding: 10px 0;
+ font-size: 10px;
+ color: $lighttextgrey;
+ border-top: 1px solid $greyborder;
+ }
+}
+
+// Typist CSS
+.Typist .Cursor {
+ display: inline-block;
+}
+.Typist .Cursor--blinking {
+ opacity: 1;
+ animation: blink 1s linear infinite;
+}
+
+@keyframes blink {
+ 0% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
+}
diff --git a/src/client/views/pdf/GPTPopup.tsx b/src/client/views/pdf/GPTPopup.tsx
new file mode 100644
index 000000000..ec4fa58dc
--- /dev/null
+++ b/src/client/views/pdf/GPTPopup.tsx
@@ -0,0 +1,131 @@
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action, observable } from 'mobx';
+import { observer } from 'mobx-react';
+import React = require('react');
+import ReactLoading from 'react-loading';
+import Typist from 'react-typist';
+import { Doc } from '../../../fields/Doc';
+import { Docs } from '../../documents/Documents';
+import './GPTPopup.scss';
+
+interface GPTPopupProps {
+ visible: boolean;
+ text: string;
+ loadingSummary: boolean;
+ callApi: (e: React.PointerEvent) => Promise<void>;
+}
+
+@observer
+export class GPTPopup extends React.Component<GPTPopupProps> {
+ static Instance: GPTPopup;
+
+ @observable
+ private summaryDone: boolean = false;
+ @observable
+ private sidebarId: string = '';
+ @action
+ public setSummaryDone = (done: boolean) => {
+ this.summaryDone = done;
+ };
+ @action
+ public setSidebarId = (id: string) => {
+ this.sidebarId = id;
+ };
+
+ public addDoc: (doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean = () => false;
+
+ /**
+ * Transfers the summarization text to a sidebar annotation text document.
+ */
+ private transferToText = () => {
+ const newDoc = Docs.Create.TextDocument(this.props.text.trim(), {
+ _width: 200,
+ _height: 50,
+ _fitWidth: true,
+ _autoHeight: true,
+ });
+ this.addDoc(newDoc, this.sidebarId);
+ };
+
+ constructor(props: GPTPopupProps) {
+ super(props);
+ GPTPopup.Instance = this;
+ }
+
+ componentDidUpdate = () => {
+ if (this.props.loadingSummary) {
+ this.setSummaryDone(false);
+ }
+ };
+
+ render() {
+ return (
+ <div className="summary-box" style={{ display: this.props.visible ? 'flex' : 'none' }}>
+ <div className="summary-heading">
+ <label className="summary-text">SUMMARY</label>
+ {this.props.loadingSummary && <ReactLoading type="spin" color="#bcbcbc" width={14} height={14} />}
+ </div>
+ <div className="content-wrapper">
+ {!this.props.loadingSummary &&
+ (!this.summaryDone ? (
+ <Typist
+ key={this.props.text}
+ avgTypingDelay={15}
+ cursor={{ hideWhenDone: true }}
+ onTypingDone={action(() => {
+ setTimeout(
+ action(() => {
+ this.summaryDone = true;
+ }),
+ 500
+ );
+ })}>
+ {this.props.text}
+ </Typist>
+ ) : (
+ this.props.text
+ ))}
+ </div>
+ {!this.props.loadingSummary && (
+ <div className="btns-wrapper">
+ {this.summaryDone ? (
+ <>
+ <button className="icon-btn" onPointerDown={e => this.props.callApi(e)}>
+ <FontAwesomeIcon icon="redo-alt" size="lg" />
+ </button>
+ <button
+ className="text-btn"
+ onClick={e => {
+ this.transferToText();
+ }}>
+ Transfer to Text
+ </button>
+ </>
+ ) : (
+ <div className="summarizing">
+ <label>Summarizing</label>
+ <ReactLoading type="bubbles" color="#bcbcbc" width={20} height={20} />
+ <button
+ className="btn-secondary"
+ onClick={e => {
+ this.setSummaryDone(true);
+ }}>
+ Stop Animation
+ </button>
+ </div>
+ )}
+ </div>
+ )}
+ {this.summaryDone && (
+ <div className="ai-warning">
+ <FontAwesomeIcon icon="exclamation-circle" size="sm" style={{ paddingRight: '5px' }} />
+ AI generated responses can contain inaccurate or misleading content.{' '}
+ <a target="_blank" href="https://www.nytimes.com/2023/02/08/technology/ai-chatbots-disinformation.html">
+ Learn More
+ </a>
+ </div>
+ )}
+ </div>
+ );
+ }
+}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 86d14c22e..3f891789a 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -24,6 +24,7 @@ import { AnchorMenu } from './AnchorMenu';
import { Annotation } from './Annotation';
import './PDFViewer.scss';
import React = require('react');
+import { GPTPopup } from './GPTPopup';
const PDFJSViewer = require('pdfjs-dist/web/pdf_viewer');
const pdfjsLib = require('pdfjs-dist');
const _global = (window /* browser */ || global) /* node */ as any;
@@ -40,9 +41,10 @@ interface IViewerProps extends FieldViewProps {
fieldKey: string;
pdf: Pdfjs.PDFDocumentProxy;
url: string;
+ sidebarAddDoc: (doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean;
loaded?: (nw: number, nh: number, np: number) => void;
setPdfViewer: (view: PDFViewer) => void;
- anchorMenuClick?: () => undefined | ((anchor: Doc) => void);
+ anchorMenuClick?: () => undefined | ((anchor: Doc, summarize?: boolean) => void);
crop: (region: Doc | undefined, addCrop?: boolean) => Doc | undefined;
}
@@ -415,10 +417,18 @@ export class PDFViewer extends React.Component<IViewerProps> {
document.removeEventListener('pointerup', this.onSelectEnd);
const sel = window.getSelection();
+ if (sel) {
+ AnchorMenu.Instance.setSelectedText(sel.toString());
+ }
+
if (sel?.type === 'Range') {
this.createTextAnnotation(sel, sel.getRangeAt(0));
AnchorMenu.Instance.jumpTo(e.clientX, e.clientY);
}
+
+ // Changing which document to add the annotation to (the currently selected PDF)
+ GPTPopup.Instance.setSidebarId('data-sidebar');
+ GPTPopup.Instance.addDoc = this.props.sidebarAddDoc;
};
@action