aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-08-23 20:56:42 -0400
committerbobzel <zzzman@gmail.com>2023-08-23 20:56:42 -0400
commit288a74c91d9f8eecbae68fd6b2fe1e18ed2254e7 (patch)
treea1581c1f633543a99ece2c0b0ffc72953b7423ef /src
parent1bb554c64e235c89db47b7ca5bb86a5edfb13ec8 (diff)
parent1367f56a7898a125d46d9ebfb8cbfe81617180ad (diff)
Merge branch 'master' into UI_Update_Eric_Ma
Diffstat (limited to 'src')
-rw-r--r--src/client/util/CurrentUserUtils.ts12
-rw-r--r--src/client/util/RTFMarkup.tsx3
-rw-r--r--src/client/util/SettingsManager.tsx39
-rw-r--r--src/client/views/DashboardView.tsx8
-rw-r--r--src/client/views/PropertiesView.scss7
-rw-r--r--src/client/views/PropertiesView.tsx30
-rw-r--r--src/client/views/StyleProvider.tsx9
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx6
-rw-r--r--src/client/views/collections/TreeView.tsx27
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx4
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss6
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx7
-rw-r--r--src/client/views/newlightbox/components/Recommendation/Recommendation.tsx4
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/ImageBox.tsx1
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx2
-rw-r--r--src/server/ApiManagers/AzureManager.ts19
-rw-r--r--src/server/DashUploadUtils.ts17
-rw-r--r--src/server/server_Initialization.ts4
21 files changed, 157 insertions, 54 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index b63d501de..d9aad5a6f 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -294,7 +294,7 @@ export class CurrentUserUtils {
{ toolTip: "Tap or drag to create a note", title: "Note", icon: "sticky-note", dragFactory: doc.emptyNote as Doc, clickFactory: DocCast(doc.emptyNote)},
{ toolTip: "Tap or drag to create a flashcard", title: "Flashcard", icon: "id-card", dragFactory: doc.emptyFlashcard as Doc, clickFactory: DocCast(doc.emptyFlashcard)},
{ toolTip: "Tap or drag to create an equation", title: "Math", icon: "calculator", dragFactory: doc.emptyEquation as Doc, clickFactory: DocCast(doc.emptyEquation)},
- { toolTip: "Tap or drag to create a physics simulation",title: "Simulation", icon: "rocket",dragFactory: doc.emptySimulation as Doc, clickFactory: DocCast(doc.emptySimulation)},
+ { toolTip: "Tap or drag to create a physics simulation",title: "Simulation", icon: "rocket",dragFactory: doc.emptySimulation as Doc, clickFactory: DocCast(doc.emptySimulation), funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a note board", title: "Notes", icon: "folder", dragFactory: doc.emptyNoteboard as Doc, clickFactory: DocCast(doc.emptyNoteboard)},
{ toolTip: "Tap or drag to create a collection", title: "Col", icon: "folder", dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab)},
{ toolTip: "Tap or drag to create a webpage", title: "Web", icon: "globe-asia", dragFactory: doc.emptyWebpage as Doc, clickFactory: DocCast(doc.emptyWebpage)},
@@ -304,12 +304,12 @@ export class CurrentUserUtils {
{ toolTip: "Tap or drag to create a screen grabber", title: "Grab", icon: "photo-video", dragFactory: doc.emptyScreengrab as Doc, clickFactory: DocCast(doc.emptyScreengrab), openFactoryLocation: OpenWhere.overlay},
{ toolTip: "Tap or drag to create a WebCam recorder", title: "WebCam", icon: "photo-video", dragFactory: doc.emptyWebCam as Doc, clickFactory: DocCast(doc.emptyWebCam), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a button", title: "Button", icon: "bolt", dragFactory: doc.emptyButton as Doc, clickFactory: DocCast(doc.emptyButton)},
- { toolTip: "Tap or drag to create a scripting box", title: "Script", icon: "terminal", dragFactory: doc.emptyScript as Doc, clickFactory: DocCast(doc.emptyScript)},
- { toolTip: "Tap or drag to create a data viz node", title: "DataViz", icon: "chart-bar", dragFactory: doc.emptyDataViz as Doc, clickFactory: DocCast(doc.emptyDataViz)},
- { toolTip: "Tap or drag to create a bullet slide", title: "PPT Slide", icon: "file", dragFactory: doc.emptySlide as Doc, clickFactory: DocCast(doc.emptySlide), openFactoryLocation: OpenWhere.overlay},
- { toolTip: "Tap or drag to create a data note", title: "DataNote", icon: "window-maximize",dragFactory: doc.emptyHeader as Doc,clickFactory: DocCast(doc.emptyHeader), openFactoryAsDelegate: true },
+ { toolTip: "Tap or drag to create a scripting box", title: "Script", icon: "terminal", dragFactory: doc.emptyScript as Doc, clickFactory: DocCast(doc.emptyScript), funcs: { hidden: "IsNoviceMode()"}},
+ { toolTip: "Tap or drag to create a data viz node", title: "DataViz", icon: "chart-bar", dragFactory: doc.emptyDataViz as Doc, clickFactory: DocCast(doc.emptyDataViz)},
+ { toolTip: "Tap or drag to create a bullet slide", title: "PPT Slide", icon: "file", dragFactory: doc.emptySlide as Doc, clickFactory: DocCast(doc.emptySlide), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
+ { toolTip: "Tap or drag to create a data note", title: "DataNote", icon: "window-maximize",dragFactory: doc.emptyHeader as Doc,clickFactory: DocCast(doc.emptyHeader), openFactoryAsDelegate: true, funcs: { hidden: "IsNoviceMode()"} },
{ toolTip: "Toggle a Calculator REPL", title: "replviewer", icon: "calculator", clickFactory: '<ScriptingRepl />' as any, openFactoryLocation: OpenWhere.overlay}, // hack: clickFactory is not a Doc but will get interpreted as a custom UI by the openDoc() onClick script
- { toolTip: "Toggle an UndoStack", title: "undostacker", icon: "calculator", clickFactory: "<UndoStack>" as any, openFactoryLocation: OpenWhere.overlay},
+ // { toolTip: "Toggle an UndoStack", title: "undostacker", icon: "calculator", clickFactory: "<UndoStack>" as any, openFactoryLocation: OpenWhere.overlay},
].map(tuple => (
{ openFactoryLocation: OpenWhere.addRight,
scripts: { onClick: 'openDoc(copyDragFactory(this.clickFactory,this.openFactoryAsDelegate), this.openFactoryLocation)',
diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx
index c2f121e1f..a0fc617ab 100644
--- a/src/client/util/RTFMarkup.tsx
+++ b/src/client/util/RTFMarkup.tsx
@@ -2,6 +2,7 @@ import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { MainViewModal } from '../views/MainViewModal';
+import { SettingsManager } from './SettingsManager';
@observer
export class RTFMarkup extends React.Component<{}> {
@@ -30,7 +31,7 @@ export class RTFMarkup extends React.Component<{}> {
*/
@computed get cheatSheet() {
return (
- <div style={{ background: 'white', textAlign: 'initial', height: '100%' }}>
+ <div style={{ background: SettingsManager.Instance?.userBackgroundColor, color: SettingsManager.Instance?.userColor, textAlign: 'initial', height: '100%' }}>
<p>
<b style={{ fontSize: 'larger' }}>{`wiki:phrase`}</b>
{` display wikipedia page for entered text (terminate with carriage return)`}
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 6acba8af4..8133e9eff 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -169,9 +169,33 @@ export class SettingsManager extends React.Component<{}> {
/>
{userTheme === ColorScheme.Custom && (
<Group formLabel="Custom Theme">
- <ColorPicker tooltip={'User Color'} color={this.userColor} type={Type.SEC} icon={<FaFillDrip />} selectedColor={this.userColor} setSelectedColor={this.switchUserColor} />
- <ColorPicker tooltip={'User Background Color'} color={this.userColor} type={Type.SEC} icon={<FaPalette />} selectedColor={this.userBackgroundColor} setSelectedColor={this.switchUserBackgroundColor} />
- <ColorPicker tooltip={'User Variant Color'} color={this.userColor} type={Type.SEC} icon={<FaPalette />} selectedColor={this.userVariantColor} setSelectedColor={this.switchUserVariantColor} />
+ <ColorPicker
+ tooltip={'User Color'} //
+ color={this.userColor}
+ type={Type.SEC}
+ icon={<FaFillDrip />}
+ selectedColor={this.userColor}
+ setSelectedColor={this.switchUserColor}
+ setFinalColor={this.switchUserColor}
+ />
+ <ColorPicker
+ tooltip={'User Background Color'}
+ color={this.userColor}
+ type={Type.SEC}
+ icon={<FaPalette />}
+ selectedColor={this.userBackgroundColor}
+ setSelectedColor={this.switchUserBackgroundColor}
+ setFinalColor={this.switchUserBackgroundColor}
+ />
+ <ColorPicker
+ tooltip={'User Variant Color'}
+ color={this.userColor}
+ type={Type.SEC}
+ icon={<FaPalette />}
+ selectedColor={this.userVariantColor}
+ setSelectedColor={this.switchUserVariantColor}
+ setFinalColor={this.switchUserVariantColor}
+ />
</Group>
)}
</div>
@@ -235,6 +259,15 @@ export class SettingsManager extends React.Component<{}> {
size={Size.XSMALL}
color={this.userColor}
/>
+ <Toggle
+ formLabel={'Show Link Lines'}
+ formLabelPlacement={'right'}
+ toggleType={ToggleType.SWITCH}
+ onClick={e => (Doc.UserDoc().showLinkLines = !Doc.UserDoc().showLinkLines)}
+ toggleStatus={BoolCast(Doc.UserDoc().showLinkLines)}
+ size={Size.XSMALL}
+ color={this.userColor}
+ />
</div>
);
}
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 3e4827c83..5a821faee 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -47,12 +47,12 @@ export class DashboardView extends React.Component {
@action abortCreateNewDashboard = () => {
this.newDashboardName = undefined;
};
- @action setNewDashboardName(name: string) {
+ @action setNewDashboardName = (name: string) => {
this.newDashboardName = name;
- }
- @action setNewDashboardColor(color: string) {
+ };
+ @action setNewDashboardColor = (color: string) => {
this.newDashboardColor = color;
- }
+ };
@action
selectDashboardGroup = (group: DashboardGroup) => {
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
index 1a7c9eb64..a0b054851 100644
--- a/src/client/views/PropertiesView.scss
+++ b/src/client/views/PropertiesView.scss
@@ -1,5 +1,12 @@
@import './global/globalCssVariables.scss';
+.propertiesView-presentationTrails-title {
+ display: flex;
+}
+.propertiesView-presentationTrails-title-icon {
+ position: absolute;
+ right: 4;
+}
.propertiesView {
height: 100%;
width: 250;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 1b6037ed9..82ab54787 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -39,6 +39,7 @@ import { DefaultStyleProvider } from './StyleProvider';
import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView';
import { KeyValueBox } from './nodes/KeyValueBox';
import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails';
+import { SettingsManager } from '../util/SettingsManager';
const higflyout = require('@hig/flyout');
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -1701,7 +1702,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</div>
{!selectedItem ? null : (
<div className="propertiesView-presentationTrails">
- <div className="propertiesView-presentationTrails-title" onPointerDown={action(() => (this.openPresTransitions = !this.openPresTransitions))} style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
+ <div
+ className="propertiesView-presentationTrails-title"
+ onPointerDown={action(() => (this.openPresTransitions = !this.openPresTransitions))}
+ style={{
+ color: SettingsManager.Instance.userColor,
+ backgroundColor: this.openPresTransitions ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor,
+ }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Transitions
<div className="propertiesView-presentationTrails-title-icon">
<FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg" />
@@ -1715,7 +1722,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<div
className="propertiesView-presentationTrails-title"
onPointerDown={action(() => (this.openPresVisibilityAndDuration = !this.openPresVisibilityAndDuration))}
- style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
+ style={{
+ color: SettingsManager.Instance.userColor,
+ backgroundColor: this.openPresVisibilityAndDuration ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor,
+ }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Visibilty
<div className="propertiesView-presentationTrails-title-icon">
<FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" />
@@ -1726,7 +1736,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
)}
{!selectedItem ? null : (
<div className="propertiesView-presentationTrails">
- <div className="propertiesView-presentationTrails-title" onPointerDown={action(() => (this.openPresProgressivize = !this.openPresProgressivize))} style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
+ <div
+ className="propertiesView-presentationTrails-title"
+ onPointerDown={action(() => (this.openPresProgressivize = !this.openPresProgressivize))}
+ style={{
+ color: SettingsManager.Instance.userColor,
+ backgroundColor: this.openPresProgressivize ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor,
+ }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Progressivize
<div className="propertiesView-presentationTrails-title-icon">
<FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg" />
@@ -1737,7 +1753,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
)}
{!selectedItem || (type !== DocumentType.VID && type !== DocumentType.AUDIO) ? null : (
<div className="propertiesView-presentationTrails">
- <div className="propertiesView-presentationTrails-title" onPointerDown={action(() => (this.openSlideOptions = !this.openSlideOptions))} style={{ backgroundColor: this.openSlideOptions ? 'black' : '' }}>
+ <div
+ className="propertiesView-presentationTrails-title"
+ onPointerDown={action(() => (this.openSlideOptions = !this.openSlideOptions))}
+ style={{
+ color: SettingsManager.Instance.userColor,
+ backgroundColor: this.openSlideOptions ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor,
+ }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={type === DocumentType.AUDIO ? 'file-audio' : 'file-video'} /> &nbsp; {type === DocumentType.AUDIO ? 'Audio Options' : 'Video Options'}
<div className="propertiesView-presentationTrails-title-icon">
<FontAwesomeIcon icon={this.openSlideOptions ? 'caret-down' : 'caret-right'} size="lg" />
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index c2dcf071d..24a269927 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -109,10 +109,10 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
return Doc.toIcon(doc, isEmpty ? undefined : isOpen);
case StyleProp.TreeViewSortings:
const allSorts: { [key: string]: { color: string; icon: JSX.Element | string } | undefined } = {};
- allSorts[TreeSort.Down] = { color: Colors.MEDIUM_BLUE, icon: <BsArrowDown/> };
- allSorts[TreeSort.Up] = { color: 'crimson', icon: <BsArrowUp/> };
+ allSorts[TreeSort.AlphaDown] = { color: Colors.MEDIUM_BLUE, icon: <BsArrowDown/> };
+ allSorts[TreeSort.AlphaUp] = { color: 'crimson', icon: <BsArrowUp/> };
if (doc?._type_collection === CollectionViewType.Freeform) allSorts[TreeSort.Zindex] = { color: 'green', icon: 'Z' };
- allSorts[TreeSort.None] = { color: 'darkgray', icon: <BsArrowDownUp/> };
+ allSorts[TreeSort.WhenAdded] = { color: 'darkgray', icon: <BsArrowDownUp/> };
return allSorts;
case StyleProp.Highlighting:
if (doc && (Doc.IsSystem(doc) || doc.type === DocumentType.FONTICON)) return undefined;
@@ -166,8 +166,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
if (docColor) return docColor;
const docView = props?.DocumentView?.();
const backColor = backgroundCol() || docView?.props.styleProvider?.(docView.props.treeViewDoc, docView.props, StyleProp.BackgroundColor);
- if (!backColor) return undefined;
- return lightOrDark(backColor);
+ return backColor ? lightOrDark(backColor) : undefined;
case StyleProp.BorderRounding:
return StrCast(doc?.[fieldKey + 'borderRounding'], StrCast(doc?.layout_borderRounding, doc?._type_collection === CollectionViewType.Pile ? '50%' : ''));
case StyleProp.BorderPath:
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 0052c4196..95f88f14e 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -498,6 +498,7 @@ export class CollectionDockingView extends CollectionSubView() {
_layout_fitWidth: true,
title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`,
});
+ Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd);
inheritParentAcls(this.rootDoc, docToAdd, false);
CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack);
}
@@ -541,6 +542,7 @@ export class CollectionDockingView extends CollectionSubView() {
_freeform_backgroundGrid: true,
title: `Untitled Tab ${NumCast(dashboard['pane-count'])}`,
});
+ Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd);
inheritParentAcls(this.dataDoc, docToAdd, false);
CollectionDockingView.AddSplit(docToAdd, OpenWhereMod.none, stack);
}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index c189ef126..eb4685834 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -298,7 +298,11 @@ export function CollectionSubView<X>(moreProps?: X) {
let source = split;
if (split.startsWith('data:image') && split.includes('base64')) {
const [{ accessPaths }] = await Networking.PostToServer('/uploadRemoteImage', { sources: [split] });
- source = Utils.prepend(accessPaths.agnostic.client);
+ if (accessPaths.agnostic.client.indexOf("dashblobstore") === -1) {
+ source = Utils.prepend(accessPaths.agnostic.client);
+ } else {
+ source = accessPaths.agnostic.client;
+ }
}
if (source.startsWith('http')) {
const doc = Docs.Create.ImageDocument(source, { ...options, _width: 300 });
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 27f9ebc49..3402a8c8d 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -78,10 +78,10 @@ const treeBulletWidth = function () {
};
export enum TreeSort {
- Up = 'up',
- Down = 'down',
- Zindex = 'z',
- None = 'none',
+ AlphaUp = 'alphabetical from z',
+ AlphaDown = 'alphabetical from A',
+ Zindex = 'by Z index',
+ WhenAdded = 'when added',
}
/**
* Renders a treeView of a collection of documents
@@ -538,7 +538,7 @@ export class TreeView extends React.Component<TreeViewProps> {
const expandKey = this.treeViewExpandedView;
const sortings = (this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewSortings) as { [key: string]: { color: string; icon: JSX.Element | string } }) ?? {};
if (['links', 'annotations', 'embeddings', this.fieldKey].includes(expandKey)) {
- const sorting = StrCast(this.doc.treeView_SortCriterion, TreeSort.None);
+ const sorting = StrCast(this.doc.treeView_SortCriterion, TreeSort.WhenAdded);
const sortKeys = Object.keys(sortings);
const curSortIndex = Math.max(
0,
@@ -578,10 +578,11 @@ export class TreeView extends React.Component<TreeViewProps> {
return (
<div>
{!docs?.length || this.props.AddToMap /* hack to identify pres box trees */ ? null : (
- <div className={'treeView-sorting'}>
+ <div className='treeView-sorting'>
<IconButton
color={sortings[sorting]?.color}
size={Size.XSMALL}
+ tooltip={`Sorted by : ${this.doc.treeView_SortCriterion}. click to cycle`}
icon={sortings[sorting]?.icon}
onPointerDown={e => {
downX = e.clientX;
@@ -600,8 +601,8 @@ export class TreeView extends React.Component<TreeViewProps> {
<ul
style={{ cursor: 'inherit' }}
key={expandKey + 'more'}
- title="click to change sort order"
- className={''} //this.doc.treeView_HideTitle ? 'no-indent' : ''}
+ title={`Sorted by : ${this.doc.treeView_SortCriterion}. click to cycle`}
+ className='' //this.doc.treeView_HideTitle ? 'no-indent' : ''}
onPointerDown={e => {
downX = e.clientX;
downY = e.clientY;
@@ -1089,7 +1090,7 @@ export class TreeView extends React.Component<TreeViewProps> {
};
@computed get renderBorder() {
- const sorting = StrCast(this.doc.treeView_SortCriterion, TreeSort.None);
+ const sorting = StrCast(this.doc.treeView_SortCriterion, TreeSort.WhenAdded);
const sortings = (this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewSortings) ?? {}) as { [key: string]: { color: string; label: string } };
return (
<div className={`treeView-border${this.props.treeView.outlineMode ? TreeViewType.outline : ''}`} style={{ borderColor: sortings[sorting]?.color }}>
@@ -1131,7 +1132,7 @@ export class TreeView extends React.Component<TreeViewProps> {
public static sortDocs(childDocs: Doc[], criterion: string | undefined) {
const docs = childDocs.slice();
- if (criterion !== TreeSort.None) {
+ if (criterion !== TreeSort.WhenAdded) {
const sortAlphaNum = (a: string, b: string): 0 | 1 | -1 => {
const reN = /[0-9]*$/;
const aA = a.replace(reN, '') ? a.replace(reN, '') : +a; // get rid of trailing numbers
@@ -1146,8 +1147,8 @@ export class TreeView extends React.Component<TreeViewProps> {
}
};
docs.sort(function (d1, d2): 0 | 1 | -1 {
- const a = criterion === TreeSort.Up ? d2 : d1;
- const b = criterion === TreeSort.Up ? d1 : d2;
+ const a = criterion === TreeSort.AlphaUp ? d2 : d1;
+ const b = criterion === TreeSort.AlphaUp ? d1 : d2;
const first = a[criterion === TreeSort.Zindex ? 'zIndex' : 'title'];
const second = b[criterion === TreeSort.Zindex ? 'zIndex' : 'title'];
if (typeof first === 'number' && typeof second === 'number') return first - second > 0 ? 1 : -1;
@@ -1198,7 +1199,7 @@ export class TreeView extends React.Component<TreeViewProps> {
childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
}
- const docs = TreeView.sortDocs(childDocs, StrCast(treeView_Parent.treeView_SortCriterion, TreeSort.None));
+ const docs = TreeView.sortDocs(childDocs, StrCast(treeView_Parent.treeView_SortCriterion, TreeSort.WhenAdded));
const rowWidth = () => panelWidth() - treeBulletWidth() * (treeView.props.NativeDimScaling?.() || 1);
const treeView_Refs = new Map<Doc, TreeView | undefined>();
return docs
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index fb8ec93b2..fd9aa3fa5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -59,7 +59,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
0
); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render()
setTimeout(
- action(() => (!LinkDocs.length || !linkDoc.link_displayLine) && (this._opacity = 0.05)),
+ action(() => (!LinkDocs.length || !(linkDoc.link_displayLine || Doc.UserDoc().showLinkLines)) && (this._opacity = 0.05)),
750
); // this will unhighlight the link line.
const a = A.ContentDiv.getBoundingClientRect();
@@ -269,7 +269,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
link.link_displayArrow = false;
}
- return link.opacity === 0 || !a.width || !b.width || (!link.link_displayLine && !aActive && !bActive) ? null : (
+ return link.opacity === 0 || !a.width || !b.width || (!(Doc.UserDoc().showLinkLines || link.link_displayLine) && !aActive && !bActive) ? null : (
<>
<defs>
<marker id={`${link[Id] + 'arrowhead'}`} markerWidth="4" markerHeight="3" refX="0" refY="1.5" orient="auto">
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
index f87a06033..cb0d5e03f 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
@@ -9,6 +9,12 @@
flex-direction: column;
width: 100%;
align-items: center;
+ position: relative;
+ > .iconButton-container {
+ top: 0;
+ left: 0;
+ position: absolute;
+ }
.contentFittingDocumentView {
width: unset;
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 10532b9d9..80da4e1a2 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -1,3 +1,5 @@
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Button } from 'browndash-components';
import { action, computed } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
@@ -6,7 +8,7 @@ import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types
import { returnFalse } from '../../../../Utils';
import { DragManager, dropActionType } from '../../../util/DragManager';
import { Transform } from '../../../util/Transform';
-import { undoBatch } from '../../../util/UndoManager';
+import { undoable, undoBatch } from '../../../util/UndoManager';
import { DocumentView } from '../../nodes/DocumentView';
import { CollectionSubView } from '../CollectionSubView';
import './CollectionMulticolumnView.scss';
@@ -301,6 +303,9 @@ export class CollectionMulticolumnView extends CollectionSubView() {
collector.push(
<div className="document-wrapper" key={'wrapper' + i} style={{ width: width() }}>
{this.getDisplayDoc(layout, dxf, docwidth, docheight, shouldNotScale)}
+ <Button icon={<FontAwesomeIcon icon={'times'} size={'lg'} />} onClick={undoable(e => {
+ this.props.removeDocument?.(layout);
+ }, "close doc")} color={StrCast(Doc.UserDoc().userColor)} />
<WidthLabel layout={layout} collectionDoc={Document} />
</div>,
<ResizeBar
diff --git a/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx b/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx
index 2c2f04b9f..96846673b 100644
--- a/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx
+++ b/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx
@@ -25,11 +25,11 @@ export const Recommendation = (props: IRecommendation) => {
switch (type) {
case 'YouTube':
console.log('create ', type, 'document');
- doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript: transcript });
+ doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript });
break;
case 'Video':
console.log('create ', type, 'document');
- doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript: transcript });
+ doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript });
break;
case 'Webpage':
console.log('create ', type, 'document');
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index ca5ec9389..a334e75f1 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -96,7 +96,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
const anchor = Docs.Create.ConfigDocument({
title: 'CompareAnchor:' + this.rootDoc.title,
// set presentation timing properties for restoring view
- presTransition: 1000,
+ presentation_transition: 1000,
annotationOn: this.rootDoc,
});
if (anchor) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 91e461acf..1e17320bf 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -993,7 +993,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
// the small blue dots that mark the endpoints of links
TraceMobx();
if (this.props.hideLinkAnchors || this.layoutDoc.layout_hideLinkAnchors || this.props.dontRegisterView || this.layoutDoc.layout_unrendered) return null;
- const filtered = DocUtils.FilterDocs(this.directLinks, this.props.childFilters?.() ?? [], []).filter(d => d.link_displayLine);
+ const filtered = DocUtils.FilterDocs(this.directLinks, this.props.childFilters?.() ?? [], []).filter(d => d.link_displayLine || Doc.UserDoc().showLinkLines);
return filtered.map(link => (
<div className="documentView-anchorCont" key={link[Id]}>
<DocumentView
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index c7ccd1ea0..44da98f75 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -82,7 +82,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
config_panX: NumCast(this.layoutDoc._freeform_panX),
config_panY: NumCast(this.layoutDoc._freeform_panY),
config_viewScale: Cast(this.layoutDoc._freeform_scale, 'number', null),
- presentation_transition: 1000,
annotationOn: this.rootDoc,
});
if (anchor) {
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 232bbc111..a94f1f04b 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -257,7 +257,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const serial = nextSelected + 1 < this.childDocs.length && NumCast(this.childDocs[nextSelected + 1].presentation_groupWithUp) > 1;
if (serial) {
this.gotoDocument(nextSelected, this.activeItem, true, async () => {
- const waitTime = NumCast(this.activeItem.presentation_duration) - NumCast(this.activeItem.presentation_transition);
+ const waitTime = NumCast(this.activeItem.presentation_duration);
await new Promise<void>(res => setTimeout(() => res(), Math.max(0, waitTime)));
doGroupWithUp(nextSelected + 1)();
});
diff --git a/src/server/ApiManagers/AzureManager.ts b/src/server/ApiManagers/AzureManager.ts
index 12bb98ad0..2d0ab3aa6 100644
--- a/src/server/ApiManagers/AzureManager.ts
+++ b/src/server/ApiManagers/AzureManager.ts
@@ -1,8 +1,18 @@
import { ContainerClient, BlobServiceClient } from "@azure/storage-blob";
import * as fs from "fs";
import { Readable, Stream } from "stream";
+import * as path from "path";
const AZURE_STORAGE_CONNECTION_STRING = process.env.AZURE_STORAGE_CONNECTION_STRING;
+const extToType: { [suffix: string]: string } = {
+ ".jpeg" : "image/jpeg",
+ ".jpg" : "image/jpeg",
+ ".png" : "image/png",
+ ".svg" : "image/svg+xml",
+ ".webp" : "image/webp",
+ ".gif" : "image/gif"
+}
+
export class AzureManager {
private _containerClient: ContainerClient;
private _blobServiceClient: BlobServiceClient;
@@ -10,6 +20,7 @@ export class AzureManager {
public static CONTAINER_NAME = "dashmedia";
public static STORAGE_ACCOUNT_NAME = "dashblobstore";
+ public static BASE_STRING = `https://${AzureManager.STORAGE_ACCOUNT_NAME}.blob.core.windows.net/${AzureManager.CONTAINER_NAME}`;
constructor() {
if (!AZURE_STORAGE_CONNECTION_STRING) {
@@ -38,6 +49,14 @@ export class AzureManager {
return blockBlobClient.uploadStream(stream, undefined, undefined, blobOptions);
}
+ public static UploadBase64ImageBlob(filename: string, data: string, filetype?: string) {
+ const confirmedFiletype = filetype ? filetype : extToType[path.extname(filename)];
+ const buffer = Buffer.from(data, "base64");
+ const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename);
+ const blobOptions = { blobHTTPHeaders: { blobContentType: confirmedFiletype } };
+ return blockBlobClient.upload(buffer, buffer.length, blobOptions);
+ }
+
public static UploadBlobStream(stream: Readable, filename: string, filetype: string) {
const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename);
const blobOptions = { blobHTTPHeaders: { blobContentType: filetype }};
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index 117981a7c..e5e15ce99 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -383,13 +383,18 @@ export namespace DashUploadUtils {
if ((rawMatches = /^data:image\/([a-z]+);base64,(.*)/.exec(source)) !== null) {
const [ext, data] = rawMatches.slice(1, 3);
const resolved = (filename = `upload_${Utils.GenerateGuid()}.${ext}`);
- const error = await new Promise<Error | null>(resolve => {
- writeFile(serverPathToFile(Directory.images, resolved), data, 'base64', resolve);
- });
- if (error !== null) {
- return error;
+ if (usingAzure()) {
+ const response = await AzureManager.UploadBase64ImageBlob(resolved, data);
+ source = `${AzureManager.BASE_STRING}/${resolved}`;
+ } else {
+ const error = await new Promise<Error | null>(resolve => {
+ writeFile(serverPathToFile(Directory.images, resolved), data, 'base64', resolve);
+ });
+ if (error !== null) {
+ return error;
+ }
+ source = `${resolvedServerUrl}${clientPathToFile(Directory.images, resolved)}`;
}
- source = `${resolvedServerUrl}${clientPathToFile(Directory.images, resolved)}`;
}
let resolvedUrl: string;
/**
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index 354f809e0..ee32de152 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -176,8 +176,8 @@ function proxyServe(req: any, requrl: string, response: any) {
const htmlText = htmlInputText
.toString('utf8')
.replace('<head>', '<head> <style>[id ^= "google"] { display: none; } </style>')
- .replace('<script', '<noscript')
- .replace('</script', '</noscript')
+ // .replace('<script', '<noscript')
+ // .replace('</script', '</noscript')
// .replace(/href="https?([^"]*)"/g, httpsToCors)
.replace(/data-srcset="[^"]*"/g, '')
.replace(/srcset="[^"]*"/g, '')