From 0fc47fefcb72592bd34e238949db9e98a84b8a63 Mon Sep 17 00:00:00 2001 From: geireann Date: Mon, 5 Jun 2023 19:42:06 -0400 Subject: topbar, buttons etc --- src/client/util/CurrentUserUtils.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 4a702cef3..52ed2ef83 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -694,19 +694,19 @@ export class CurrentUserUtils { CollectionViewType.Carousel3D, CollectionViewType.Linear, CollectionViewType.Map, CollectionViewType.Grid, CollectionViewType.NoteTaking]), title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: 'setView(value, _readOnly_)'}}, - { title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, expertMode: false, width: 20, scripts: { onClick: 'pinWithView(altKey)'}}, - { title: "Fill", icon: "fill-drip", toolTip: "Background Fill Color",btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, width: 20, scripts: { script: 'return setBackgroundColor(value, _readOnly_)'}}, // Only when a document is selected + { title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, expertMode: false, width: 30, scripts: { onClick: 'pinWithView(altKey)'}}, + { title: "Fill", icon: "fill-drip", toolTip: "Background Fill Color",btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, width: 30, scripts: { script: 'return setBackgroundColor(value, _readOnly_)'}}, // Only when a document is selected { title: "Header", icon: "heading", toolTip: "Header Color", btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'}}, { title: "Overlay", icon: "layer-group", toolTip: "Overlay", btnType: ButtonType.ToggleButton, expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)'}, scripts: { onClick: 'toggleOverlay(_readOnly_)'}}, // Only when floating document is selected in freeform - { title: "Back", icon: "chevron-left", toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 20, scripts: { onClick: 'prevKeyFrame(_readOnly_)'}}, + { title: "Back", icon: "chevron-left", toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'prevKeyFrame(_readOnly_)'}}, { title: "Num", icon:"",toolTip: "Frame Number (click to toggle edit mode)",btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}}, - { title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 20, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}}, + { title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}}, { title: "Text", icon: "Text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), expertMode: false, toolType:DocumentType.RTF, funcs: { linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: { linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)`, linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected - { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions", subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} } // Only when Schema is selected + { title: "Schema", icon: "Schema",linearBtnWidth:58, toolTip: "Schema functions", subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} } // Only when Schema is selected ]; } -- cgit v1.2.3-70-g09d2 From 10ed9b42d8fd56364ca8dcfd5b9005fae28b305f Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Sun, 9 Jul 2023 20:08:14 -0400 Subject: fixing dropdown components --- package-lock.json | 25 ++++---- package.json | 2 +- src/client/util/CurrentUserUtils.ts | 28 ++++---- src/client/views/nodes/button/FontIconBox.tsx | 92 ++++++++------------------- src/client/views/topbar/TopBar.tsx | 13 ++-- 5 files changed, 57 insertions(+), 103 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/package-lock.json b/package-lock.json index c48c57357..d938d9658 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4856,9 +4856,13 @@ "integrity": "sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg=" }, "D": { - "version": "1.0.0", + "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==" + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } }, "abab": { "version": "2.0.6", @@ -6195,9 +6199,9 @@ } }, "browndash-components": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.42.tgz", - "integrity": "sha512-GRw4Jx5ZM08zk4W8HGPo2U/Q5zrDJ+d3pbLEj42TJKDkzsQ+SNK2y6RovJTR5SiavrmTx0JZYv902378QZ2u1g==", + "version": "0.0.47", + "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.47.tgz", + "integrity": "sha512-eFiTens6b8+lizT8gkSMZJW7cbroq2chUppLDd4xTlXGUGNwd1qPL+KIF4L21DY4tDouZVKtKI32gODWlIKkjw==", "requires": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", @@ -8160,7 +8164,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, "requires": { "es5-ext": "^0.10.50", "type": "^1.0.1" @@ -9550,7 +9553,6 @@ "version": "0.10.62", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, "requires": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", @@ -9561,7 +9563,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, "requires": { "d": "1", "es5-ext": "^0.10.35", @@ -9577,7 +9578,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, "requires": { "d": "^1.0.1", "ext": "^1.1.2" @@ -11202,7 +11202,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, "requires": { "type": "^2.7.2" }, @@ -11210,8 +11209,7 @@ "type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" } } }, @@ -25314,8 +25312,7 @@ "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, "type-check": { "version": "0.4.0", diff --git a/package.json b/package.json index 5519e0c17..2bfd01211 100644 --- a/package.json +++ b/package.json @@ -177,7 +177,7 @@ "body-parser": "^1.19.2", "bootstrap": "^4.6.1", "brotli": "^1.3.3", - "browndash-components": "0.0.42", + "browndash-components": "0.0.47", "browser-assert": "^1.2.1", "bson": "^4.6.1", "canvas": "^2.9.3", diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 4c5fea260..3475cab82 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -338,19 +338,19 @@ export class CurrentUserUtils { } /// returns descriptions needed to buttons for the left sidebar to open up panes displaying different collections of documents - static leftSidebarMenuBtnDescriptions(doc: Doc):{title:string, target:Doc, icon:string, scripts:{[key:string]:any}, funcs?:{[key:string]:any}}[] { + static leftSidebarMenuBtnDescriptions(doc: Doc):{title:string, target:Doc, icon:string, toolTip: string, scripts:{[key:string]:any}, funcs?:{[key:string]:any}}[] { const badgeValue = "((len) => len && len !== '0' ? len: undefined)(docList(self.target.data).filter(doc => !docList(self.target.viewed).includes(doc)).length.toString())"; const getActiveDashTrails = "Doc.ActiveDashboard?.myTrails"; return [ - { title: "Dashboards", target: this.setupDashboards(doc, "myDashboards"), icon: "desktop", funcs: {hidden: "IsNoviceMode()"} }, - { title: "Search", target: this.setupSearcher(doc, "mySearcher"), icon: "search", }, - { title: "Files", target: this.setupFilesystem(doc, "myFilesystem"), icon: "folder-open", }, - { title: "Tools", target: this.setupToolsBtnPanel(doc, "myTools"), icon: "wrench", funcs: {hidden: "IsNoviceMode()"} }, - { title: "Imports", target: this.setupImportSidebar(doc, "myImports"), icon: "upload", }, - { title: "Recently Closed", target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), icon: "archive", }, - { title: "Shared Docs", target: Doc.MySharedDocs, icon: "users", funcs: {badgeValue:badgeValue}}, - { title: "Trails", target: Doc.UserDoc(), icon: "pres-trail", funcs: {target: getActiveDashTrails}}, - { title: "User Doc View", target: this.setupUserDocView(doc, "myUserDocView"), icon: "address-card",funcs: {hidden: "IsNoviceMode()"} }, + { title: "Dashboards", toolTip: "Dashboards ⌘D", target: this.setupDashboards(doc, "myDashboards"), icon: "desktop", funcs: {hidden: "IsNoviceMode()"} }, + { title: "Search", toolTip: "Search ⌘F", target: this.setupSearcher(doc, "mySearcher"), icon: "search", }, + { title: "Files", toolTip: "Files ⌘⇧F", target: this.setupFilesystem(doc, "myFilesystem"), icon: "folder-open", }, + { title: "Tools", toolTip: "Tools ⌘T", target: this.setupToolsBtnPanel(doc, "myTools"), icon: "wrench", funcs: {hidden: "IsNoviceMode()"} }, + { title: "Imports", toolTip: "Imports ⌘I", target: this.setupImportSidebar(doc, "myImports"), icon: "upload", }, + { title: "Recently Closed", toolTip: "Recently Closed ⌘R", target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), icon: "archive", }, + { title: "Shared Docs", toolTip: "Shared Docs ⌘⇧S", target: Doc.MySharedDocs, icon: "users", funcs: {badgeValue:badgeValue}}, + { title: "Trails", toolTip: "Trails ⌘⇧", target: Doc.UserDoc(), icon: "pres-trail", funcs: {target: getActiveDashTrails}}, + { title: "User Doc View", toolTip: "User Doc ⌘U", target: this.setupUserDocView(doc, "myUserDocView"), icon: "address-card",funcs: {hidden: "IsNoviceMode()"} }, ].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(self)'}})); } @@ -363,10 +363,10 @@ export class CurrentUserUtils { static setupLeftSidebarMenu(doc: Doc, field="myLeftSidebarMenu") { this.setupLeftSidebarPanel(doc); const myLeftSidebarMenu = DocCast(doc[field]); - const menuBtns = CurrentUserUtils.leftSidebarMenuBtnDescriptions(doc).map(({ title, target, icon, scripts, funcs }) => { + const menuBtns = CurrentUserUtils.leftSidebarMenuBtnDescriptions(doc).map(({ title, target, icon, toolTip, scripts, funcs }) => { const btnDoc = myLeftSidebarMenu ? DocListCast(myLeftSidebarMenu.data).find(doc => doc.title === title) : undefined; const reqdBtnOpts:DocumentOptions = { - title, icon, target, btnType: ButtonType.MenuButton, isSystem: true, undoIgnoreFields: new List(['height', 'data_columnHeaders']), dontRegisterView: true, + title, icon, target, toolTip, btnType: ButtonType.MenuButton, isSystem: true, undoIgnoreFields: new List(['height', 'data_columnHeaders']), dontRegisterView: true, _width: 60, _height: 60, _dragOnlyWithinContainer: true, _layout_hideContextMenu: true, }; return DocUtils.AssignScripts(DocUtils.AssignOpts(btnDoc, reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), scripts, funcs); @@ -639,7 +639,7 @@ export class CurrentUserUtils { btnList: new List(["Roboto", "Roboto Mono", "Nunito", "Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"]) }, { title: "Font Size",toolTip: "Font size (%size)", btnType: ButtonType.NumberDropdownButton, width: 75, toolType:"fontSize", ignoreClick: true, scripts: {script: '{ return setFontAttr(self.toolType, value, _readOnly_);}'}, numBtnMax: 200, numBtnMin: 0 }, { title: "Color", toolTip: "Font color (%color)", btnType: ButtonType.ColorButton, icon: "font", toolType:"fontColor",ignoreClick: true, scripts: {script: '{ return setFontAttr(self.toolType, value, _readOnly_);}'}}, - { title: "Highlight",toolTip:"Font highlight", btnType: ButtonType.ColorButton, icon: "highlighter", toolType:"highlight",ignoreClick: true, scripts: {script: '{ return setFontAttr(self.toolType, value, _readOnly_);}'},funcs: {hidden: "IsNoviceMode()"} }, + { title: "Highlight",toolTip:"Font highlight", btnType: ButtonType.ColorButton, icon: "highlighter", toolType:"highlight",ignoreClick: true, scripts: {script: '{ return setFontAttr(self.toolType, value, _readOnly_);}'},funcs: {hidden: "IsNoviceMode()"} }, { title: "Bold", toolTip: "Bold (Ctrl+B)", btnType: ButtonType.ToggleButton, icon: "bold", toolType:"bold", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} }, { title: "Italic", toolTip: "Italic (Ctrl+I)", btnType: ButtonType.ToggleButton, icon: "italic", toolType:"italics", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} }, { title: "Under", toolTip: "Underline (Ctrl+U)", btnType: ButtonType.ToggleButton, icon: "underline", toolType:"underline", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} }, @@ -698,7 +698,7 @@ export class CurrentUserUtils { { title: "Header", icon: "heading", toolTip: "Header Color", btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'}}, { title: "Overlay", icon: "layer-group", toolTip: "Overlay", btnType: ButtonType.ToggleButton, expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)'}, scripts: { onClick: 'toggleOverlay(_readOnly_)'}}, // Only when floating document is selected in freeform { title: "Back", icon: "chevron-left", toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'prevKeyFrame(_readOnly_)'}}, - { title: "Num", icon:"",toolTip: "Frame Number (click to toggle edit mode)",btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}}, + { title: "Num", icon:"", toolTip: "Frame Number (click to toggle edit mode)", btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}}, { title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}}, { title: "Text", icon: "Text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), expertMode: false, toolType:DocumentType.RTF, funcs: { linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: { linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx index b9f75444f..7d5c38140 100644 --- a/src/client/views/nodes/button/FontIconBox.tsx +++ b/src/client/views/nodes/button/FontIconBox.tsx @@ -1,11 +1,12 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@material-ui/core'; -import { Button, ColorPicker, Dropdown, DropdownType, IconButton, IListItemProps, OrientationType, Size, Toggle, ToggleType, Type } from 'browndash-components'; +import { ColorPicker, Dropdown, DropdownType, IconButton, IListItemProps, OrientationType, Size, Toggle, ToggleType, Type } from 'browndash-components'; import { action, computed, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { ColorState, SketchPicker } from 'react-color'; +import * as fa from 'react-icons/fa'; import { Doc, StrListCast } from '../../../../fields/Doc'; import { Height, Width } from '../../../../fields/DocSymbols'; import { InkTool } from '../../../../fields/InkField'; @@ -33,8 +34,6 @@ import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentVie import { OpenWhere } from '../DocumentView'; import { RichTextMenu } from '../formattedText/RichTextMenu'; import { WebBox } from '../WebBox'; -import { FontIconBadge } from './FontIconBadge'; -import * as fa from 'react-icons/fa' import './FontIconBox.scss'; export enum ButtonType { @@ -316,8 +315,8 @@ export class FontIconBox extends DocComponent() { .map(value => ( { text: value, - shortcut: '#', - icon: + style: { fontFamily: value } + // shortcut: '#', } //
() { ); return ( - + ) return ( @@ -405,6 +404,7 @@ export class FontIconBox extends DocComponent() { const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const curColor = this.colorScript?.script.run({ self: this.rootDoc, value: undefined, _readOnly_: true }).result ?? 'transparent'; + const tooltip: string = StrCast(this.rootDoc.toolTip); const label = !this.label || !FontIconBox.GetShowLabels() ? null : ( @@ -414,12 +414,15 @@ export class FontIconBox extends DocComponent() { ); return ( - { - this.colorPickerClosed = !this.colorPickerClosed; - this.noTooltip = !this.colorPickerClosed; - setTimeout(() => Doc.UnBrushAllDocs()); - e.stopPropagation(); - }}/> + { + this.colorPickerClosed = !this.colorPickerClosed; + setTimeout(() => Doc.UnBrushAllDocs()); + e.stopPropagation(); + }} + icon={this.Icon(color)!} + tooltip={tooltip} + /> ) return ( @@ -462,40 +465,15 @@ export class FontIconBox extends DocComponent() { // Determine the type of toggle button const switchToggle: boolean = BoolCast(this.rootDoc.switchToggle); const buttonText: string = StrCast(this.rootDoc.buttonText); + const tooltip: string = StrCast(this.rootDoc.toolTip); // Colors const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); - // Button label - const label = - !this.label || !FontIconBox.GetShowLabels() ? null : ( -
- {this.label} -
- ); - console.log("switchToggle", switchToggle, this.rootDoc.title) + console.log(buttonText, tooltip); return ( - + ) - - if (switchToggle) { - return ( -
- {buttonText ? buttonText : null} - -
- ); - } else { - return ( -
- {this.Icon(color)} - {label} -
- ); - } } /** @@ -504,24 +482,11 @@ export class FontIconBox extends DocComponent() { @computed get defaultButton() { const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); + const tooltip: string = StrCast(this.rootDoc.toolTip); return ( - + ) - - return ( -
-
- {this.Icon(color)} - {!this.label || !FontIconBox.GetShowLabels() ? null : ( -
- {' '} - {this.label}{' '} -
- )} -
-
- ); } @computed get editableText() { @@ -544,6 +509,8 @@ export class FontIconBox extends DocComponent() { render() { const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); + const tooltip: string = StrCast(this.rootDoc.toolTip); + const label = (noBackground: boolean = false) => !this.label || !FontIconBox.GetShowLabels() ? null : (
@@ -577,25 +544,16 @@ export class FontIconBox extends DocComponent() { break; case ButtonType.ClickButton: case ButtonType.ToolButton: button = ( - - //
- // {this.Icon(color)} - // {label()} - //
+ ); break; case ButtonType.MenuButton: button = ( - - //
- // {this.Icon(color)} - // {label(true)} - // - //
+ ); break; } - return !this.layoutDoc.toolTip || this.noTooltip ? button : {StrCast(this.layoutDoc.toolTip)}
}>{button}; + return button; } } diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx index a73d5cce0..80294917f 100644 --- a/src/client/views/topbar/TopBar.tsx +++ b/src/client/views/topbar/TopBar.tsx @@ -166,13 +166,12 @@ export class TopBar extends React.Component { render() { return ( //TODO:glr Add support for light / dark mode -
-
+
+
{this.topbarLeft} {this.topbarCenter} {this.topbarRight} -- cgit v1.2.3-70-g09d2 From 9a63f35496c82fd8be89e9490f65ac6354c7b752 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Mon, 10 Jul 2023 02:25:25 -0400 Subject: fixed collection linear view to an extent still errors remaining and work that needs to be done! --- package-lock.json | 27 ++++---- package.json | 2 +- src/client/util/CurrentUserUtils.ts | 10 +-- src/client/views/collections/CollectionMenu.scss | 2 +- src/client/views/collections/CollectionMenu.tsx | 20 ++++-- .../collectionLinear/CollectionLinearView.tsx | 43 ++++--------- src/client/views/nodes/button/FontIconBox.tsx | 74 +++++++++++++++++----- 7 files changed, 105 insertions(+), 73 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/package-lock.json b/package-lock.json index d938d9658..66ac0fca2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4856,13 +4856,9 @@ "integrity": "sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg=" }, "D": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/D/-/D-1.0.0.tgz", + "integrity": "sha512-nQvrCBu7K2pSSEtIM0EEF03FVjcczCXInMt3moLNFbjlWx6bZrX72uT6/1uAXDbnzGUAx9gTyDiQ+vrFi663oA==" }, "abab": { "version": "2.0.6", @@ -6199,9 +6195,9 @@ } }, "browndash-components": { - "version": "0.0.47", - "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.47.tgz", - "integrity": "sha512-eFiTens6b8+lizT8gkSMZJW7cbroq2chUppLDd4xTlXGUGNwd1qPL+KIF4L21DY4tDouZVKtKI32gODWlIKkjw==", + "version": "0.0.52", + "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.52.tgz", + "integrity": "sha512-rnlHX+h0TQkNLhbS533k4nmPOSyapGHyA7rp0sJw9kzNmjt7Xk75djfimgyoTElU37/k67KKaHnEwaSRro3x3g==", "requires": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", @@ -8164,6 +8160,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, "requires": { "es5-ext": "^0.10.50", "type": "^1.0.1" @@ -9553,6 +9550,7 @@ "version": "0.10.62", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, "requires": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", @@ -9563,6 +9561,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, "requires": { "d": "1", "es5-ext": "^0.10.35", @@ -9578,6 +9577,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, "requires": { "d": "^1.0.1", "ext": "^1.1.2" @@ -11202,6 +11202,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, "requires": { "type": "^2.7.2" }, @@ -11209,7 +11210,8 @@ "type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true } } }, @@ -25312,7 +25314,8 @@ "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true }, "type-check": { "version": "0.4.0", diff --git a/package.json b/package.json index 2bfd01211..45da1e5f4 100644 --- a/package.json +++ b/package.json @@ -177,7 +177,7 @@ "body-parser": "^1.19.2", "bootstrap": "^4.6.1", "brotli": "^1.3.3", - "browndash-components": "0.0.47", + "browndash-components": "0.0.52", "browser-assert": "^1.2.1", "bson": "^4.6.1", "canvas": "^2.9.3", diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 3475cab82..736aeceae 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -347,10 +347,10 @@ export class CurrentUserUtils { { title: "Files", toolTip: "Files ⌘⇧F", target: this.setupFilesystem(doc, "myFilesystem"), icon: "folder-open", }, { title: "Tools", toolTip: "Tools ⌘T", target: this.setupToolsBtnPanel(doc, "myTools"), icon: "wrench", funcs: {hidden: "IsNoviceMode()"} }, { title: "Imports", toolTip: "Imports ⌘I", target: this.setupImportSidebar(doc, "myImports"), icon: "upload", }, - { title: "Recently Closed", toolTip: "Recently Closed ⌘R", target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), icon: "archive", }, - { title: "Shared Docs", toolTip: "Shared Docs ⌘⇧S", target: Doc.MySharedDocs, icon: "users", funcs: {badgeValue:badgeValue}}, + { title: "Closed", toolTip: "Recently Closed ⌘R", target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), icon: "archive", }, + { title: "Shared", toolTip: "Shared Docs ⌘⇧S", target: Doc.MySharedDocs, icon: "users", funcs: {badgeValue:badgeValue}}, { title: "Trails", toolTip: "Trails ⌘⇧", target: Doc.UserDoc(), icon: "pres-trail", funcs: {target: getActiveDashTrails}}, - { title: "User Doc View", toolTip: "User Doc ⌘U", target: this.setupUserDocView(doc, "myUserDocView"), icon: "address-card",funcs: {hidden: "IsNoviceMode()"} }, + { title: "User Doc", toolTip: "User Doc ⌘U", target: this.setupUserDocView(doc, "myUserDocView"), icon: "address-card",funcs: {hidden: "IsNoviceMode()"} }, ].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(self)'}})); } @@ -600,8 +600,8 @@ export class CurrentUserUtils { CurrentUserUtils.createToolButton(opts), scripts, funcs); const btnDescs = [// setup reactions to change the highlights on the undo/redo buttons -- would be better to encode this in the undo/redo buttons, but the undo/redo stacks are not wired up that way yet - { scripts: { onClick: "undo()"}, opts: { title: "undo", icon: "undo-alt", toolTip: "Click to undo" }}, - { scripts: { onClick: "redo()"}, opts: { title: "redo", icon: "redo-alt", toolTip: "Click to redo" }}, + { scripts: { onClick: "undo()"}, opts: { title: "Undo", icon: "undo-alt", toolTip: "Undo ⌘Z" }}, + { scripts: { onClick: "redo()"}, opts: { title: "Redo", icon: "redo-alt", toolTip: "Redo ⌘R" }}, { scripts: { }, opts: { title: "undoStack", layout: "", toolTip: "Undo/Redo Stack"}}, // note: layout fields are hacks -- they don't actually run through the JSX parser (yet) { scripts: { }, opts: { title: "linker", layout: "", toolTip: "link started"}}, { scripts: { }, opts: { title: "currently playing", layout: "", toolTip: "currently playing media"}}, diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index c35f088a6..9db8fe532 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -8,7 +8,7 @@ background-color: $dark-gray; height: 35px; border-bottom: $standard-border; - padding-right: 5px; + padding: 0 10px; align-items: center; .collectionMenu-hardCodedButton { diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 7d71bce13..38692b924 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -42,6 +42,7 @@ import './CollectionMenu.scss'; import { COLLECTION_BORDER_WIDTH } from './CollectionView'; import { TabDocView } from './TabDocView'; import { CollectionFreeFormView } from './collectionFreeForm'; +import { Group, IconButton, Toggle, ToggleType, Type } from 'browndash-components'; interface CollectionMenuProps { panelHeight: () => number; @@ -142,12 +143,17 @@ export class CollectionMenu extends AntimodeMenu { const propIcon = SettingsManager.headerBarHeight > 0 ? 'angle-double-up' : 'angle-double-down'; const propTitle = SettingsManager.headerBarHeight > 0 ? 'Close Header Bar' : 'Open Header Bar'; - const prop = ( - {propTitle}
} key="topar" placement="bottom"> -
0 ? Colors.MEDIUM_BLUE : undefined }} onPointerDown={this.toggleTopBar}> - -
- + const hardCodedButtons = ( +
+ 0} + icon={} + /> +
); // NEW BUTTONS @@ -155,7 +161,7 @@ export class CollectionMenu extends AntimodeMenu { const contMenuButtons = (
{this.contMenuButtons} - {prop} + {hardCodedButtons}
); diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index 8f90e4444..446e720e8 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -20,6 +20,7 @@ import { UndoStack } from '../../UndoStack'; import { CollectionStackedTimeline } from '../CollectionStackedTimeline'; import { CollectionSubView } from '../CollectionSubView'; import './CollectionLinearView.scss'; +import { Button, Type } from 'browndash-components'; /** * CollectionLinearView is the class for rendering the horizontal collection @@ -201,40 +202,22 @@ export class CollectionLinearView extends CollectionSubView() { const isExpanded = BoolCast(this.layoutDoc.linearView_IsExpanded); const menuOpener = ( - + +
); @@ -289,9 +297,7 @@ export class SettingsManager extends React.Component<{}> { @computed get accountOthersContent() { return (
- +
); } @@ -311,7 +317,7 @@ export class SettingsManager extends React.Component<{}> { ); } - setFreeformScrollMode = (mode: freeformScrollMode) => { + setFreeformScrollMode = (mode: string) => { Doc.UserDoc().freeformScrollMode = mode; }; @@ -321,45 +327,77 @@ export class SettingsManager extends React.Component<{}> {
Modes
- -
- -
Playground Mode
-
+ {this.selectUserMode(val as string)}} + dropdownType={DropdownType.SELECT} + type={Type.TERT} + placement='bottom-start' + color={StrCast(Doc.SharingDoc().userColor)} + /> +
-
- Freeform scrolling +
+ Freeform Navigation
- -
-
Scrolling pans canvas, shift + scrolling zooms
-
- -
Scrolling zooms canvas
+ this.setFreeformScrollMode(val as string)} + dropdownType={DropdownType.SELECT} + type={Type.TERT} + placement='bottom-start' + color={StrCast(Doc.SharingDoc().userColor)} + />
Permissions
- -
- (Doc.defaultAclPrivate = !Doc.defaultAclPrivate))} /> -
Default access private
-
+
@@ -390,14 +428,20 @@ export class SettingsManager extends React.Component<{}> {
{Doc.CurrentUserEmail}
- +
-
- + +
+
@@ -418,7 +462,7 @@ export class SettingsManager extends React.Component<{}> { isDisplayed={this.isOpen} interactive={true} closeOnExternalClick={this.close} - dialogueBoxStyle={{ width: '500px', height: '300px', background: Cast(Doc.SharingDoc().userColor, 'string', null) }} + dialogueBoxStyle={{ width: 'fit-content', height: '300px', background: Cast(Doc.SharingDoc().userColor, 'string', null) }} /> ); } diff --git a/src/client/util/SharingManager.scss b/src/client/util/SharingManager.scss index 932e94664..1be27fa62 100644 --- a/src/client/util/SharingManager.scss +++ b/src/client/util/SharingManager.scss @@ -17,10 +17,8 @@ .close-button { position: absolute; - right: 1em; - top: 1em; - cursor: pointer; - z-index: 999; + right: 2px; + top: 2px; } .share-container { diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 1a7a4d342..3bd6ac61c 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -394,6 +394,7 @@ export class DashboardView extends React.Component { _layout_hideContextMenu: true, title: 'New trail', toolTip: 'Create new trail', + color: Colors.BLACK, btnType: ButtonType.ClickButton, buttonText: 'New trail', icon: 'plus', diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index b0b757388..e84e2620f 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -16,6 +16,7 @@ import { CollectionView } from './collections/CollectionView'; import { MainView } from './MainView'; import * as dotenv from 'dotenv'; // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import import { PingManager } from '../util/PingManager'; +import './global/globalScripts'; dotenv.config(); AssignAllExtensions(); diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts new file mode 100644 index 000000000..8f6d898fe --- /dev/null +++ b/src/client/views/global/globalScripts.ts @@ -0,0 +1,407 @@ +import { Colors } from "browndash-components"; +import { runInAction, action } from "mobx"; +import { aggregateBounds } from "../../../Utils"; +import { Doc } from "../../../fields/Doc"; +import { Width, Height } from "../../../fields/DocSymbols"; +import { InkTool } from "../../../fields/InkField"; +import { Cast, StrCast, NumCast, BoolCast } from "../../../fields/Types"; +import { WebField } from "../../../fields/URLField"; +import { GestureUtils } from "../../../pen-gestures/GestureUtils"; +import { LinkManager } from "../../util/LinkManager"; +import { ScriptingGlobals } from "../../util/ScriptingGlobals"; +import { SelectionManager } from "../../util/SelectionManager"; +import { UndoManager } from "../../util/UndoManager"; +import { GestureOverlay } from "../GestureOverlay"; +import { InkTranscription } from "../InkTranscription"; +import { ActiveFillColor, SetActiveFillColor, ActiveIsInkMask, SetActiveIsInkMask, ActiveInkWidth, SetActiveInkWidth, ActiveInkColor, SetActiveInkColor } from "../InkingStroke"; +import { CollectionFreeFormView } from "../collections/collectionFreeForm"; +import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; +import { WebBox } from "../nodes/WebBox"; +import { RichTextMenu } from "../nodes/formattedText/RichTextMenu"; +import { DocumentType } from "../../documents/DocumentTypes"; + +// toggle: Set overlay status of selected document +ScriptingGlobals.add(function setView(view: string) { + const selected = SelectionManager.Docs().lastElement(); + selected ? (selected._type_collection = view) : console.log('[FontIconBox.tsx] changeView failed'); +}); + +// toggle: Set overlay status of selected document +ScriptingGlobals.add(function setBackgroundColor(color?: string, checkResult?: boolean) { + const selectedViews = SelectionManager.Views(); + console.log(color, checkResult); + if (Doc.ActiveTool !== InkTool.None) { + if (checkResult) { + return ActiveFillColor(); + } + SetActiveFillColor(color ?? 'transparent'); + } else if (selectedViews.length) { + if (checkResult) { + const selView = selectedViews.lastElement(); + const fieldKey = selView.rootDoc.type === DocumentType.INK ? 'fillColor' : 'backgroundColor'; + const layoutFrameNumber = Cast(selView.props.docViewPath().lastElement()?.rootDoc?._currentFrame, 'number'); // frame number that container is at which determines layout frame values + const contentFrameNumber = Cast(selView.rootDoc?._currentFrame, 'number', layoutFrameNumber ?? null); // frame number that content is at which determines what content is displayed + return CollectionFreeFormDocumentView.getStringValues(selView?.rootDoc, contentFrameNumber)[fieldKey] ?? 'transparent'; + } + selectedViews.forEach(dv => { + const fieldKey = dv.rootDoc.type === DocumentType.INK ? 'fillColor' : 'backgroundColor'; + const layoutFrameNumber = Cast(dv.props.docViewPath().lastElement()?.rootDoc?._currentFrame, 'number'); // frame number that container is at which determines layout frame values + const contentFrameNumber = Cast(dv.rootDoc?._currentFrame, 'number', layoutFrameNumber ?? null); // frame number that content is at which determines what content is displayed + if (contentFrameNumber !== undefined) { + CollectionFreeFormDocumentView.setStringValues(contentFrameNumber, dv.rootDoc, { fieldKey: color }); + } else { + console.log('setting color to: ', color) + dv.rootDoc['_' + fieldKey] = color; + } + }); + } else { + const selected = SelectionManager.Docs().length ? SelectionManager.Docs() : LinkManager.currentLink ? [LinkManager.currentLink] : []; + if (checkResult) { + return selected.lastElement()?._backgroundColor ?? 'transparent'; + } + selected.forEach(doc => (doc._backgroundColor = color)); + } +}); + +// toggle: Set overlay status of selected document +ScriptingGlobals.add(function setHeaderColor(color?: string, checkResult?: boolean) { + if (checkResult) { + return Doc.SharingDoc().userColor; + } + Doc.SharingDoc().userColor = undefined; + Doc.GetProto(Doc.SharingDoc()).userColor = color; + Doc.UserDoc().layout_showTitle = color === 'transparent' ? undefined : StrCast(Doc.UserDoc().layout_showTitle, 'author_date'); +}); + +// toggle: Set overlay status of selected document +ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) { + const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined; + if (checkResult) { + if (NumCast(selected?.Document.z) >= 1) return Colors.MEDIUM_BLUE; + return 'transparent'; + } + selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log('[FontIconBox.tsx] toggleOverlay failed'); +}); + +ScriptingGlobals.add(function showFreeform(attr: 'flashcards' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll', checkResult?: boolean) { + const selected = SelectionManager.Docs().lastElement(); + // prettier-ignore + const map: Map<'flashcards' | 'grid' | 'snaplines' | 'clusters' | 'arrange'| 'viewAll', { waitForRender?: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc) => void;}> = new Map([ + ['grid', { + checkResult: (doc:Doc) => doc._freeform_backgroundGrid, + setDoc: (doc:Doc) => doc._freeform_backgroundGrid = !doc._freeform_backgroundGrid, + }], + ['snaplines', { + checkResult: (doc:Doc) => doc._freeform_snapLines, + setDoc: (doc:Doc) => doc._freeform_snapLines = !doc._freeform_snapLines, + }], + ['viewAll', { + checkResult: (doc:Doc) => doc._freeform_fitContentsToBox, + setDoc: (doc:Doc) => doc._freeform_fitContentsToBox = !doc._freeform_fitContentsToBox, + }], + ['clusters', { + waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire + checkResult: (doc:Doc) => doc._freeform_useClusters, + setDoc: (doc:Doc) => doc._freeform_useClusters = !doc._freeform_useClusters, + }], + ['arrange', { + waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire + checkResult: (doc:Doc) => doc._autoArrange, + setDoc: (doc:Doc) => doc._autoArrange = !doc._autoArrange, + }], + ['flashcards', { + checkResult: (doc:Doc) => Doc.UserDoc().defaultToFlashcards, + setDoc: (doc:Doc) => Doc.UserDoc().defaultToFlashcards = !Doc.UserDoc().defaultToFlashcards, + }], + ]); + + if (checkResult) { + return map.get(attr)?.checkResult(selected) ? Colors.MEDIUM_BLUE : 'transparent'; + } + const batch = map.get(attr)?.waitForRender ? UndoManager.StartBatch('set freeform attribute') : { end: () => {} }; + SelectionManager.Docs().map(dv => map.get(attr)?.setDoc(dv)); + setTimeout(() => batch.end(), 100); +}); +ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highlight' | 'fontSize', value: any, checkResult?: boolean) { + const editorView = RichTextMenu.Instance?.TextView?.EditorView; + const selected = SelectionManager.Docs().lastElement(); + // prettier-ignore + const map: Map<'font'|'fontColor'|'highlight'|'fontSize', { checkResult: () => any; setDoc: () => void;}> = new Map([ + ['font', { + checkResult: () => RichTextMenu.Instance?.fontFamily, + setDoc: () => value && RichTextMenu.Instance.setFontFamily(value), + }], + ['highlight', { + checkResult: () =>(selected ?? Doc.UserDoc())._fontHighlight, + setDoc: () => value && RichTextMenu.Instance.setHighlight(value), + }], + ['fontColor', { + checkResult: () => RichTextMenu.Instance?.fontColor, + setDoc: () => value && RichTextMenu.Instance.setColor(value), + }], + ['fontSize', { + checkResult: () => RichTextMenu.Instance?.fontSize.replace('px', ''), + setDoc: () => { + if (typeof value === 'number') value = value.toString(); + if (value && Number(value).toString() === value) value += 'px'; + RichTextMenu.Instance.setFontSize(value); + }, + }], + ]); + + if (checkResult) { + return map.get(attr)?.checkResult(); + } + map.get(attr)?.setDoc?.(); +}); + +type attrname = 'noAutoLink' | 'dictation' | 'bold' | 'italics' | 'underline' | 'left' | 'center' | 'right' | 'bullet' | 'decimal'; +type attrfuncs = [attrname, { checkResult: () => boolean; toggle: () => any }]; +ScriptingGlobals.add(function toggleCharStyle(charStyle: attrname, checkResult?: boolean) { + const textView = RichTextMenu.Instance?.TextView; + const editorView = textView?.EditorView; + // prettier-ignore + const alignments:attrfuncs[] = (['left','right','center'] as ("left"|"center"|"right")[]).map((where) => + [ where, { checkResult: () =>(editorView ? (RichTextMenu.Instance.textAlign ===where): (Doc.UserDoc().textAlign ===where) ? true:false), + toggle: () => (editorView?.state ? RichTextMenu.Instance.align(editorView, editorView.dispatch, where):(Doc.UserDoc().textAlign = where))}]); + // prettier-ignore + const listings:attrfuncs[] = (['bullet','decimal'] as attrname[]).map(list => + [ list, { checkResult: () => (editorView ? RichTextMenu.Instance.getActiveListStyle() === list:false), + toggle: () => editorView?.state && RichTextMenu.Instance.changeListType(list) }]); + // prettier-ignore + const attrs:attrfuncs[] = [ + ['dictation', { checkResult: () => textView?._recording ? true:false, + toggle: () => textView && runInAction(() => (textView._recording = !textView._recording)) }], + ['noAutoLink',{ checkResult: () => (editorView ? RichTextMenu.Instance.noAutoLink : false), + toggle: () => editorView && RichTextMenu.Instance?.toggleNoAutoLinkAnchor()}], + ['bold', { checkResult: () => (editorView ? RichTextMenu.Instance.bold : (Doc.UserDoc().fontWeight === 'bold') ? true:false), + toggle: editorView ? RichTextMenu.Instance.toggleBold : () => (Doc.UserDoc().fontWeight = Doc.UserDoc().fontWeight === 'bold' ? undefined : 'bold')}], + ['italics', { checkResult: () => (editorView ? RichTextMenu.Instance.italics : (Doc.UserDoc().fontStyle === 'italics') ? true:false), + toggle: editorView ? RichTextMenu.Instance.toggleItalics : () => (Doc.UserDoc().fontStyle = Doc.UserDoc().fontStyle === 'italics' ? undefined : 'italics')}], + ['underline', { checkResult: () => (editorView ? RichTextMenu.Instance.underline : (Doc.UserDoc().textDecoration === 'underline') ? true:false), + toggle: editorView ? RichTextMenu.Instance.toggleUnderline : () => (Doc.UserDoc().textDecoration = Doc.UserDoc().textDecoration === 'underline' ? undefined : 'underline') }]] + + const map = new Map(attrs.concat(alignments).concat(listings)); + if (checkResult) return map.get(charStyle)?.checkResult() ? Colors.MEDIUM_BLUE : 'transparent'; + map.get(charStyle)?.toggle(); +}); + +export function checkInksToGroup() { + // console.log("getting here to inks group"); + if (Doc.ActiveTool === InkTool.Write) { + CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => { + // TODO: nda - will probably want to go through ffView unprocessed docs and then see if any of the inksToGroup docs are in it and only use those + // find all inkDocs in ffView.unprocessedDocs that are within 200 pixels of each other + const inksToGroup = ffView.unprocessedDocs.filter(inkDoc => { + // console.log(inkDoc.x, inkDoc.y); + }); + }); + } +} + +export function createInkGroup(inksToGroup?: Doc[], isSubGroup?: boolean) { + // TODO nda - if document being added to is a inkGrouping then we can just add to that group + if (Doc.ActiveTool === InkTool.Write) { + CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => { + // TODO: nda - will probably want to go through ffView unprocessed docs and then see if any of the inksToGroup docs are in it and only use those + const selected = ffView.unprocessedDocs; + // loop through selected an get the bound + const bounds: { x: number; y: number; width?: number; height?: number }[] = []; + + selected.map( + action(d => { + const x = NumCast(d.x); + const y = NumCast(d.y); + const width = d[Width](); + const height = d[Height](); + bounds.push({ x, y, width, height }); + }) + ); + + const aggregBounds = aggregateBounds(bounds, 0, 0); + const marqViewRef = ffView._marqueeViewRef.current; + + // set the vals for bounds in marqueeView + if (marqViewRef) { + marqViewRef._downX = aggregBounds.x; + marqViewRef._downY = aggregBounds.y; + marqViewRef._lastX = aggregBounds.r; + marqViewRef._lastY = aggregBounds.b; + } + + selected.map( + action(d => { + const dx = NumCast(d.x); + const dy = NumCast(d.y); + delete d.x; + delete d.y; + delete d.activeFrame; + delete d._timecodeToShow; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection + delete d._timecodeToHide; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection + // calculate pos based on bounds + if (marqViewRef?.Bounds) { + d.x = dx - marqViewRef.Bounds.left - marqViewRef.Bounds.width / 2; + d.y = dy - marqViewRef.Bounds.top - marqViewRef.Bounds.height / 2; + } + return d; + }) + ); + ffView.props.removeDocument?.(selected); + // TODO: nda - this is the code to actually get a new grouped collection + const newCollection = marqViewRef?.getCollection(selected, undefined, true); + if (newCollection) { + newCollection.height = newCollection[Height](); + newCollection.width = newCollection[Width](); + } + + // nda - bug: when deleting a stroke before leaving writing mode, delete the stroke from unprocessed ink docs + newCollection && ffView.props.addDocument?.(newCollection); + // TODO: nda - will probably need to go through and only remove the unprocessed selected docs + ffView.unprocessedDocs = []; + + InkTranscription.Instance.transcribeInk(newCollection, selected, false); + }); + } + CollectionFreeFormView.collectionsWithUnprocessedInk.clear(); +} + +function setActiveTool(tool: InkTool | GestureUtils.Gestures, keepPrim: boolean, checkResult?: boolean) { + InkTranscription.Instance?.createInkGroup(); + if (checkResult) { + return (Doc.ActiveTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool + ? GestureOverlay.Instance?.KeepPrimitiveMode || ![GestureUtils.Gestures.Circle, GestureUtils.Gestures.Line, GestureUtils.Gestures.Rectangle].includes(tool as GestureUtils.Gestures) + ? Colors.MEDIUM_BLUE + : Colors.MEDIUM_BLUE_ALT + : 'transparent'; + } + runInAction(() => { + if (GestureOverlay.Instance) { + GestureOverlay.Instance.KeepPrimitiveMode = keepPrim; + } + if (Object.values(GestureUtils.Gestures).includes(tool as any)) { + if (GestureOverlay.Instance.InkShape === tool && !keepPrim) { + Doc.ActiveTool = InkTool.None; + GestureOverlay.Instance.InkShape = undefined; + } else { + Doc.ActiveTool = InkTool.Pen; + GestureOverlay.Instance.InkShape = tool as GestureUtils.Gestures; + } + } else if (tool) { + // pen or eraser + if (Doc.ActiveTool === tool && !GestureOverlay.Instance.InkShape && !keepPrim) { + Doc.ActiveTool = InkTool.None; + } else { + Doc.ActiveTool = tool as any; + GestureOverlay.Instance.InkShape = undefined; + } + } else { + Doc.ActiveTool = InkTool.None; + } + }); +} + +ScriptingGlobals.add(setActiveTool, 'sets the active ink tool mode'); + +// toggle: Set overlay status of selected document +ScriptingGlobals.add(function setInkProperty(option: 'inkMask' | 'fillColor' | 'strokeWidth' | 'strokeColor', value: any, checkResult?: boolean) { + const selected = SelectionManager.Docs().lastElement(); + // prettier-ignore + const map: Map<'inkMask' | 'fillColor' | 'strokeWidth' | 'strokeColor', { checkResult: () => any; setInk: (doc: Doc) => void; setMode: () => void }> = new Map([ + ['inkMask', { + checkResult: () => ((selected?.type === DocumentType.INK ? BoolCast(selected.stroke_isInkMask) : ActiveIsInkMask()) ? Colors.MEDIUM_BLUE : 'transparent'), + setInk: (doc: Doc) => (doc.stroke_isInkMask = !doc.stroke_isInkMask), + setMode: () => selected?.type !== DocumentType.INK && SetActiveIsInkMask(!ActiveIsInkMask()), + }], + ['fillColor', { + checkResult: () => (selected?.type === DocumentType.INK ? StrCast(selected.fillColor) : ActiveFillColor() ?? "transparent"), + setInk: (doc: Doc) => (doc.fillColor = StrCast(value)), + setMode: () => SetActiveFillColor(StrCast(value)), + }], + [ 'strokeWidth', { + checkResult: () => (selected?.type === DocumentType.INK ? NumCast(selected.stroke_width) : ActiveInkWidth()), + setInk: (doc: Doc) => (doc.stroke_width = NumCast(value)), + setMode: () => SetActiveInkWidth(value.toString()), + }], + ['strokeColor', { + checkResult: () => (selected?.type === DocumentType.INK ? StrCast(selected.color) : ActiveInkColor()), + setInk: (doc: Doc) => (doc.color = String(value)), + setMode: () => SetActiveInkColor(StrCast(value)), + }], + ]); + + if (checkResult) { + return map.get(option)?.checkResult(); + } + map.get(option)?.setMode(); + SelectionManager.Docs() + .filter(doc => doc.type === DocumentType.INK) + .map(doc => map.get(option)?.setInk(doc)); +}); + +/** WEB + * webSetURL + **/ +ScriptingGlobals.add(function webSetURL(url: string, checkResult?: boolean) { + const selected = SelectionManager.Views().lastElement(); + if (selected?.rootDoc.type === DocumentType.WEB) { + if (checkResult) { + return StrCast(selected.rootDoc.data, Cast(selected.rootDoc.data, WebField, null)?.url?.href); + } + selected.ComponentView?.setData?.(url); + //selected.rootDoc.data = new WebField(url); + } +}); +ScriptingGlobals.add(function webForward(checkResult?: boolean) { + const selected = SelectionManager.Views().lastElement()?.ComponentView as WebBox; + if (checkResult) { + return selected?.forward(checkResult) ? undefined : 'lightGray'; + } + selected?.forward(); +}); +ScriptingGlobals.add(function webBack(checkResult?: boolean) { + const selected = SelectionManager.Views().lastElement()?.ComponentView as WebBox; + if (checkResult) { + return selected?.back(checkResult) ? undefined : 'lightGray'; + } + selected?.back(); +}); + +/** Schema + * toggleSchemaPreview + **/ +ScriptingGlobals.add(function toggleSchemaPreview(checkResult?: boolean) { + const selected = SelectionManager.Docs().lastElement(); + if (checkResult && selected) { + const result: boolean = NumCast(selected.schema_previewWidth) > 0; + if (result) return Colors.MEDIUM_BLUE; + else return 'transparent'; + } else if (selected) { + if (NumCast(selected.schema_previewWidth) > 0) { + selected.schema_previewWidth = 0; + } else { + selected.schema_previewWidth = 200; + } + } +}); +ScriptingGlobals.add(function toggleSingleLineSchema(checkResult?: boolean) { + const selected = SelectionManager.Docs().lastElement(); + if (checkResult && selected) { + return NumCast(selected._schema_singleLine) > 0 ? Colors.MEDIUM_BLUE : 'transparent'; + } + if (selected) { + selected._schema_singleLine = !selected._schema_singleLine; + } +}); + +/** STACK + * groupBy + */ +ScriptingGlobals.add(function setGroupBy(key: string, checkResult?: boolean) { + SelectionManager.Docs().map(doc => (doc._text_fontFamily = key)); + const editorView = RichTextMenu.Instance.TextView?.EditorView; + if (checkResult) { + return StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily); + } + if (editorView) RichTextMenu.Instance.setFontFamily(key); + else Doc.UserDoc().fontFamily = key; +}); diff --git a/src/client/views/nodes/button/ButtonInterface.ts b/src/client/views/nodes/button/ButtonInterface.ts deleted file mode 100644 index 0aa2ac8e1..000000000 --- a/src/client/views/nodes/button/ButtonInterface.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Doc } from "../../../../fields/Doc"; -import { IconProp } from "@fortawesome/fontawesome-svg-core"; -import { ButtonType } from "./FontIconBox"; - -export interface IButtonProps { - type: string | ButtonType; - rootDoc: Doc; - label: any; - icon: IconProp; - color: string; - backgroundColor: string; -} \ No newline at end of file diff --git a/src/client/views/nodes/button/FontIconBadge.scss b/src/client/views/nodes/button/FontIconBadge.scss deleted file mode 100644 index 78f506e57..000000000 --- a/src/client/views/nodes/button/FontIconBadge.scss +++ /dev/null @@ -1,11 +0,0 @@ -.fontIconBadge { - background: red; - width: 15px; - height: 15px; - top: 8px; - display: block; - position: absolute; - right: 5; - border-radius: 50%; - text-align: center; -} \ No newline at end of file diff --git a/src/client/views/nodes/button/FontIconBadge.tsx b/src/client/views/nodes/button/FontIconBadge.tsx deleted file mode 100644 index b50588ce2..000000000 --- a/src/client/views/nodes/button/FontIconBadge.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { observer } from 'mobx-react'; -import * as React from 'react'; -import './FontIconBadge.scss'; - -interface FontIconBadgeProps { - value: string | undefined; -} - -@observer -export class FontIconBadge extends React.Component { - _notifsRef = React.createRef(); - - // onPointerDown = (e: React.PointerEvent) => { - // setupMoveUpEvents(this, e, - // (e: PointerEvent) => { - // const dragData = new DragManager.DocumentDragData([this.props.collection!]); - // DragManager.StartDocumentDrag([this._notifsRef.current!], dragData, e.x, e.y); - // return true; - // }, - // returnFalse, emptyFunction, false); - // } - - render() { - if (this.props.value === undefined) return null; - return ( -
-
- {this.props.value} -
-
- ); - } -} diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx index d181de8d0..e31407f4b 100644 --- a/src/client/views/nodes/button/FontIconBox.tsx +++ b/src/client/views/nodes/button/FontIconBox.tsx @@ -1,39 +1,23 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; -import { ColorPicker, Dropdown, DropdownType, IconButton, IListItemProps, Size, Toggle, ToggleType, Type } from 'browndash-components'; -import { action, computed, observable, runInAction } from 'mobx'; +import { Button, ColorPicker, Dropdown, DropdownType, EditableText, IconButton, IListItemProps, NumberDropdown, NumberDropdownType, Size, Toggle, ToggleType, Type } from 'browndash-components'; +import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { ColorState, SketchPicker } from 'react-color'; -import * as fa from 'react-icons/fa'; import { Doc, StrListCast } from '../../../../fields/Doc'; -import { Height, Width } from '../../../../fields/DocSymbols'; -import { InkTool } from '../../../../fields/InkField'; import { ScriptField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; -import { WebField } from '../../../../fields/URLField'; -import { GestureUtils } from '../../../../pen-gestures/GestureUtils'; -import { aggregateBounds, Utils } from '../../../../Utils'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; -import { LinkManager } from '../../../util/LinkManager'; -import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { SelectionManager } from '../../../util/SelectionManager'; -import { undoable, undoBatch, UndoManager } from '../../../util/UndoManager'; -import { CollectionFreeFormView } from '../../collections/collectionFreeForm'; +import { undoable, UndoManager } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; import { DocComponent } from '../../DocComponent'; import { EditableView } from '../../EditableView'; -import { GestureOverlay } from '../../GestureOverlay'; import { Colors } from '../../global/globalEnums'; -import { ActiveFillColor, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth, SetActiveIsInkMask } from '../../InkingStroke'; -import { InkTranscription } from '../../InkTranscription'; import { StyleProp } from '../../StyleProvider'; import { FieldView, FieldViewProps } from '.././FieldView'; -import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentView'; import { OpenWhere } from '../DocumentView'; import { RichTextMenu } from '../formattedText/RichTextMenu'; -import { WebBox } from '../WebBox'; import './FontIconBox.scss'; export enum ButtonType { @@ -136,116 +120,35 @@ export class FontIconBox extends DocComponent() { /** * Number button */ - @computed get numberSliderButton() { + @computed get numberDropdown() { + let type: NumberDropdownType; + switch(this.type) { + case ButtonType.NumberDropdownButton: + type = 'dropdown' + break; + case ButtonType.NumberInlineButton: + type = 'input' + break; + case ButtonType.NumberSliderButton: + default: + type = 'slider' + break; + } const numScript = (value?: number) => ScriptCast(this.rootDoc.script).script.run({ self: this.rootDoc, value, _readOnly_: value === undefined }); + const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); // Script for checking the outcome of the toggle - const checkResult = Number(numScript().result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3)); + const checkResult = Number(Number(numScript().result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3))); const label = !FontIconBox.GetShowLabels() ? null :
{this.label}
; - const dropdown = ( -
e.stopPropagation()}> - (this._batch = UndoManager.StartBatch('num slider changing'))} - onPointerUp={() => this._batch?.end()} - onChange={undoable(e => { - e.stopPropagation(); - numScript(Number(e.target.value)); - }, 'set num value')} - /> -
- ); - return ( -
e.stopPropagation()} - onClick={action(() => { - this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen; - this.noTooltip = this.rootDoc.dropDownOpen; - Doc.UnBrushAllDocs(); - })}> - {checkResult} - {label} - {this.rootDoc.dropDownOpen ? dropdown : null} -
- ); - } - /** - * Number button - */ - @computed get numberDropdownButton() { - const numScript = (value?: number) => ScriptCast(this.rootDoc.script)?.script.run({ self: this.rootDoc, value, _readOnly_: value === undefined }); - - const checkResult = Number(numScript().result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3)); - - const items: number[] = []; - for (let i = 0; i < 100; i += 2) items.push(i); - - const list = items.map(value => { - return ( -
numScript(value), `${this.rootDoc.title} button set from list`)}> - {value} -
- ); - }); - return ( -
-
numScript(Number(checkResult) - 1), `${this.rootDoc.title} decrement value`)}> - -
-
{ - e.stopPropagation(); - e.preventDefault(); - }} - onClick={action(() => { - this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen; - this.noTooltip = this.rootDoc.dropDownOpen; - Doc.UnBrushAllDocs(); - })}> - numScript(Number(e.target.value)), `${this.rootDoc.title} button set value`)} /> -
-
numScript(Number(checkResult) + 1), `${this.rootDoc.title} increment value`)}> - -
- - {this.rootDoc.dropDownOpen ? ( -
-
- {list} -
-
{ - e.stopPropagation(); - this.rootDoc.dropDownOpen = false; - this.noTooltip = false; - Doc.UnBrushAllDocs(); - })} - /> -
- ) : null} -
- ); - } - /** - * Number button - */ - @computed get numberInlineButton() { - return
; + return numScript(value), `${this.rootDoc.title} button set from list`)} + /> } /** @@ -296,18 +199,22 @@ export class FontIconBox extends DocComponent() { try { if (script?.script.originalScript.startsWith('setView')) { const selected = SelectionManager.Docs().lastElement(); + console.log('selected') if (selected) { if (StrCast(selected.type) === DocumentType.COL) { text = StrCast(selected._type_collection); } else { + console.log("doc selected", selected.title) dropdown = false; text = selected.type === DocumentType.RTF ? 'Text' : StrCast(selected.type); icon = Doc.toIcon(selected); + return
Hi!
} } else { dropdown = false; icon = 'globe-asia'; text = 'User Default'; + return
Hi!
} noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking, CollectionViewType.NoteTaking]; } else text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily); @@ -323,79 +230,32 @@ export class FontIconBox extends DocComponent() { .map(value => ( { text: value, + val: value, style: { fontFamily: value }, onClick: undoable(() => script.script.run({ self: this.rootDoc, value }), value) // shortcut: '#', } )); - const label = - !this.label || !FontIconBox.GetShowLabels() ? null : ( -
- {this.label} -
- ); return ( - + script.script.run({ self: this.rootDoc, val }), `dropdown select ${this.label}`)} + color={Colors.WHITE} + type={Type.PRIM} + dropdownType={DropdownType.SELECT} + items={list} + tooltip={this.label} + /> ) - - return ( -
{ - this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen; - this.noTooltip = this.rootDoc.dropDownOpen; - Doc.UnBrushAllDocs(); - }) - : undefined - }> - {dropdown ? null : } -
{text && text[0].toUpperCase() + text.slice(1)}
- {label} - {!dropdown ? null : ( -
- -
- )} - {this.rootDoc.dropDownOpen ? ( -
-
- {list} -
-
{ - e.stopPropagation(); - this.rootDoc.dropDownOpen = false; - this.noTooltip = false; - Doc.UnBrushAllDocs(); - })} - /> -
- ) : null} -
- ); } - @observable colorPickerClosed: boolean = true; + @computed get colorScript() { return ScriptCast(this.rootDoc.script); } - colorPicker = (curColor: string) => { - const change = (value: ColorState, ev: MouseEvent) => { - ev.preventDefault(); - ev.stopPropagation(); - const s = this.colorScript; - s && undoBatch(() => s.script.run({ self: this.rootDoc, value: Utils.colorString(value), _readOnly_: false }).result)(); - }; - const presets = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']; - return ; - }; /** * Color button */ @@ -405,61 +265,20 @@ export class FontIconBox extends DocComponent() { const curColor = this.colorScript?.script.run({ self: this.rootDoc, value: undefined, _readOnly_: true }).result ?? 'transparent'; const tooltip: string = StrCast(this.rootDoc.toolTip); - const label = - !this.label || !FontIconBox.GetShowLabels() ? null : ( -
- {this.label} -
- ); - return ( { - this.colorPickerClosed = !this.colorPickerClosed; - setTimeout(() => Doc.UnBrushAllDocs()); - e.stopPropagation(); + setSelectedColor={(value) => { + const s = this.colorScript; + s && undoable(() => s.script.run({ self: this.rootDoc, value: value, _readOnly_: false }).result, `Set ${tooltip} to ${value}`)(); }} - color={color} + selectedColor={curColor} type={Type.PRIM} + color={color} icon={this.Icon(color)!} tooltip={tooltip} + label={this.label} /> ) - - return ( -
{ - this.colorPickerClosed = !this.colorPickerClosed; - this.noTooltip = !this.colorPickerClosed; - setTimeout(() => Doc.UnBrushAllDocs()); - e.stopPropagation(); - })} - onPointerDown={e => e.stopPropagation()}> - {this.Icon(color)} -
- {label} - {/* {dropdownCaret} */} - {this.colorPickerClosed ? null : ( -
-
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onClick={e => e.stopPropagation()}> - {this.colorPicker(curColor)} -
-
{ - e.preventDefault(); - e.stopPropagation(); - this.colorPickerClosed = true; - this.noTooltip = false; - Doc.UnBrushAllDocs(); - })} - /> -
- )} -
- ); } @computed get toggleButton() { @@ -498,6 +317,11 @@ export class FontIconBox extends DocComponent() { const checkResult = script?.script.run({ value: '', _readOnly_: true }).result; const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ value, _readOnly_: false }).result; + + return {}} setEditing={(editing: boolean) => {}} + /> + return (
@@ -514,78 +338,39 @@ export class FontIconBox extends DocComponent() { const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const tooltip: string = StrCast(this.rootDoc.toolTip); - const label = (noBackground: boolean = false) => - !this.label || !FontIconBox.GetShowLabels() ? null : ( -
- {this.label} -
- ); // TODO:glr Add label of button type let button: JSX.Element = this.defaultButton; - // prettier-ignore switch (this.type) { - case ButtonType.EditableText: return this.editableText; + case ButtonType.EditableText: + button = this.editableText; + break; case ButtonType.DropdownList: - let script = ScriptCast(this.rootDoc.script); - let noviceList: string[] = []; - let text: string | undefined; - let dropdown = true; - let icon: IconProp = 'caret-down'; - try { - if (script?.script.originalScript.startsWith('setView')) { - const selected = SelectionManager.Docs().lastElement(); - if (selected) { - if (StrCast(selected.type) === DocumentType.COL) { - text = StrCast(selected._type_collection); - } else { - dropdown = false; - text = selected.type === DocumentType.RTF ? 'Text' : StrCast(selected.type); - icon = Doc.toIcon(selected); - } - } else { - dropdown = false; - icon = 'globe-asia'; - text = 'User Default'; - } - noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking, CollectionViewType.NoteTaking]; - } else text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily); - } catch (e) { - console.log(e); - } - // Get items to place into the list - const list: IListItemProps[] = this.buttonList - .filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value)) - .map(value => ( - { - text: value, - style: { fontFamily: value }, - onClick: undoable(() => script.script.run({ self: this.rootDoc, value }), value) - // shortcut: '#', - } - )); - button = + button = this.dropdownListButton; + break; + case ButtonType.ColorButton: + button = this.colorButton; + break; + case ButtonType.NumberDropdownButton: + case ButtonType.NumberInlineButton: + case ButtonType.NumberSliderButton: + button = this.numberDropdown; + break; + case ButtonType.DropdownButton: + button = this.dropdownButton; break; - case ButtonType.ColorButton: button = this.colorButton; break; - case ButtonType.NumberDropdownButton: button = this.numberDropdownButton; break; - case ButtonType.NumberInlineButton: button = this.numberInlineButton; break; - case ButtonType.NumberSliderButton: button = this.numberSliderButton; break; - case ButtonType.DropdownButton: button = this.dropdownButton; break; case ButtonType.ToggleButton: button = this.toggleButton; break; case ButtonType.TextButton: - // Script for checking the outcome of the toggle - script = ScriptCast(this.rootDoc.script); - const checkResult = script?.script.run({ _readOnly_: true }).result; - button = ( -
- {this.Icon(color)} - {StrCast(this.rootDoc.buttonText) ?
{StrCast(this.rootDoc.buttonText)}
: null} - {label()} -
+ // Script for checking the outcome of the toggle + const script = ScriptCast(this.rootDoc.script); + const checkResult = script?.script.run({ _readOnly_: true }).result; + button = ( +
+ this.changeVal(val as string, 'curr')} + fillWidth + password + /> + this.changeVal(val as string, 'new')} + fillWidth + password + /> + this.changeVal(val as string, 'conf')} + fillWidth + password + /> + {!this.passwordResultText ? null :
{this.passwordResultText}
} +
); } @@ -346,14 +396,15 @@ export class SettingsManager extends React.Component<{}> { dropdownType={DropdownType.SELECT} type={Type.TERT} placement='bottom-start' - color={StrCast(Doc.SharingDoc().userColor)} + color={this.userColor} + fillWidth />
@@ -379,7 +430,7 @@ export class SettingsManager extends React.Component<{}> { dropdownType={DropdownType.SELECT} type={Type.TERT} placement='bottom-start' - color={StrCast(Doc.SharingDoc().userColor)} + color={this.userColor} />
@@ -390,12 +441,12 @@ export class SettingsManager extends React.Component<{}> { text={"Manage Groups"} type={Type.TERT} onClick={() => GroupManager.Instance?.open()} - color={StrCast(Doc.SharingDoc().userColor)} + color={this.userColor} /> (Doc.defaultAclPrivate = !Doc.defaultAclPrivate))}/>
@@ -414,23 +465,35 @@ export class SettingsManager extends React.Component<{}> { { title: 'Appearance', ele: this.appearanceContent }, { title: 'Text', ele: this.textContent }, ]; - return (
-
+
- {tabs.map(tab => ( -
(this.activeTab = tab.title))}> - {tab.title} -
- ))} + {tabs.map(tab => { + const isActive = this.activeTab === tab.title + return ( +
(this.activeTab = tab.title)) + }> + {tab.title} +
+ ) + })}
-
{Doc.CurrentUserEmail}
+
{Doc.CurrentUserEmail}
@@ -439,12 +502,13 @@ export class SettingsManager extends React.Component<{}> {
-
+
{tabs.map(tab => (
{tab.ele} @@ -462,7 +526,7 @@ export class SettingsManager extends React.Component<{}> { isDisplayed={this.isOpen} interactive={true} closeOnExternalClick={this.close} - dialogueBoxStyle={{ width: 'fit-content', height: '300px', background: Cast(Doc.SharingDoc().userColor, 'string', null) }} + dialogueBoxStyle={{ width: 'fit-content', height: '300px', background: Cast(Doc.UserDoc().userColor, 'string', null) }} /> ); } diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss index 8a0e5480e..b205a0f1e 100644 --- a/src/client/views/AntimodeMenu.scss +++ b/src/client/views/AntimodeMenu.scss @@ -5,11 +5,15 @@ position: absolute; z-index: 10001; height: $antimodemenu-height; - background: $dark-gray; - border-bottom: $standard-border; + width: fit-content; + border-radius: $standard-border-radius; + overflow: hidden; // box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25); // border-radius: 0px 6px 6px 6px; display: flex; + justify-content: center; + align-items: center; + gap: 3px; &.with-rows { flex-direction: column @@ -20,30 +24,6 @@ height: 35px; } - .antimodeMenu-button { - background-color: transparent; - width: 35px; - height: 35px; - padding: 5; - text-align: center; - display: flex; - justify-content: center; - align-items: center; - position: relative; - - .svg { - margin: 0; - } - - &.active { - background-color: #121212; - } - } - - .antimodeMenu-button:hover { - background-color: rgba(0, 0, 0, 0.4); - } - .antimodeMenu-dragger { height: 100%; transition: width .2s; diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index de1207ce4..c41ea7053 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -1,6 +1,8 @@ import React = require('react'); import { observable, action, runInAction } from 'mobx'; import './AntimodeMenu.scss'; +import { StrCast } from '../../fields/Types'; +import { Doc } from '../../fields/Doc'; export interface AntimodeMenuProps {} /** @@ -148,6 +150,7 @@ export abstract class AntimodeMenu extends React.Co left: this._left, top: this._top, opacity: this._opacity, + background: StrCast(Doc.UserDoc().userBackgroundColor), transitionProperty: this._transitionProperty, transitionDuration: this._transitionDuration, transitionDelay: this._transitionDelay, @@ -173,6 +176,7 @@ export abstract class AntimodeMenu extends React.Co height: 'inherit', width: 200, opacity: this._opacity, + background: StrCast(Doc.UserDoc().userBackgroundColor), transitionProperty: this._transitionProperty, transitionDuration: this._transitionDuration, transitionDelay: this._transitionDelay, @@ -195,6 +199,7 @@ export abstract class AntimodeMenu extends React.Co left: this._left, top: this._top, opacity: this._opacity, + background: StrCast(Doc.UserDoc().userBackgroundColor), transitionProperty: this._transitionProperty, transitionDuration: this._transitionDuration, transitionDelay: this._transitionDelay, diff --git a/src/client/views/DashboardView.scss b/src/client/views/DashboardView.scss index b8a6f6c05..b95312ea0 100644 --- a/src/client/views/DashboardView.scss +++ b/src/client/views/DashboardView.scss @@ -14,6 +14,7 @@ flex-direction: column; width: 250px; min-width: 250px; + gap: 5px; } .all-dashboards { @@ -56,15 +57,26 @@ display: flex; justify-content: center; align-items: center; + position: relative; &:hover { color: $light-blue; border: solid 2px $light-blue; } + + .background { + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + z-index: -1; + } } .dashboard-container { border-radius: 10px; + position: relative; cursor: pointer; width: 250px; height: 200px; @@ -99,10 +111,20 @@ .more { z-index: 100; } + + .background { + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + z-index: -1; + } } .new-dashboard { color: $dark-gray; + padding: 10px; display: flex; width: 100%; height: 100%; diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 3bd6ac61c..dd1079d88 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Button, ColorPicker, FontSize, IconButton, Size, Type } from 'browndash-components'; +import { Button, ColorPicker, EditableText, FontSize, IconButton, Size, Type } from 'browndash-components'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -24,7 +24,7 @@ import { ContextMenu } from './ContextMenu'; import './DashboardView.scss'; import { Colors } from './global/globalEnums'; import { MainViewModal } from './MainViewModal'; -import { ButtonType } from './nodes/button/FontIconBox'; +import { ButtonType } from './nodes/FontIconBox/FontIconBox'; import { FaPlus } from 'react-icons/fa'; enum DashboardGroup { @@ -43,13 +43,16 @@ export class DashboardView extends React.Component { @observable private selectedDashboardGroup = DashboardGroup.MyDashboards; @observable private newDashboardName: string | undefined = undefined; - @observable private newDashboardColor: string | undefined = undefined; + @observable private newDashboardColor: string | undefined = "#AFAFAF"; @action abortCreateNewDashboard = () => { this.newDashboardName = undefined; }; @action setNewDashboardName(name: string) { this.newDashboardName = name; } + @action setNewDashboardColor(color: string) { + this.newDashboardColor = color; + } @action selectDashboardGroup = (group: DashboardGroup) => { @@ -95,23 +98,33 @@ export class DashboardView extends React.Component { const dashboardCount = DocListCast(Doc.MyDashboards.data).length + 1; const placeholder = `Dashboard ${dashboardCount}`; return ( -
+
Create New Dashboard
-
- Title - this.setNewDashboardName((e.target as any).value)} /> -
-
- Background - { - this.newDashboardColor = color; - }} - /> -
+ this.setNewDashboardName(val as string)} + fillWidth + /> + { + this.setNewDashboardColor(color); + }} + />
-
); @@ -150,32 +163,49 @@ export class DashboardView extends React.Component { }; render() { + const color = StrCast(Doc.UserDoc().userColor) + const variant = StrCast(Doc.UserDoc().userVariantColor) return ( <>
-
-
-
this.selectDashboardGroup(DashboardGroup.MyDashboards)}> - My Dashboards -
-
this.selectDashboardGroup(DashboardGroup.SharedDashboards)}> - Shared Dashboards -
+
{this.getDashboards().map(dashboard => { const href = ImageCast(dashboard.thumb)?.url.href; return ( -
this.onContextMenu(dashboard, e)} onClick={e => this.clickDashboard(e, dashboard)}> +
this.onContextMenu(dashboard, e)} onClick={e => this.clickDashboard(e, dashboard)}>
- e.stopPropagation()} defaultValue={StrCast(dashboard.title)} onChange={e => (Doc.GetProto(dashboard).title = (e.target as any).value)} /> + (Doc.GetProto(dashboard).title = val)} + /> {this.selectedDashboardGroup === DashboardGroup.SharedDashboards && this.isUnviewedSharedDashboard(dashboard) ?
unviewed
:
}
-
+
); })} @@ -200,6 +234,10 @@ export class DashboardView extends React.Component { this.setNewDashboardName(''); }}> + +
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 7043edcee..4deed5ed9 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -6,6 +6,7 @@ import { ObjectField } from '../../fields/ObjectField'; import './EditableView.scss'; import { DocumentIconContainer } from './nodes/DocumentIcon'; import { OverlayView } from './OverlayView'; +import { EditableText } from 'browndash-components'; export interface EditableProps { /** @@ -231,39 +232,49 @@ export class EditableView extends React.Component { onChange: this.props.autosuggestProps.onChange, }} /> - ) : this.props.oneLine !== false && this.props.GetValue()?.toString().indexOf('\n') === -1 ? ( - (this._inputref = r)} - style={{ display: this.props.display, overflow: 'auto', fontSize: this.props.fontSize, minWidth: 20, background: this.props.background }} - placeholder={this.props.placeholder} - onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)} - defaultValue={this.props.GetValue()} - autoFocus={true} - onChange={this.onChange} - onKeyDown={this.onKeyDown} - onKeyPress={this.stopPropagation} - onPointerDown={this.stopPropagation} - onClick={this.stopPropagation} - onPointerUp={this.stopPropagation} + ) : - ) : ( -