From 8d1f4cdf924a4002f132886230eb85a40dfcae3f Mon Sep 17 00:00:00 2001 From: anika-ahluwalia Date: Mon, 3 Aug 2020 00:33:37 -0500 Subject: several UI changes to tooltips, menu, properties, buttons, and ink --- src/client/util/CurrentUserUtils.ts | 1 + src/client/util/SettingsManager.scss | 15 +- src/client/util/SettingsManager.tsx | 2 +- src/client/views/DocumentDecorations.tsx | 6 +- src/client/views/InkingStroke.tsx | 2 +- src/client/views/MainView.scss | 6 +- src/client/views/MainView.tsx | 20 +- src/client/views/PropertiesButtons.scss | 7 +- src/client/views/PropertiesButtons.tsx | 83 +++++--- src/client/views/collections/CollectionMenu.tsx | 227 ++++++++++++--------- src/client/views/globalCssVariables.scss | 4 +- .../views/nodes/formattedText/RichTextMenu.tsx | 39 ++-- 12 files changed, 243 insertions(+), 169 deletions(-) (limited to 'src') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index a094ac5a6..c27290e74 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -49,6 +49,7 @@ export class CurrentUserUtils { @observable public static searchStack: any | undefined; @observable public static selectedPanel: string = "none"; + @observable public static propertiesWidth: number = 0; // sets up the default User Templates - slideView, queryView, descriptionView static setupUserTemplateButtons(doc: Doc) { diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss index c1627e69f..6923fe879 100644 --- a/src/client/util/SettingsManager.scss +++ b/src/client/util/SettingsManager.scss @@ -7,7 +7,7 @@ height: 300px; button { - background: $lighter-alt-accent; + background: #315a96; outline: none; border-radius: 5px; border: 0px; @@ -29,8 +29,12 @@ button { width: 100%; align-self: center; - background: $darker-alt-accent; + background: #252b33; margin-top: 4px; + + &:hover { + background: $main-accent; + } } .delete-button { @@ -102,11 +106,12 @@ } h1 { - color: $dark-color; + color: #121721; text-transform: uppercase; letter-spacing: 2px; - font-size: 120%; + font-size: 19; margin-top: 0; + font-weight: bold; } .container { @@ -151,7 +156,7 @@ .settings-interface button { width: 100%; font-size: 30px; - background: #b2cef8; + background: #315a96; } .settings-interface .settings-heading { diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 207c78964..6276fae96 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -136,7 +136,7 @@ export default class SettingsManager extends React.Component<{}> { {this.errorText ?
{this.errorText}
: undefined} {this.successText ?
{this.successText}
: undefined} - forgot password? + forgot password? : undefined} diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index b8670a1af..f16cb273b 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -619,9 +619,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } : <> - {/* {minimal ? (null) :
Show context menu
} placement="top">
- -
} */} + {minimal ? (null) :
Show context menu
} placement="top">
+ +
}
{`${this.selectionTitle}`}
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 5892e8346..8e3f72cee 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -178,7 +178,7 @@ export class InkingStroke extends ViewBoxBaseComponent diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 054a409df..a57d22afd 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -105,7 +105,7 @@ .mainView-propertiesDragger { background-color: rgb(140, 139, 139); height: 55px; - width: 15.5px; + width: 17px; position: absolute; top: 55%; border: 1px black solid; @@ -119,7 +119,7 @@ width: 10px; height: 10px; float: left; - margin-left: 3px; + margin-left: 5.5px; padding-top: 19px; } @@ -297,7 +297,7 @@ position: absolute; z-index: 2; touch-action: none; - cursor: ew-resize; + cursor: grab; .mainView-libraryHandle-icon { width: 10px; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index c83aeee25..fdf4c1626 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -91,8 +91,7 @@ export class MainView extends React.Component { } else { return undefined; } } - @observable _propertiesWidth: number = 0; - propertiesWidth = () => Math.max(0, Math.min(this._panelWidth - 50, this._propertiesWidth)); + propertiesWidth = () => Math.max(0, Math.min(this._panelWidth - 50, CurrentUserUtils.propertiesWidth)); @computed get propertiesIcon() { if (this.propertiesWidth() < 10) { @@ -141,6 +140,9 @@ export class MainView extends React.Component { MainView.Instance = this; this._urlState = HistoryUtil.parseUrl(window.location) || {} as any; // causes errors to be generated when modifying an observable outside of an action + + CurrentUserUtils.propertiesWidth = 0; + configure({ enforceActions: "observed" }); if (window.location.pathname !== "/home") { const pathname = window.location.pathname.substr(1).split("/"); @@ -172,7 +174,7 @@ export class MainView extends React.Component { fa.faFillDrip, fa.faLink, fa.faUnlink, fa.faBold, fa.faItalic, fa.faChevronLeft, fa.faUnderline, fa.faStrikethrough, fa.faSuperscript, fa.faSubscript, fa.faIndent, fa.faEyeDropper, fa.faPaintRoller, fa.faBars, fa.faBrush, fa.faShapes, fa.faEllipsisH, fa.faHandPaper, fa.faMap, fa.faUser, faHireAHelper, fa.faDesktop, fa.faTrashRestore, fa.faUsers, fa.faWrench, fa.faCog, fa.faMap, fa.faBellSlash, fa.faExpandAlt, fa.faArchive, fa.faBezierCurve, fa.faCircle, - fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer, fa.faExpand, fa.faUndo, fa.faSlidersH); + fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer, fa.faExpand, fa.faUndo, fa.faSlidersH, fa.faAngleDoubleLeft); this.initEventListeners(); this.initAuthenticationRouters(); } @@ -376,9 +378,9 @@ export class MainView extends React.Component { @action onPropertiesPointerDown = (e: React.PointerEvent) => { setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => { - this._propertiesWidth = this._panelWidth - e.clientX; + CurrentUserUtils.propertiesWidth = this._panelWidth - e.clientX; return false; - }), returnFalse, action(() => this._propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._panelWidth - 50, 250) : 0), false); + }), returnFalse, action(() => CurrentUserUtils.propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._panelWidth - 50, 250) : 0), false); } @action @@ -419,7 +421,7 @@ export class MainView extends React.Component {
{this.flyoutWidth > 0 ?
- +
: null} { - this._propertiesWidth = 0; + CurrentUserUtils.propertiesWidth = 0; } @computed get propertiesView() { @@ -553,7 +555,7 @@ export class MainView extends React.Component {
{this.flyoutWidth !== 0 ?
+ style={{ backgroundColor: 'lightgrey' }}> + style={{ right: rightFlyout, top: "50%" }}>
diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss index b3a317a6b..1cba252de 100644 --- a/src/client/views/PropertiesButtons.scss +++ b/src/client/views/PropertiesButtons.scss @@ -45,13 +45,13 @@ $linkGap : 3px; } .propertiesButtons { - margin-top: $linkGap; + margin-top: 3px; grid-column: 1/4; - width: max-content; + width: 100%; height: auto; display: flex; flex-direction: row; - overflow-x: visible; + flex-wrap: wrap; } .onClickFlyout-editScript { @@ -69,6 +69,7 @@ $linkGap : 3px; width: 25px; border-radius: 5px; margin-right: 18px; + margin-bottom: 8px; } .propertiesButtons-linker { diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index d3f056a34..68969b413 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -29,6 +29,7 @@ import { ImageField } from '../../fields/URLField'; import { undoBatch, UndoManager } from '../util/UndoManager'; import { DocumentType } from '../documents/DocumentTypes'; import { CollectionFreeFormView } from './collections/collectionFreeForm/CollectionFreeFormView'; +import { InkField } from '../../fields/InkField'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -524,6 +525,32 @@ export class PropertiesButtons extends React.Component<{}, {}> { ; } + @undoBatch + @action + private makeMask = () => { + if (this.selectedDoc) { + this.selectedDoc._backgroundColor = "rgba(0,0,0,0.7)"; + this.selectedDoc.mixBlendMode = "hard-light"; + this.selectedDoc.color = "#9b9b9bff"; + this.selectedDoc.stayInCollection = true; + this.selectedDoc.isInkMask = true; + } + } + + @computed + get maskButton() { + const targetDoc = this.selectedDoc; + return !targetDoc ? (null) :
Make Mask
}> +
+ {} +
+
; + } + + // @computed // get importButton() { // const targetDoc = this.selectedDoc; @@ -549,6 +576,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { const considerPull = isText && this.considerGoogleDocsPull; const considerPush = isText && this.considerGoogleDocsPush; const isImage = this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof ImageField; + const isInk = this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof InkField; const isCollection = this.selectedDoc.type === DocumentType.COL ? true : false; const isFreeForm = this.selectedDoc._viewType === "freeform" ? true : false; @@ -571,39 +599,40 @@ export class PropertiesButtons extends React.Component<{}, {}> {
{this.downloadButton}
-
-
-
- {this.deleteButton} -
-
- {this.onClickButton} -
-
- {this.sharingButton} -
-
- {this.considerGoogleDocsPush} -
-
- {this.considerGoogleDocsPull} -
-
- {this.googlePhotosButton} -
- {/*
+
+ {this.deleteButton} +
+
+ {this.onClickButton} +
+
+ {this.sharingButton} +
+
+ {this.considerGoogleDocsPush} +
+
+ {this.considerGoogleDocsPull} +
+
+ {this.googlePhotosButton} +
+ {/*
{this.importButton}
*/} -
- {this.clustersButton} -
+
+ {this.clustersButton} +
-
- {this.fitContentButton} -
+
+ {this.fitContentButton} +
+
+ {this.maskButton}
+
; } } diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 59e6ac7ff..0a3f77888 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -30,6 +30,8 @@ import { RichTextField } from "../../../fields/RichTextField"; import { ScriptField } from "../../../fields/ScriptField"; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { DocUtils } from "../../documents/Documents"; +import { Tooltip } from "@material-ui/core"; +import { CurrentUserUtils } from "../../util/CurrentUserUtils"; @observer export default class CollectionMenu extends AntimodeMenu { @@ -65,16 +67,38 @@ export default class CollectionMenu extends AntimodeMenu { } } + @action + toggleProperties = () => { + if (CurrentUserUtils.propertiesWidth > 0) { + CurrentUserUtils.propertiesWidth = 0; + } else { + CurrentUserUtils.propertiesWidth = 250; + } + } + render() { - const button = ; + const button = Pin Menu
} placement="bottom"> + + ; + + const propIcon = CurrentUserUtils.propertiesWidth > 0 ? "angle-double-right" : "angle-double-left"; + const propTitle = CurrentUserUtils.propertiesWidth > 0 ? "Close Properties Panel" : "Open Properties Panel"; + + const prop = {propTitle}} placement="bottom"> + + ; return this.getElement(!this.SelectedCollection ? [button] : [, + prop, button]); } } @@ -271,43 +295,47 @@ export class CollectionViewBaseChrome extends React.Component -
- - -
+ drop document to apply or drag to create button} placement="bottom"> +
+ + +
+
; } @computed get viewModes() { return
-
- - -
+ drop document to apply or drag to create button
} placement="bottom"> +
+ + +
+ ; } @@ -332,18 +360,23 @@ export class CollectionViewBaseChrome extends React.Component - - } - - {this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? (null) : } + {Doc.UserDoc().noviceMode ? (null) : + filter documents to show} placement="bottom"> +
+ +
+
} + + {this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? (null) : + Toggle Overlay Layer} placement="bottom"> + + } {this.subChrome} @@ -491,22 +524,26 @@ export class CollectionFreeFormViewChrome extends React.Component {this._draw.map((icon, i) => - )} + {this._title[i]}} placement="bottom"> + + )} ; } toggleButton = (key: string, value: boolean, setter: () => {}, icon: FontAwesomeIconProps["icon"], ele: JSX.Element | null) => { - return ; + return {key}} placement="bottom"> + + ; } @computed get widthPicker() { @@ -515,11 +552,13 @@ export class CollectionFreeFormViewChrome extends React.Component {widthPicker} {this._width.map((wid, i) => - )} + change width} placement="bottom"> + + )} ; } @@ -554,43 +593,42 @@ export class CollectionFreeFormViewChrome extends React.Component; } - @computed get formatPane() { - // return ; - return null; - } - render() { return !this.props.docView.layoutDoc ? (null) :
- {this.props.docView.props.renderDepth !== 0 || this.isText ? (null) : -
+ {this.props.docView.props.renderDepth !== 0 || this.isText ? (null) : Toggle Mini Map
} placement="bottom"> +
+ } - {!!!this.isText ?
- -
: null} - {!!!this.isText ?
this.document.editing = !this.document.editing)} > - {NumCast(this.document.currentFrame)} -
: null} - {!!!this.isText ?
- -
: null} + {!!!this.isText ? Back Frame
} placement="bottom"> +
+ +
+ : null} + {!!!this.isText ? Toggle View All} placement="bottom"> +
this.document.editing = !this.document.editing)} > + {NumCast(this.document.currentFrame)} +
+
: null} + {!!!this.isText ? Forward Frame} placement="bottom"> +
+ +
+
: null} {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText ? (null) : - + Use Hypothesis} placement="bottom"> + + } {(!this.props.isOverlay || this.props.docView.layoutDoc.isAnnotating) && !this.isText ? <> @@ -598,7 +636,6 @@ export class CollectionFreeFormViewChrome extends React.Component : (null) } diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss index 3e54d001b..4c79a7c2f 100644 --- a/src/client/views/globalCssVariables.scss +++ b/src/client/views/globalCssVariables.scss @@ -9,10 +9,10 @@ $main-accent: #aaaaa3; //$alt-accent: #59dff7; $alt-accent: #c2c2c5; $lighter-alt-accent: rgb(207, 220, 240); -$darker-alt-accent: rgb(178, 206, 248); +$darker-alt-accent: #b2cef8; $intermediate-color: #9c9396; $dark-color: #121721; -$link-color: lightBlue; +$link-color: #add8e6; $antimodemenu-height: 35px; // fonts $sans-serif: "Noto Sans", diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 85cc5c1a1..d7eb73bb4 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -617,8 +617,11 @@ export default class RichTextMenu extends AntimodeMenu { label = "No marks are currently stored"; } + //onPointerDown={onBrushClick} + const button = style brush} placement="bottom"> - ; @@ -631,7 +634,7 @@ export default class RichTextMenu extends AntimodeMenu { ; return ( - + ); } @@ -690,8 +693,9 @@ export default class RichTextMenu extends AntimodeMenu { self.TextView.EditorView!.focus(); } + // onPointerDown={onColorClick} const button = set font color} placement="bottom"> - @@ -712,7 +716,7 @@ export default class RichTextMenu extends AntimodeMenu { ; return ( - + ); } @@ -744,8 +748,9 @@ export default class RichTextMenu extends AntimodeMenu { UndoManager.RunInBatch(() => self.view && self.insertHighlight(self.activeHighlightColor, self.view.state, self.view.dispatch), "rt highlighter"); } + //onPointerDown={onHighlightClick} const button = set highlight color} placement="bottom"> - @@ -766,7 +771,7 @@ export default class RichTextMenu extends AntimodeMenu { ; return ( - + ); } @@ -789,7 +794,7 @@ export default class RichTextMenu extends AntimodeMenu { const link = this.currentLink ? this.currentLink : ""; const button = set hyperlink} placement="bottom"> -
+
; const dropdownContent = @@ -801,7 +806,8 @@ export default class RichTextMenu extends AntimodeMenu { ; - return ; + return ; } async getTextLinkTargetTitle() { @@ -1001,6 +1007,7 @@ interface ButtonDropdownProps { button: JSX.Element; dropdownContent: JSX.Element; openDropdownOnButton?: boolean; + link?: boolean; } @observer @@ -1043,18 +1050,10 @@ export class ButtonDropdown extends React.Component { render() { return (
this.ref = node}> - {this.props.openDropdownOnButton ? - : - <> - {this.props.button} - - } - + {this.showDropdown ? this.props.dropdownContent : (null)}
); -- cgit v1.2.3-70-g09d2