diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/documents/Documents.ts | 2 | ||||
-rw-r--r-- | src/client/views/Main.scss | 9 | ||||
-rw-r--r-- | src/client/views/MainView.tsx | 28 | ||||
-rw-r--r-- | src/client/views/PreviewCursor.tsx | 7 | ||||
-rw-r--r-- | src/client/views/collections/CollectionBaseView.scss | 3 | ||||
-rw-r--r-- | src/client/views/collections/CollectionBaseView.tsx | 6 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackingView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 5 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss | 1 | ||||
-rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 27 | ||||
-rw-r--r-- | src/client/views/nodes/WebBox.tsx | 35 | ||||
-rw-r--r-- | src/server/authentication/models/current_user_utils.ts | 5 |
12 files changed, 94 insertions, 36 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 30e4637b0..2a3827782 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -118,7 +118,7 @@ export namespace Docs { options: { nativeWidth: 600, curPage: 0 } }], [DocumentType.WEB, { - layout: { view: WebBox }, + layout: { view: WebBox, collectionView: [CollectionView, data, anno] as CollectionViewType }, options: { height: 300 } }], [DocumentType.COL, { diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss index f52e3b658..a16123476 100644 --- a/src/client/views/Main.scss +++ b/src/client/views/Main.scss @@ -235,16 +235,17 @@ ul#add-options-list { } .mainView-libraryHandle { - opacity: 0.6; width: 20px; height: 40px; top: 50%; - border-radius: 20px; + border: 1px solid black; + border-radius: 5px; position: absolute; z-index: 1; - background: gray; } - +.svg-inline--fa { + vertical-align: unset; +} .mainView-workspace { height:200px; position:relative; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 935f00332..ec5ec6e8b 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -1,5 +1,5 @@ import { IconName, library } from '@fortawesome/fontawesome-svg-core'; -import { faArrowDown, faArrowUp, faClone, faCheck, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt } from '@fortawesome/free-solid-svg-icons'; +import { faArrowDown, faArrowUp, faClone, faCheck, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faPortrait, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, configure, observable, runInAction, reaction, trace } from 'mobx'; import { observer } from 'mobx-react'; @@ -13,7 +13,7 @@ import { Id } from '../../new_fields/FieldSymbols'; import { InkTool } from '../../new_fields/InkField'; import { List } from '../../new_fields/List'; import { listSpec } from '../../new_fields/Schema'; -import { Cast, FieldValue, NumCast, BoolCast } from '../../new_fields/Types'; +import { Cast, FieldValue, NumCast, BoolCast, StrCast } from '../../new_fields/Types'; import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils'; import { RouteStore } from '../../server/RouteStore'; import { emptyFunction, returnOne, returnTrue } from '../../Utils'; @@ -105,7 +105,7 @@ export class MainView extends React.Component { library.add(faFont); library.add(faExclamation); - library.add(faImage); + library.add(faPortrait); library.add(faFilePdf); library.add(faObjectGroup); library.add(faTable); @@ -325,13 +325,15 @@ export class MainView extends React.Component { } @computed get mainContent() { + let sidebar = CurrentUserUtils.UserDocument.sidebar; + if (!(sidebar instanceof Doc)) return (null); return <div> <div className="mainView-libraryHandle" - style={{ left: `${this.flyoutWidth - 10}px` }} + style={{ left: `${this.flyoutWidth - 10}px`, backgroundColor: `${StrCast(sidebar.backgroundColor, "lightGray")}` }} onPointerDown={this.onPointerDown}> <span title="library View Dragger" style={{ width: "100%", height: "100%", position: "absolute" }} /> </div> - <div className="mainView-libraryFlyout" style={{ width: `${this.flyoutWidth}px` }}> + <div className="mainView-libraryFlyout" style={{ width: `${this.flyoutWidth}px`, zIndex: 1 }}> {this.flyout} </div> {this.dockingContent} @@ -371,28 +373,21 @@ export class MainView extends React.Component { let addImportCollectionNode = action(() => Docs.Create.DirectoryImportDocument({ title: "Directory Import", width: 400, height: 400 })); let btns: [React.RefObject<HTMLDivElement>, IconName, string, () => Doc][] = [ - [React.createRef<HTMLDivElement>(), "image", "Add Image", addImageNode], + [React.createRef<HTMLDivElement>(), "portrait", "Add Cat Image", addImageNode], [React.createRef<HTMLDivElement>(), "object-group", "Add Collection", addColNode], - [React.createRef<HTMLDivElement>(), "tree", "Add Tree", addTreeNode], - [React.createRef<HTMLDivElement>(), "table", "Add Schema", addSchemaNode], // [React.createRef<HTMLDivElement>(), "clone", "Add Docking Frame", addDockingNode], [React.createRef<HTMLDivElement>(), "arrow-up", "Import Directory", addImportCollectionNode], ]; return < div id="add-nodes-menu" style={{ left: this.flyoutWidth + 5 }} > <input type="checkbox" id="add-menu-toggle" ref={this.addMenuToggle} /> - <label htmlFor="add-menu-toggle" title="Add Node"><p>+</p></label> + <label htmlFor="add-menu-toggle" style={{ marginTop: 2 }} title="Add Node"><p>+</p></label> <div id="add-options-content"> <ul id="add-options-list"> <li key="search"><button className="add-button round-button" title="Search" onClick={this.toggleSearch}><FontAwesomeIcon icon="search" size="sm" /></button></li> <li key="undo"><button className="add-button round-button" title="Undo" style={{ opacity: UndoManager.CanUndo() ? 1 : 0.5, transition: "0.4s ease all" }} onClick={() => UndoManager.Undo()}><FontAwesomeIcon icon="undo-alt" size="sm" /></button></li> <li key="redo"><button className="add-button round-button" title="Redo" style={{ opacity: UndoManager.CanRedo() ? 1 : 0.5, transition: "0.4s ease all" }} onClick={() => UndoManager.Redo()}><FontAwesomeIcon icon="redo-alt" size="sm" /></button></li> - <li key="color"><button className="add-button round-button" title="Select Color" onClick={() => this.toggleColorPicker()}><div className="toolbar-color-button" style={{ backgroundColor: InkingControl.Instance.selectedColor }} > - <div className="toolbar-color-picker" onClick={this.onColorClick} style={this._colorPickerDisplay ? { color: "black", display: "block" } : { color: "black", display: "none" }}> - <SketchPicker color={InkingControl.Instance.selectedColor} onChange={InkingControl.Instance.switchColor} /> - </div> - </div></button></li> {btns.map(btn => <li key={btn[1]} ><div ref={btn[0]}> <button className="round-button add-button" title={btn[2]} onPointerDown={SetupDrag(btn[0], btn[3])}> @@ -400,6 +395,11 @@ export class MainView extends React.Component { </button> </div></li>)} <li key="undoTest"><button className="add-button round-button" onClick={() => UndoManager.PrintBatches()}><FontAwesomeIcon icon="exclamation" size="sm" /></button></li> + <li key="color"><button className="add-button round-button" title="Select Color" onClick={() => this.toggleColorPicker()}><div className="toolbar-color-button" style={{ backgroundColor: InkingControl.Instance.selectedColor }} > + <div className="toolbar-color-picker" onClick={this.onColorClick} style={this._colorPickerDisplay ? { color: "black", display: "block" } : { color: "black", display: "none" }}> + <SketchPicker color={InkingControl.Instance.selectedColor} onChange={InkingControl.Instance.switchColor} /> + </div> + </div></button></li> <li key="ink" style={{ paddingRight: "6px" }}><button className="toolbar-button round-button" title="Ink" onClick={() => InkingControl.Instance.toggleDisplay()}><FontAwesomeIcon icon="pen-nib" size="sm" /> </button></li> <li key="pen"><button onClick={() => InkingControl.Instance.switchTool(InkTool.Pen)} title="Pen" style={this.selected(InkTool.Pen)}><FontAwesomeIcon icon="pen" size="lg" /></button></li> <li key="marker"><button onClick={() => InkingControl.Instance.switchTool(InkTool.Highlighter)} title="Highlighter" style={this.selected(InkTool.Highlighter)}><FontAwesomeIcon icon="highlighter" size="lg" /></button></li> diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 7c1d00eb0..ef68c4489 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -35,9 +35,10 @@ export class PreviewCursor extends React.Component<{}> { // DASHFormattedTextBoxHandled flag when a text box consumes a key press so that we can ignore // the keyPress here. //if not these keys, make a textbox if preview cursor is active! - if (e.key.startsWith("F") && !e.key.endsWith("F")) { - } else if (e.key !== "Escape" && e.key !== "Alt" && e.key !== "Shift" && e.key !== "Meta" && e.key !== "Control" && !e.defaultPrevented && !(e as any).DASHFormattedTextBoxHandled) { - if ((!e.ctrlKey && !e.metaKey) || (e.key >= "a" && e.key <= "z")) { + if (e.key !== "Escape" && e.key !== "Backspace" && e.key !== "Delete" && + e.key !== "Alt" && e.key !== "Shift" && e.key !== "Meta" && e.key !== "Control" && + !e.defaultPrevented && !(e as any).DASHFormattedTextBoxHandled) { + if (!e.ctrlKey && !e.metaKey) {// /^[a-zA-Z0-9$*^%#@+-=_|}{[]"':;?/><.,}]$/.test(e.key)) { PreviewCursor.Visible && PreviewCursor._onKeyPress && PreviewCursor._onKeyPress(e); PreviewCursor.Visible = false; } diff --git a/src/client/views/collections/CollectionBaseView.scss b/src/client/views/collections/CollectionBaseView.scss index 1f5acb96a..34bcb705e 100644 --- a/src/client/views/collections/CollectionBaseView.scss +++ b/src/client/views/collections/CollectionBaseView.scss @@ -1,11 +1,12 @@ @import "../globalCssVariables"; #collectionBaseView { border-width: 0; - box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw; border-color: $light-color-secondary; border-style: solid; border-radius: 0 0 $border-radius $border-radius; box-sizing: border-box; border-radius: inherit; pointer-events: all; + width:100%; + height:100%; }
\ No newline at end of file diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 2eb2a727c..eba69b448 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -5,7 +5,7 @@ import { Doc } from '../../../new_fields/Doc'; import { Id } from '../../../new_fields/FieldSymbols'; import { List } from '../../../new_fields/List'; import { listSpec } from '../../../new_fields/Schema'; -import { BoolCast, Cast, NumCast, PromiseValue } from '../../../new_fields/Types'; +import { BoolCast, Cast, NumCast, PromiseValue, StrCast } from '../../../new_fields/Types'; import { DocumentManager } from '../../util/DocumentManager'; import { SelectionManager } from '../../util/SelectionManager'; import { ContextMenu } from '../ContextMenu'; @@ -145,7 +145,9 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> { }; const viewtype = this.collectionViewType; return ( - <div id="collectionBaseView" className={this.props.className || "collectionView-cont"} + <div id="collectionBaseView" + style={{ boxShadow: `#9c9396 ${StrCast(this.props.Document.boxShadow, "0.2vw 0.2vw 0.8vw")}` }} + className={this.props.className || "collectionView-cont"} onContextMenu={this.props.onContextMenu} ref={this.props.contentRef}> {viewtype !== undefined ? this.props.children(viewtype, props) : (null)} </div> diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index c667b3f3c..a84fd9cfe 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -14,7 +14,6 @@ import { undoBatch } from "../../util/UndoManager"; import { DragManager } from "../../util/DragManager"; import { DocumentType } from "../../documents/Documents"; import { Transform } from "../../util/Transform"; -import { resolve } from "bluebird"; @observer export class CollectionStackingView extends CollectionSubView(doc => doc) { @@ -56,7 +55,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { getDisplayDoc(layoutDoc: Doc, d: Doc, dxf: () => Transform) { let resolvedDataDoc = !this.props.Document.isTemplate && this.props.DataDoc !== this.props.Document ? this.props.DataDoc : undefined; - let dataDoc = d !== this.props.DataDoc ? this.props.DataDoc : undefined; let width = () => d.nativeWidth ? Math.min(layoutDoc[WidthSym](), this.columnWidth) : this.columnWidth; let height = () => this.getDocHeight(layoutDoc); let finalDxf = () => dxf().scale(this.columnWidth / layoutDoc[WidthSym]()); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 188b78d63..200e9558d 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -153,7 +153,8 @@ class TreeView extends React.Component<TreeViewProps> { let docList = Cast(this.resolvedDataDoc[this.fieldKey], listSpec(Doc)); let doc = Cast(this.resolvedDataDoc[this.fieldKey], Doc); let isDoc = doc instanceof Doc || docList; - return <div className="bullet" onClick={action(() => this._collapsed = !this._collapsed)}> + let c + return <div className="bullet" onClick={action(() => this._collapsed = !this._collapsed)} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}> {<FontAwesomeIcon icon={this._collapsed ? (isDoc ? "caret-square-right" : "caret-right") : (isDoc ? "caret-square-down" : "caret-down")} />} </div>; } @@ -532,7 +533,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc); return !this.childDocs ? (null) : ( <div id="body" className="collectionTreeView-dropTarget" - style={{ overflow: "auto" }} + style={{ overflow: "auto", background: StrCast(this.props.Document.backgroundColor, "gray") }} onContextMenu={this.onContextMenu} onWheel={(e: React.WheelEvent) => (e.target as any).scrollHeight > (e.target as any).clientHeight && e.stopPropagation()} onDrop={this.onTreeDrop} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss index ec0e446e9..00407d39a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss @@ -36,7 +36,6 @@ // linear-gradient(to bottom, $light-color-secondary 1px, transparent 1px); // background-size: 30px 30px; // } - box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw; opacity: 0.99; border: 0px solid $light-color-secondary; border-radius: inherit; diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index c65dfe0bd..895d9a422 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -70,6 +70,18 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD componentDidMount() { if (this.props.setVideoBox) this.props.setVideoBox(this); + + let field = Cast(this.Document[this.props.fieldKey], VideoField); + if (field && field.url.href.indexOf("youtube") !== -1) { + let youtubeaspect = 400 / 315; + var nativeWidth = FieldValue(this.Document.nativeWidth, 0); + var nativeHeight = FieldValue(this.Document.nativeHeight, 0); + if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) { + if (!this.Document.nativeWidth) this.Document.nativeWidth = 600; + this.Document.nativeHeight = this.Document.nativeWidth / youtubeaspect; + this.Document.height = FieldValue(this.Document.width, 0) / youtubeaspect; + } + } } componentWillUnmount() { this.Pause(); @@ -145,12 +157,17 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD // }); // // - let interactive = InkingControl.Instance.selectedTool ? "" : "-interactive"; + let interactive = InkingControl.Instance.selectedTool || !this.props.isSelected() ? "" : "-interactive"; let style = "videoBox-cont" + (this._fullScreen ? "-fullScreen" : interactive); + let videoid = field ? ((arr: string[]) => arr[arr.length - 1])(field.url.href.split("/")) : ""; return !field ? <div>Loading</div> : - <video className={`${style}`} ref={this.setVideoRef} onCanPlay={this.videoLoad} onPointerDown={this.onPointerDown} onContextMenu={this.specificContextMenu} controls={VideoBox._showControls}> - <source src={field.url.href} type="video/mp4" /> - Not supported. - </video>; + field.url.href.indexOf("youtube") !== -1 ? + <embed className={`${style}`} onLoad={this.videoLoad} id="video" onPointerDown={this.onPointerDown} onContextMenu={this.specificContextMenu} + src={`https://www.youtube.com/v/${videoid}`} type="application/x-shockwave-flash" style={{ height: "100%" }} title="Adobe Flash Player"> + </embed> : + <video className={`${style}`} ref={this.setVideoRef} onCanPlay={this.videoLoad} onPointerDown={this.onPointerDown} onContextMenu={this.specificContextMenu} controls={VideoBox._showControls}> + <source src={field.url.href} type="video/mp4" /> + Not supported. + </video>; } }
\ No newline at end of file diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 98c57fc75..96b972a1c 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -6,12 +6,45 @@ import { InkingControl } from "../InkingControl"; import { FieldView, FieldViewProps } from './FieldView'; import "./WebBox.scss"; import React = require("react"); +import { InkTool } from "../../../new_fields/InkField"; +import { Cast, FieldValue, NumCast } from "../../../new_fields/Types"; +export function onYouTubeIframeAPIReady() { + console.log("player"); + return; + let player = new YT.Player('player', { + events: { + 'onReady': onPlayerReady + } + }); +} +// must cast as any to set property on window +const _global = (window /* browser */ || global /* node */) as any +_global.onYouTubeIframeAPIReady = onYouTubeIframeAPIReady; + +function onPlayerReady(event: any) { + event.target.playVideo(); +} @observer export class WebBox extends React.Component<FieldViewProps> { public static LayoutString() { return FieldView.LayoutString(WebBox); } + componentWillMount() { + + let field = Cast(this.props.Document[this.props.fieldKey], WebField); + if (field && field.url.href.indexOf("youtube") !== -1) { + let youtubeaspect = 400 / 315; + var nativeWidth = NumCast(this.props.Document.nativeWidth, 0); + var nativeHeight = NumCast(this.props.Document.nativeHeight, 0); + if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) { + if (!nativeWidth) this.props.Document.nativeWidth = 600; + this.props.Document.nativeHeight = NumCast(this.props.Document.nativeWidth) / youtubeaspect; + this.props.Document.height = NumCast(this.props.Document.width) / youtubeaspect; + } + } + } + _ignore = 0; onPreWheel = (e: React.WheelEvent) => { this._ignore = e.timeStamp; @@ -46,7 +79,7 @@ export class WebBox extends React.Component<FieldViewProps> { let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting; - let classname = "webBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : ""); + let classname = "webBox-cont" + (this.props.isSelected() && InkingControl.Instance.selectedTool === InkTool.None && !DocumentDecorations.Instance.Interacting ? "-interactive" : ""); return ( <> <div className={classname} > diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 763693dd6..695ddc3ec 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -37,6 +37,7 @@ export class CurrentUserUtils { doc.gridGap = 5; doc.xMargin = 5; doc.yMargin = 5; + doc.boxShadow = "0 0"; doc.excludeFromLibrary = true; doc.optionalRightCollection = Docs.Create.StackingDocument([], { title: "New mobile uploads" }); // doc.library = Docs.Create.TreeDocument([doc], { title: `Library: ${CurrentUserUtils.email}` }); @@ -49,11 +50,13 @@ export class CurrentUserUtils { const workspaces = Docs.Create.TreeDocument([], { title: "Workspaces", height: 100 }); workspaces.excludeFromLibrary = true; workspaces.workspaceLibrary = true; + workspaces.boxShadow = "0 0"; doc.workspaces = workspaces; } if (doc.recentlyClosed === undefined) { const recentlyClosed = Docs.Create.TreeDocument([], { title: "Recently Closed", height: 75 }); recentlyClosed.excludeFromLibrary = true; + recentlyClosed.boxShadow = "0 0"; doc.recentlyClosed = recentlyClosed; } if (doc.sidebar === undefined) { @@ -62,6 +65,8 @@ export class CurrentUserUtils { sidebar.gridGap = 5; sidebar.xMargin = 5; sidebar.yMargin = 5; + Doc.GetProto(sidebar).backgroundColor = "lightGray"; + sidebar.boxShadow = "1 1 3"; doc.sidebar = sidebar; } |