From 6b52b5d97ec5bf49923801e0b04a67925a37eda8 Mon Sep 17 00:00:00 2001 From: Brandon Date: Tue, 5 Mar 2019 18:47:19 -0500 Subject: Finished kvp again --- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/KeyValueBox.tsx | 54 +++++++++++++++++++++++++++++++-- src/client/views/nodes/KeyValuePair.tsx | 31 ++++++++++++++++++- 3 files changed, 82 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e01e1d4cd..5ce8bb637 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,4 +1,4 @@ -import { action, computed } from "mobx"; +import { action, computed } from "mobx" import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; import { Field, FieldWaiting, Opt } from "../../../fields/Field"; diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index e8ebd50be..6192cd278 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -4,12 +4,18 @@ import { observer } from "mobx-react"; import { EditorView } from 'prosemirror-view'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app import { Document } from '../../../fields/Document'; -import { Opt, FieldWaiting } from '../../../fields/Field'; +import { Opt, FieldWaiting, Field } from '../../../fields/Field'; import { KeyStore } from '../../../fields/KeyStore'; import { FieldView, FieldViewProps } from './FieldView'; import { KeyValuePair } from "./KeyValuePair"; import "./KeyValueBox.scss"; import React = require("react") +import { Server } from "../../Server" +import { EditableView } from "../EditableView"; +import { CompileScript, ToField } from "../../util/Scripting"; +import { useState } from 'react' +import { Key } from '../../../fields/Key'; +import { TextField } from '../../../fields/TextField'; @observer export class KeyValueBox extends React.Component { @@ -18,12 +24,18 @@ export class KeyValueBox extends React.Component { private _ref: React.RefObject; private _editorView: Opt; private _reactionDisposer: Opt; + private _newKey = ''; + private _newValue = ''; constructor(props: FieldViewProps) { super(props); this._ref = React.createRef(); + this.state = { + key: '', + value: '' + } } @@ -32,6 +44,26 @@ export class KeyValueBox extends React.Component { return false; } + onEnterKey = (e: React.KeyboardEvent): void => { + if (e.key == 'Enter') { + if (this._newKey != '' && this._newValue != '') { + let doc = this.props.doc.GetT(KeyStore.Data, Document); + if (!doc || doc == FieldWaiting) { + return + } + let realDoc = doc; + realDoc.Set(new Key(this._newKey), new TextField(this._newValue)); + if (this.refs.newKVPKey instanceof HTMLInputElement) { + this.refs.newKVPKey.value = '' + } + if (this.refs.newKVPValue instanceof HTMLInputElement) { + this.refs.newKVPValue.value = '' + } + this._newKey = '' + this._newValue = '' + } + } + } onPointerDown = (e: React.PointerEvent): void => { if (e.buttons === 1 && this.props.isSelected()) { @@ -52,7 +84,7 @@ export class KeyValueBox extends React.Component { let ids: { [key: string]: string } = {}; let protos = doc.GetAllPrototypes(); for (const proto of protos) { - proto._proxies.forEach((val, key) => { + proto._proxies.forEach((val: any, key: string) => { if (!(key in ids)) { ids[key] = key; } @@ -67,9 +99,24 @@ export class KeyValueBox extends React.Component { return rows; } + keyChanged = (e: React.ChangeEvent) => { + this._newKey = e.currentTarget.value; + } - render() { + valueChanged = (e: React.ChangeEvent) => { + this._newValue = e.currentTarget.value; + } + newKeyValue = () => { + return ( + + + + + ) + } + + render() { return (
@@ -78,6 +125,7 @@ export class KeyValueBox extends React.Component { {this.createTable()} + {this.newKeyValue()}
Fields
) diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index a97e98313..111f85a05 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -8,6 +8,8 @@ import { observable, action } from 'mobx'; import { Document } from '../../../fields/Document'; import { Key } from '../../../fields/Key'; import { Server } from "../../Server" +import { EditableView } from "../EditableView"; +import { CompileScript, ToField } from "../../util/Scripting"; // Represents one row in a key value plane @@ -48,10 +50,37 @@ export class KeyValuePair extends React.Component { bindings: {}, selectOnLoad: false, } + let contents = ( + + ); return ( {this.key.Name} - + { + let field = props.doc.Get(props.fieldKey); + if (field && field instanceof Field) { + return field.ToScriptString(); + } + return field || ""; + }} + SetValue={(value: string) => { + let script = CompileScript(value, undefined, true); + if (!script.compiled) { + return false; + } + let field = script(); + if (field instanceof Field) { + props.doc.Set(props.fieldKey, field); + return true; + } else { + let dataField = ToField(field); + if (dataField) { + props.doc.Set(props.fieldKey, dataField); + return true; + } + } + return false; + }}> ) } -- cgit v1.2.3-70-g09d2 From fd27ddf326c5e6bec5dd63568afc9234c75dcb66 Mon Sep 17 00:00:00 2001 From: Jude Date: Mon, 11 Mar 2019 18:04:34 -0400 Subject: imported noto @hannah --- package-lock.json | 132 ++++++++++++++++---------------- src/client/views/_global_variables.scss | 18 ++--- 2 files changed, 72 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/package-lock.json b/package-lock.json index 4830b4ac1..dd5d44bd9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3707,24 +3707,24 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "resolved": false, "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "resolved": false, "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "aproba": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "resolved": false, "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "optional": true }, "are-we-there-yet": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "resolved": false, "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "optional": true, "requires": { @@ -3734,12 +3734,12 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "resolved": false, "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "resolved": false, "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { "balanced-match": "^1.0.0", @@ -3748,34 +3748,34 @@ }, "chownr": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "resolved": false, "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "resolved": false, "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "resolved": false, "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "console-control-strings": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "resolved": false, "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "core-util-is": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "resolved": false, "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "optional": true }, "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "resolved": false, "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "optional": true, "requires": { @@ -3784,25 +3784,25 @@ }, "deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "resolved": false, "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "optional": true }, "delegates": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "resolved": false, "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "resolved": false, "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "optional": true }, "fs-minipass": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", + "resolved": false, "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", "optional": true, "requires": { @@ -3811,13 +3811,13 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "resolved": false, "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "optional": true }, "gauge": { "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "resolved": false, "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "optional": true, "requires": { @@ -3833,7 +3833,7 @@ }, "glob": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "resolved": false, "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "optional": true, "requires": { @@ -3847,13 +3847,13 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "resolved": false, "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "optional": true }, "iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "resolved": false, "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "optional": true, "requires": { @@ -3862,7 +3862,7 @@ }, "ignore-walk": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", + "resolved": false, "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "optional": true, "requires": { @@ -3871,7 +3871,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "resolved": false, "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "optional": true, "requires": { @@ -3881,18 +3881,18 @@ }, "inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "resolved": false, "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "resolved": false, "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { "number-is-nan": "^1.0.0" @@ -3900,13 +3900,13 @@ }, "isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "resolved": false, "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { "brace-expansion": "^1.1.7" @@ -3914,12 +3914,12 @@ }, "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": false, "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "minipass": { "version": "2.3.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", + "resolved": false, "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "requires": { "safe-buffer": "^5.1.2", @@ -3928,7 +3928,7 @@ }, "minizlib": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", + "resolved": false, "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", "optional": true, "requires": { @@ -3937,7 +3937,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": false, "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" @@ -3945,13 +3945,13 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": false, "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "optional": true }, "needle": { "version": "2.2.4", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.4.tgz", + "resolved": false, "integrity": "sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA==", "optional": true, "requires": { @@ -3962,7 +3962,7 @@ }, "node-pre-gyp": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz", + "resolved": false, "integrity": "sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A==", "optional": true, "requires": { @@ -3980,7 +3980,7 @@ }, "nopt": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "resolved": false, "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "optional": true, "requires": { @@ -3990,13 +3990,13 @@ }, "npm-bundled": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz", + "resolved": false, "integrity": "sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g==", "optional": true }, "npm-packlist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.2.0.tgz", + "resolved": false, "integrity": "sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ==", "optional": true, "requires": { @@ -4006,7 +4006,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "resolved": false, "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "optional": true, "requires": { @@ -4018,18 +4018,18 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "resolved": false, "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "resolved": false, "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "optional": true }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "resolved": false, "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1" @@ -4037,19 +4037,19 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": false, "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": false, "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "optional": true }, "osenv": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "resolved": false, "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "optional": true, "requires": { @@ -4059,19 +4059,19 @@ }, "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "optional": true }, "process-nextick-args": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "resolved": false, "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "optional": true }, "rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "resolved": false, "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "optional": true, "requires": { @@ -4083,7 +4083,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": false, "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "optional": true } @@ -4091,7 +4091,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": false, "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "optional": true, "requires": { @@ -4106,7 +4106,7 @@ }, "rimraf": { "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "resolved": false, "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "optional": true, "requires": { @@ -4115,42 +4115,42 @@ }, "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==" }, "safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "resolved": false, "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "optional": true }, "sax": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "resolved": false, "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "optional": true }, "semver": { "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "resolved": false, "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "resolved": false, "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "resolved": false, "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "optional": true }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": false, "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { "code-point-at": "^1.0.0", @@ -4160,7 +4160,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": false, "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "optional": true, "requires": { @@ -4169,7 +4169,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": false, "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -4177,13 +4177,13 @@ }, "strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "resolved": false, "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "optional": true }, "tar": { "version": "4.4.8", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", + "resolved": false, "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", "optional": true, "requires": { @@ -4198,13 +4198,13 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "resolved": false, "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "optional": true }, "wide-align": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "resolved": false, "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "optional": true, "requires": { @@ -4213,12 +4213,12 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "resolved": false, "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "yallist": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "resolved": false, "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" } } diff --git a/src/client/views/_global_variables.scss b/src/client/views/_global_variables.scss index a832d9614..b448d43f0 100644 --- a/src/client/views/_global_variables.scss +++ b/src/client/views/_global_variables.scss @@ -1,23 +1,17 @@ -@import url("https://fonts.googleapis.com/css?family=Roboto+Slab:300,700|Crimson+Text:400,400i,700"); +@import url("https://fonts.googleapis.com/css?family=Noto+Sans:400,700|Crimson+Text:400,400i,700"); // colors $light-color: #fcfbf7; -$light-color-secondary: rgb(241, -239, -235); +$light-color-secondary: rgb(241, 239, 235); $main-accent: #61aaa3; // $alt-accent: #cdd5ec; // $alt-accent: #cdeceb; $alt-accent: #f9e1db; -$lighter-alt-accent: rgb(207, -220, -240); +$lighter-alt-accent: rgb(207, 220, 240); $intermediate-color: #9c9396; $dark-color: #121721; // fonts -$sans-serif: "Noto Sans", -sans-serif; +$sans-serif: "Noto Sans", sans-serif; // $sans-serif: "Roboto Slab", sans-serif; -$serif: "Crimson Text", -serif; +$serif: "Crimson Text", serif; // misc values -$border-radius: 0.3em; \ No newline at end of file +$border-radius: 0.3em; -- cgit v1.2.3-70-g09d2 From adad36606a17642fffdcb492a5ed1326f9adb010 Mon Sep 17 00:00:00 2001 From: Hannah Chow Date: Mon, 11 Mar 2019 18:09:33 -0400 Subject: starting on linking UI --- src/client/views/DocumentDecorations.scss | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index a29bf36fa..a9621efa5 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -67,6 +67,18 @@ grid-column: 1/4 } +.linkButton-empty:hover { + background: $main-accent; + transform: scale(1.05); + cursor: pointer; +} + +.linkButton-nonempty:hover { + background: $main-accent; + transform: scale(1.05); + cursor: pointer; +} + .linkButton-empty { height: 20px; width: 20px; @@ -74,7 +86,12 @@ border-radius: 50%; opacity: 0.6; pointer-events: auto; - background-color: #2B6091; + background-color: $dark-color; + color: $light-color; + text-transform: uppercase; + letter-spacing: 2px; + font-size: 75%; + transition: transform 0.2s; } .linkButton-nonempty { @@ -84,5 +101,10 @@ border-radius: 50%; opacity: 0.6; pointer-events: auto; - background-color: rgb(35, 165, 42); + background-color: $dark-color; + color: $light-color; + text-transform: uppercase; + letter-spacing: 2px; + font-size: 75%; + transition: transform 0.2s; } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 31c9722ed5e587d3ae294db83c134b8e6ad050f8 Mon Sep 17 00:00:00 2001 From: Hannah Chow Date: Mon, 11 Mar 2019 18:32:28 -0400 Subject: added tooltips --- src/client/views/DocumentDecorations.scss | 12 ++++++------ src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/nodes/LinkBox.scss | 22 +++++++++++++++++----- src/client/views/nodes/LinkBox.tsx | 6 +++--- src/client/views/nodes/LinkMenu.tsx | 4 ++-- 5 files changed, 29 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index a9621efa5..9e3034829 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -80,11 +80,11 @@ } .linkButton-empty { - height: 20px; - width: 20px; + height: 16px; + width: 16px; margin-top: 10px; border-radius: 50%; - opacity: 0.6; + opacity: 0.9; pointer-events: auto; background-color: $dark-color; color: $light-color; @@ -95,11 +95,11 @@ } .linkButton-nonempty { - height: 20px; - width: 20px; + height: 16px; + width: 16px; margin-top: 10px; border-radius: 50%; - opacity: 0.6; + opacity: 0.9; pointer-events: auto; background-color: $dark-color; color: $light-color; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index b75644ecd..313b35ca8 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -234,7 +234,7 @@ export class DocumentDecorations extends React.Component {
e.preventDefault()}>
e.preventDefault()}>
-
{linkButton}
+
{linkButton}
) diff --git a/src/client/views/nodes/LinkBox.scss b/src/client/views/nodes/LinkBox.scss index 00e5ebb3d..bdedbc103 100644 --- a/src/client/views/nodes/LinkBox.scss +++ b/src/client/views/nodes/LinkBox.scss @@ -1,3 +1,4 @@ +@import "../global_variables"; .link-container { width: 100%; height: 30px; @@ -29,11 +30,22 @@ } .button { - height: 15px; - width: 15px; - margin: 8px 5px; + height: 16px; + width: 16px; + margin: 8px 4px; border-radius: 50%; - opacity: 0.6; + opacity: 0.9; pointer-events: auto; - background-color: #2B6091; + background-color: $dark-color; + color: $light-color; + text-transform: uppercase; + letter-spacing: 2px; + font-size: 75%; + transition: transform 0.2s; +} + +.button:hover { + background: $main-accent; + transform: scale(1.05); + cursor: pointer; } \ No newline at end of file diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 69df676ff..44b3dccb7 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -79,9 +79,9 @@ export class LinkBox extends React.Component {
-
-
-
+
+
+
) diff --git a/src/client/views/nodes/LinkMenu.tsx b/src/client/views/nodes/LinkMenu.tsx index 5c6b06d00..5eeb40772 100644 --- a/src/client/views/nodes/LinkMenu.tsx +++ b/src/client/views/nodes/LinkMenu.tsx @@ -39,8 +39,8 @@ export class LinkMenu extends React.Component {
- {this.renderLinkItems(linkTo, KeyStore.LinkedToDocs, "Source: ")} - {this.renderLinkItems(linkFrom, KeyStore.LinkedFromDocs, "Destination: ")} + {this.renderLinkItems(linkTo, KeyStore.LinkedToDocs, "Destination: ")} + {this.renderLinkItems(linkFrom, KeyStore.LinkedFromDocs, "Source: ")}
) -- cgit v1.2.3-70-g09d2 From bff0093163bdc05fb661eb744c2333069544dc89 Mon Sep 17 00:00:00 2001 From: laurawilsonri Date: Mon, 11 Mar 2019 18:48:58 -0400 Subject: added a method to check if block has a syle ie bullets --- src/client/util/RichTextSchema.tsx | 44 +++++++++++++++++++++++++---- src/client/util/TooltipTextMenu.tsx | 3 +- src/client/views/nodes/FormattedTextBox.tsx | 2 ++ 3 files changed, 41 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index abf448c9f..341d5a443 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -1,12 +1,31 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Schema, NodeSpec, MarkSpec, DOMOutputSpecArray } from "prosemirror-model" +import { Schema, NodeSpec, MarkSpec, DOMOutputSpecArray, NodeType } from "prosemirror-model" import { joinUp, lift, setBlockType, toggleMark, wrapIn } from 'prosemirror-commands' import { redo, undo } from 'prosemirror-history' -import { orderedList, bulletList, listItem } from 'prosemirror-schema-list' +import { orderedList, bulletList, listItem, } from 'prosemirror-schema-list' +import { EditorState, Transaction, NodeSelection, } from "prosemirror-state"; +import { EditorView, } from "prosemirror-view"; const pDOM: DOMOutputSpecArray = ["p", 0], blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"], preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0] +//adapted this method - use it to check if block has a tag (ie bulleting) +const blockActive = (type: NodeType>, attrs = {}) => (state: EditorState) => { + + if (state.selection instanceof NodeSelection) { + const sel: NodeSelection = state.selection; + let $from = sel.$from; + let to = sel.to; + let node = sel.node; + + if (node) { + return node.hasMarkup(type, attrs); + } + + return to <= $from.end() && $from.parent.hasMarkup(type, attrs); + } +}; + // :: Object // [Specs](#model.NodeSpec) for the nodes defined in this schema. export const nodes: { [index: string]: NodeSpec } = { @@ -113,11 +132,24 @@ export const nodes: { [index: string]: NodeSpec } = { content: 'list_item+', group: 'block' }, + //bullet_list: { + // ...bulletList, + // content: 'list_item+', + // group: 'block', + //parseDOM: [{ tag: "ul" }, { style: 'list-style-type=disc' }], + //toDOM() { return ulDOM } + //}, bullet_list: { - content: 'list_item+', - group: 'block', - parseDOM: [{ tag: "ul" }, { style: "list-style-type=disc;" }], - toDOM() { return ulDOM } + title: "Wrap in bullet list", + content: icons.bullet_list, + active: blockActive(state.config.schema.nodes.bullet_list), + enable: state => wrapInList(state.config.schema.nodes.bullet_list), + run: state => wrapInList(state.config.schema.nodes.bullet_list), + active: blockActive(schema.nodes.bullet_list), + enable: wrapInList(schema.nodes.bullet_list), + run: wrapInList(schema.nodes.bullet_list), + select: state => true, + menu: props => - - - + + + +
  • - +
    this.toggleColorPicker()}> {/* {this._colorPickerDisplay ? : } */} @@ -95,9 +95,9 @@ export class InkingControl extends React.Component {
  • - - {/* ) => this.switchWidth(e.target.value)} /> */} + + ) => this.switchWidth(e.target.value)} /> ) => this.switchWidth(e.target.value)} />
  • -- cgit v1.2.3-70-g09d2 From 31bb06320481ce6fc1dd0de11610d0efcc008866 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 11 Mar 2019 20:20:14 -0400 Subject: removed Docking option --- src/client/views/collections/CollectionView.tsx | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 548a51bf1..17a0fbd23 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -99,7 +99,6 @@ export class CollectionView extends React.Component { ContextMenu.Instance.addItem({ description: "Freeform", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) }) ContextMenu.Instance.addItem({ description: "Schema", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema) }) ContextMenu.Instance.addItem({ description: "Treeview", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Tree) }) - ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) }) } } -- cgit v1.2.3-70-g09d2 From 151566e396249991e24d49b3db5c246431e62262 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 11 Mar 2019 20:28:23 -0400 Subject: fixed marquee selection and collection view creation --- .../views/collections/CollectionFreeFormView.tsx | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 97e7aefa2..b5dc5ab18 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -95,8 +95,6 @@ export class CollectionFreeFormView extends CollectionViewBase { if (this._marquee) { document.removeEventListener("keydown", this.marqueeCommand); } - document.removeEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); e.stopPropagation(); if (this._marquee) { @@ -105,7 +103,6 @@ export class CollectionFreeFormView extends CollectionViewBase { } var selectedDocs = this.marqueeSelect(); selectedDocs.map(s => this.props.CollectionView.SelectedDocs.push(s.Id)); - this._marquee = false; } else if (!this._marquee && Math.abs(this._downX - e.clientX) < 3 && Math.abs(this._downY - e.clientY) < 3) { //show preview text cursor on tap @@ -115,11 +112,11 @@ export class CollectionFreeFormView extends CollectionViewBase { this.props.select(false); } } - + this.cleanupInteractions(); } @action - clearMarquee = () => { + cleanupInteractions = () => { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); this._marquee = false; @@ -136,7 +133,7 @@ export class CollectionFreeFormView extends CollectionViewBase { marqueeSelect() { this.props.CollectionView.SelectedDocs.length = 0; var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1); - let p = this.getTransform().transformPoint(this._downX, this._downY); + let p = this.getTransform().transformPoint(this._downX < this._lastX ? this._downX : this._lastX, this._downY < this._lastY ? this._downY : this._lastY); let v = this.getTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY); let selRect = { left: p[0], top: p[1], right: p[0] + v[0], bottom: p[1] + v[1] } @@ -187,23 +184,24 @@ export class CollectionFreeFormView extends CollectionViewBase { marqueeCommand = (e: KeyboardEvent) => { if (e.key == "Backspace") { this.marqueeSelect().map(d => this.props.removeDocument(d)); - this.clearMarquee(); + this.cleanupInteractions(); } if (e.key == "c") { - let p = this.getTransform().transformPoint(this._downX, this._downY); + let p = this.getTransform().transformPoint(this._downX < this._lastX ? this._downX : this._lastX, this._downY < this._lastY ? this._downY : this._lastY); let v = this.getTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY); + let selected = this.marqueeSelect().map(m => m); this.marqueeSelect().map(d => this.props.removeDocument(d)); //setTimeout(() => { this.props.CollectionView.addDocument(Documents.FreeformDocument(selected.map(d => { - d.SetNumber(KeyStore.X, d.GetNumber(KeyStore.X, 0) - p[0] - 400); - d.SetNumber(KeyStore.Y, d.GetNumber(KeyStore.Y, 0) - p[1] - 400); + d.SetNumber(KeyStore.X, d.GetNumber(KeyStore.X, 0) - p[0] - v[0] / 2); + d.SetNumber(KeyStore.Y, d.GetNumber(KeyStore.Y, 0) - p[1] - v[1] / 2); d.SetNumber(KeyStore.Page, this.props.Document.GetNumber(KeyStore.Page, 0)); d.SetText(KeyStore.Title, "" + d.GetNumber(KeyStore.Width, 0) + " " + d.GetNumber(KeyStore.Height, 0)); return d; - }), { x: p[0], y: p[1], panx: 0, pany: 0, width: 800, height: 800, title: "a nested collection" })); + }), { x: p[0], y: p[1], panx: 0, pany: 0, width: v[0], height: v[1], title: "a nested collection" })); // }, 100); - this.clearMarquee(); + this.cleanupInteractions(); } } -- cgit v1.2.3-70-g09d2 From eb1c48dc6ff1403372f820d07b46c08f58cc7306 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 11 Mar 2019 20:46:22 -0400 Subject: added modifier options for macbook --- src/client/util/DragManager.ts | 2 +- src/client/views/collections/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/FormattedTextBox.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 4a61220a5..9bd7d5c24 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -158,7 +158,7 @@ export namespace DragManager { e.preventDefault(); x += e.movementX; y += e.movementY; - if (e.shiftKey) { + if (e.shiftKey && (e.button == 2 || e.altKey)) { abortDrag(); CollectionDockingView.Instance.StartOtherDrag(doc, { pageX: e.pageX, pageY: e.pageY, preventDefault: () => { }, button: 0 }); } diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index b5dc5ab18..74d37ccec 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -77,7 +77,7 @@ export class CollectionFreeFormView extends CollectionViewBase { @action onPointerDown = (e: React.PointerEvent): void => { - if (((e.button === 2 && this.props.active()) || !e.defaultPrevented) && !e.shiftKey && + if (((e.button === 2 && this.props.active()) || !e.defaultPrevented) && (!this.isAnnotationOverlay || this.zoomScaling != 1 || e.button == 0)) { document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index dc793c16d..da40f0dc1 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -182,7 +182,7 @@ export class DocumentView extends React.Component { if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { document.removeEventListener("pointermove", this.onPointerMove) document.removeEventListener("pointerup", this.onPointerUp); - if (!this.topMost || e.buttons == 2) { + if (!this.topMost || e.buttons == 2 || e.altKey) { this.startDragging(e.x, e.y); } } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index ad7ddf37a..5c7aaf9fe 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -113,7 +113,7 @@ export class FormattedTextBox extends React.Component { this.props.doc.SetData(this.props.fieldKey, e.target.value, RichTextField); } onPointerDown = (e: React.PointerEvent): void => { - if (e.buttons === 1 && this.props.isSelected()) { + if (e.buttons === 1 && this.props.isSelected() && !e.altKey) { e.stopPropagation(); } } -- cgit v1.2.3-70-g09d2 From 91338b2cea4f006e5813145009cb471b17679cd7 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 11 Mar 2019 23:10:22 -0400 Subject: fixed drop of PDFs --- src/client/views/collections/CollectionViewBase.tsx | 3 +++ src/client/views/nodes/PDFBox.tsx | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index b126b40a9..31c89a75d 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -130,6 +130,9 @@ export class CollectionViewBase extends React.Component if (type.indexOf("audio") !== -1) { doc = Documents.AudioDocument(path, { ...options, nativeWidth: 300, width: 300, }) } + if (type.indexOf("pdf") !== -1) { + doc = Documents.PdfDocument(path, { ...options, nativeWidth: 300, width: 300, }) + } let docs = that.props.Document.GetT(KeyStore.Data, ListField); if (docs != FieldWaiting) { if (!docs) { diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 70a70c7c8..368a80b8e 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -423,7 +423,9 @@ export class PDFBox extends React.Component { // so this design is flawed. var nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 0); if (!this.props.doc.GetNumber(KeyStore.NativeHeight, 0)) { - this.props.doc.SetNumber(KeyStore.NativeHeight, nativeWidth * r.entry.height / r.entry.width); + var nativeHeight = nativeWidth * r.entry.height / r.entry.width; + this.props.doc.SetNumber(KeyStore.Height, nativeHeight / nativeWidth * this.props.doc.GetNumber(KeyStore.Width, 0)); + this.props.doc.SetNumber(KeyStore.NativeHeight, nativeHeight); } if (!this.props.doc.GetT(KeyStore.Thumbnail, ImageField)) { this.saveThumbnail(); -- cgit v1.2.3-70-g09d2 From a680579f74380eb016f0ffd61b3818d0850984b5 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 11 Mar 2019 23:32:58 -0400 Subject: fixed css for images --- src/client/views/collections/CollectionFreeFormView.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss index d487cd7ce..d294dc4d7 100644 --- a/src/client/views/collections/CollectionFreeFormView.scss +++ b/src/client/views/collections/CollectionFreeFormView.scss @@ -40,7 +40,7 @@ } border-style: solid; - box-sizing: border-box; + box-sizing: content-box; position: absolute; top: 0; left: 0; -- cgit v1.2.3-70-g09d2 From e5c0eab1b3896cf28b6f54f5893d2998b70ef9af Mon Sep 17 00:00:00 2001 From: Hannah Chow Date: Mon, 11 Mar 2019 23:46:45 -0400 Subject: UI pretty much stable --- src/client/views/EditableView.scss | 6 +++ src/client/views/EditableView.tsx | 1 + .../views/collections/CollectionTreeView.scss | 59 +++++++++++----------- 3 files changed, 36 insertions(+), 30 deletions(-) create mode 100644 src/client/views/EditableView.scss (limited to 'src') diff --git a/src/client/views/EditableView.scss b/src/client/views/EditableView.scss new file mode 100644 index 000000000..be3c5069a --- /dev/null +++ b/src/client/views/EditableView.scss @@ -0,0 +1,6 @@ +.editableView-container-editing { + overflow-wrap: break-word; + word-wrap: break-word; + hyphens: auto; + max-width: 300px; +} \ No newline at end of file diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 84b1b91c3..757bfeae6 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -1,6 +1,7 @@ import React = require('react') import { observer } from 'mobx-react'; import { observable, action } from 'mobx'; +import "./EditableView.scss" export interface EditableProps { /** diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss index c2b376a34..fa0f1c761 100644 --- a/src/client/views/collections/CollectionTreeView.scss +++ b/src/client/views/collections/CollectionTreeView.scss @@ -1,62 +1,61 @@ @import "../global_variables"; - #body { - padding: 20px; - background: $light-color-secondary; - font-size: 13px; - overflow: scroll; + padding: 20px; + background: $light-color-secondary; + font-size: 13px; + overflow: scroll; } ul { - list-style: none; - padding-left: 20px; + list-style: none; + padding-left: 20px; } li { - margin: 5px 0; + margin: 5px 0; } .collection-child { - margin-top: 10px; - margin-bottom: 10px; + margin-top: 10px; + margin-bottom: 10px; } .no-indent { - padding-left: 0; + padding-left: 0; } .bullet { - width: 1.5em; - display: inline-block; - color: $intermediate-color; + width: 1.5em; + display: inline-block; + color: $intermediate-color; } .coll-title { - font-size: 24px; - margin-bottom: 20px; + font-size: 24px; + margin-bottom: 20px; } .collectionTreeView-dropTarget { - border: 0px solid transparent; - border-radius: $border-radius; - box-sizing: border-box; - height: 100%; + border: 0px solid transparent; + border-radius: $border-radius; + box-sizing: border-box; + height: 100%; } .docContainer { - display: inline-table; + display: inline-table; } .docContainer:hover { - .delete-button { - display: inline; - } + .delete-button { + display: inline; + } } .delete-button { - color: $intermediate-color; - float: right; - margin-left: 15px; - margin-top: 3px; - display: none; -} + color: $intermediate-color; + float: right; + margin-left: 15px; + margin-top: 3px; + display: none; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 5021cc23beec55085167bd974299fb314d3bdbcf Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 11 Mar 2019 23:51:05 -0400 Subject: changed API --- src/client/documents/Documents.ts | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index bb463b36f..e6e2378c4 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -89,9 +89,12 @@ export namespace Documents { function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Document { return assignOptions(new Document(protoId), { ...options, title: title, layout: layout }); } - function SetInstanceOptions(doc: Document, options: DocumentOptions, value: T, ctor: { new(): U }, id?: string) { + function SetInstanceOptions(doc: Document, options: DocumentOptions, value: [T, { new(): U }] | Document, id?: string) { var deleg = doc.MakeDelegate(id); - deleg.SetData(KeyStore.Data, value, ctor); + if (value instanceof Document) + deleg.Set(KeyStore.Data, value) + else + deleg.SetData(KeyStore.Data, value[0], value[1]); return assignOptions(deleg, options); } @@ -146,44 +149,42 @@ export namespace Documents { export function ImageDocument(url: string, options: DocumentOptions = {}) { - let doc = SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }, - new URL(url), ImageField); + return SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }, + [new URL(url), ImageField]); // doc.SetText(KeyStore.Caption, "my caption..."); // doc.SetText(KeyStore.BackgroundLayout, EmbeddedCaption()); // doc.SetText(KeyStore.OverlayLayout, FixedCaption()); - return doc; + // return doc; } export function VideoDocument(url: string, options: DocumentOptions = {}) { - return SetInstanceOptions(GetVideoPrototype(), options, new URL(url), VideoField); + return SetInstanceOptions(GetVideoPrototype(), options, [new URL(url), VideoField]); } export function AudioDocument(url: string, options: DocumentOptions = {}) { - return SetInstanceOptions(GetAudioPrototype(), options, new URL(url), AudioField); + return SetInstanceOptions(GetAudioPrototype(), options, [new URL(url), AudioField]); } export function TextDocument(options: DocumentOptions = {}) { - return SetInstanceOptions(GetTextPrototype(), options, "", RichTextField); + return SetInstanceOptions(GetTextPrototype(), options, ["", RichTextField]); } export function PdfDocument(url: string, options: DocumentOptions = {}) { - return SetInstanceOptions(GetPdfPrototype(), options, new URL(url), PDFField); + return SetInstanceOptions(GetPdfPrototype(), options, [new URL(url), PDFField]); } export function WebDocument(url: string, options: DocumentOptions = {}) { - return SetInstanceOptions(GetWebPrototype(), options, new URL(url), WebField); + return SetInstanceOptions(GetWebPrototype(), options, [new URL(url), WebField]); } export function HtmlDocument(html: string, options: DocumentOptions = {}) { - return SetInstanceOptions(GetWebPrototype(), options, html, HtmlField); + return SetInstanceOptions(GetWebPrototype(), options, [html, HtmlField]); + } + export function KVPDocument(document: Document, options: DocumentOptions = {}, id?: string) { + return SetInstanceOptions(GetKVPPrototype(), options, document, id) } export function FreeformDocument(documents: Array, options: DocumentOptions, id?: string) { - return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Freeform }, documents, ListField, id) + return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id) } export function SchemaDocument(documents: Array, options: DocumentOptions, id?: string) { - return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Schema }, documents, ListField, id) + return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Schema }, [documents, ListField], id) } export function DockDocument(config: string, options: DocumentOptions, id?: string) { - return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Docking }, config, TextField, id) - } - export function KVPDocument(document: Document, options: DocumentOptions = {}, id?: string) { - var deleg = GetKVPPrototype().MakeDelegate(id); - deleg.Set(KeyStore.Data, document); - return assignOptions(deleg, options); + return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Docking }, [config, TextField], id) } // example of custom display string for an image that shows a caption. -- cgit v1.2.3-70-g09d2 From 2100f1b25fa822d14a49a1ddbb38182860db6edb Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 12 Mar 2019 00:15:05 -0400 Subject: finally got css right for images? --- src/client/documents/Documents.ts | 4 +++- src/client/views/collections/CollectionFreeFormView.scss | 2 +- src/client/views/nodes/ImageBox.scss | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index e6e2378c4..3d9f4a0cb 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -151,6 +151,8 @@ export namespace Documents { export function ImageDocument(url: string, options: DocumentOptions = {}) { return SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }, [new URL(url), ImageField]); + // let doc = SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }, + // [new URL(url), ImageField]); // doc.SetText(KeyStore.Caption, "my caption..."); // doc.SetText(KeyStore.BackgroundLayout, EmbeddedCaption()); // doc.SetText(KeyStore.OverlayLayout, FixedCaption()); @@ -190,7 +192,7 @@ export namespace Documents { // example of custom display string for an image that shows a caption. function EmbeddedCaption() { return `
    -
    ` +
    ` + ImageBox.LayoutString() + `
    ` diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss index d294dc4d7..d487cd7ce 100644 --- a/src/client/views/collections/CollectionFreeFormView.scss +++ b/src/client/views/collections/CollectionFreeFormView.scss @@ -40,7 +40,7 @@ } border-style: solid; - box-sizing: content-box; + box-sizing: border-box; position: absolute; top: 0; left: 0; diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index ea459b911..31452bc85 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -10,8 +10,8 @@ } .imageBox-cont img { - object-fit: contain; height: 100%; + width:100%; } .imageBox-button { -- cgit v1.2.3-70-g09d2 From cb26f129873a821b8457b9069ce8f801aa2b4e16 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 12 Mar 2019 00:21:07 -0400 Subject: fixed marquee select from bottom/right --- src/client/views/collections/CollectionFreeFormView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 74d37ccec..618f1ec7c 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -135,7 +135,7 @@ export class CollectionFreeFormView extends CollectionViewBase { var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1); let p = this.getTransform().transformPoint(this._downX < this._lastX ? this._downX : this._lastX, this._downY < this._lastY ? this._downY : this._lastY); let v = this.getTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY); - let selRect = { left: p[0], top: p[1], right: p[0] + v[0], bottom: p[1] + v[1] } + let selRect = { left: p[0], top: p[1], right: p[0] + Math.abs(v[0]), bottom: p[1] + Math.abs(v[1]) } var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1); const lvalue = this.props.Document.GetT>(this.props.fieldKey, ListField); -- cgit v1.2.3-70-g09d2 From c1e1e373b8b9afc68df8dcbbe38990378909d38f Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 12 Mar 2019 01:19:54 -0400 Subject: more cleanup of events --- src/client/util/DragManager.ts | 2 +- src/client/views/collections/CollectionFreeFormView.tsx | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 9bd7d5c24..4a61220a5 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -158,7 +158,7 @@ export namespace DragManager { e.preventDefault(); x += e.movementX; y += e.movementY; - if (e.shiftKey && (e.button == 2 || e.altKey)) { + if (e.shiftKey) { abortDrag(); CollectionDockingView.Instance.StartOtherDrag(doc, { pageX: e.pageX, pageY: e.pageY, preventDefault: () => { }, button: 0 }); } diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 618f1ec7c..989347126 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -77,8 +77,7 @@ export class CollectionFreeFormView extends CollectionViewBase { @action onPointerDown = (e: React.PointerEvent): void => { - if (((e.button === 2 && this.props.active()) || !e.defaultPrevented) && - (!this.isAnnotationOverlay || this.zoomScaling != 1 || e.button == 0)) { + if ((e.button === 2 && this.props.active() && (!this.isAnnotationOverlay || this.zoomScaling != 1)) || e.button == 0) { document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); @@ -159,21 +158,25 @@ export class CollectionFreeFormView extends CollectionViewBase { @action onPointerMove = (e: PointerEvent): void => { if (!e.cancelBubble && this.props.active()) { - e.stopPropagation(); - e.preventDefault(); let wasMarquee = this._marquee; this._marquee = e.buttons != 2 && !e.altKey && !e.metaKey; if (this._marquee && !wasMarquee) { this._previewCursorVisible = false; document.addEventListener("keydown", this.marqueeCommand); } + if (this._marquee) { + e.stopPropagation(); + e.preventDefault(); + } - if (!this._marquee) { + if (!this._marquee && (!this.isAnnotationOverlay || this.zoomScaling != 1) && !e.shiftKey) { let x = this.props.Document.GetNumber(KeyStore.PanX, 0); let y = this.props.Document.GetNumber(KeyStore.PanY, 0); let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY); this._previewCursorVisible = false; this.SetPan(x - dx, y - dy); + e.stopPropagation(); + e.preventDefault(); } } this._lastX = e.pageX; -- cgit v1.2.3-70-g09d2 From 1b2eac89b8f88358ecf1ba0e782c90379090b9c8 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 12 Mar 2019 09:32:55 -0400 Subject: minor fixes. --- src/client/views/collections/CollectionFreeFormView.tsx | 1 + src/client/views/collections/CollectionViewBase.tsx | 3 ++- src/client/views/nodes/DocumentView.tsx | 2 -- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 989347126..761c3ba56 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -210,6 +210,7 @@ export class CollectionFreeFormView extends CollectionViewBase { @action onPointerWheel = (e: React.WheelEvent): void => { + this.props.select(false); e.stopPropagation(); e.preventDefault(); let coefficient = 1000; diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index 31c89a75d..a77133e6c 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -52,11 +52,12 @@ export class CollectionViewBase extends React.Component docView.props.RemoveDocument(docView.props.Document); } this.props.addDocument(docView.props.Document); + e.stopPropagation(); } else if (doc) { this.props.removeDocument(doc); this.props.addDocument(doc); + e.stopPropagation(); } - e.stopPropagation(); } @action diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index da40f0dc1..ea39e2ac0 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -246,8 +246,6 @@ export class DocumentView extends React.Component { destDoc.GetOrCreateAsync(KeyStore.LinkedFromDocs, ListField, field => { (field as ListField).Data.push(linkDoc) }); linkDoc.Set(KeyStore.LinkedFromDocs, sourceDoc); - - e.stopPropagation(); } -- cgit v1.2.3-70-g09d2 From ae8bc0f99f35f6c72aaa9be3f5617d54ba64299b Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 12 Mar 2019 11:03:19 -0400 Subject: Fixes --- package-lock.json | 8 ++++++-- src/client/views/collections/CollectionFreeFormView.tsx | 1 + src/client/views/collections/CollectionViewBase.tsx | 16 +--------------- 3 files changed, 8 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/package-lock.json b/package-lock.json index dd5d44bd9..5b9cb598d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3735,12 +3735,14 @@ "balanced-match": { "version": "1.0.0", "resolved": false, - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "optional": true }, "brace-expansion": { "version": "1.1.11", "resolved": false, "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3760,7 +3762,8 @@ "concat-map": { "version": "0.0.1", "resolved": false, - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "optional": true }, "console-control-strings": { "version": "1.1.0", @@ -3908,6 +3911,7 @@ "version": "3.0.4", "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "optional": true, "requires": { "brace-expansion": "^1.1.7" } diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 761c3ba56..ab41d1378 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -116,6 +116,7 @@ export class CollectionFreeFormView extends CollectionViewBase { @action cleanupInteractions = () => { + document.removeEventListener("keydown", this.marqueeCommand); document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); this._marquee = false; diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index a77133e6c..b581d3060 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -82,21 +82,7 @@ export class CollectionViewBase extends React.Component const upload = window.location.origin + "/upload"; let item = e.dataTransfer.items[i]; if (item.kind === "string" && item.type.indexOf("uri") != -1) { - e.dataTransfer.items[i].getAsString(function (s) { - action(() => { - var img = Documents.ImageDocument(s, { ...options, nativeWidth: 300, width: 300, }) - - let docs = that.props.Document.GetT(KeyStore.Data, ListField); - if (docs != FieldWaiting) { - if (!docs) { - docs = new ListField(); - that.props.Document.Set(KeyStore.Data, docs) - } - docs.Data.push(img); - } - })() - - }) + e.dataTransfer.items[i].getAsString(action((s: string) => this.props.addDocument(Documents.WebDocument(s, options)))) } let type = item.type console.log(type) -- cgit v1.2.3-70-g09d2 From 50477f0a9b0b371b4f381b6cef14030a9d7de21e Mon Sep 17 00:00:00 2001 From: laurawilsonri Date: Tue, 12 Mar 2019 16:14:13 -0400 Subject: added some helpful comments --- package-lock.json | 9 ++++++ package.json | 1 + src/client/util/RichTextRules.ts | 43 ++++++++++++++++++++++++++ src/client/util/RichTextSchema.tsx | 47 +++++++++-------------------- src/client/util/TooltipTextMenu.tsx | 24 ++++++++++++--- src/client/views/nodes/FormattedTextBox.tsx | 2 ++ 6 files changed, 88 insertions(+), 38 deletions(-) create mode 100644 src/client/util/RichTextRules.ts (limited to 'src') diff --git a/package-lock.json b/package-lock.json index 9343a2e88..e780b247f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -320,6 +320,15 @@ "@types/prosemirror-state": "*" } }, + "@types/prosemirror-inputrules": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.2.tgz", + "integrity": "sha512-bKFneQUPnkZmzCJ1uoitpKH6PFW0hc4q55NsC7mFUCvX0eZl0GRKxyfV47jkJbsbyUQoO/QFv0WwLDz2bo15sA==", + "requires": { + "@types/prosemirror-model": "*", + "@types/prosemirror-state": "*" + } + }, "@types/prosemirror-keymap": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/prosemirror-keymap/-/prosemirror-keymap-1.0.1.tgz", diff --git a/package.json b/package.json index a89d82645..841796bb4 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "@types/passport-local": "^1.0.33", "@types/prosemirror-commands": "^1.0.1", "@types/prosemirror-history": "^1.0.1", + "@types/prosemirror-inputrules": "^1.0.2", "@types/prosemirror-keymap": "^1.0.1", "@types/prosemirror-model": "^1.7.0", "@types/prosemirror-schema-basic": "^1.0.1", diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts new file mode 100644 index 000000000..3b8396510 --- /dev/null +++ b/src/client/util/RichTextRules.ts @@ -0,0 +1,43 @@ +import { + inputRules, + wrappingInputRule, + textblockTypeInputRule, + smartQuotes, + emDash, + ellipsis +} from "prosemirror-inputrules"; +import { Schema, NodeSpec, MarkSpec, DOMOutputSpecArray, NodeType } from "prosemirror-model"; + +import { schema } from "./RichTextSchema"; + +export const inpRules = { + rules: [ + ...smartQuotes, + ellipsis, + emDash, + + // > blockquote + wrappingInputRule(/^\s*>\s$/, schema.nodes.blockquote), + + // 1. ordered list + wrappingInputRule( + /^(\d+)\.\s$/, + schema.nodes.ordered_list, + match => ({ order: +match[1] }), + (match, node) => node.childCount + node.attrs.order === +match[1] + ), + + // * bullet list + wrappingInputRule(/^\s*([-+*])\s$/, schema.nodes.bullet_list), + + // ``` code block + textblockTypeInputRule(/^```$/, schema.nodes.code_block), + + // # heading + textblockTypeInputRule( + new RegExp("^(#{1,6})\\s$"), + schema.nodes.heading, + match => ({ level: match[1].length }) + ) + ] +}; diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 341d5a443..2a3c1da6e 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -9,22 +9,6 @@ import { EditorView, } from "prosemirror-view"; const pDOM: DOMOutputSpecArray = ["p", 0], blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"], preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0] -//adapted this method - use it to check if block has a tag (ie bulleting) -const blockActive = (type: NodeType>, attrs = {}) => (state: EditorState) => { - - if (state.selection instanceof NodeSelection) { - const sel: NodeSelection = state.selection; - let $from = sel.$from; - let to = sel.to; - let node = sel.node; - - if (node) { - return node.hasMarkup(type, attrs); - } - - return to <= $from.end() && $from.parent.hasMarkup(type, attrs); - } -}; // :: Object // [Specs](#model.NodeSpec) for the nodes defined in this schema. @@ -132,25 +116,22 @@ export const nodes: { [index: string]: NodeSpec } = { content: 'list_item+', group: 'block' }, - //bullet_list: { - // ...bulletList, - // content: 'list_item+', - // group: 'block', - //parseDOM: [{ tag: "ul" }, { style: 'list-style-type=disc' }], - //toDOM() { return ulDOM } - //}, + //this doesn't currently work for some reason bullet_list: { - title: "Wrap in bullet list", - content: icons.bullet_list, - active: blockActive(state.config.schema.nodes.bullet_list), - enable: state => wrapInList(state.config.schema.nodes.bullet_list), - run: state => wrapInList(state.config.schema.nodes.bullet_list), - active: blockActive(schema.nodes.bullet_list), - enable: wrapInList(schema.nodes.bullet_list), - run: wrapInList(schema.nodes.bullet_list), - select: state => true, - menu: props =>
    ); } -} +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx new file mode 100644 index 000000000..a6471f53c --- /dev/null +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -0,0 +1,50 @@ +import { action, computed } from "mobx"; +import { observer } from "mobx-react"; +import { Document } from "../../../fields/Document"; +import { KeyStore } from "../../../fields/KeyStore"; +import { ContextMenu } from "../ContextMenu"; +import { CollectionView, CollectionViewType } from "./CollectionView"; +import { CollectionViewProps } from "./CollectionViewBase"; +import React = require("react"); +import { FieldId } from "../../../fields/Field"; + + +@observer +export class CollectionVideoView extends React.Component { + + public static LayoutString(fieldKey: string = "DataKey") { + return `<${CollectionVideoView.name} Document={Document} + ScreenToLocalTransform={ScreenToLocalTransform} fieldKey={${fieldKey}} panelWidth={PanelWidth} panelHeight={PanelHeight} isSelected={isSelected} select={select} bindings={bindings} + isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`; + } + + public SelectedDocs: FieldId[] = [] + @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : 0; + @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : 0; + + @computed private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, 0); } + @computed private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); } + // "inherited" CollectionView API starts here... + + public active: () => boolean = () => CollectionView.Active(this); + + addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); } + removeDocument = (doc: Document): boolean => { return CollectionView.RemoveDocument(this.props, doc); } + + specificContextMenu = (e: React.MouseEvent): void => { + if (!e.isPropagationStopped() && this.props.Document.Id != "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 + ContextMenu.Instance.addItem({ description: "VideoOptions", event: () => { } }); + } + } + + get collectionViewType(): CollectionViewType { return CollectionViewType.Freeform; } + get subView(): any { return CollectionView.SubView(this); } + + render() { + return (
    + {/* */} +
    ) + } +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index b581d3060..eda62a4ca 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -52,12 +52,11 @@ export class CollectionViewBase extends React.Component docView.props.RemoveDocument(docView.props.Document); } this.props.addDocument(docView.props.Document); - e.stopPropagation(); } else if (doc) { this.props.removeDocument(doc); this.props.addDocument(doc); - e.stopPropagation(); } + e.stopPropagation(); } @action @@ -109,7 +108,7 @@ export class CollectionViewBase extends React.Component var doc: any; if (type.indexOf("image") !== -1) { - doc = Documents.ImageDocument(path, { ...options, nativeWidth: 300, width: 300, }) + doc = Documents.ImageDocument(path, { ...options, nativeWidth: 200, width: 200, }) } if (type.indexOf("video") !== -1) { doc = Documents.VideoDocument(path, { ...options, nativeWidth: 300, width: 300, }) diff --git a/src/client/views/collections/MarqueeView.scss b/src/client/views/collections/MarqueeView.scss new file mode 100644 index 000000000..6d9a79344 --- /dev/null +++ b/src/client/views/collections/MarqueeView.scss @@ -0,0 +1,8 @@ + +.marqueeView { + border-style: dashed; + box-sizing: border-box; + position: absolute; + border-width: 1px; + border-color: black; +} \ No newline at end of file diff --git a/src/client/views/collections/MarqueeView.tsx b/src/client/views/collections/MarqueeView.tsx new file mode 100644 index 000000000..d9e4df1e9 --- /dev/null +++ b/src/client/views/collections/MarqueeView.tsx @@ -0,0 +1,135 @@ +import { action, IReactionDisposer, observable, reaction } from "mobx"; +import { observer } from "mobx-react"; +import { Document } from "../../../fields/Document"; +import { FieldWaiting, Opt } from "../../../fields/Field"; +import { KeyStore } from "../../../fields/KeyStore"; +import { ListField } from "../../../fields/ListField"; +import { Documents } from "../../documents/Documents"; +import { SelectionManager } from "../../util/SelectionManager"; +import { Transform } from "../../util/Transform"; +import { CollectionFreeFormView } from "./CollectionFreeFormView"; +import "./MarqueeView.scss"; +import React = require("react"); + + +interface MarqueeViewProps { + getMarqueeTransform: () => Transform; + getTransform: () => Transform; + container: CollectionFreeFormView; + addDocument: (doc: Document) => void; + activeDocuemnts: () => Document[]; + selectDocuments: (docs: Document[]) => void; + removeDocument: (doc: Document) => boolean; +} + +@observer +export class MarqueeView extends React.Component +{ + private _reactionDisposer: Opt; + + @observable _lastX: number = 0; + @observable _lastY: number = 0; + @observable _downX: number = 0; + @observable _downY: number = 0; + + componentDidMount() { + this._reactionDisposer = reaction( + () => this.props.container.MarqueeVisible, + (visible: boolean) => this.onPointerDown(visible, this.props.container.DownX, this.props.container.DownY)) + } + componentWillUnmount() { + if (this._reactionDisposer) { + this._reactionDisposer(); + } + this.cleanupInteractions(); + } + + @action + cleanupInteractions = () => { + document.removeEventListener("pointermove", this.onPointerMove, true) + document.removeEventListener("pointerup", this.onPointerUp, true); + document.removeEventListener("keydown", this.marqueeCommand, true); + } + + @action + onPointerDown = (visible: boolean, downX: number, downY: number): void => { + if (visible) { + this._downX = this._lastX = downX; + this._downY = this._lastY = downY; + document.addEventListener("pointermove", this.onPointerMove, true) + document.addEventListener("pointerup", this.onPointerUp, true); + document.addEventListener("keydown", this.marqueeCommand, true); + } + } + + @action + onPointerMove = (e: PointerEvent): void => { + this._lastX = e.pageX; + this._lastY = e.pageY; + } + + @action + onPointerUp = (e: PointerEvent): void => { + this.cleanupInteractions(); + if (!e.shiftKey) { + SelectionManager.DeselectAll(); + } + this.props.selectDocuments(this.marqueeSelect()); + } + + intersectRect(r1: { left: number, top: number, width: number, height: number }, + r2: { left: number, top: number, width: number, height: number }) { + return !(r2.left > r1.left + r1.width || r2.left + r2.width < r1.left || r2.top > r1.top + r1.height || r2.top + r2.height < r1.top); + } + + get Bounds() { + let left = this._downX < this._lastX ? this._downX : this._lastX; + let top = this._downY < this._lastY ? this._downY : this._lastY; + let topLeft = this.props.getTransform().transformPoint(left, top); + let size = this.props.getTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY); + return { left: topLeft[0], top: topLeft[1], width: Math.abs(size[0]), height: Math.abs(size[1]) } + } + + @action + marqueeCommand = (e: KeyboardEvent) => { + if (e.key == "Backspace") { + this.marqueeSelect().map(d => this.props.removeDocument(d)); + this.cleanupInteractions(); + } + if (e.key == "c") { + let bounds = this.Bounds; + let selected = this.marqueeSelect().map(m => m); + this.marqueeSelect().map(d => this.props.removeDocument(d)); + //setTimeout(() => { + this.props.addDocument(Documents.FreeformDocument(selected.map(d => { + d.SetNumber(KeyStore.X, d.GetNumber(KeyStore.X, 0) - bounds.left - bounds.width / 2); + d.SetNumber(KeyStore.Y, d.GetNumber(KeyStore.Y, 0) - bounds.top - bounds.height / 2); + d.SetNumber(KeyStore.Page, 0); + d.SetText(KeyStore.Title, "" + d.GetNumber(KeyStore.Width, 0) + " " + d.GetNumber(KeyStore.Height, 0)); + return d; + }), { x: bounds.left, y: bounds.top, panx: 0, pany: 0, width: bounds.width, height: bounds.height, title: "a nested collection" })); + // }, 100); + this.cleanupInteractions(); + } + } + + marqueeSelect() { + let selRect = this.Bounds; + let selection: Document[] = []; + this.props.activeDocuemnts().map(doc => { + var x = doc.GetNumber(KeyStore.X, 0); + var y = doc.GetNumber(KeyStore.Y, 0); + var w = doc.GetNumber(KeyStore.Width, 0); + var h = doc.GetNumber(KeyStore.Height, 0); + if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) + selection.push(doc) + }) + return selection; + } + + render() { + let p = this.props.getMarqueeTransform().transformPoint(this._downX < this._lastX ? this._downX : this._lastX, this._downY < this._lastY ? this._downY : this._lastY); + let v = this.props.getMarqueeTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY); + return (!this.props.container.MarqueeVisible ? (null) :
    ); + } +} \ No newline at end of file diff --git a/src/client/views/collections/PreviewCursor.scss b/src/client/views/collections/PreviewCursor.scss new file mode 100644 index 000000000..a797411f6 --- /dev/null +++ b/src/client/views/collections/PreviewCursor.scss @@ -0,0 +1,18 @@ + +.previewCursor { + color: black; + position: absolute; + transform-origin: left top; + pointer-events: none; +} + +//this is an animation for the blinking cursor! +@keyframes blink { + 0% {opacity: 0} + 49%{opacity: 0} + 50% {opacity: 1} +} + +#previewCursor { + animation: blink 1s infinite; +} \ No newline at end of file diff --git a/src/client/views/collections/PreviewCursor.tsx b/src/client/views/collections/PreviewCursor.tsx new file mode 100644 index 000000000..ab68fbc46 --- /dev/null +++ b/src/client/views/collections/PreviewCursor.tsx @@ -0,0 +1,76 @@ +import { trace } from "mobx"; +import "./PreviewCursor.scss"; +import React = require("react"); +import { action, IReactionDisposer, observable, reaction } from "mobx"; +import { observer } from "mobx-react"; +import { Document } from "../../../fields/Document"; +import { FieldWaiting, Opt } from "../../../fields/Field"; +import { KeyStore } from "../../../fields/KeyStore"; +import { ListField } from "../../../fields/ListField"; +import { Documents } from "../../documents/Documents"; +import { SelectionManager } from "../../util/SelectionManager"; +import { Transform } from "../../util/Transform"; +import { CollectionFreeFormView } from "./CollectionFreeFormView"; + + +export interface PreviewCursorProps { + getTransform: () => Transform; + container: CollectionFreeFormView; + addLiveTextDocuemnt: (doc: Document) => void; +} + +@observer +export class PreviewCursor extends React.Component { + private _reactionDisposer: Opt; + + @observable _lastX: number = 0; + @observable _lastY: number = 0; + + componentDidMount() { + this._reactionDisposer = reaction( + () => this.props.container.PreviewCursorVisible, + (visible: boolean) => this.onCursorPlaced(visible, this.props.container.DownX, this.props.container.DownY)) + } + componentWillUnmount() { + if (this._reactionDisposer) { + this._reactionDisposer(); + } + this.cleanupInteractions(); + } + + + @action + cleanupInteractions = () => { + document.removeEventListener("keypress", this.onKeyPress, true); + } + + @action + onCursorPlaced = (visible: boolean, downX: number, downY: number): void => { + if (visible) { + document.addEventListener("keypress", this.onKeyPress, true); + this._lastX = downX; + this._lastY = downY; + } else + this.cleanupInteractions(); + } + + @action + onKeyPress = (e: KeyboardEvent) => { + //if not these keys, make a textbox if preview cursor is active! + if (!e.ctrlKey && !e.altKey) { + //make textbox and add it to this collection + let [x, y] = this.props.getTransform().transformPoint(this._lastX, this._lastY); + let newBox = Documents.TextDocument({ width: 200, height: 100, x: x, y: y, title: "new" }); + this.props.addLiveTextDocuemnt(newBox); + } + } + + render() { + //get local position and place cursor there! + let [x, y] = this.props.getTransform().transformPoint(this._lastX, this._lastY); + return ( + !this.props.container.PreviewCursorVisible ? (null) : +
    I
    ) + + } +} \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ea39e2ac0..77aadabdf 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,4 +1,4 @@ -import { action, computed, IReactionDisposer, runInAction, reaction } from "mobx"; +import { action, computed, IReactionDisposer, runInAction, reaction, trace } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; import { Field, FieldWaiting, Opt } from "../../../fields/Field"; @@ -13,6 +13,7 @@ import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView, CollectionViewType } from "../collections/CollectionView"; import { CollectionPDFView } from "../collections/CollectionPDFView"; +import { CollectionVideoView } from "../collections/CollectionVideoView"; import { ContextMenu } from "../ContextMenu"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; @@ -275,9 +276,10 @@ export class DocumentView extends React.Component { SelectionManager.SelectDoc(this, e.ctrlKey); } + @computed get mainContent() { return { } render() { - if (!this.props.Document) return
    + if (!this.props.Document) { + return (null); + } let lkeys = this.props.Document.GetT(KeyStore.LayoutKeys, ListField); if (!lkeys || lkeys === "") { return

    Error loading layout keys

    ; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 30910fb1f..f4417248c 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,5 +1,5 @@ -import { action, observable } from 'mobx'; +import { action, observable, trace } from 'mobx'; import { observer } from "mobx-react"; import Lightbox from 'react-image-lightbox'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app @@ -98,6 +98,7 @@ export class ImageBox extends React.Component { } render() { + trace(); let field = this.props.doc.Get(this.props.fieldKey); let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : field instanceof ImageField ? field.Data.href : "http://www.cs.brown.edu/~bcz/face.gif"; diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 368a80b8e..544af41a2 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -1,5 +1,5 @@ import * as htmlToImage from "html-to-image"; -import { action, computed, observable, reaction, IReactionDisposer } from 'mobx'; +import { action, computed, observable, reaction, IReactionDisposer, trace } from 'mobx'; import { observer } from "mobx-react"; import 'react-image-lightbox/style.css'; import Measure from "react-measure"; diff --git a/src/client/views/nodes/VideoBox.scss b/src/client/views/nodes/VideoBox.scss index 7306450d9..76bbeb37c 100644 --- a/src/client/views/nodes/VideoBox.scss +++ b/src/client/views/nodes/VideoBox.scss @@ -1,4 +1,4 @@ .videobox-cont{ width: 100%; - height: 100%; + height: Auto; } \ No newline at end of file diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 22ff5c5ad..d6c856d3b 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -1,12 +1,13 @@ import React = require("react") -import { FieldViewProps, FieldView } from './FieldView'; +import { observer } from "mobx-react"; import { FieldWaiting } from '../../../fields/Field'; -import { observer } from "mobx-react" -import { VideoField } from '../../../fields/VideoField'; -import "./VideoBox.scss" -import { ContextMenu } from "../../views/ContextMenu"; -import { observable, action } from 'mobx'; -import { KeyStore } from '../../../fields/KeyStore'; +import { VideoField } from '../../../fields/VideoField'; +import { FieldView, FieldViewProps } from './FieldView'; +import "./VideoBox.scss"; +import Measure from "react-measure"; +import { action, trace, observable } from "mobx"; +import { KeyStore } from "../../../fields/KeyStore"; +import { number } from "prop-types"; @observer export class VideoBox extends React.Component { @@ -17,26 +18,46 @@ export class VideoBox extends React.Component { super(props); } - - componentDidMount() { - } + _loaded: boolean = false; - componentWillUnmount() { + @action + setScaling = (r: any) => { + if (this._loaded) { + // bcz: the nativeHeight should really be set when the document is imported. + // also, the native dimensions could be different for different pages of the PDF + // so this design is flawed. + var nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 0); + var nativeHeight = this.props.doc.GetNumber(KeyStore.NativeHeight, 0); + var newNativeHeight = nativeWidth * r.entry.height / r.entry.width; + if (newNativeHeight != nativeHeight && !isNaN(newNativeHeight)) { + this.props.doc.SetNumber(KeyStore.Height, newNativeHeight / nativeWidth * this.props.doc.GetNumber(KeyStore.Width, 0)); + this.props.doc.SetNumber(KeyStore.NativeHeight, newNativeHeight); + } + } else { + this._loaded = true; + } } - + + render() { + trace(); let field = this.props.doc.Get(this.props.fieldKey) - let path = field == FieldWaiting ? "http://techslides.com/demos/sample-videos/small.mp4": + let path = field == FieldWaiting ? "http://techslides.com/demos/sample-videos/small.mp4" : field instanceof VideoField ? field.Data.href : "http://techslides.com/demos/sample-videos/small.mp4"; - + + //setTimeout(action(() => this._loaded = true), 500); return ( -
    - +
    + + {({ measureRef }) => + + } +
    ) } diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index f93a68c85..6481e14fe 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -33,6 +33,7 @@ export namespace KeyStore { export const LinkTags = new Key("LinkTag"); export const Thumbnail = new Key("Thumbnail"); export const CurPage = new Key("CurPage"); + export const CurFrame = new Key("CurFrame"); export const NumPages = new Key("NumPages"); export const Ink = new Key("Ink"); } -- cgit v1.2.3-70-g09d2 From e7442d33d959f36f92fdcc12ad85f68d1d9ee4ca Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 13 Mar 2019 15:18:20 -0400 Subject: from last --- src/client/views/nodes/ImageBox.tsx | 1 - src/client/views/nodes/VideoBox.tsx | 1 - 2 files changed, 2 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index f4417248c..bceeedbc6 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -98,7 +98,6 @@ export class ImageBox extends React.Component { } render() { - trace(); let field = this.props.doc.Get(this.props.fieldKey); let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : field instanceof ImageField ? field.Data.href : "http://www.cs.brown.edu/~bcz/face.gif"; diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index d6c856d3b..9c60d4348 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -42,7 +42,6 @@ export class VideoBox extends React.Component { render() { - trace(); let field = this.props.doc.Get(this.props.fieldKey) let path = field == FieldWaiting ? "http://techslides.com/demos/sample-videos/small.mp4" : field instanceof VideoField ? field.Data.href : "http://techslides.com/demos/sample-videos/small.mp4"; -- cgit v1.2.3-70-g09d2 From 6a3407a2d70542752305e4360fec0dffcc1a2dfa Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Wed, 13 Mar 2019 16:32:20 -0400 Subject: Made document contents class --- src/client/views/nodes/DocumentView.tsx | 63 ++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 77aadabdf..a91d2071b 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -85,10 +85,27 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs { return args; } +interface JsxBindings { + Document: Document; + layout: string; + [prop: string]: any; +} + +export class DocumentContents extends React.PureComponent { + render() { + return { console.log(test) }} + /> + } +} + @observer export class DocumentView extends React.Component { private _mainCont = React.createRef(); - private _documentBindings: any = null; private _downX: number = 0; private _downY: number = 0; private _reactionDisposer: Opt; @@ -276,16 +293,6 @@ export class DocumentView extends React.Component { SelectionManager.SelectDoc(this, e.ctrlKey); } - @computed - get mainContent() { - return { console.log(test) }} - /> - } isSelected = () => { return SelectionManager.IsSelected(this); @@ -295,28 +302,34 @@ export class DocumentView extends React.Component { SelectionManager.SelectDoc(this, ctrlPressed) } - render() { - if (!this.props.Document) { - return (null); - } - let lkeys = this.props.Document.GetT(KeyStore.LayoutKeys, ListField); - if (!lkeys || lkeys === "") { - return

    Error loading layout keys

    ; - } - this._documentBindings = { + @computed + get getProps() { + let bindings: any = { ...this.props, isSelected: this.isSelected, select: this.select, - focus: this.props.focus + layout: this.layout }; for (const key of this.layoutKeys) { - this._documentBindings[key.Name + "Key"] = key; // this maps string values of the form Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data + bindings[key.Name + "Key"] = key; // this maps string values of the form Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data } for (const key of this.layoutFields) { let field = this.props.Document.Get(key); - this._documentBindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field; + bindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field; + } + bindings.bindings = bindings; + + return bindings + } + + render() { + if (!this.props.Document) { + return (null); + } + let lkeys = this.props.Document.GetT(KeyStore.LayoutKeys, ListField); + if (!lkeys || lkeys === "") { + return

    Error loading layout keys

    ; } - this._documentBindings.bindings = this._documentBindings; var scaling = this.props.ContentScaling(); var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0); var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0); @@ -330,7 +343,7 @@ export class DocumentView extends React.Component { }} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} > - {this.mainContent} +
    ) } -- cgit v1.2.3-70-g09d2 From b8c0dc61d535caeb2142678dffea2a841776e3a8 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 13 Mar 2019 16:39:45 -0400 Subject: moved DocumentContents into DocumentContentsView file. --- src/client/views/nodes/DocumentContentsView.tsx | 35 ++++++++++++++++++++++ src/client/views/nodes/DocumentView.tsx | 40 ++++--------------------- 2 files changed, 41 insertions(+), 34 deletions(-) create mode 100644 src/client/views/nodes/DocumentContentsView.tsx (limited to 'src') diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx new file mode 100644 index 000000000..55b4938a0 --- /dev/null +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -0,0 +1,35 @@ +import { Document } from "../../../fields/Document"; +import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; +import { CollectionDockingView } from "../collections/CollectionDockingView"; +import { CollectionSchemaView } from "../collections/CollectionSchemaView"; +import { CollectionView, CollectionViewType } from "../collections/CollectionView"; +import { CollectionPDFView } from "../collections/CollectionPDFView"; +import { CollectionVideoView } from "../collections/CollectionVideoView"; +import { FormattedTextBox } from "../nodes/FormattedTextBox"; +import { ImageBox } from "../nodes/ImageBox"; +import { VideoBox } from "../nodes/VideoBox"; +import { AudioBox } from "../nodes/AudioBox"; +import { KeyValueBox } from "./KeyValueBox" +import { WebBox } from "../nodes/WebBox"; +import { PDFBox } from "../nodes/PDFBox"; +import "./DocumentView.scss"; +import React = require("react"); +const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? + +interface JsxBindings { + Document: Document; + layout: string; + [prop: string]: any; +} + +export class DocumentContentsView extends React.PureComponent { + render() { + return { console.log(test) }} + /> + } +} \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index a91d2071b..8cd406d7d 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,32 +1,22 @@ -import { action, computed, IReactionDisposer, runInAction, reaction, trace } from "mobx"; +import { action, computed, IReactionDisposer, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; import { Field, FieldWaiting, Opt } from "../../../fields/Field"; import { Key } from "../../../fields/Key"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; +import { TextField } from "../../../fields/TextField"; +import { Documents } from "../../documents/Documents"; +import { DocumentManager } from "../../util/DocumentManager"; import { DragManager } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { Transform } from "../../util/Transform"; import { CollectionDockingView } from "../collections/CollectionDockingView"; -import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; -import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView, CollectionViewType } from "../collections/CollectionView"; -import { CollectionPDFView } from "../collections/CollectionPDFView"; -import { CollectionVideoView } from "../collections/CollectionVideoView"; import { ContextMenu } from "../ContextMenu"; -import { FormattedTextBox } from "../nodes/FormattedTextBox"; -import { ImageBox } from "../nodes/ImageBox"; -import { VideoBox } from "../nodes/VideoBox"; -import { AudioBox } from "../nodes/AudioBox"; -import { Documents } from "../../documents/Documents" -import { KeyValueBox } from "./KeyValueBox" -import { WebBox } from "../nodes/WebBox"; -import { PDFBox } from "../nodes/PDFBox"; import "./DocumentView.scss"; import React = require("react"); -import { TextField } from "../../../fields/TextField"; -import { DocumentManager } from "../../util/DocumentManager"; +import { DocumentContentsView } from "./DocumentContentsView"; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? @@ -85,24 +75,6 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs { return args; } -interface JsxBindings { - Document: Document; - layout: string; - [prop: string]: any; -} - -export class DocumentContents extends React.PureComponent { - render() { - return { console.log(test) }} - /> - } -} - @observer export class DocumentView extends React.Component { private _mainCont = React.createRef(); @@ -343,7 +315,7 @@ export class DocumentView extends React.Component { }} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} > - +
    ) } -- cgit v1.2.3-70-g09d2 From 41f458fb4f383bfbf8d5b651189c2f4731262ff8 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 13 Mar 2019 20:33:51 -0400 Subject: added annotations for videos. added custom play controls for videos. --- src/client/documents/Documents.ts | 5 +- src/client/views/InkingCanvas.tsx | 6 +- .../views/collections/CollectionFreeFormView.tsx | 8 +-- src/client/views/collections/CollectionPDFView.tsx | 13 ++-- .../views/collections/CollectionVideoView.scss | 35 +++++++++ .../views/collections/CollectionVideoView.tsx | 83 +++++++++++++++++++--- src/client/views/collections/CollectionView.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 2 +- src/client/views/nodes/VideoBox.tsx | 2 +- src/fields/KeyStore.ts | 1 - 10 files changed, 126 insertions(+), 31 deletions(-) create mode 100644 src/client/views/collections/CollectionVideoView.scss (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f35d553b1..15e16a491 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -23,6 +23,7 @@ import { PDFField } from "../../fields/PDFField"; import { PDFBox } from "../views/nodes/PDFBox"; import { CollectionPDFView } from "../views/collections/CollectionPDFView"; import { RichTextField } from "../../fields/RichTextField"; +import { CollectionVideoView } from "../views/collections/CollectionVideoView"; export interface DocumentOptions { x?: number; @@ -138,9 +139,9 @@ export namespace Documents { } function GetVideoPrototype(): Document { if (!videoProto) { - videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionView.LayoutString("AnnotationsKey"), + videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("AnnotationsKey"), { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] }); - videoProto.SetNumber(KeyStore.CurFrame, 1); + videoProto.SetNumber(KeyStore.CurPage, 0); videoProto.SetText(KeyStore.BackgroundLayout, VideoBox.LayoutString()); } return videoProto; diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx index 0d87c1239..064d1cba2 100644 --- a/src/client/views/InkingCanvas.tsx +++ b/src/client/views/InkingCanvas.tsx @@ -74,7 +74,7 @@ export class InkingCanvas extends React.Component { color: InkingControl.Instance.selectedColor, width: InkingControl.Instance.selectedWidth, tool: InkingControl.Instance.selectedTool, - page: this.props.Document.GetNumber(KeyStore.CurPage, 0) + page: this.props.Document.GetNumber(KeyStore.CurPage, -1) }); this.inkData = data; this._isDrawing = true; @@ -145,11 +145,11 @@ export class InkingCanvas extends React.Component { // parse data from server let paths: Array = [] - let curPage = this.props.Document.GetNumber(KeyStore.CurPage, 0) + let curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1) Array.from(lines).map(item => { let id = item[0]; let strokeData = item[1]; - if (strokeData.page == 0 || strokeData.page == curPage) + if (strokeData.page == -1 || strokeData.page == curPage) paths.push( { - var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1); + var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1); const lvalue = this.props.Document.GetT>(this.props.fieldKey, ListField); let active: Document[] = []; if (lvalue && lvalue != FieldWaiting) { lvalue.Data.map(doc => { - var page = doc.GetNumber(KeyStore.Page, 0); - if (page == curPage || page == 0) { + var page = doc.GetNumber(KeyStore.Page, -1); + if (page == curPage || page == -1) { active.push(doc); } }) @@ -257,7 +257,7 @@ export class CollectionFreeFormView extends CollectionViewBase { @computed get views() { - var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1); + var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1); const lvalue = this.props.Document.GetT>(this.props.fieldKey, ListField); if (lvalue && lvalue != FieldWaiting) { return lvalue.Data.map(doc => { diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx index f22c07060..91ffc9500 100644 --- a/src/client/views/collections/CollectionPDFView.tsx +++ b/src/client/views/collections/CollectionPDFView.tsx @@ -18,13 +18,12 @@ export class CollectionPDFView extends React.Component { isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`; } - public SelectedDocs: FieldId[] = [] - @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : 0; - @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : 0; + private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, -1); } + private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); } + @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : -1; + @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : -1; - @computed private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, 0); } - @computed private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); } - @computed private get uIButtons() { + private get uIButtons() { return (
    @@ -33,7 +32,7 @@ export class CollectionPDFView extends React.Component { } // "inherited" CollectionView API starts here... - + public SelectedDocs: FieldId[] = [] public active: () => boolean = () => CollectionView.Active(this); addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); } diff --git a/src/client/views/collections/CollectionVideoView.scss b/src/client/views/collections/CollectionVideoView.scss new file mode 100644 index 000000000..6c2f5a62a --- /dev/null +++ b/src/client/views/collections/CollectionVideoView.scss @@ -0,0 +1,35 @@ +.collectionVideoView-controls{ + width: 100%; + height: 100%; + position: absolute; +} +.collectionVideoView-time{ + color : white; + top :25px; + left : 25px; + position: absolute; + background-color: rgba(50, 50, 50, 0.2); +} +.collectionVideoView-play { + width: 25px; + height: 20px; + bottom: 25px; + left : 25px; + position: absolute; + color : white; + background-color: rgba(50, 50, 50, 0.2); + border-radius: 4px; + text-align: center; +} +.collectionVideoView-full { + width: 25px; + height: 20px; + bottom: 25px; + right : 25px; + position: absolute; + color : white; + background-color: rgba(50, 50, 50, 0.2); + border-radius: 4px; + text-align: center; + +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx index a6471f53c..058325b21 100644 --- a/src/client/views/collections/CollectionVideoView.tsx +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -1,4 +1,4 @@ -import { action, computed } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; import { KeyStore } from "../../../fields/KeyStore"; @@ -7,6 +7,8 @@ import { CollectionView, CollectionViewType } from "./CollectionView"; import { CollectionViewProps } from "./CollectionViewBase"; import React = require("react"); import { FieldId } from "../../../fields/Field"; +import { ReplaceAroundStep } from "prosemirror-transform"; +import "./CollectionVideoView.scss" @observer @@ -18,14 +20,10 @@ export class CollectionVideoView extends React.Component { isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`; } - public SelectedDocs: FieldId[] = [] - @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : 0; - @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : 0; - - @computed private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, 0); } - @computed private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); } + private _mainCont = React.createRef(); // "inherited" CollectionView API starts here... + public SelectedDocs: FieldId[] = [] public active: () => boolean = () => CollectionView.Active(this); addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); } @@ -40,11 +38,74 @@ export class CollectionVideoView extends React.Component { get collectionViewType(): CollectionViewType { return CollectionViewType.Freeform; } get subView(): any { return CollectionView.SubView(this); } + componentDidMount() { + this.repete(); + } + + player = (): HTMLVideoElement => { + return this._mainCont.current!.getElementsByTagName("video")[0]; + } + + @action + repete = () => { + if (this.player()) { + this.ctime = this.player().currentTime; + this.props.Document.SetNumber(KeyStore.CurPage, Math.round(this.ctime)); + } + setTimeout(() => this.repete(), 100) + } + + + @observable + ctime: number = 0 + @observable + playing: boolean = false; + + @action + onPlayDown = () => { + if (this.player()) { + if (this.player().paused) { + this.player().play(); + this.playing = true; + } else { + this.player().pause(); + this.playing = false; + } + } + } + @action + onFullDown = (e: React.PointerEvent) => { + if (this.player()) { + this.player().requestFullscreen(); + e.stopPropagation(); + e.preventDefault(); + } + } + + @action + onResetDown = () => { + if (this.player()) { + this.player().pause(); + this.player().currentTime = 0; + } + + } + render() { - return (
    - {/* */} + return (
    +
    + {this.subView} +
    + {"" + Math.round(this.ctime)} + {" " + Math.round((this.ctime - Math.trunc(this.ctime)) * 100)} +
    +
    + {this.playing ? "\"" : ">"} +
    +
    + F +
    +
    ) } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 17a0fbd23..bbb4a5d83 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -50,7 +50,7 @@ export class CollectionView extends React.Component { @action public static AddDocument(props: CollectionViewProps, doc: Document) { - doc.SetNumber(KeyStore.Page, props.Document.GetNumber(KeyStore.CurPage, 0)); + doc.SetNumber(KeyStore.Page, props.Document.GetNumber(KeyStore.CurPage, -1)); if (props.Document.Get(props.fieldKey) instanceof Field) { //TODO This won't create the field if it doesn't already exist const value = props.Document.GetData(props.fieldKey, ListField, new Array()) diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 544af41a2..b0b5a63a4 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -86,7 +86,7 @@ export class PDFBox extends React.Component { @observable private _interactive: boolean = false; @observable private _loaded: boolean = false; - @computed private get curPage() { return this.props.doc.GetNumber(KeyStore.CurPage, 0); } + @computed private get curPage() { return this.props.doc.GetNumber(KeyStore.CurPage, -1); } componentDidMount() { this._reactionDisposer = reaction( diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 9c60d4348..053d9dd56 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -51,7 +51,7 @@ export class VideoBox extends React.Component {
    {({ measureRef }) => -
    diff --git a/src/client/views/collections/CollectionPDFView.scss b/src/client/views/collections/CollectionPDFView.scss new file mode 100644 index 000000000..28878c6fa --- /dev/null +++ b/src/client/views/collections/CollectionPDFView.scss @@ -0,0 +1,28 @@ +.collectionPdfView-buttonTray { + width: 100%; + height: 100%; + top : 25px; + left : 20px; + position: relative; + transform-origin: left top; + position: absolute; +} +.collectionPdfView-cont{ + width: 100%; + height: 100%; + position: absolute; +} +.collectionPdfView-backward { + color : white; + top :0px; + left : 0px; + position: absolute; + background-color: rgba(50, 50, 50, 0.2); +} +.collectionPdfView-forward { + color : white; + top :0px; + left : 25px; + position: absolute; + background-color: rgba(50, 50, 50, 0.2); +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx index be3a281f2..124d82c8b 100644 --- a/src/client/views/collections/CollectionPDFView.tsx +++ b/src/client/views/collections/CollectionPDFView.tsx @@ -5,6 +5,7 @@ import { KeyStore } from "../../../fields/KeyStore"; import { ContextMenu } from "../ContextMenu"; import { CollectionView, CollectionViewType } from "./CollectionView"; import { CollectionViewProps } from "./CollectionViewBase"; +import "./CollectionPDFView.scss" import React = require("react"); import { FieldId } from "../../../fields/Field"; @@ -24,10 +25,11 @@ export class CollectionPDFView extends React.Component { @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : -1; private get uIButtons() { + let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().transformDirection(1, 1)[0]); return ( -
    - - +
    + +
    ); } @@ -49,7 +51,7 @@ export class CollectionPDFView extends React.Component { get subView(): any { return CollectionView.SubView(this); } render() { - return (
    + return (
    {this.subView} {this.props.isSelected() ? this.uIButtons : (null)}
    ) diff --git a/src/client/views/collections/CollectionVideoView.scss b/src/client/views/collections/CollectionVideoView.scss index 6c2f5a62a..ec3c0327d 100644 --- a/src/client/views/collections/CollectionVideoView.scss +++ b/src/client/views/collections/CollectionVideoView.scss @@ -1,4 +1,9 @@ -.collectionVideoView-controls{ +.collectionVideoView-buttonTray{ + width: 100%; + height: 100%; + position: absolute; +} +.collectionVideoView-cont{ width: 100%; height: 100%; position: absolute; @@ -9,6 +14,7 @@ left : 25px; position: absolute; background-color: rgba(50, 50, 50, 0.2); + transform-origin: left top; } .collectionVideoView-play { width: 25px; @@ -20,6 +26,7 @@ background-color: rgba(50, 50, 50, 0.2); border-radius: 4px; text-align: center; + transform-origin: left bottom; } .collectionVideoView-full { width: 25px; @@ -31,5 +38,6 @@ background-color: rgba(50, 50, 50, 0.2); border-radius: 4px; text-align: center; + transform-origin: right bottom; } \ No newline at end of file diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx index 9856a1284..9b01c23c9 100644 --- a/src/client/views/collections/CollectionVideoView.tsx +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -7,7 +7,6 @@ import { CollectionView, CollectionViewType } from "./CollectionView"; import { CollectionViewProps } from "./CollectionViewBase"; import React = require("react"); import { FieldId } from "../../../fields/Field"; -import { ReplaceAroundStep } from "prosemirror-transform"; import "./CollectionVideoView.scss" @@ -21,6 +20,25 @@ export class CollectionVideoView extends React.Component { } private _mainCont = React.createRef(); + + private get uIButtons() { + let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().transformDirection(1, 1)[0]); + return ( +
    +
    + {"" + Math.round(this.ctime)} + {" " + Math.round((this.ctime - Math.trunc(this.ctime)) * 100)} +
    +
    + {this.playing ? "\"" : ">"} +
    +
    + F +
    +
    ); + } + + // "inherited" CollectionView API starts here... @observable @@ -40,20 +58,20 @@ export class CollectionVideoView extends React.Component { get subView(): any { return CollectionView.SubView(this); } componentDidMount() { - this.repete(); + this.updateTimecode(); } - player = (): HTMLVideoElement => { - return this._mainCont.current!.getElementsByTagName("video")[0]; + get player(): HTMLVideoElement | undefined { + return this._mainCont.current ? this._mainCont.current.getElementsByTagName("video")[0] : undefined; } @action - repete = () => { - if (this.player()) { - this.ctime = this.player().currentTime; + updateTimecode = () => { + if (this.player) { + this.ctime = this.player.currentTime; this.props.Document.SetNumber(KeyStore.CurPage, Math.round(this.ctime)); } - setTimeout(() => this.repete(), 100) + setTimeout(() => this.updateTimecode(), 100) } @@ -64,20 +82,20 @@ export class CollectionVideoView extends React.Component { @action onPlayDown = () => { - if (this.player()) { - if (this.player().paused) { - this.player().play(); + if (this.player) { + if (this.player.paused) { + this.player.play(); this.playing = true; } else { - this.player().pause(); + this.player.pause(); this.playing = false; } } } @action onFullDown = (e: React.PointerEvent) => { - if (this.player()) { - this.player().requestFullscreen(); + if (this.player) { + this.player.requestFullscreen(); e.stopPropagation(); e.preventDefault(); } @@ -85,28 +103,17 @@ export class CollectionVideoView extends React.Component { @action onResetDown = () => { - if (this.player()) { - this.player().pause(); - this.player().currentTime = 0; + if (this.player) { + this.player.pause(); + this.player.currentTime = 0; } } render() { return (
    -
    - {this.subView} -
    - {"" + Math.round(this.ctime)} - {" " + Math.round((this.ctime - Math.trunc(this.ctime)) * 100)} -
    -
    - {this.playing ? "\"" : ">"} -
    -
    - F -
    -
    + {this.subView} + {this.uIButtons}
    ) } } \ No newline at end of file diff --git a/src/client/views/collections/PreviewCursor.tsx b/src/client/views/collections/PreviewCursor.tsx index ab68fbc46..a1411250a 100644 --- a/src/client/views/collections/PreviewCursor.tsx +++ b/src/client/views/collections/PreviewCursor.tsx @@ -16,7 +16,7 @@ import { CollectionFreeFormView } from "./CollectionFreeFormView"; export interface PreviewCursorProps { getTransform: () => Transform; container: CollectionFreeFormView; - addLiveTextDocuemnt: (doc: Document) => void; + addLiveTextDocument: (doc: Document) => void; } @observer @@ -57,11 +57,13 @@ export class PreviewCursor extends React.Component { @action onKeyPress = (e: KeyboardEvent) => { //if not these keys, make a textbox if preview cursor is active! - if (!e.ctrlKey && !e.altKey) { + if (!e.ctrlKey && !e.altKey && !e.defaultPrevented) { //make textbox and add it to this collection let [x, y] = this.props.getTransform().transformPoint(this._lastX, this._lastY); let newBox = Documents.TextDocument({ width: 200, height: 100, x: x, y: y, title: "new" }); - this.props.addLiveTextDocuemnt(newBox); + this.props.addLiveTextDocument(newBox); + e.stopPropagation(); + e.preventDefault(); } } diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index 9f92410d4..ad947afd5 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -11,5 +11,5 @@ } .pdfBox-contentContainer { position: absolute; - transform-origin: "left top"; + transform-origin: left top; } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From f5ae101d3faa696379aae2b2573c1f073f11621d Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 14 Mar 2019 10:22:17 -0400 Subject: fixed schema scroll --- src/client/views/collections/CollectionPDFView.scss | 2 -- src/client/views/collections/CollectionSchemaView.scss | 7 ++++++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionPDFView.scss b/src/client/views/collections/CollectionPDFView.scss index 28878c6fa..cc1402498 100644 --- a/src/client/views/collections/CollectionPDFView.scss +++ b/src/client/views/collections/CollectionPDFView.scss @@ -1,6 +1,4 @@ .collectionPdfView-buttonTray { - width: 100%; - height: 100%; top : 25px; left : 20px; position: relative; diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index c4e6528e5..1c58c0cd8 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -8,10 +8,15 @@ height: 100%; .collectionSchemaView-previewRegion { position: relative; - background: black; float: left; height: 100%; } + .collectionSchemaView-content { + position: absolute; + height:100%; + width:100%; + overflow:auto; + } .collectionSchemaView-previewHandle { position: absolute; height: 37px; -- cgit v1.2.3-70-g09d2 From 0eca487586cb52f8d729479f50f9f8d40484998d Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 14 Mar 2019 10:34:12 -0400 Subject: fixed video controls layout --- src/client/views/collections/CollectionFreeFormView.scss | 1 + src/client/views/collections/CollectionPDFView.scss | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss index 2ec0dc371..a00c01898 100644 --- a/src/client/views/collections/CollectionFreeFormView.scss +++ b/src/client/views/collections/CollectionFreeFormView.scss @@ -41,6 +41,7 @@ background: $light-color-secondary; } + position:absolute; border: 0px solid transparent; border-radius: $border-radius; box-sizing: border-box; diff --git a/src/client/views/collections/CollectionPDFView.scss b/src/client/views/collections/CollectionPDFView.scss index cc1402498..107f9bbbe 100644 --- a/src/client/views/collections/CollectionPDFView.scss +++ b/src/client/views/collections/CollectionPDFView.scss @@ -20,7 +20,7 @@ .collectionPdfView-forward { color : white; top :0px; - left : 25px; + left : 35px; position: absolute; background-color: rgba(50, 50, 50, 0.2); } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 09e895c0aceaa4227cfbbe3a70f07f1ded486a1f Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 14 Mar 2019 10:40:27 -0400 Subject: don't know why the z-index needs to be -1 for the controls to show up in a schema view... --- src/client/views/collections/CollectionPDFView.scss | 3 +++ src/client/views/collections/CollectionVideoView.scss | 3 +++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/client/views/collections/CollectionPDFView.scss b/src/client/views/collections/CollectionPDFView.scss index 107f9bbbe..152c0dd23 100644 --- a/src/client/views/collections/CollectionPDFView.scss +++ b/src/client/views/collections/CollectionPDFView.scss @@ -9,6 +9,9 @@ width: 100%; height: 100%; position: absolute; + .collectionfreeformview-overlay { + z-index: -1; + } } .collectionPdfView-backward { color : white; diff --git a/src/client/views/collections/CollectionVideoView.scss b/src/client/views/collections/CollectionVideoView.scss index ec3c0327d..442e3837e 100644 --- a/src/client/views/collections/CollectionVideoView.scss +++ b/src/client/views/collections/CollectionVideoView.scss @@ -7,6 +7,9 @@ width: 100%; height: 100%; position: absolute; + .collectionfreeformview-overlay { + z-index: -1; + } } .collectionVideoView-time{ color : white; -- cgit v1.2.3-70-g09d2 From a3678862b48d6bb44f37533b827d290c883ce542 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 14 Mar 2019 16:54:48 -0400 Subject: added a background color --- src/client/documents/Documents.ts | 2 ++ src/client/views/Main.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 ++ src/fields/KeyStore.ts | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 15e16a491..4e0eefcc6 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -40,6 +40,7 @@ export interface DocumentOptions { layout?: string; layoutKeys?: Key[]; viewType?: number; + backgroundColor?: string; } export namespace Documents { @@ -83,6 +84,7 @@ export namespace Documents { if (options.page !== undefined) { doc.SetNumber(KeyStore.Page, options.page); } if (options.scale !== undefined) { doc.SetNumber(KeyStore.Scale, options.scale); } if (options.viewType !== undefined) { doc.SetNumber(KeyStore.ViewType, options.viewType); } + if (options.backgroundColor !== undefined) { doc.SetText(KeyStore.BackgroundColor, options.backgroundColor); } if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); } if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); } return doc; diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index d73e9b8fe..8ee028076 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -58,7 +58,7 @@ Documents.initProtos(mainDocId, (res?: Document) => { let videourl = "http://techslides.com/demos/sample-videos/small.mp4"; let clearDatabase = action(() => Utils.Emit(Server.Socket, MessageStore.DeleteAll, {})) let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" })) - let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" })); + let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, backgroundColor: "Transparent", title: "a freeform collection" })); let addSchemaNode = action(() => Documents.SchemaDocument([Documents.TextDocument()], { width: 200, height: 200, title: "a schema collection" })); let addVideoNode = action(() => Documents.VideoDocument(videourl, { width: 200, title: "video node" })); let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 200, title: "a schema collection" })); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 8cd406d7d..4b50e40a3 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -305,9 +305,11 @@ export class DocumentView extends React.Component { var scaling = this.props.ContentScaling(); var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0); var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0); + var backgroundcolor = this.props.Document.GetText(KeyStore.BackgroundColor, ""); return (
    0 ? nativeWidth.toString() + "px" : "100%", height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%", transformOrigin: "left top", diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index f93a68c85..0c8b7e260 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -19,6 +19,7 @@ export namespace KeyStore { export const Annotations = new Key("Annotations"); export const ViewType = new Key("ViewType"); export const Layout = new Key("Layout"); + export const BackgroundColor = new Key("BackgroundColor"); export const BackgroundLayout = new Key("BackgroundLayout"); export const OverlayLayout = new Key("OverlayLayout"); export const LayoutKeys = new Key("LayoutKeys"); -- cgit v1.2.3-70-g09d2 From 05b23c6b94b47393ba4d34a393e5080f20aff099 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 14 Mar 2019 19:14:07 -0400 Subject: fixed scrollzooming on videos. --- .../views/collections/CollectionVideoView.scss | 6 +----- .../views/collections/CollectionVideoView.tsx | 23 +++++++++++----------- 2 files changed, 12 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionVideoView.scss b/src/client/views/collections/CollectionVideoView.scss index ec3c0327d..ddcd74616 100644 --- a/src/client/views/collections/CollectionVideoView.scss +++ b/src/client/views/collections/CollectionVideoView.scss @@ -1,8 +1,4 @@ -.collectionVideoView-buttonTray{ - width: 100%; - height: 100%; - position: absolute; -} + .collectionVideoView-cont{ width: 100%; height: 100%; diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx index 9b01c23c9..0e2d250aa 100644 --- a/src/client/views/collections/CollectionVideoView.tsx +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -23,19 +23,18 @@ export class CollectionVideoView extends React.Component { private get uIButtons() { let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().transformDirection(1, 1)[0]); - return ( -
    -
    - {"" + Math.round(this.ctime)} - {" " + Math.round((this.ctime - Math.trunc(this.ctime)) * 100)} + return ([ +
    + {"" + Math.round(this.ctime)} + {" " + Math.round((this.ctime - Math.trunc(this.ctime)) * 100)} +
    , +
    + {this.playing ? "\"" : ">"} +
    , +
    + F
    -
    - {this.playing ? "\"" : ">"} -
    -
    - F -
    -
    ); + ]); } -- cgit v1.2.3-70-g09d2 From f089e10dfd42edc395729a6b71e42385745f364e Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 14 Mar 2019 22:21:16 -0400 Subject: marquees can now delete ink or move it to a new collection. --- src/client/documents/Documents.ts | 3 ++ src/client/views/InkingCanvas.scss | 3 +- src/client/views/InkingCanvas.tsx | 22 +++++----- src/client/views/InkingStroke.tsx | 2 - src/client/views/Main.tsx | 2 +- .../views/collections/CollectionFreeFormView.tsx | 4 +- .../views/collections/CollectionVideoView.tsx | 6 +-- src/client/views/collections/MarqueeView.tsx | 47 +++++++++++++++++----- 8 files changed, 63 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 4e0eefcc6..8402118b8 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -24,10 +24,12 @@ import { PDFBox } from "../views/nodes/PDFBox"; import { CollectionPDFView } from "../views/collections/CollectionPDFView"; import { RichTextField } from "../../fields/RichTextField"; import { CollectionVideoView } from "../views/collections/CollectionVideoView"; +import { StrokeData, InkField } from "../../fields/InkField"; export interface DocumentOptions { x?: number; y?: number; + ink?: Map; width?: number; height?: number; nativeWidth?: number; @@ -87,6 +89,7 @@ export namespace Documents { if (options.backgroundColor !== undefined) { doc.SetText(KeyStore.BackgroundColor, options.backgroundColor); } if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); } if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); } + if (options.ink !== undefined) { doc.Set(KeyStore.Ink, new InkField(options.ink)); } return doc; } function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Document { diff --git a/src/client/views/InkingCanvas.scss b/src/client/views/InkingCanvas.scss index f654b194b..37fa3143d 100644 --- a/src/client/views/InkingCanvas.scss +++ b/src/client/views/InkingCanvas.scss @@ -1,8 +1,9 @@ .inking-canvas { - position: fixed; + position: absolute; top: -50000px; left: -50000px; // z-index: 99; //overlays ink on top of everything svg { + position:absolute; width: 100000px; height: 100000px; .highlight { diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx index 064d1cba2..84c47f616 100644 --- a/src/client/views/InkingCanvas.tsx +++ b/src/client/views/InkingCanvas.tsx @@ -1,4 +1,5 @@ import { observer } from "mobx-react"; +import { observable } from "mobx"; import { action, computed } from "mobx"; import { InkingControl } from "./InkingControl"; import React = require("react"); @@ -6,14 +7,10 @@ import { Transform } from "../util/Transform"; import { Document } from "../../fields/Document"; import { KeyStore } from "../../fields/KeyStore"; import { InkField, InkTool, StrokeData, StrokeMap } from "../../fields/InkField"; -import { JsxArgs } from "./nodes/DocumentView"; import { InkingStroke } from "./InkingStroke"; import "./InkingCanvas.scss" -import { CollectionDockingView } from "./collections/CollectionDockingView"; import { Utils } from "../../Utils"; import { FieldWaiting } from "../../fields/Field"; -import { getMapLikeKeys } from "mobx/lib/internal"; - interface InkCanvasProps { getScreenTransform: () => Transform; @@ -22,7 +19,16 @@ interface InkCanvasProps { @observer export class InkingCanvas extends React.Component { - + static InkOffset: number = 50000; + public static IntersectStrokeRect(stroke: StrokeData, selRect: { left: number, top: number, width: number, height: number }): boolean { + let inside = false; + stroke.pathData.map(val => { + if (selRect.left < val.x - InkingCanvas.InkOffset && selRect.left + selRect.width > val.x - InkingCanvas.InkOffset && + selRect.top < val.y - InkingCanvas.InkOffset && selRect.top + selRect.height > val.y - InkingCanvas.InkOffset) + inside = true; + }); + return inside + } private _isDrawing: boolean = false; private _idGenerator: string = ""; @@ -51,7 +57,6 @@ export class InkingCanvas extends React.Component { document.removeEventListener("mouseup", this.handleMouseUp); } - @action handleMouseDown = (e: React.PointerEvent): void => { if (e.button != 0 || @@ -62,7 +67,6 @@ export class InkingCanvas extends React.Component { if (InkingControl.Instance.selectedTool === InkTool.Eraser) { return } - e.stopPropagation() const point = this.relativeCoordinatesForEvent(e); // start the new line, saves a uuid to represent the field of the stroke @@ -110,8 +114,8 @@ export class InkingCanvas extends React.Component { relativeCoordinatesForEvent = (e: React.MouseEvent): { x: number, y: number } => { let [x, y] = this.props.getScreenTransform().transformPoint(e.clientX, e.clientY); - x += 50000 - y += 50000 + x += InkingCanvas.InkOffset; + y += InkingCanvas.InkOffset; return { x, y }; } diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index d724421d3..87b5c43d8 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -21,8 +21,6 @@ export class InkingStroke extends React.Component { @observable private _strokeColor: string = this.props.color; @observable private _strokeWidth: string = this.props.width; - private _canvasColor: string = "#cdcdcd"; - deleteStroke = (e: React.MouseEvent): void => { if (InkingControl.Instance.selectedTool === InkTool.Eraser && e.buttons === 1) { this.props.deleteCallback(this.props.id); diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 8ee028076..d73e9b8fe 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -58,7 +58,7 @@ Documents.initProtos(mainDocId, (res?: Document) => { let videourl = "http://techslides.com/demos/sample-videos/small.mp4"; let clearDatabase = action(() => Utils.Emit(Server.Socket, MessageStore.DeleteAll, {})) let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" })) - let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, backgroundColor: "Transparent", title: "a freeform collection" })); + let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" })); let addSchemaNode = action(() => Documents.SchemaDocument([Documents.TextDocument()], { width: 200, height: 200, title: "a schema collection" })); let addVideoNode = action(() => Documents.VideoDocument(videourl, { width: 200, title: "video node" })); let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 200, title: "a schema collection" })); diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 98fb23fa4..c8b745254 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -338,7 +338,9 @@ export class CollectionFreeFormView extends CollectionViewBase { {this.views}
    - + {this.overlayView}
    ); diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx index 0e2d250aa..b64ef3c07 100644 --- a/src/client/views/collections/CollectionVideoView.tsx +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -24,14 +24,14 @@ export class CollectionVideoView extends React.Component { private get uIButtons() { let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().transformDirection(1, 1)[0]); return ([ -
    +
    {"" + Math.round(this.ctime)} {" " + Math.round((this.ctime - Math.trunc(this.ctime)) * 100)}
    , -
    +
    {this.playing ? "\"" : ">"}
    , -
    +
    F
    ]); diff --git a/src/client/views/collections/MarqueeView.tsx b/src/client/views/collections/MarqueeView.tsx index d9e4df1e9..67716f99a 100644 --- a/src/client/views/collections/MarqueeView.tsx +++ b/src/client/views/collections/MarqueeView.tsx @@ -3,21 +3,22 @@ import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; import { FieldWaiting, Opt } from "../../../fields/Field"; import { KeyStore } from "../../../fields/KeyStore"; -import { ListField } from "../../../fields/ListField"; import { Documents } from "../../documents/Documents"; import { SelectionManager } from "../../util/SelectionManager"; import { Transform } from "../../util/Transform"; import { CollectionFreeFormView } from "./CollectionFreeFormView"; import "./MarqueeView.scss"; import React = require("react"); - +import { InkField, StrokeData } from "../../../fields/InkField"; +import { Utils } from "../../../Utils"; +import { InkingCanvas } from "../InkingCanvas"; interface MarqueeViewProps { getMarqueeTransform: () => Transform; getTransform: () => Transform; container: CollectionFreeFormView; addDocument: (doc: Document) => void; - activeDocuemnts: () => Document[]; + activeDocuments: () => Document[]; selectDocuments: (docs: Document[]) => void; removeDocument: (doc: Document) => boolean; } @@ -94,29 +95,57 @@ export class MarqueeView extends React.Component marqueeCommand = (e: KeyboardEvent) => { if (e.key == "Backspace") { this.marqueeSelect().map(d => this.props.removeDocument(d)); + this.props.container.props.Document.SetData(KeyStore.Ink, this.marqueeInkSelect(false), InkField); this.cleanupInteractions(); } if (e.key == "c") { let bounds = this.Bounds; - let selected = this.marqueeSelect().map(m => m); - this.marqueeSelect().map(d => this.props.removeDocument(d)); - //setTimeout(() => { - this.props.addDocument(Documents.FreeformDocument(selected.map(d => { + let selected = this.marqueeSelect().map(d => { + this.props.removeDocument(d); d.SetNumber(KeyStore.X, d.GetNumber(KeyStore.X, 0) - bounds.left - bounds.width / 2); d.SetNumber(KeyStore.Y, d.GetNumber(KeyStore.Y, 0) - bounds.top - bounds.height / 2); d.SetNumber(KeyStore.Page, 0); d.SetText(KeyStore.Title, "" + d.GetNumber(KeyStore.Width, 0) + " " + d.GetNumber(KeyStore.Height, 0)); return d; - }), { x: bounds.left, y: bounds.top, panx: 0, pany: 0, width: bounds.width, height: bounds.height, title: "a nested collection" })); + }); + let liftedInk = this.marqueeInkSelect(true); + this.props.container.props.Document.SetData(KeyStore.Ink, this.marqueeInkSelect(false), InkField); + //setTimeout(() => { + this.props.addDocument(Documents.FreeformDocument(selected, { x: bounds.left, y: bounds.top, panx: 0, pany: 0, width: bounds.width, backgroundColor: "Transparent", height: bounds.height, ink: liftedInk, title: "a nested collection" })); // }, 100); this.cleanupInteractions(); } } + marqueeInkSelect(select: boolean) { + let selRect = this.Bounds; + let centerShiftX = 0 - (selRect.left + selRect.width / 2); // moves each point by the offset that shifts the selection's center to the origin. + let centerShiftY = 0 - (selRect.top + selRect.height / 2); + let ink = this.props.container.props.Document.GetT(KeyStore.Ink, InkField); + if (ink && ink != FieldWaiting) { + let idata = new Map(); + ink.Data.forEach((value: StrokeData, key: string, map: any) => { + let inside = InkingCanvas.IntersectStrokeRect(value, selRect); + if (inside && select) { + idata.set(key, + { + pathData: value.pathData.map(val => { return { x: val.x + centerShiftX, y: val.y + centerShiftY } }), + color: value.color, + width: value.width, + tool: value.tool, + page: -1 + }); + } else if (!inside && !select) { + idata.set(key, value); + } + }) + return idata; + } + } marqueeSelect() { let selRect = this.Bounds; let selection: Document[] = []; - this.props.activeDocuemnts().map(doc => { + this.props.activeDocuments().map(doc => { var x = doc.GetNumber(KeyStore.X, 0); var y = doc.GetNumber(KeyStore.Y, 0); var w = doc.GetNumber(KeyStore.Width, 0); -- cgit v1.2.3-70-g09d2 From b90e4714f44f6e6cb948784d5ea77654c1d164d8 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 15 Mar 2019 08:43:18 -0400 Subject: fixed pdf/video zooming/dropping. --- src/client/views/collections/CollectionPDFView.scss | 4 +--- src/client/views/collections/CollectionVideoView.scss | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionPDFView.scss b/src/client/views/collections/CollectionPDFView.scss index 152c0dd23..0144625c1 100644 --- a/src/client/views/collections/CollectionPDFView.scss +++ b/src/client/views/collections/CollectionPDFView.scss @@ -9,9 +9,7 @@ width: 100%; height: 100%; position: absolute; - .collectionfreeformview-overlay { - z-index: -1; - } + } .collectionPdfView-backward { color : white; diff --git a/src/client/views/collections/CollectionVideoView.scss b/src/client/views/collections/CollectionVideoView.scss index ea59d6e2e..cbb981b13 100644 --- a/src/client/views/collections/CollectionVideoView.scss +++ b/src/client/views/collections/CollectionVideoView.scss @@ -3,9 +3,7 @@ width: 100%; height: 100%; position: absolute; - .collectionfreeformview-overlay { - z-index: -1; - } + } .collectionVideoView-time{ color : white; -- cgit v1.2.3-70-g09d2 From c17605b4d1fe04429b029ff5a161f31ce19f5fd4 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 15 Mar 2019 10:48:23 -0400 Subject: think video resizing is fixed now. --- src/client/views/collections/CollectionSchemaView.tsx | 2 +- src/client/views/nodes/VideoBox.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 37620cd7c..14e1df8ca 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -49,7 +49,7 @@ export class CollectionSchemaView extends CollectionViewBase { let reference = React.createRef(); let onItemDown = setupDrag(reference, () => props.doc); return ( -
    +
    { let field = props.doc.Get(props.fieldKey); diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 053d9dd56..fef278cec 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -30,7 +30,7 @@ export class VideoBox extends React.Component { var nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 0); var nativeHeight = this.props.doc.GetNumber(KeyStore.NativeHeight, 0); var newNativeHeight = nativeWidth * r.entry.height / r.entry.width; - if (newNativeHeight != nativeHeight && !isNaN(newNativeHeight)) { + if (!nativeHeight && newNativeHeight != nativeHeight && !isNaN(newNativeHeight)) { this.props.doc.SetNumber(KeyStore.Height, newNativeHeight / nativeWidth * this.props.doc.GetNumber(KeyStore.Width, 0)); this.props.doc.SetNumber(KeyStore.NativeHeight, newNativeHeight); } @@ -48,7 +48,7 @@ export class VideoBox extends React.Component { //setTimeout(action(() => this._loaded = true), 500); return ( -
    +
    {({ measureRef }) =>