aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2019-08-15 23:19:50 -0400
committerGitHub <noreply@github.com>2019-08-15 23:19:50 -0400
commite0986156ac3fa92d57f3fbe9bc5e36e413764357 (patch)
tree342a09d7ea8d95c897c74da095afde864e09ca55 /src
parent46386fd73a06e52d606f891c812a9af0598eec79 (diff)
parenta7307ca3dc46782cc9e4cae4daa9b30911ace1dd (diff)
Merge pull request #249 from browngraphicslab/monika_ellie_UI
mac compatibility and UI
Diffstat (limited to 'src')
-rw-r--r--src/client/views/ContextMenu.tsx50
-rw-r--r--src/client/views/DocumentDecorations.scss17
-rw-r--r--src/client/views/DocumentDecorations.tsx14
-rw-r--r--src/client/views/Main.scss2
-rw-r--r--src/client/views/MainView.tsx3
-rw-r--r--src/client/views/nodes/FormattedTextBox.scss4
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx2
-rw-r--r--src/client/views/search/SearchBox.scss5
-rw-r--r--src/client/views/search/SearchBox.tsx21
9 files changed, 101 insertions, 17 deletions
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index 1bf6e383d..760736501 100644
--- a/src/client/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
@@ -1,6 +1,6 @@
import React = require("react");
import { ContextMenuItem, ContextMenuProps, OriginalMenuProps } from "./ContextMenuItem";
-import { observable, action, computed } from "mobx";
+import { observable, action, computed, runInAction, IReactionDisposer, reaction } from "mobx";
import { observer } from "mobx-react";
import "./ContextMenu.scss";
import { library } from '@fortawesome/fontawesome-svg-core';
@@ -27,6 +27,13 @@ export class ContextMenu extends React.Component {
@observable private _width: number = 0;
@observable private _height: number = 0;
+ @observable private _mouseX: number = -1;
+ @observable private _mouseY: number = -1;
+ @observable private _shouldDisplay: boolean = false;
+ @observable private _mouseDown: boolean = false;
+
+ private _reactionDisposer?: IReactionDisposer;
+
constructor(props: Readonly<{}>) {
super(props);
@@ -34,6 +41,40 @@ export class ContextMenu extends React.Component {
}
@action
+ onPointerDown = (e: PointerEvent) => {
+ this._mouseDown = true;
+ this._mouseX = e.clientX;
+ this._mouseY = e.clientY;
+ }
+ @action
+ onPointerUp = (e: PointerEvent) => {
+ this._mouseDown = false;
+ let curX = e.clientX;
+ let curY = e.clientY;
+ if (this._mouseX !== curX || this._mouseY !== curY) {
+ this._shouldDisplay = false;
+ }
+
+ this._shouldDisplay && (this._display = true);
+ }
+ componentWillUnmount() {
+ document.removeEventListener("pointerdown", this.onPointerDown);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ this._reactionDisposer && this._reactionDisposer();
+ }
+
+ @action
+ componentDidMount = () => {
+ document.addEventListener("pointerdown", this.onPointerDown);
+ document.addEventListener("pointerup", this.onPointerUp);
+
+ this._reactionDisposer = reaction(
+ () => this._shouldDisplay,
+ () => this._shouldDisplay && !this._mouseDown && runInAction(() => this._display = true)
+ );
+ }
+
+ @action
clearItems() {
this._items = [];
}
@@ -83,22 +124,21 @@ export class ContextMenu extends React.Component {
}
@action
- displayMenu(x: number, y: number) {
+ displayMenu = (x: number, y: number) => {
//maxX and maxY will change if the UI/font size changes, but will work for any amount
//of items added to the menu
this._pageX = x;
this._pageY = y;
-
this._searchString = "";
-
- this._display = true;
+ this._shouldDisplay = true;
}
@action
closeMenu = () => {
this.clearItems();
this._display = false;
+ this._shouldDisplay = false;
}
@computed get filteredItems(): (OriginalMenuProps | string[])[] {
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index 0b7411fca..3627edaae 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -24,13 +24,13 @@ $linkGap : 3px;
.documentDecorations-resizer {
pointer-events: auto;
background: $alt-accent;
- opacity: 0.8;
+ opacity: 1;
}
.documentDecorations-radius {
pointer-events: auto;
background: black;
- opacity: 0.8;
+ opacity: 1;
transform: translate(10px, 10px);
grid-row: 4;
}
@@ -92,27 +92,30 @@ $linkGap : 3px;
.title {
background: $alt-accent;
+ opacity: 1;
grid-column-start: 3;
grid-column-end: 4;
pointer-events: auto;
overflow: hidden;
+ text-align: center;
}
}
.documentDecorations-closeButton {
background: $alt-accent;
- opacity: 0.8;
+ opacity: 1;
grid-column-start: 4;
grid-column-end: 6;
pointer-events: all;
text-align: center;
cursor: pointer;
+ padding-right: 10px;
}
.documentDecorations-minimizeButton {
background: $alt-accent;
- opacity: 0.8;
+ opacity: 1;
grid-column-start: 1;
grid-column-end: 3;
pointer-events: all;
@@ -121,6 +124,7 @@ $linkGap : 3px;
position: absolute;
left: 0px;
top: 0px;
+ padding-top: 5px;
width: $MINIMIZED_ICON_SIZE;
height: $MINIMIZED_ICON_SIZE;
}
@@ -219,6 +223,11 @@ $linkGap : 3px;
margin-top: 3px;
}
+.documentdecorations-times {
+ margin-top: 3px;
+ padding-right: 3px;
+}
+
.templating-button,
.docDecs-tagButton {
width: 20px;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index df526e01c..d24762443 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -1,5 +1,5 @@
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faLink, faTag } from '@fortawesome/free-solid-svg-icons';
+import { faLink, faTag, faTimes } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, computed, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
@@ -36,6 +36,7 @@ export const Flyout = higflyout.default;
library.add(faLink);
library.add(faTag);
+library.add(faTimes);
@observer
export class DocumentDecorations extends React.Component<{}, { value: string }> {
@@ -65,6 +66,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
@observable private _opacity = 1;
@observable private _removeIcon = false;
@observable public Interacting = false;
+ @observable private _isMoving = false;
constructor(props: Readonly<{}>) {
super(props);
@@ -346,9 +348,14 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
document.addEventListener("pointermove", this.onRadiusMove);
document.addEventListener("pointerup", this.onRadiusUp);
}
+ if (!this._isMoving) {
+ SelectionManager.SelectedDocuments().map(dv => dv.props.Document.layout instanceof Doc ? dv.props.Document.layout : dv.props.Document.isTemplate ? dv.props.Document : Doc.GetProto(dv.props.Document)).
+ map(d => d.borderRounding = "0%");
+ }
}
onRadiusMove = (e: PointerEvent): void => {
+ this._isMoving = true;
let dist = Math.sqrt((e.clientX - this._radiusDown[0]) * (e.clientX - this._radiusDown[0]) + (e.clientY - this._radiusDown[1]) * (e.clientY - this._radiusDown[1]));
SelectionManager.SelectedDocuments().map(dv => dv.props.Document.layout instanceof Doc ? dv.props.Document.layout : dv.props.Document.isTemplate ? dv.props.Document : Doc.GetProto(dv.props.Document)).
map(d => d.borderRounding = `${Math.min(100, dist)}%`);
@@ -361,6 +368,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
e.preventDefault();
this._isPointerDown = false;
this._resizeUndo && this._resizeUndo.end();
+ this._isMoving = false;
document.removeEventListener("pointermove", this.onRadiusMove);
document.removeEventListener("pointerup", this.onRadiusUp);
}
@@ -743,7 +751,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
{this._edtingTitle ?
<input ref={this.keyinput} className="title" type="text" name="dynbox" value={this._title} onBlur={this.titleBlur} onChange={this.titleChanged} onKeyPress={this.titleEntered} /> :
<div className="title" onPointerDown={this.onTitleDown} ><span>{`${this.selectionTitle}`}</span></div>}
- <div className="documentDecorations-closeButton" title="Close Document" onPointerDown={this.onCloseDown}>X</div>
+ <div className="documentDecorations-closeButton" title="Close Document" onPointerDown={this.onCloseDown}>
+ <FontAwesomeIcon className="documentdecorations-times" icon={faTimes} size="lg" />
+ </div>
<div id="documentDecorations-topLeftResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
<div id="documentDecorations-topResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
<div id="documentDecorations-topRightResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss
index f76abaff3..a0b4b2f16 100644
--- a/src/client/views/Main.scss
+++ b/src/client/views/Main.scss
@@ -140,6 +140,8 @@ button:hover {
// font-size: 8px;
// user-select: none;
// }
+ margin-top: -2.55px;
+ margin-left: -2.55px;
}
// add nodes menu. Note that the + button is actually an input label, not an actual button.
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 110d47941..00a9c0950 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -38,6 +38,7 @@ import { PreviewCursor } from './PreviewCursor';
import { FilterBox } from './search/FilterBox';
import { CollectionTreeView } from './collections/CollectionTreeView';
import { ClientUtils } from '../util/ClientUtils';
+import { SearchBox } from './search/SearchBox';
import { SchemaHeaderField, RandomPastel } from '../../new_fields/SchemaHeaderField';
import { DictationManager } from '../util/DictationManager';
@@ -538,7 +539,7 @@ export class MainView extends React.Component {
}
@observable isSearchVisible = false;
- @action
+ @action.bound
toggleSearch = () => {
// console.log("search toggling")
this.isSearchVisible = !this.isSearchVisible;
diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss
index 247f7d1ea..d86aab09c 100644
--- a/src/client/views/nodes/FormattedTextBox.scss
+++ b/src/client/views/nodes/FormattedTextBox.scss
@@ -33,8 +33,8 @@
}
.formattedTextBox-inner-rounded {
- height: calc(100% - 25px);
- width: calc(100% - 40px);
+ height: calc(90%);
+ width: calc(85%);
position: absolute;
overflow: auto;
top: 15;
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 516e36d5b..330bd135d 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -616,7 +616,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
let dh = NumCast(this.props.Document.height, 0);
let sh = scrBounds.height;
const ChromeHeight = MainOverlayTextBox.Instance.ChromeHeight;
- this.props.Document.height = (nh ? dh / nh * sh : sh) + (ChromeHeight ? ChromeHeight() : 0);
+ this.props.Document.height = Math.max(10, (nh ? dh / nh * sh : sh) + (ChromeHeight ? ChromeHeight() : 0));
this.dataDoc.nativeHeight = nh ? sh : undefined;
}
}
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index fcdc79220..5ed33a596 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -37,6 +37,11 @@
margin-left: 2px;
margin-right: 2px
}
+
+ &.searchBox-close {
+ color: $light-color;
+ max-height: 32px;
+ }
}
}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 2214ac8af..4dc409e77 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -4,6 +4,8 @@ import { observable, action, runInAction, flow, computed } from 'mobx';
import "./SearchBox.scss";
import "./FilterBox.scss";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faTimes } from '@fortawesome/free-solid-svg-icons';
+import { library } from '@fortawesome/fontawesome-svg-core';
import { SetupDrag } from '../../util/DragManager';
import { Docs } from '../../documents/Documents';
import { NumCast, Cast } from '../../../new_fields/Types';
@@ -14,8 +16,12 @@ import { Id } from '../../../new_fields/FieldSymbols';
import { SearchUtil } from '../../util/SearchUtil';
import { RouteStore } from '../../../server/RouteStore';
import { FilterBox } from './FilterBox';
+import { ReadStream } from 'fs';
+import * as $ from 'jquery';
+import { MainView } from '../MainView';
import { Utils } from '../../../Utils';
+library.add(faTimes);
@observer
export class SearchBox extends React.Component {
@@ -29,6 +35,7 @@ export class SearchBox extends React.Component {
@observable private _visibleElements: JSX.Element[] = [];
private resultsRef = React.createRef<HTMLDivElement>();
+ public inputRef = React.createRef<HTMLInputElement>();
private _isSearch: ("search" | "placeholder" | undefined)[] = [];
private _numTotalResults = -1;
@@ -46,6 +53,15 @@ export class SearchBox extends React.Component {
this.resultsScrolled = this.resultsScrolled.bind(this);
}
+ componentDidMount = () => {
+ if (this.inputRef.current) {
+ this.inputRef.current.focus();
+ runInAction(() => {
+ this._searchbarOpen = true;
+ });
+ }
+ }
+
@action
getViews = async (doc: Doc) => {
const results = await SearchUtil.GetViewsOfDocument(doc);
@@ -229,6 +245,7 @@ export class SearchBox extends React.Component {
@action.bound
closeSearch = () => {
+ console.log("closing search")
FilterBox.Instance.closeFilter();
this.closeResults();
this._searchbarOpen = false;
@@ -321,11 +338,12 @@ export class SearchBox extends React.Component {
<span className="searchBox-barChild searchBox-collection" onPointerDown={SetupDrag(this.collectionRef, this.startDragCollection)} ref={this.collectionRef} title="Drag Results as Collection">
<FontAwesomeIcon icon="object-group" size="lg" />
</span>
- <input value={this._searchString} onChange={this.onChange} type="text" placeholder="Search..."
+ <input value={this._searchString} onChange={this.onChange} type="text" placeholder="Search..." id="search-input" ref={this.inputRef}
className="searchBox-barChild searchBox-input" onPointerDown={this.openSearch} onKeyPress={this.enter}
style={{ width: this._searchbarOpen ? "500px" : "100px" }} />
<button className="searchBox-barChild searchBox-submit" onClick={this.submitSearch} onPointerDown={FilterBox.Instance.stopProp}>Submit</button>
<button className="searchBox-barChild searchBox-filter" onClick={FilterBox.Instance.openFilter} onPointerDown={FilterBox.Instance.stopProp}>Filter</button>
+ <button className="searchBox-barChild searchBox-close" title={"Close Search Bar"} onPointerDown={MainView.Instance.toggleSearch}><FontAwesomeIcon icon={faTimes} size="lg" /></button>
</div>
<div className="searchBox-results" onScroll={this.resultsScrolled} style={{
display: this._resultsOpen ? "flex" : "none",
@@ -336,5 +354,4 @@ export class SearchBox extends React.Component {
</div>
);
}
-
} \ No newline at end of file