aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts5
-rw-r--r--src/client/util/CurrentUserUtils.ts36
-rw-r--r--src/client/util/SelectionManager.ts14
-rw-r--r--src/client/util/SettingsManager.tsx19
-rw-r--r--src/client/views/ContextMenu.scss1
-rw-r--r--src/client/views/DocumentDecorations.scss28
-rw-r--r--src/client/views/DocumentDecorations.tsx42
-rw-r--r--src/client/views/MainView.scss12
-rw-r--r--src/client/views/MainView.tsx27
-rw-r--r--src/client/views/PreviewCursor.scss5
-rw-r--r--src/client/views/PreviewCursor.tsx4
-rw-r--r--src/client/views/StyleProvider.tsx5
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx2
-rw-r--r--src/client/views/collections/TreeView.tsx9
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx3
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx6
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx4
-rw-r--r--src/client/views/collections/collectionLinear/CollectionLinearView.tsx1
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx7
-rw-r--r--src/client/views/nodes/DocumentView.scss1
-rw-r--r--src/client/views/nodes/DocumentView.tsx17
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx216
-rw-r--r--src/client/views/nodes/formattedText/DashDocView.tsx3
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx22
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx194
-rw-r--r--src/client/views/nodes/formattedText/marks_rts.ts6
-rw-r--r--src/mobile/MobileInterface.tsx4
27 files changed, 355 insertions, 338 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index fafbc4a7d..8ac647b99 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -141,8 +141,8 @@ export class DocumentOptions {
_columnWidth?: number;
_columnsHideIfEmpty?: boolean; // whether stacking view column headings should be hidden
_fontSize?: string;
- _fontWeight?: number;
_fontFamily?: string;
+ _fontWeight?: string;
_pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views
_curPage?: number; // current page of a PDF or other? paginated document
_currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video) value is in seconds
@@ -862,7 +862,7 @@ export namespace Docs {
export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) {
const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", _fitWidth: true, system: true, isFolder: true });
const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", system: true, isFolder: true });
- return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id);
+ return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id);
}
export function DirectoryImportDocument(options: DocumentOptions = {}) {
@@ -1188,7 +1188,6 @@ export namespace DocUtils {
description: ":" + StrCast(note.title),
event: undoBatch((args: { x: number, y: number }) => {
const textDoc = Docs.Create.TextDocument("", {
- _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
_width: 200, x, y, _autoHeight: note._autoHeight !== false,
title: StrCast(note.title) + "#" + (note.aliasCount = NumCast(note.aliasCount) + 1)
});
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index d5dc9e2be..297d4b241 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -20,6 +20,7 @@ import { Networking } from "../Network";
import { CollectionDockingView } from "../views/collections/CollectionDockingView";
import { DimUnit } from "../views/collections/collectionMulticolumn/CollectionMulticolumnView";
import { CollectionView, CollectionViewType } from "../views/collections/CollectionView";
+import { TreeView } from "../views/collections/TreeView";
import { Colors } from "../views/global/globalEnums";
import { MainView } from "../views/MainView";
import { ButtonType, NumButtonType } from "../views/nodes/button/FontIconBox";
@@ -38,7 +39,6 @@ import { ColorScheme } from "./SettingsManager";
import { SharingManager } from "./SharingManager";
import { SnappingManager } from "./SnappingManager";
import { UndoManager } from "./UndoManager";
-import { TreeView } from "../views/collections/TreeView";
interface Button {
title?: string;
@@ -816,16 +816,19 @@ export class CurrentUserUtils {
_lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", treeViewType: "fileSystem", isFolder: true, system: true,
explainer: "This is your collection of dashboards. A dashboard represents the tab configuration of your workspace. To manage documents as folders, go to the Files."
}));
- // const toggleTheme = ScriptField.MakeScript(`Doc.UserDoc().darkScheme = !Doc.UserDoc().darkScheme`);
- // const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
- // const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`);
+ const toggleDarkTheme = ScriptField.MakeScript(`this.colorScheme = this.colorScheme ? undefined : "${ColorScheme.Dark}"`);
+ const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
+ const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`);
const shareDashboard = ScriptField.MakeScript(`shareDashboard(self)`);
const removeDashboard = ScriptField.MakeScript('removeDashboard(self)');
- (doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, shareDashboard!, removeDashboard!]);
- (doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Share Dashboard", "Remove Dashboard"]);
- (doc.myDashboards as any as Doc).childContextMenuIcons = new List<string>(["plus", "user-friends", "times"]);
- // (doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, toggleTheme!, toggleComic!, snapshotDashboard!, shareDashboard!, removeDashboard!]);
- // (doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]);
+ const developerFilter = ScriptField.MakeFunction('!IsNoviceMode()');
+ // (doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, shareDashboard!, removeDashboard!]);
+ // (doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Share Dashboard", "Remove Dashboard"]);
+ // (doc.myDashboards as any as Doc).childContextMenuIcons = new List<string>(["plus", "user-friends", "times"]);
+ (doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, toggleDarkTheme!, toggleComic!, snapshotDashboard!, shareDashboard!, removeDashboard!]);
+ (doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Toggle Dark Theme", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]);
+ (doc.myDashboards as any as Doc).childContextMenuIcons = new List<string>(["plus", "chalkboard", "tv", "camera", "users", "times"]);
+ (doc.myDashboards as any as Doc).childContextMenuFilters = new List<ScriptField>([undefined as any, developerFilter, developerFilter, developerFilter, undefined as any, undefined as any]);
}
return doc.myDashboards as any as Doc;
}
@@ -1302,7 +1305,6 @@ export class CurrentUserUtils {
}, { fireImmediately: true });
// Document properties on load
doc.system = true;
- doc.darkScheme = ColorScheme.Dark;
doc.noviceMode = doc.noviceMode === undefined ? "true" : doc.noviceMode;
doc.title = Doc.CurrentUserEmail;
doc._raiseWhenDragged = true;
@@ -1321,7 +1323,6 @@ export class CurrentUserUtils {
doc.fontColor = StrCast(doc.fontColor, "black");
doc.fontHighlight = StrCast(doc.fontHighlight, "");
doc.defaultAclPrivate = BoolCast(doc.defaultAclPrivate, false);
- doc.activeCollectionBackground = StrCast(doc.activeCollectionBackground, "white");
doc.activeCollectionNestedBackground = Cast(doc.activeCollectionNestedBackground, "string", null);
doc.noviceMode = BoolCast(doc.noviceMode, true);
doc["constants-snapThreshold"] = NumCast(doc["constants-snapThreshold"], 10); //
@@ -1358,6 +1359,13 @@ export class CurrentUserUtils {
// });
setTimeout(() => DocServer.UPDATE_SERVER_CACHE(), 2500);
doc.fieldInfos = await Docs.setupFieldInfos();
+ if (doc.activeDashboard instanceof Doc) {
+ // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
+ doc.activeDashboard.colorScheme = doc.activeDashboard.colorScheme === ColorScheme.Light ? undefined : doc.activeDashboard.colorScheme;
+ }
+ if (doc.activeCollectionBackground === "white") { // temporary to avoid having to rebuild the databse for old accounts that have this set by default.
+ doc.activeCollectionBackground = undefined;
+ }
return doc;
}
@@ -1527,8 +1535,7 @@ export class CurrentUserUtils {
public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, noMargins?: boolean, annotationOn?: Doc, maxHeight?: number, backgroundColor?: string) {
const tbox = Docs.Create.TextDocument("", {
_xMargin: noMargins ? 0 : undefined, _yMargin: noMargins ? 0 : undefined, annotationOn, docMaxAutoHeight: maxHeight, backgroundColor: backgroundColor,
- _width: width || 200, _height: height || 100, x: x, y: y, _fitWidth: true, _autoHeight: true, _fontSize: StrCast(Doc.UserDoc().fontSize),
- _fontFamily: StrCast(Doc.UserDoc().fontFamily), title
+ _width: width || 200, _height: height || 100, x: x, y: y, _fitWidth: true, _autoHeight: true, title
});
const template = Doc.UserDoc().defaultTextLayout;
if (template instanceof Doc) {
@@ -1637,4 +1644,7 @@ Scripting.addGlobal(function makeTopLevelFolder() {
const folder = Docs.Create.TreeDocument([], { title: "Untitled folder", _stayInCollection: true, isFolder: true });
TreeView._editTitleOnLoad = { id: folder[Id], parent: undefined };
return Doc.AddDocToList(Doc.UserDoc().myFilesystem as Doc, "data", folder);
+});
+Scripting.addGlobal(function toggleComicMode() {
+ Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic";
}); \ No newline at end of file
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index bac13373c..e507ec3bf 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -2,7 +2,6 @@ import { action, observable, ObservableMap } from "mobx";
import { computedFn } from "mobx-utils";
import { Doc, Opt } from "../../fields/Doc";
import { DocumentType } from "../documents/DocumentTypes";
-import { CollectionSchemaView } from "../views/collections/collectionSchema/CollectionSchemaView";
import { CollectionViewType } from "../views/collections/CollectionView";
import { DocumentView } from "../views/nodes/DocumentView";
@@ -13,12 +12,10 @@ export namespace SelectionManager {
@observable IsDragging: boolean = false;
SelectedViews: ObservableMap<DocumentView, Doc> = new ObservableMap();
@observable SelectedSchemaDocument: Doc | undefined;
- @observable SelectedSchemaCollection: CollectionSchemaView | undefined;
@action
- SelectSchemaView(collectionView: Opt<CollectionSchemaView>, doc: Opt<Doc>) {
+ SelectSchemaViewDoc(doc: Opt<Doc>) {
manager.SelectedSchemaDocument = doc;
- manager.SelectedSchemaCollection = collectionView;
}
@action
SelectView(docView: DocumentView, ctrlPressed: boolean): void {
@@ -33,7 +30,6 @@ export namespace SelectionManager {
} else if (!ctrlPressed && Array.from(manager.SelectedViews.entries()).length > 1) {
Array.from(manager.SelectedViews.keys()).map(dv => dv !== docView && dv.props.whenChildContentsActiveChanged(false));
manager.SelectedSchemaDocument = undefined;
- manager.SelectedSchemaCollection = undefined;
manager.SelectedViews.clear();
manager.SelectedViews.set(docView, docView.rootDoc);
}
@@ -47,7 +43,6 @@ export namespace SelectionManager {
}
@action
DeselectAll(): void {
- manager.SelectedSchemaCollection = undefined;
manager.SelectedSchemaDocument = undefined;
Array.from(manager.SelectedViews.keys()).map(dv => dv.props.whenChildContentsActiveChanged(false));
manager.SelectedViews.clear();
@@ -62,8 +57,8 @@ export namespace SelectionManager {
export function SelectView(docView: DocumentView, ctrlPressed: boolean): void {
manager.SelectView(docView, ctrlPressed);
}
- export function SelectSchemaView(colSchema: Opt<CollectionSchemaView>, document: Opt<Doc>): void {
- manager.SelectSchemaView(colSchema, document);
+ export function SelectSchemaViewDoc(document: Opt<Doc>): void {
+ manager.SelectSchemaViewDoc(document);
}
const IsSelectedCache = computedFn(function isSelected(doc: DocumentView) { // wrapping get() in a computedFn only generates mobx() invalidations when the return value of the function for the specific get parameters has changed
@@ -96,9 +91,6 @@ export namespace SelectionManager {
export function SelectedSchemaDoc(): Doc | undefined {
return manager.SelectedSchemaDocument;
}
- export function SelectedSchemaCollection(): CollectionSchemaView | undefined {
- return manager.SelectedSchemaCollection;
- }
export function Docs(): Doc[] {
return Array.from(manager.SelectedViews.values()).filter(doc => doc?._viewType !== CollectionViewType.Docking);
}
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index bd91db779..6a26dfdc7 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -19,9 +19,9 @@ export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
export enum ColorScheme {
- Dark = "Dark",
- Light = "Light",
- System = "Match System"
+ Dark = "-Dark",
+ Light = "-Light",
+ System = "-MatchSystem"
}
@observer
@@ -38,7 +38,7 @@ export class SettingsManager extends React.Component<{}> {
@observable activeTab = "Accounts";
@computed get backgroundColor() { return Doc.UserDoc().activeCollectionBackground; }
- @computed get colorScheme() { return Doc.UserDoc().colorScheme; }
+ @computed get colorScheme() { return CurrentUserUtils.ActiveDashboard.colorScheme; }
constructor(props: {}) {
super(props);
@@ -81,16 +81,16 @@ export class SettingsManager extends React.Component<{}> {
const scheme: ColorScheme = (e.currentTarget as any).value;
switch (scheme) {
case ColorScheme.Light:
- Doc.UserDoc().colorScheme = ColorScheme.Light;
+ CurrentUserUtils.ActiveDashboard.colorScheme = undefined; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
addStyleSheetRule(SettingsManager._settingsStyle, "lm_header", { background: "#d3d3d3 !important" });
break;
case ColorScheme.Dark:
- Doc.UserDoc().colorScheme = ColorScheme.Dark;
+ CurrentUserUtils.ActiveDashboard.colorScheme = ColorScheme.Dark;
addStyleSheetRule(SettingsManager._settingsStyle, "lm_header", { background: "black !important" });
break;
case ColorScheme.System: default:
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
- Doc.UserDoc().colorScheme = e.matches ? ColorScheme.Dark : ColorScheme.Light;
+ CurrentUserUtils.ActiveDashboard.colorScheme = e.matches ? ColorScheme.Dark : undefined; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
});
break;
}
@@ -119,6 +119,7 @@ export class SettingsManager extends React.Component<{}> {
</div>;
const colorSchemes = [ColorScheme.Light, ColorScheme.Dark, ColorScheme.System];
+ const schemeMap = ["Light", "Dark", "Match system"];
return <div className="colors-content">
<div className="preferences-color">
@@ -132,8 +133,8 @@ export class SettingsManager extends React.Component<{}> {
<div className="preferences-colorScheme">
<div className="preferences-color-text">Color Scheme</div>
<div className="preferences-color-controls">
- <select className="scheme-select" onChange={this.changeColorScheme} defaultValue={StrCast(Doc.UserDoc().colorScheme)}>
- {colorSchemes.map(scheme => <option key={scheme} value={scheme}> {scheme} </option>)}
+ <select className="scheme-select" onChange={this.changeColorScheme} defaultValue={StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme)}>
+ {colorSchemes.map((scheme, i) => <option key={scheme} value={scheme}> {schemeMap[i]} </option>)}
</select>
</div>
</div>
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index 47ae0424b..ea24dbf6d 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -8,7 +8,6 @@
flex-direction: column;
background: whitesmoke;
border-radius: 3px;
- border: solid $light-gray 1px;
}
// .contextMenu-item:first-child {
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index a9f50f81b..d8ad47ecb 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -2,10 +2,14 @@
$linkGap: 3px;
+.documentDecorations-Dark,
.documentDecorations {
position: absolute;
z-index: 2000;
}
+.documentDecorations-Dark {
+ background: dimgray;
+}
.documentDecorations-container {
z-index: $docDecorations-zindex;
position: absolute;
@@ -50,12 +54,17 @@ $linkGap: 3px;
pointer-events: auto;
background: $medium-gray;
opacity: 0.1;
-
&:hover {
opacity: 1;
}
}
+ .documentDecorations-resizer-Dark
+ {
+ background: $light-gray;
+ opacity: 0.2;
+ }
+
.documentDecorations-topLeftResizer,
.documentDecorations-leftResizer,
.documentDecorations-bottomLeftResizer {
@@ -221,6 +230,7 @@ $linkGap: 3px;
cursor: ns-resize;
}
+ .documentDecorations-title-Dark,
.documentDecorations-title {
opacity: 1;
grid-column-start: 2;
@@ -233,14 +243,22 @@ $linkGap: 3px;
height: 22px;
position: absolute;
- .documentDecorations-titleSpan {
+ .documentDecorations-titleSpan,
+ .documentDecorations-titleSpan-Dark {
width: 100%;
border-radius: 8px;
- background: #ffffffcf;
+ background: #ffffffa0;
position: absolute;
display: inline-block;
cursor: move;
}
+ .documentDecorations-titleSpan-Dark {
+ background: hsla(0, 0%, 0%, 0.412);
+ }
+ }
+ .documentDecorations-title-Dark {
+ color: white;
+ background: black;
}
.documentDecorations-contextMenu {
@@ -439,10 +457,6 @@ $linkGap: 3px;
}
}
-.documentDecorations-darkScheme {
- background: dimgray;
-}
-
#template-list {
position: absolute;
top: 25px;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 29fcee822..c4f6625fc 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -8,7 +8,7 @@ import { AclAdmin, AclEdit, DataSym, Doc, DocListCast, Field, HeightSym, WidthSy
import { Document } from '../../fields/documentSchemas';
import { InkField } from "../../fields/InkField";
import { ScriptField } from '../../fields/ScriptField';
-import { Cast, NumCast } from "../../fields/Types";
+import { Cast, NumCast, StrCast } from "../../fields/Types";
import { GetEffectiveAcl } from '../../fields/util';
import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../Utils";
import { Docs } from "../documents/Documents";
@@ -27,6 +27,8 @@ import { LightboxView } from './LightboxView';
import { DocumentView } from "./nodes/DocumentView";
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import React = require("react");
+import { dark } from '@material-ui/core/styles/createPalette';
+import { color } from 'd3-color';
@observer
export class DocumentDecorations extends React.Component<{ PanelWidth: number, PanelHeight: number, boundsLeft: number, boundsTop: number }, { value: string }> {
@@ -241,7 +243,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P
InkStrokeProperties.Instance?._lock && SelectionManager.Views().filter(dv => dv.rootDoc.type === DocumentType.INK)
.forEach(dv => fixedAspect = Doc.NativeAspect(dv.rootDoc));
- if (fixedAspect && (this._resizeHdlId === "documentDecorations-bottomRightResizer" || this._resizeHdlId === "documentDecorations-topLeftResizer")) { // need to generalize for bl and tr drag handles
+ const resizeHdl = this._resizeHdlId.split(" ")[0];
+ if (fixedAspect && (resizeHdl === "documentDecorations-bottomRightResizer" || resizeHdl === "documentDecorations-topLeftResizer")) { // need to generalize for bl and tr drag handles
const project = (p: number[], a: number[], b: number[]) => {
const atob = [b[0] - a[0], b[1] - a[1]];
const atop = [p[0] - a[0], p[1] - a[1]];
@@ -264,7 +267,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P
this._snapY = thisPt.y;
let dragBottom = false, dragRight = false, dragBotRight = false;
let dX = 0, dY = 0, dW = 0, dH = 0;
- switch (this._resizeHdlId) {
+ switch (this._resizeHdlId.split(" ")[0]) {
case "": break;
case "documentDecorations-topLeftResizer":
dX = -1;
@@ -437,11 +440,17 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P
</div>
</Tooltip>);
+ const colorScheme = StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme);
const titleArea = this._edtingTitle ?
- <input ref={this._keyinput} className="documentDecorations-title" style={{ width: `calc(100% - ${seldoc?.props.hideResizeHandles ? 0 : 20}px` }} type="text" name="dynbox" autoComplete="on" value={this._accumulatedTitle}
- onBlur={e => this.titleBlur()} onChange={action(e => this._accumulatedTitle = e.target.value)} onKeyPress={this.titleEntered} /> :
+ <input ref={this._keyinput} className={`documentDecorations-title${colorScheme}`}
+ style={{ width: `calc(100% - ${seldoc?.props.hideResizeHandles ? 0 : 20}px` }}
+ type="text" name="dynbox" autoComplete="on"
+ value={this._accumulatedTitle}
+ onBlur={e => this.titleBlur()}
+ onChange={action(e => this._accumulatedTitle = e.target.value)}
+ onKeyPress={this.titleEntered} /> :
<div className="documentDecorations-title" style={{ width: `calc(100% - ${seldoc?.props.hideResizeHandles ? 0 : 20}px` }} key="title" onPointerDown={this.onTitleDown} >
- <span className="documentDecorations-titleSpan">{`${this.selectionTitle}`}</span>
+ <span className={`documentDecorations-titleSpan${colorScheme}`}>{`${this.selectionTitle}`}</span>
</div>;
let inMainMenuPanel = false;
@@ -457,8 +466,9 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P
bounds.b = Math.max(bounds.y, Math.max(topBounds, Math.min(window.innerHeight, bounds.b + this._resizeBorderWidth / 2 + this._linkBoxHeight) - this._resizeBorderWidth / 2 - this._linkBoxHeight));
const useRotation = seldoc.rootDoc.type === DocumentType.INK;
+ const resizerScheme = colorScheme ? "documentDecorations-resizer" + colorScheme : "";
- return (<div className="documentDecorations" style={{ background: CurrentUserUtils.ActiveDashboard?.darkScheme ? "dimgray" : "" }} >
+ return (<div className={`documentDecorations${colorScheme}`}>
<div className="documentDecorations-background" style={{
width: (bounds.r - bounds.x + this._resizeBorderWidth) + "px",
height: (bounds.b - bounds.y + this._resizeBorderWidth) + "px",
@@ -481,15 +491,15 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P
<>
{SelectionManager.Views().length !== 1 || hideTitle ? (null) :
topBtn("iconify", `window-${seldoc.finalLayoutKey.includes("icon") ? "restore" : "minimize"}`, undefined, this.onIconifyClick, `${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`)}
- <div key="tl" className="documentDecorations-topLeftResizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
- <div key="t" className="documentDecorations-topResizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
- <div key="tr" className="documentDecorations-topRightResizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
- <div key="l" className="documentDecorations-leftResizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
- <div key="c" className="documentDecorations-centerCont"></div>
- <div key="r" className="documentDecorations-rightResizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
- <div key="bl" className="documentDecorations-bottomLeftResizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
- <div key="b" className="documentDecorations-bottomResizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
- <div key="br" className="documentDecorations-bottomRightResizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
+ <div key="tl" className={`documentDecorations-topLeftResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
+ <div key="t" className={`documentDecorations-topResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
+ <div key="tr" className={`documentDecorations-topRightResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
+ <div key="l" className={`documentDecorations-leftResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
+ <div key="c" className={`documentDecorations-centerCont ${resizerScheme}`}></div>
+ <div key="r" className={`documentDecorations-rightResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
+ <div key="bl" className={`documentDecorations-bottomLeftResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
+ <div key="b" className={`documentDecorations-bottomResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
+ <div key="br" className={`documentDecorations-bottomRightResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} />
{seldoc.props.renderDepth <= 1 || !seldoc.props.ContainingCollectionView ? (null) :
topBtn("selector", "arrow-alt-circle-up", undefined, this.onSelectorClick, "tap to select containing document")}
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 4f871f5ec..7fa841002 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -41,7 +41,7 @@
}
.mainView-container,
-.mainView-container-dark {
+.mainView-container-Dark {
width: 100%;
height: 100%;
position: absolute;
@@ -65,7 +65,7 @@
}
}
-.mainView-container-dark {
+.mainView-container-Dark {
color: $light-gray;
.lm_goldenlayout {
@@ -91,7 +91,7 @@
.contextMenu-cont,
.contextMenu-item {
- background: $medium-gray;
+ background: $dark-gray;
}
.contextMenu-item:hover {
@@ -144,7 +144,7 @@
}
}
-.mainView-innerContent, .mainView-innerContent-dark {
+.mainView-innerContent, .mainView-innerContent-Dark {
display: contents;
flex-direction: row;
position: relative;
@@ -175,7 +175,7 @@
.mainView-libraryHandle {
background-color: $light-gray;
}
-.mainView-innerContent-dark
+.mainView-innerContent-Dark
{
.propertiesView {
background-color: #252525;
@@ -198,7 +198,7 @@
background: #353535;
}
}
-.mainView-container-dark {
+.mainView-container-Dark {
.contextMenu-cont {
background: $medium-gray;
color: $white;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index d854f118f..35c5801e5 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -12,7 +12,7 @@ import { Doc, DocListCast, Opt } from '../../fields/Doc';
import { List } from '../../fields/List';
import { PrefetchProxy } from '../../fields/Proxy';
import { ScriptField } from '../../fields/ScriptField';
-import { BoolCast, PromiseValue, StrCast } from '../../fields/Types';
+import { PromiseValue, StrCast } from '../../fields/Types';
import { TraceMobx } from '../../fields/util';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick, Utils } from '../../Utils';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
@@ -26,7 +26,7 @@ import { HistoryUtil } from '../util/History';
import { Hypothesis } from '../util/HypothesisUtils';
import { Scripting } from '../util/Scripting';
import { SelectionManager } from '../util/SelectionManager';
-import { SettingsManager } from '../util/SettingsManager';
+import { ColorScheme, SettingsManager } from '../util/SettingsManager';
import { SharingManager } from '../util/SharingManager';
import { SnappingManager } from '../util/SnappingManager';
import { Transform } from '../util/Transform';
@@ -88,7 +88,7 @@ export class MainView extends React.Component {
@computed private get topOfMainDocContent() { return this.topOfMainDoc + this.dashboardTabHeight; }
@computed private get leftScreenOffsetOfMainDocView() { return this.leftMenuWidth() - 2; }
@computed private get userDoc() { return Doc.UserDoc(); }
- @computed private get darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); }
+ @computed private get colorScheme() { return StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme); }
@computed private get mainContainer() { return this.userDoc ? CurrentUserUtils.ActiveDashboard : CurrentUserUtils.GuestDashboard; }
@computed public get mainFreeform(): Opt<Doc> { return (docs => (docs?.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); }
@@ -101,7 +101,7 @@ export class MainView extends React.Component {
propertiesWidth = () => Math.max(0, Math.min(this._dashUIWidth - 50, CurrentUserUtils.propertiesWidth || 0));
propertiesHeight = () => this._dashUIHeight;
mainDocViewWidth = () => this._dashUIWidth - this.propertiesWidth() - this.leftMenuWidth();
- mainDocViewHeight = () => this._dashUIHeight - this.topMenuHeight();
+ mainDocViewHeight = () => this._dashUIHeight;
componentDidMount() {
document.getElementById("root")?.addEventListener("scroll", e => ((ele) => ele.scrollLeft = ele.scrollTop = 0)(document.getElementById("root")!));
@@ -430,18 +430,17 @@ export class MainView extends React.Component {
const transform = this._leftMenuFlyoutWidth ? 'translate(-28px, 0px)' : undefined;
return <>
{this.leftMenuPanel}
- <div key="inner" className={`mainView-innerContent${this.darkScheme ? "-dark" : ""}`}>
+ <div key="inner" className={`mainView-innerContent${this.colorScheme}`}>
{this.flyout}
<div className="mainView-libraryHandle" style={{ display: !this._leftMenuFlyoutWidth ? "none" : undefined }} onPointerDown={this.onFlyoutPointerDown} >
- <FontAwesomeIcon icon="chevron-left" color={this.darkScheme ? "white" : "black"} style={{ opacity: "50%" }} size="sm" />
+ <FontAwesomeIcon icon="chevron-left" color={this.colorScheme === ColorScheme.Dark ? "white" : "black"} style={{ opacity: "50%" }} size="sm" />
</div>
<div className="mainView-innerContainer" style={{ width: `calc(100% - ${width}px)`, transform: transform }}>
- <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} />
{this.dockingContent}
<div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this._leftMenuFlyoutWidth ? 0 : this.propertiesWidth() - 1 }}>
- <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color={this.darkScheme ? Colors.WHITE : Colors.BLACK} size="sm" />
+ <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color={this.colorScheme === ColorScheme.Dark ? Colors.WHITE : Colors.BLACK} size="sm" />
</div>
<div className="properties-container">
{this.propertiesWidth() < 10 ? (null) : <PropertiesView styleProvider={DefaultStyleProvider} width={this.propertiesWidth()} height={this.propertiesHeight()} />}
@@ -459,8 +458,8 @@ export class MainView extends React.Component {
this._dashUIHeight = r.getBoundingClientRect().height;
})).observe(r);
}} style={{
- color: this.darkScheme ? "rgb(205,205,205)" : "black",
- height: `calc(100% - ${this.topOfDashUI}px)`,
+ color: this.colorScheme === ColorScheme.Dark ? "rgb(205,205,205)" : "black",
+ height: `calc(100% - ${this.topOfDashUI + this.topMenuHeight()}px)`,
width: "100%",
}} >
{this.mainInnerContent}
@@ -471,7 +470,6 @@ export class MainView extends React.Component {
this._leftMenuFlyoutWidth = (this._leftMenuFlyoutWidth || 250);
this._sidebarContent.proto = button.target as any;
this.LastButton = button;
- console.log(button.title);
});
closeFlyout = action(() => {
@@ -601,7 +599,7 @@ export class MainView extends React.Component {
}
render() {
- return (<div className={"mainView-container" + (this.darkScheme ? "-dark" : "")}
+ return (<div className={`mainView-container${this.colorScheme}`}
onScroll={() => ((ele) => ele.scrollTop = ele.scrollLeft = 0)(document.getElementById("root")!)}
ref={r => {
r && new _global.ResizeObserver(action(() => { this._windowWidth = r.getBoundingClientRect().width; this._windowHeight = r.getBoundingClientRect().height; })).observe(r);
@@ -614,11 +612,14 @@ export class MainView extends React.Component {
<GroupManager />
<GoogleAuthenticationManager />
<DocumentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDoc} PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} />
- <ComponentDecorations boundsLeft={this.leftScreenOffsetOfMainDocView} boundsTop={this.topOfMainDocContent} />
+ <ComponentDecorations boundsLeft={0} boundsTop={this.topOfMainDocContent} />
{this.topbar}
{LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
{DocumentLinksButton.LinkEditorDocView ? <LinkMenu docView={DocumentLinksButton.LinkEditorDocView} changeFlyout={emptyFunction} /> : (null)}
{LinkDocPreview.LinkInfo ? <LinkDocPreview {...LinkDocPreview.LinkInfo} /> : (null)}
+ <div style={{ position: "relative", display: LightboxView.LightboxDoc ? "none" : undefined, zIndex: 2001 }} >
+ <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} />
+ </div>
<GestureOverlay >
{this.mainDashboardArea}
</GestureOverlay>
diff --git a/src/client/views/PreviewCursor.scss b/src/client/views/PreviewCursor.scss
index de9bd69c4..60b7d14a0 100644
--- a/src/client/views/PreviewCursor.scss
+++ b/src/client/views/PreviewCursor.scss
@@ -1,4 +1,5 @@
+.previewCursor-Dark,
.previewCursor {
color: black;
position: absolute;
@@ -8,4 +9,8 @@
pointer-events: none;
opacity: 1;
z-index: 1001;
+}
+
+.previewCursor-Dark {
+ color: white;
} \ No newline at end of file
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index 2b82ef475..ef1360ef1 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -3,7 +3,7 @@ import { observer } from 'mobx-react';
import "normalize.css";
import * as React from 'react';
import { Doc } from '../../fields/Doc';
-import { Cast, NumCast } from '../../fields/Types';
+import { Cast, NumCast, StrCast } from '../../fields/Types';
import { DocServer } from '../DocServer';
import { Docs, DocUtils } from '../documents/Documents';
import { CurrentUserUtils } from '../util/CurrentUserUtils';
@@ -158,7 +158,7 @@ export class PreviewCursor extends React.Component<{}> {
}
render() {
return (!PreviewCursor._clickPoint || !PreviewCursor.Visible) ? (null) :
- <div className="previewCursor" onBlur={this.onBlur} tabIndex={0} ref={e => e?.focus()}
+ <div className={`previewCursor${StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme)}`} onBlur={this.onBlur} tabIndex={0} ref={e => e?.focus()}
style={{ transform: `translate(${PreviewCursor._clickPoint[0]}px, ${PreviewCursor._clickPoint[1]}px)` }}>
I
</div >;
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 3c88a4830..1eb7a222e 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -22,6 +22,7 @@ import "./StyleProvider.scss";
import React = require("react");
import Color = require('color');
import { lightOrDark } from '../../Utils';
+import { ColorScheme } from '../util/SettingsManager';
export enum StyleLayers {
Background = "background"
@@ -49,7 +50,7 @@ export enum StyleProp {
FontSize = "fontSize", // size of text font
}
-function darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); }
+function darkScheme() { return CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark; }
function toggleBackground(doc: Doc) {
UndoManager.RunInBatch(() => runInAction(() => {
@@ -143,7 +144,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
doc.annotationOn ? "#00000015" : // faint interior for collections on PDFs, images, etc
StrCast((props?.renderDepth || 0) > 0 ?
Doc.UserDoc().activeCollectionNestedBackground :
- Doc.UserDoc().activeCollectionBackground)));
+ Doc.UserDoc().activeCollectionBackground ?? (darkScheme() ? Colors.BLACK : Colors.WHITE))));
break;
//if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "rgb(62,62,62)";
default: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.WHITE); break;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 6a22acae8..3ea190a98 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -353,7 +353,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
@action setFocused = (doc: Doc) => this._focusedTable = doc;
@action setPreviewDoc = (doc: Opt<Doc>) => {
- SelectionManager.SelectSchemaView(this, doc);
+ SelectionManager.SelectSchemaViewDoc(doc);
this._previewDoc = doc;
}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 97de097e0..a3da0e0e4 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -481,13 +481,16 @@ export class TreeView extends React.Component<TreeViewProps> {
}
@computed get validExpandViewTypes() {
- if (this.doc.viewType === CollectionViewType.Docking) return [this.fieldKey];
+ if (this.props.treeView.dashboardMode && Doc.UserDoc().noviceMode) {
+ return [this.doc.viewType === CollectionViewType.Docking ? this.fieldKey : "layout"];
+ }
const annos = () => DocListCast(this.doc[this.fieldKey + "-annotations"]).length ? "annotations" : "";
const links = () => DocListCast(this.doc.links).length ? "links" : "";
- const data = () => this.childDocs && !this.props.treeView.dashboardMode ? this.fieldKey : "";
+ const data = () => this.childDocs ? this.fieldKey : "";
const aliases = () => this.props.treeView.dashboardMode ? "" : "aliases";
const fields = () => Doc.UserDoc().noviceMode ? "" : "fields";
- return [data(), "layout", ...(this.props.treeView.fileSysMode ? [aliases(), links(), annos()] : []), fields()].filter(m => m);
+ const layout = this.doc.viewType === CollectionViewType.Docking ? [] : ["layout"];
+ return [data(), ...layout, ...(this.props.treeView.fileSysMode ? [aliases(), links(), annos()] : []), fields()].filter(m => m);
}
@action
expandNextviewType = () => {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 37444a9dc..b3c57d33a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -7,6 +7,7 @@ import { Cast, NumCast, StrCast } from "../../../../fields/Types";
import { aggregateBounds } from "../../../../Utils";
import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
import React = require("react");
+import { ColorScheme } from "../../../util/SettingsManager";
export interface ViewDefBounds {
type: string;
@@ -361,7 +362,7 @@ export function computeTimelineLayout(
groupNames.push({ type: "text", text: toLabel(Math.ceil(maxTime)), x: Math.ceil(maxTime - minTime) * scaling, y: 0, height: fontHeight, fontSize, payload: undefined });
}
- const divider = { type: "div", color: CurrentUserUtils.ActiveDashboard?.darkScheme ? "dimGray" : "black", x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined };
+ const divider = { type: "div", color: CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "dimGray" : "black", x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined };
return normalizeResults(panelDim, fontHeight, docMap, poolData, viewDefsToJSX, groupNames, (maxTime - minTime) * scaling, [divider]);
function layoutDocsAtTime(keyDocs: Doc[], key: number) {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index 2cb487588..f6c2707da 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -3,9 +3,11 @@ import { observer } from "mobx-react";
import { Doc, Field } from "../../../../fields/Doc";
import { Id } from "../../../../fields/FieldSymbols";
import { List } from "../../../../fields/List";
-import { NumCast, StrCast } from "../../../../fields/Types";
+import { NumCast } from "../../../../fields/Types";
import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils';
+import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
import { LinkManager } from "../../../util/LinkManager";
+import { ColorScheme } from "../../../util/SettingsManager";
import { SnappingManager } from "../../../util/SnappingManager";
import { DocumentView } from "../../nodes/DocumentView";
import "./CollectionFreeFormLinkView.scss";
@@ -184,7 +186,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
const linkRelationshipList = Doc.UserDoc().linkRelationshipList as List<string>;
const linkColorList = Doc.UserDoc().linkColorList as List<string>;
//access stroke color using index of the relationship in the color list (default black)
- const strokeColor = linkRelationshipList.indexOf(linkRelationship) === -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)];
+ const strokeColor = linkRelationshipList.indexOf(linkRelationship) === -1 ? (CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "white" : "black") : linkColorList[linkRelationshipList.indexOf(linkRelationship)];
return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<>
<path className="collectionfreeformlinkview-linkLine" style={{ opacity: this._opacity, strokeDasharray: "2 2", stroke: strokeColor }}
d={`M ${pt1[0]} ${pt1[1]} C ${pt1[0] + pt1norm[0]} ${pt1[1] + pt1norm[1]}, ${pt2[0] + pt2norm[0]} ${pt2[1] + pt2norm[1]}, ${pt2[0]} ${pt2[1]}`} />
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 94cf1c5a6..0b12f6c21 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -51,6 +51,7 @@ import "./CollectionFreeFormView.scss";
import { MarqueeView } from "./MarqueeView";
import React = require("react");
import Color = require("color");
+import { ColorScheme } from "../../../util/SettingsManager";
export const panZoomSchema = createSchema({
_panX: "number",
@@ -1419,6 +1420,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const renderGridSpace = gridSpace * this.zoomScaling();
const w = this.props.PanelWidth() + 2 * renderGridSpace;
const h = this.props.PanelHeight() + 2 * renderGridSpace;
+ const strokeStyle = CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "rgba(255,255,255,0.5)" : "rgba(0, 0,0,0.5)";
return <canvas className="collectionFreeFormView-grid" width={w} height={h} style={{ transform: `translate(${shiftX}px, ${shiftY}px)` }}
ref={(el) => {
const ctx = el?.getContext('2d');
@@ -1429,7 +1431,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
ctx.setLineDash(gridSpace > 50 ? [3, 3] : [1, 5]);
ctx.clearRect(0, 0, w, h);
if (ctx) {
- ctx.strokeStyle = "rgba(0, 0, 0, 0.5)";
+ ctx.strokeStyle = strokeStyle;
ctx.beginPath();
for (let x = Cx - renderGridSpace; x <= w - Cx; x += renderGridSpace) {
ctx.moveTo(x, Cy - h);
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index 7fe95fef0..18a715edf 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -109,7 +109,6 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
}
myContextMenu = (e: React.MouseEvent) => {
- console.log("STOPPING");
e.stopPropagation();
e.preventDefault();
}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index dfe99ffc8..12493ecc1 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -337,8 +337,9 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
{this.renderTypes(this._col)}
{this.renderColors(this._col)}
<div className="collectionSchema-headerMenu-group">
- <button onClick={() => { this.deleteColumn(this._col.heading); }}
- >Hide Column</button>
+ <button onClick={() => { this.deleteColumn(this._col.heading); }}>
+ Hide Column
+ </button>
</div>
</div>;
}
@@ -353,7 +354,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
@action setFocused = (doc: Doc) => this._focusedTable = doc;
@action setPreviewDoc = (doc: Opt<Doc>) => {
- SelectionManager.SelectSchemaView(this, doc);
+ SelectionManager.SelectSchemaViewDoc(doc);
this._previewDoc = doc;
}
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index 7f164ca48..1ec7bf72a 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -175,6 +175,7 @@
position: absolute;
bottom: 0;
width: 100%;
+ overflow-y: scroll;
transform-origin: bottom left;
opacity: 0.1;
transition: opacity 0.5s;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6e7590a78..b44b32832 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -25,7 +25,6 @@ import { InteractionUtils } from '../../util/InteractionUtils';
import { LinkManager } from '../../util/LinkManager';
import { Scripting } from '../../util/Scripting';
import { SelectionManager } from "../../util/SelectionManager";
-import { ColorScheme } from "../../util/SettingsManager";
import { SharingManager } from '../../util/SharingManager';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from "../../util/Transform";
@@ -50,6 +49,7 @@ import { ScriptingBox } from "./ScriptingBox";
import { PresBox } from './trails/PresBox';
import React = require("react");
import { IconProp } from "@fortawesome/fontawesome-svg-core";
+import { ColorScheme } from "../../util/SettingsManager";
const { Howl } = require('howler');
interface Window {
@@ -973,19 +973,26 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
captionStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewInternalProps>, property: string) => this.props?.styleProvider?.(doc, props, property + ":caption");
@computed get innards() {
TraceMobx();
+ const ffscale = (this.props.DocumentView().props.CollectionFreeFormDocumentView?.().props.ScreenToLocalTransform().Scale || 1);
const showTitle = this.ShowTitle?.split(":")[0];
const showTitleHover = this.ShowTitle?.includes(":hover");
const showCaption = !this.props.hideCaptions && this.Document._viewType !== CollectionViewType.Carousel ? StrCast(this.layoutDoc._showCaption) : undefined;
const captionView = !showCaption ? (null) :
<div className="documentView-captionWrapper"
- style={{ pointerEvents: this.onClickHandler || this.Document.ignoreClick ? "none" : this.isContentActive() || this.props.isDocumentActive?.() ? "all" : undefined, }}>
+ style={{
+ pointerEvents: this.onClickHandler || this.Document.ignoreClick ? "none" : this.isContentActive() || this.props.isDocumentActive?.() ? "all" : undefined,
+ minWidth: 50 * ffscale,
+ maxHeight: `max(100%, ${20 * ffscale}px)`
+ }}>
<FormattedTextBox {...OmitKeys(this.props, ['children']).omit}
yPadding={10}
xPadding={10}
fieldKey={showCaption}
- fontSize={Math.min(32, 12 * this.props.ScreenToLocalTransform().Scale)}
+ fontSize={12 * Math.max(1, 2 * ffscale / 3)}
styleProvider={this.captionStyleProvider}
dontRegisterView={true}
+ noSidebar={true}
+ dontScale={true}
isContentActive={this.isContentActive}
onClick={this.onClickFunc}
/>
@@ -1055,9 +1062,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
render() {
TraceMobx();
const highlightIndex = this.props.LayoutTemplateString ? (Doc.IsHighlighted(this.props.Document) ? 6 : 0) : Doc.isBrushedHighlightedDegree(this.props.Document); // bcz: Argh!! need to identify a tree view doc better than a LayoutTemlatString
- const highlightColor = (Doc.UserDoc().colorScheme === ColorScheme.Dark ?
- ["transparent", "#65350c", "#65350c", "yellow", "magenta", "cyan", "orange"] :
- ["transparent", "#4476F7", "#4476F7", "yellow", "magenta", "cyan", "orange"])[highlightIndex];
+ const highlightColor = ["transparent", "rgb(68, 118, 247)", "rgb(68, 118, 247)", "yellow", "magenta", "cyan", "orange"][highlightIndex];
const highlightStyle = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"][highlightIndex];
const excludeTypes = !this.props.treeViewDoc ? [DocumentType.FONTICON, DocumentType.INK] : [DocumentType.FONTICON];
let highlighting = !this.props.disableDocBrushing && highlightIndex && !excludeTypes.includes(this.layoutDoc.type as any) && this.layoutDoc._viewType !== CollectionViewType.Linear;
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index 9d1ef937f..511df8786 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -5,7 +5,7 @@ import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { ColorState, SketchPicker } from 'react-color';
-import { Doc, StrListCast } from '../../../../fields/Doc';
+import { Doc, StrListCast, WidthSym, HeightSym } from '../../../../fields/Doc';
import { InkTool } from '../../../../fields/InkField';
import { createSchema, makeInterface } from '../../../../fields/Schema';
import { ScriptField } from '../../../../fields/ScriptField';
@@ -14,7 +14,6 @@ import { WebField } from '../../../../fields/URLField';
import { DocumentType } from '../../../documents/DocumentTypes';
import { Scripting } from "../../../util/Scripting";
import { SelectionManager } from '../../../util/SelectionManager';
-import { ColorScheme } from '../../../util/SettingsManager';
import { UndoManager, undoBatch } from '../../../util/UndoManager';
import { CollectionViewType } from '../../collections/CollectionView';
import { ContextMenu } from '../../ContextMenu';
@@ -114,7 +113,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
// Script for checking the outcome of the toggle
const checkScript: string = StrCast(this.rootDoc.script) + "(0, true)";
- const checkResult: number = ScriptField.MakeScript(checkScript)?.script.run().result;
+ const checkResult: number = ScriptField.MakeScript(checkScript)?.script.run().result || 0;
if (numBtnType === NumButtonType.Slider) {
@@ -159,7 +158,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
<div
className={`menuButton ${this.type} ${numBtnType}`}
>
- <div className={`button`} onClick={action((e) => setValue(checkResult - 1))}>
+ <div className={`button`} onClick={action((e) => setValue(Number(checkResult) - 1))}>
<FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"minus"} />
</div>
<div
@@ -178,7 +177,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
onChange={action((e) => setValue(Number(e.target.value)))}
/>
</div>
- <div className={`button`} onClick={action((e) => setValue(checkResult + 1))}>
+ <div className={`button`} onClick={action((e) => setValue(Number(checkResult) + 1))}>
<FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"plus"} />
</div>
@@ -262,8 +261,8 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
}
noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
} else if (script === 'setFont') {
- const selected = SelectionManager.Docs().lastElement();
- text = StrCast((selected?.type === DocumentType.RTF ? selected : Doc.UserDoc())._fontFamily);
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
+ text = StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
noviceList = ["Roboto", "Times New Roman", "Arial", "Georgia",
"Comic Sans MS", "Tahoma", "Impact", "Crimson Text"];
}
@@ -319,29 +318,35 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
);
}
+ @observable colorPickerClosed: boolean = true;
+ @computed get colorScript() {
+ const script = StrCast(this.rootDoc.script);
+ return ScriptField.MakeScript(script + '(colValue, checkResult)', { colValue: "string", checkResult: "boolean" });
+ }
+
+ colorPicker = (curColor: string) => {
+ const change = (value: ColorState) => {
+ const s = this.colorScript;
+ s && undoBatch(() => s.script.run({ colValue: Utils.colorString(value), checkResult: false }).result)();
+ };
+ const presets = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
+ '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
+ '#FFFFFF', '#f1efeb', "transparent"];
+ return <SketchPicker
+ onChange={change}
+ color={curColor}
+ presetColors={presets} />
+ }
/**
* Color button
*/
@computed get colorButton() {
- const active: string = StrCast(this.rootDoc.dropDownOpen);
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({ colValue: undefined, checkResult: true }).result ?? "transparent";
- const script: string = StrCast(this.rootDoc.script);
- const scriptCheck: string = script + "(undefined, true)";
- const boolResult = ScriptField.MakeScript(scriptCheck)?.script.run().result;
-
- const colorOptions: string[] = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
- '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
- '#FFFFFF', '#f1efeb', "transparent"];
-
- const colorBox = (func: (color: ColorState) => void) => <SketchPicker
- disableAlpha={false}
- onChange={func}
- color={boolResult ? boolResult : "#FFFFFF"}
- presetColors={colorOptions} />;
const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
- <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
+ <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}>
{this.label}
</div>;
@@ -350,30 +355,27 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
<FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
</div>;
-
- const click = (value: ColorState) => {
- const s = ScriptField.MakeScript(script + '("' + Utils.colorString(value) + '", false)');
- s && undoBatch(() => s.script.run().result)();
- };
+ setTimeout(() => this.colorPicker(curColor)); // cause an update to the color picker rendered in MainView
return (
- <div className={`menuButton ${this.type} ${active}`}
+ <div className={`menuButton ${this.type} ${this.colorPickerClosed}`}
style={{ color: color, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
- onClick={() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen}
+ onClick={action(() => this.colorPickerClosed = !this.colorPickerClosed)}
onPointerDown={e => e.stopPropagation()}>
<FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
- <div className="colorButton-color" style={{ backgroundColor: boolResult ? boolResult : "#FFFFFF" }} />
+ <div className="colorButton-color" style={{ backgroundColor: curColor }} />
{label}
{/* {dropdownCaret} */}
- {this.rootDoc.dropDownOpen ?
+ {this.colorPickerClosed ? (null) :
<div>
<div className="menuButton-dropdownBox"
onPointerDown={e => e.stopPropagation()}
onClick={e => e.stopPropagation()}>
- {colorBox(click)}
+ {this.colorPicker(curColor)}
</div>
- <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
- </div>
- : null}
+ <div className="dropbox-background" onClick={action((e) => {
+ e.stopPropagation(); this.colorPickerClosed = true;
+ })} />
+ </div>}
</div>
);
}
@@ -388,7 +390,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
// Button label
const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
- <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
+ <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}>
{this.label}
</div>;
@@ -407,7 +409,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
} else {
return (
<div className={`menuButton ${this.type}`}
- style={{ opacity: 1, backgroundColor: backgroundColor, color: color }}>
+ style={{ opacity: 1, backgroundColor, color }}>
<FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
{label}
</div>
@@ -463,7 +465,6 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
render() {
const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
- const dark: boolean = Doc.UserDoc().colorScheme === ColorScheme.Dark;
const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
<div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
@@ -573,15 +574,9 @@ Scripting.addGlobal(function setView(view: string) {
Scripting.addGlobal(function setBackgroundColor(color?: string, checkResult?: boolean) {
const selected = SelectionManager.Docs().lastElement();
if (checkResult) {
- if (selected) {
- return selected._backgroundColor;
- } else {
- return "#FFFFFF";
- }
+ return selected?._backgroundColor ?? "transparent";
}
- if (selected?.type === DocumentType.INK) selected.fillColor = color;
if (selected) selected._backgroundColor = color;
- Doc.UserDoc()._fontColor = color;
});
// toggle: Set overlay status of selected document
@@ -599,7 +594,7 @@ Scripting.addGlobal(function toggleOverlay(checkResult?: boolean) {
const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
if (checkResult && selected) {
if (NumCast(selected.Document.z) >= 1) return Colors.MEDIUM_BLUE;
- else return "transparent";
+ return "transparent";
}
selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("[FontIconBox.tsx] toggleOverlay failed");
});
@@ -620,16 +615,18 @@ Scripting.addGlobal(function toggleOverlay(checkResult?: boolean) {
Scripting.addGlobal(function setFont(font: string, checkResult?: boolean) {
SelectionManager.Docs().map(doc => doc._fontFamily = font);
const editorView = RichTextMenu.Instance.TextView?.EditorView;
- editorView?.state && RichTextMenu.Instance.setFontFamily(font, editorView);
- Doc.UserDoc()._fontFamily = font;
- return Doc.UserDoc()._fontFamily;
+ if (checkResult) {
+ return StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
+ }
+ if (editorView) RichTextMenu.Instance.setFontFamily(font);
+ else Doc.UserDoc().fontFamily = font;
});
Scripting.addGlobal(function getActiveTextInfo(info: "family" | "size" | "color" | "highlight") {
const editorView = RichTextMenu.Instance.TextView?.EditorView;
const style = editorView?.state && RichTextMenu.Instance.getActiveFontStylesOnSelection();
switch (info) {
- case "family": return style?.activeColors[0];
+ case "family": return style?.activeFamilies[0];
case "size": return style?.activeSizes[0];
case "color": return style?.activeColors[0];
case "highlight": return style?.activeHighlights[0];
@@ -646,7 +643,7 @@ Scripting.addGlobal(function setAlignment(align: "left" | "right" | "center", ch
active = StrCast(Doc.UserDoc().textAlign);
}
if (active === align) return Colors.MEDIUM_BLUE;
- else return "transparent";
+ return "transparent";
}
SelectionManager.Docs().map(doc => doc.textAlign = align);
switch (align) {
@@ -670,38 +667,25 @@ Scripting.addGlobal(function setBulletList(mapStyle: "bullet" | "decimal", check
if (checkResult) {
const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
if (active === mapStyle) return Colors.MEDIUM_BLUE;
- else return "transparent";
+ return "transparent";
}
if (editorView) {
const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
- if (active === mapStyle) {
- editorView?.state && RichTextMenu.Instance.changeListType(editorView.state.schema.nodes.ordered_list.create({ mapStyle: "" }));
- } else {
- editorView?.state && RichTextMenu.Instance.changeListType(editorView.state.schema.nodes.ordered_list.create({ mapStyle: mapStyle }));
- }
+ editorView?.state && RichTextMenu.Instance.changeListType(
+ editorView.state.schema.nodes.ordered_list.create({ mapStyle: active === mapStyle ? "" : mapStyle }));
}
});
// toggle: Set overlay status of selected document
Scripting.addGlobal(function setFontColor(color?: string, checkResult?: boolean) {
- const selected = SelectionManager.Docs().lastElement();
const editorView = RichTextMenu.Instance.TextView?.EditorView;
if (checkResult) {
- if (selected) {
- return selected._fontColor;
- } else {
- return Doc.UserDoc()._fontColor;
- }
+ return editorView ? RichTextMenu.Instance.fontColor : Doc.UserDoc().fontColor;
}
- if (selected) {
- selected._fontColor = color;
- if (color) {
- editorView?.state && RichTextMenu.Instance.setColor(color, editorView, editorView?.dispatch);
- }
- }
- Doc.UserDoc()._fontColor = color;
+ if (editorView) color && RichTextMenu.Instance.setColor(color, editorView, editorView?.dispatch);
+ else Doc.UserDoc().fontColor = color;
});
// toggle: Set overlay status of selected document
@@ -710,11 +694,7 @@ Scripting.addGlobal(function setFontHighlight(color?: string, checkResult?: bool
const editorView = RichTextMenu.Instance.TextView?.EditorView;
if (checkResult) {
- if (selected) {
- return selected._fontHighlight;
- } else {
- return Doc.UserDoc()._fontHighlight;
- }
+ return (selected ?? Doc.UserDoc())._fontHighlight;
}
if (selected) {
selected._fontColor = color;
@@ -725,62 +705,43 @@ Scripting.addGlobal(function setFontHighlight(color?: string, checkResult?: bool
Doc.UserDoc()._fontHighlight = color;
});
-
-
// toggle: Set overlay status of selected document
-Scripting.addGlobal(function setFontSize(size: string, checkResult?: boolean) {
+Scripting.addGlobal(function setFontSize(size: string | number, checkResult?: boolean) {
+ if (typeof size === "number") size = size.toString();
+ if (size && Number(size).toString() === size) size += "px";
+ const editorView = RichTextMenu.Instance.TextView?.EditorView;
if (checkResult) {
- const size: number = parseInt(StrCast(Doc.UserDoc()._fontSize), 10);
- return size;
+ return (editorView ? RichTextMenu.Instance.fontSize : StrCast(Doc.UserDoc().fontSize, "10px")).replace("px", "");
}
- const editorView = RichTextMenu.Instance.TextView?.EditorView;
- editorView?.state && RichTextMenu.Instance.setFontSize(Number(size), editorView);
- Doc.UserDoc()._fontSize = size + "px";
+ if (editorView) RichTextMenu.Instance.setFontSize(size);
+ else Doc.UserDoc()._fontSize = size;
});
Scripting.addGlobal(function toggleBold(checkResult?: boolean) {
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
if (checkResult) {
- const editorView = RichTextMenu.Instance.TextView?.EditorView;
- if (editorView) {
- const bold: boolean = editorView?.state && RichTextMenu.Instance.getBoldStatus();
- if (bold) return Colors.MEDIUM_BLUE;
- else return "transparent";
- }
- else return "transparent";
+ return (editorView ? RichTextMenu.Instance.bold : Doc.UserDoc().fontWeight === "bold") ? Colors.MEDIUM_BLUE : "transparent";
}
- const editorView = RichTextMenu.Instance.TextView?.EditorView;
- if (editorView) {
- editorView?.state && RichTextMenu.Instance.toggleBold(editorView, true);
- }
- SelectionManager.Docs().filter(doc => StrCast(doc.type) === DocumentType.RTF).map(doc => doc.bold = !doc.bold);
- Doc.UserDoc().bold = !Doc.UserDoc().bold;
- return Doc.UserDoc().bold;
+ if (editorView) RichTextMenu.Instance?.toggleBold();
+ else Doc.UserDoc().fontWeight = Doc.UserDoc().fontWeight === "bold" ? undefined : "bold";
});
Scripting.addGlobal(function toggleUnderline(checkResult?: boolean) {
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
if (checkResult) {
- return "transparent";
+ return (editorView ? RichTextMenu.Instance.underline : Doc.UserDoc().textDecoration === "underline") ? Colors.MEDIUM_BLUE : "transparent";
}
- const editorView = RichTextMenu.Instance.TextView?.EditorView;
- if (editorView) {
- editorView?.state && RichTextMenu.Instance.toggleUnderline(editorView, true);
- }
- SelectionManager.Docs().filter(doc => StrCast(doc.type) === DocumentType.RTF).map(doc => doc.underline = !doc.underline);
- Doc.UserDoc().underline = !Doc.UserDoc().underline;
- return Doc.UserDoc().underline;
+ if (editorView) RichTextMenu.Instance?.toggleUnderline();
+ else Doc.UserDoc().textDecoration = Doc.UserDoc().textDecoration === "underline" ? undefined : "underline";
});
Scripting.addGlobal(function toggleItalic(checkResult?: boolean) {
+ const editorView = RichTextMenu.Instance?.TextView?.EditorView;
if (checkResult) {
- return "transparent";
+ return (editorView ? RichTextMenu.Instance.italics : Doc.UserDoc().fontStyle === "italics") ? Colors.MEDIUM_BLUE : "transparent";
}
- const editorView = RichTextMenu.Instance.TextView?.EditorView;
- if (editorView) {
- editorView?.state && RichTextMenu.Instance.toggleItalic(editorView, true);
- }
- SelectionManager.Docs().filter(doc => StrCast(doc.type) === DocumentType.RTF).map(doc => doc.italic = !doc.italic);
- Doc.UserDoc().italic = !Doc.UserDoc().italic;
- return Doc.UserDoc().italic;
+ if (editorView) RichTextMenu.Instance?.toggleItalics();
+ else Doc.UserDoc().fontStyle = Doc.UserDoc().fontStyle === "italics" ? undefined : "italics";
});
@@ -794,24 +755,23 @@ Scripting.addGlobal(function toggleItalic(checkResult?: boolean) {
Scripting.addGlobal(function setActiveInkTool(tool: string, checkResult?: boolean) {
if (checkResult) {
- if (Doc.UserDoc().activeInkTool === tool && GestureOverlay.Instance.InkShape === "" || GestureOverlay.Instance.InkShape === tool) return Colors.MEDIUM_BLUE;
- else return "transparent";
+ return (Doc.UserDoc().activeInkTool === tool && GestureOverlay.Instance?.InkShape === "" || GestureOverlay.Instance?.InkShape === tool) ?
+ Colors.MEDIUM_BLUE : "transparent";
}
- if (tool === "circle") {
- Doc.UserDoc().activeInkTool = "pen";
- GestureOverlay.Instance.InkShape = tool;
- } else if (tool === "square") {
- Doc.UserDoc().activeInkTool = "pen";
- GestureOverlay.Instance.InkShape = tool;
- } else if (tool === "line") {
- Doc.UserDoc().activeInkTool = "pen";
- GestureOverlay.Instance.InkShape = tool;
- } else if (tool) {
- if (Doc.UserDoc().activeInkTool === tool && GestureOverlay.Instance.InkShape === "" || GestureOverlay.Instance.InkShape === tool) {
- GestureOverlay.Instance.InkShape = "";
+ if (["circle", "square", "line"].includes(tool)) {
+ if (GestureOverlay.Instance.InkShape === tool) {
+ Doc.UserDoc().activeInkTool = InkTool.None;
+ GestureOverlay.Instance.InkShape = InkTool.None;
+ } else {
+ Doc.UserDoc().activeInkTool = InkTool.Pen;
+ GestureOverlay.Instance.InkShape = tool;
+ }
+ } else if (tool) { // pen
+ if (Doc.UserDoc().activeInkTool === tool && !GestureOverlay.Instance.InkShape) {
Doc.UserDoc().activeInkTool = InkTool.None;
} else {
Doc.UserDoc().activeInkTool = tool;
+ GestureOverlay.Instance.InkShape = "";
}
} else {
Doc.UserDoc().activeInkTool = InkTool.None;
@@ -823,7 +783,7 @@ Scripting.addGlobal(function setFillColor(color?: string, checkResult?: boolean)
const selected = SelectionManager.Docs().lastElement();
if (checkResult) {
if (selected?.type === DocumentType.INK) {
- return StrCast(selected._backgroundColor);
+ return StrCast(selected.fillColor);
}
return ActiveFillColor();
}
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index e519de1c5..149836e93 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -12,6 +12,7 @@ import { FormattedTextBox } from "./FormattedTextBox";
import React = require("react");
import * as ReactDOM from 'react-dom';
import { observer } from "mobx-react";
+import { ColorScheme } from "../../../util/SettingsManager";
export class DashDocView {
_fieldWrapper: HTMLSpanElement; // container for label and value
@@ -20,7 +21,7 @@ export class DashDocView {
this._fieldWrapper = document.createElement("span");
this._fieldWrapper.style.position = "relative";
this._fieldWrapper.style.textIndent = "0";
- this._fieldWrapper.style.border = "1px solid " + StrCast(tbox.layoutDoc.color, (CurrentUserUtils.ActiveDashboard.darkScheme ? "dimGray" : "lightGray"));
+ this._fieldWrapper.style.border = "1px solid " + StrCast(tbox.layoutDoc.color, (CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "dimGray" : "lightGray"));
this._fieldWrapper.style.width = node.attrs.width;
this._fieldWrapper.style.height = node.attrs.height;
this._fieldWrapper.style.display = node.attrs.hidden ? "none" : "inline-block";
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index ebd509669..7afa54d5f 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -279,8 +279,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
(curText !== Cast(this.dataDoc[this.fieldKey], RichTextField)?.Text) && (this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now())));
if ((!curTemp && !curProto) || curText || json.includes("dash")) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended)
if (removeSelection(json) !== removeSelection(curLayout?.Data)) {
- !curText && tx.storedMarks?.filter(m => m.type.name === "pFontSize").map(m => Doc.UserDoc().fontSize = this.layoutDoc._fontSize = (m.attrs.fontSize + "px"));
- !curText && tx.storedMarks?.filter(m => m.type.name === "pFontFamily").map(m => Doc.UserDoc().fontFamily = this.layoutDoc._fontFamily = m.attrs.fontFamily);
this.dataDoc[this.props.fieldKey] = new RichTextField(json, curText);
this.dataDoc[this.props.fieldKey + "-noTemplate"] = true;//(curTemp?.Text || "") !== curText; // mark the data field as being split from the template if it has been edited
ScriptCast(this.layoutDoc.onTextChanged, null)?.script.run({ this: this.layoutDoc, self: this.rootDoc, text: curText });
@@ -833,7 +831,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this._disposers.componentHeights = reaction( // set the document height when one of the component heights changes and autoHeight is on
() => ({ sidebarHeight: this.sidebarHeight, textHeight: this.textHeight, autoHeight: this.autoHeight, marginsHeight: this.autoHeightMargins }),
({ sidebarHeight, textHeight, autoHeight, marginsHeight }) => {
- autoHeight && this.props.setHeight(marginsHeight + Math.max(sidebarHeight, textHeight));
+ autoHeight && this.props.setHeight?.(marginsHeight + Math.max(sidebarHeight, textHeight));
}, { fireImmediately: true });
this._disposers.links = reaction(() => DocListCast(this.Document.links), // if a link is deleted, then remove all hyperlinks that reference it from the text's marks
newLinks => {
@@ -894,11 +892,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
{ fireImmediately: Doc.IsSearchMatchUnmemoized(this.rootDoc) ? true : false });
this._disposers.selected = reaction(() => this.props.isSelected(),
- action((selected) => {
+ action(selected => {
if (RichTextMenu.Instance?.view === this._editorView && !selected) {
RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined);
}
- }));
+ if (this._editorView && selected) {
+ RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props);
+ }
+ }), { fireImmediately: true });
if (!this.props.dontRegisterView) {
this._disposers.record = reaction(() => this._recording,
@@ -1168,7 +1169,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
selectOnLoad && this._editorView!.focus();
// add user mark for any first character that was typed since the user mark that gets set in KeyPress won't have been called yet.
if (this._editorView && !this._editorView.state.storedMarks?.some(mark => mark.type === schema.marks.user_mark)) {
- this._editorView.state.storedMarks = [...(this._editorView.state.storedMarks ?? []), schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })];
+ this._editorView.state.storedMarks = [...(this._editorView.state.storedMarks ?? []),
+ schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) }),
+ ...(Doc.UserDoc().fontColor !== "transparent" && Doc.UserDoc().fontColor ? [schema.mark(schema.marks.pFontColor, { color: StrCast(Doc.UserDoc().fontColor) })] : []),
+ ...(Doc.UserDoc().fontStyle === "italics" ? [schema.mark(schema.marks.em)] : []),
+ ...(Doc.UserDoc().textDecoration === "underline" ? [schema.mark(schema.marks.underline)] : []),
+ ...(Doc.UserDoc().fontFamily ? [schema.mark(schema.marks.pFontFamily, { family: StrCast(Doc.UserDoc().fontFamily) })] : []),
+ ...(Doc.UserDoc().fontSize ? [schema.mark(schema.marks.pFontSize, { fontSize: StrCast(Doc.UserDoc().fontSize, "") })] : []),
+ ...(Doc.UserDoc().fontWeight === "bold" ? [schema.mark(schema.marks.strong)] : [])];
}
}
@@ -1596,7 +1604,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
background: this.props.background ? this.props.background : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor),
color: this.props.color ? this.props.color : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color),
fontSize: this.props.fontSize ? this.props.fontSize : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.FontSize),
- fontWeight: Cast(this.layoutDoc._fontWeight, "number", null),
+ fontWeight: Cast(this.layoutDoc._fontWeight, "string", null) as any,
fontFamily: StrCast(this.layoutDoc._fontFamily, "inherit"),
pointerEvents: interactive ? undefined : "none",
}}
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 9904a7939..bd05af977 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -1,8 +1,7 @@
import React = require("react");
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Tooltip } from "@material-ui/core";
-import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx";
+import { action, IReactionDisposer, observable, reaction, runInAction, computed } from "mobx";
import { observer } from "mobx-react";
import { lift, wrapIn } from "prosemirror-commands";
import { Mark, MarkType, Node as ProsNode, NodeType, ResolvedPos } from "prosemirror-model";
@@ -10,10 +9,7 @@ import { wrapInList } from "prosemirror-schema-list";
import { EditorState, NodeSelection, TextSelection } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import { Doc } from "../../../../fields/Doc";
-import { DarkPastelSchemaPalette, PastelSchemaPalette } from '../../../../fields/SchemaHeaderField';
import { Cast, StrCast } from "../../../../fields/Types";
-import { TraceMobx } from "../../../../fields/util";
-import { unimplementedFunction, Utils } from "../../../../Utils";
import { DocServer } from "../../../DocServer";
import { LinkManager } from "../../../util/LinkManager";
import { SelectionManager } from "../../../util/SelectionManager";
@@ -29,7 +25,7 @@ const { toggleMark } = require("prosemirror-commands");
@observer
export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
- static Instance: RichTextMenu;
+ @observable static Instance: RichTextMenu;
public overMenu: boolean = false; // kind of hacky way to prevent selects not being selectable
private _linkToRef = React.createRef<HTMLInputElement>();
@@ -39,22 +35,22 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
public _brushMap: Map<string, Set<Mark>> = new Map();
@observable private collapsed: boolean = false;
- @observable private boldActive: boolean = false;
- @observable private italicsActive: boolean = false;
- @observable private underlineActive: boolean = false;
- @observable private strikethroughActive: boolean = false;
- @observable private subscriptActive: boolean = false;
- @observable private superscriptActive: boolean = false;
-
- @observable private activeFontSize: string = "";
- @observable private activeFontFamily: string = "";
+ @observable private _boldActive: boolean = false;
+ @observable private _italicsActive: boolean = false;
+ @observable private _underlineActive: boolean = false;
+ @observable private _strikethroughActive: boolean = false;
+ @observable private _subscriptActive: boolean = false;
+ @observable private _superscriptActive: boolean = false;
+
+ @observable private _activeFontSize: string = "13px";
+ @observable private _activeFontFamily: string = "";
@observable private activeListType: string = "";
@observable private activeAlignment: string = "left";
@observable private brushMarks: Set<Mark> = new Set();
@observable private showBrushDropdown: boolean = false;
- @observable private activeFontColor: string = "black";
+ @observable private _activeFontColor: string = "black";
@observable private showColorDropdown: boolean = false;
@observable private activeHighlightColor: string = "transparent";
@@ -67,10 +63,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
_delayHide = false;
constructor(props: Readonly<{}>) {
super(props);
- RichTextMenu.Instance = this;
- this._canFade = false;
- //this.Pinned = BoolCast(Doc.UserDoc()["menuRichText-pinned"]);
- runInAction(() => this.Pinned = true);
+ runInAction(() => {
+ RichTextMenu.Instance = this;
+ this._canFade = false;
+ //this.Pinned = BoolCast(Doc.UserDoc()["menuRichText-pinned"]);
+ this.Pinned = true;
+ });
}
componentDidMount() {
@@ -81,6 +79,14 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
this._reaction?.();
}
+ @computed get bold() { return this._boldActive; }
+ @computed get underline() { return this._underlineActive; }
+ @computed get italics() { return this._italicsActive; }
+ @computed get strikeThrough() { return this._strikethroughActive; }
+ @computed get fontColor() { return this._activeFontColor; }
+ @computed get fontFamily() { return this._activeFontFamily; }
+ @computed get fontSize() { return this._activeFontSize; }
+
public delayHide = () => this._delayHide = true;
@action
@@ -110,10 +116,10 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
this.activeListType = this.getActiveListStyle();
this.activeAlignment = this.getActiveAlignment();
- this.activeFontFamily = !activeFamilies.length ? "Arial" : activeFamilies.length === 1 ? String(activeFamilies[0]) : "various";
- this.activeFontSize = !activeSizes.length ? "13px" : activeSizes.length === 1 ? String(activeSizes[0]) : "...";
- this.activeFontColor = !activeColors.length ? "black" : activeColors.length === 1 ? String(activeColors[0]) : "...";
- this.activeHighlightColor = !activeHighlights.length ? "" : activeHighlights.length === 1 ? String(activeHighlights[0]) : "...";
+ this._activeFontFamily = !activeFamilies.length ? "Arial" : activeFamilies.length === 1 ? String(activeFamilies[0]) : "various";
+ this._activeFontSize = !activeSizes.length ? "13px" : activeSizes[0];
+ this._activeFontColor = !activeColors.length ? "black" : activeColors.length > 0 ? String(activeColors[0]) : "...";
+ this.activeHighlightColor = !activeHighlights.length ? "" : activeHighlights.length > 0 ? String(activeHighlights[0]) : "...";
// update link in current selection
this.getTextLinkTargetTitle().then(targetTitle => this.setCurrentLink(targetTitle));
@@ -125,7 +131,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
if (node?.type === schema.nodes.ordered_list) {
let attrs = node.attrs;
if (mark.type === schema.marks.pFontFamily) attrs = { ...attrs, fontFamily: mark.attrs.family };
- if (mark.type === schema.marks.pFontSize) attrs = { ...attrs, fontSize: `${mark.attrs.fontSize}px` };
+ if (mark.type === schema.marks.pFontSize) attrs = { ...attrs, fontSize: mark.attrs.fontSize };
if (mark.type === schema.marks.pFontColor) attrs = { ...attrs, fontColor: mark.attrs.color };
const tr = updateBullets(state.tr.setNodeMarkup(state.selection.from, node.type, attrs), state.schema);
dispatch(tr.setSelection(new NodeSelection(tr.doc.resolve(state.selection.from))));
@@ -142,17 +148,6 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
}
- getBoldStatus() {
- if (this.view && this.TextView.props.isSelected(true)) {
- const path = (this.view.state.selection.$from as any).path;
- for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) {
- if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) {
- return path[i].attrs.strong;
- }
- }
- }
- }
-
// finds font sizes and families in selection
getActiveAlignment() {
if (this.view && this.TextView.props.isSelected(true)) {
@@ -193,25 +188,22 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
if (this.TextView.props.isSelected(true)) {
const state = this.view.state;
const pos = this.view.state.selection.$from;
- const ref_node = this.reference_node(pos);
- if (ref_node && ref_node !== this.view.state.doc && ref_node.isText) {
- const marks = Array.from(ref_node.marks);
- marks.push(...(this.view.state.storedMarks as any));
- marks.forEach(m => {
- m.type === state.schema.marks.pFontFamily && activeFamilies.push(m.attrs.family);
- m.type === state.schema.marks.pFontColor && activeColors.push(m.attrs.color);
- m.type === state.schema.marks.pFontSize && activeSizes.push(String(m.attrs.fontSize) + "px");
- m.type === state.schema.marks.marker && activeHighlights.push(String(m.attrs.highlight));
+ const marks: Mark<any>[] = [...(state.storedMarks ?? [])];
+ if (state.selection.empty) {
+ const ref_node = this.reference_node(pos);
+ marks.push(...(ref_node !== this.view.state.doc && ref_node?.isText ? Array.from(ref_node.marks) : []));
+ } else {
+ state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
+ node.marks?.filter(mark => !mark.isInSet(marks)).map(mark => marks.push(mark));
});
}
- !activeFamilies.length && (activeFamilies.push(StrCast(this.TextView.layoutDoc._fontFamily, StrCast(Doc.UserDoc().fontFamily))));
- !activeSizes.length && (activeSizes.push(StrCast(this.TextView.layoutDoc._fontSize, StrCast(Doc.UserDoc().fontSize))));
- !activeColors.length && (activeColors.push(StrCast(this.TextView.layoutDoc.color, StrCast(Doc.UserDoc().fontColor))));
+ marks.forEach(m => {
+ m.type === state.schema.marks.pFontFamily && activeFamilies.push(m.attrs.family);
+ m.type === state.schema.marks.pFontColor && activeColors.push(m.attrs.color);
+ m.type === state.schema.marks.pFontSize && activeSizes.push(m.attrs.fontSize);
+ m.type === state.schema.marks.marker && activeHighlights.push(String(m.attrs.highlight));
+ });
}
- !activeFamilies.length && (activeFamilies.push(StrCast(Doc.UserDoc().fontFamily)));
- !activeSizes.length && (activeSizes.push(StrCast(Doc.UserDoc().fontSize)));
- !activeColors.length && (activeColors.push(StrCast(Doc.UserDoc().fontColor, "black")));
- !activeHighlights.length && (activeHighlights.push(StrCast(Doc.UserDoc().fontHighlight, "")));
return { activeFamilies, activeSizes, activeColors, activeHighlights };
}
@@ -251,11 +243,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
return [];
}
activeMarks = markGroup.filter(mark_type => {
- if (mark_type === state.schema.marks.pFontSize) {
- return ref_node.marks.some(m => m.type.name === state.schema.marks.pFontSize.name);
- }
+ // if (mark_type === state.schema.marks.pFontSize) {
+ // return mark.isINSet
+ // ref_node.marks.some(m => m.type.name === state.schema.marks.pFontSize.name);
+ // }
const mark = state.schema.mark(mark_type);
- return ref_node.marks.includes(mark);
+ return mark.isInSet(ref_node.marks);
});
}
}
@@ -270,56 +263,66 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
setActiveMarkButtons(activeMarks: MarkType[] | undefined) {
if (!activeMarks) return;
- this.boldActive = false;
- this.italicsActive = false;
- this.underlineActive = false;
- this.strikethroughActive = false;
- this.subscriptActive = false;
- this.superscriptActive = false;
+ this._boldActive = false;
+ this._italicsActive = false;
+ this._underlineActive = false;
+ this._strikethroughActive = false;
+ this._subscriptActive = false;
+ this._superscriptActive = false;
activeMarks.forEach(mark => {
switch (mark.name) {
- case "strong": this.boldActive = true; break;
- case "em": this.italicsActive = true; break;
- case "underline": this.underlineActive = true; break;
- case "strikethrough": this.strikethroughActive = true; break;
- case "subscript": this.subscriptActive = true; break;
- case "superscript": this.superscriptActive = true; break;
+ case "strong": this._boldActive = true; break;
+ case "em": this._italicsActive = true; break;
+ case "underline": this._underlineActive = true; break;
+ case "strikethrough": this._strikethroughActive = true; break;
+ case "subscript": this._subscriptActive = true; break;
+ case "superscript": this._superscriptActive = true; break;
}
});
}
- toggleBold = (view: EditorView, forceBool?: boolean) => {
- const mark = view.state.schema.mark(view.state.schema.marks.strong, { strong: forceBool });
- this.setMark(mark, view.state, view.dispatch, false);
- view.focus();
+ toggleBold = () => {
+ if (this.view) {
+ const mark = this.view.state.schema.mark(this.view.state.schema.marks.strong);
+ this.setMark(mark, this.view.state, this.view.dispatch, false);
+ this.view.focus();
+ }
}
- toggleUnderline = (view: EditorView, forceBool?: boolean) => {
- const mark = view.state.schema.mark(view.state.schema.marks.underline, { underline: forceBool });
- this.setMark(mark, view.state, view.dispatch, false);
- view.focus();
+ toggleUnderline = () => {
+ if (this.view) {
+ const mark = this.view.state.schema.mark(this.view.state.schema.marks.underline);
+ this.setMark(mark, this.view.state, this.view.dispatch, false);
+ this.view.focus();
+ }
}
- toggleItalic = (view: EditorView, forceBool?: boolean) => {
- const mark = view.state.schema.mark(view.state.schema.marks.em, { em: forceBool });
- this.setMark(mark, view.state, view.dispatch, false);
- view.focus();
+ toggleItalics = () => {
+ if (this.view) {
+ const mark = this.view.state.schema.mark(this.view.state.schema.marks.em);
+ this.setMark(mark, this.view.state, this.view.dispatch, false);
+ this.view.focus();
+ }
}
- setFontSize = (size: number, view: EditorView) => {
- const fmark = view.state.schema.marks.pFontSize.create({ fontSize: size });
- this.setMark(fmark, view.state, (tx: any) => view.dispatch(tx.addStoredMark(fmark)), true);
- view.focus();
- this.updateMenu(view, undefined, this.props);
+ setFontSize = (fontSize: string) => {
+ if (this.view) {
+ const fmark = this.view.state.schema.marks.pFontSize.create({ fontSize });
+ this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true);
+ this.view.focus();
+ this.updateMenu(this.view, undefined, this.props);
+ }
}
- setFontFamily = (family: string, view: EditorView) => {
- const fmark = view.state.schema.marks.pFontFamily.create({ family: family });
- this.setMark(fmark, view.state, (tx: any) => view.dispatch(tx.addStoredMark(fmark)), true);
- view.focus();
- this.updateMenu(view, undefined, this.props);
+ setFontFamily = (family: string) => {
+ if (this.view) {
+ const fmark = this.view.state.schema.marks.pFontFamily.create({ family: family });
+ this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true);
+ this.view.focus();
+ this.updateMenu(this.view, undefined, this.props);
+ }
}
setHighlight(color: String, view: EditorView, dispatch: any) {
@@ -330,13 +333,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
setColor(color: String, view: EditorView, dispatch: any) {
- const colorMark = view.state.schema.mark(view.state.schema.marks.pFontColor, { color: color });
- if (view.state.selection.empty) {
- dispatch(view.state.tr.addStoredMark(colorMark));
- return false;
+ if (this.view) {
+ const colorMark = view.state.schema.mark(view.state.schema.marks.pFontColor, { color });
+ this.setMark(colorMark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(colorMark)), true);
+ view.focus();
+ this.updateMenu(this.view, undefined, this.props);
}
- this.setMark(colorMark, view.state, dispatch, true);
- view.focus();
}
// TODO: remove doesn't work
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index 655ee7e44..6103a28d6 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -61,13 +61,13 @@ export const marks: { [index: string]: MarkSpec } = {
/** FONT SIZES */
pFontSize: {
- attrs: { fontSize: { default: 10 } },
+ attrs: { fontSize: { default: "10px" } },
parseDOM: [{
tag: "span", getAttrs(dom: any) {
- return { fontSize: dom.style.fontSize ? Number(dom.style.fontSize.replace("px", "")) : "" };
+ return { fontSize: dom.style.fontSize ? dom.style.fontSize.toString() : "" };
}
}],
- toDOM: (node) => node.attrs.fontSize ? ['span', { style: `font-size: ${node.attrs.fontSize}px;` }] : ['span', 0]
+ toDOM: (node) => node.attrs.fontSize ? ['span', { style: `font-size: ${node.attrs.fontSize};` }] : ['span', 0]
},
/* FONTS */
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 404e828ea..652804126 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -17,7 +17,7 @@ import { Docs, DocumentOptions, DocUtils } from '../client/documents/Documents';
import { DocumentType } from "../client/documents/DocumentTypes";
import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
import { Scripting } from '../client/util/Scripting';
-import { SettingsManager } from '../client/util/SettingsManager';
+import { SettingsManager, ColorScheme } from '../client/util/SettingsManager';
import { Transform } from '../client/util/Transform';
import { UndoManager } from "../client/util/UndoManager";
import { TabDocView } from '../client/views/collections/TabDocView';
@@ -403,7 +403,7 @@ export class MobileInterface extends React.Component {
const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row");
- const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`);
+ const toggleTheme = ScriptField.MakeScript(`self.colorScheme = self.colorScheme ? undefined: ${ColorScheme.Dark}}`);
const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
const cloneDashboard = ScriptField.MakeScript(`cloneDashboard()`);
dashboardDoc.contextMenuScripts = new List<ScriptField>([toggleTheme!, toggleComic!, cloneDashboard!]);