From f885965824f76be69e6bd26109a5df85dc43eb80 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 26 Apr 2023 13:11:58 -0400 Subject: added stats button to mainview --- src/client/util/ServerStats.tsx | 55 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/client/util/ServerStats.tsx (limited to 'src/client/util/ServerStats.tsx') diff --git a/src/client/util/ServerStats.tsx b/src/client/util/ServerStats.tsx new file mode 100644 index 000000000..0ab411bff --- /dev/null +++ b/src/client/util/ServerStats.tsx @@ -0,0 +1,55 @@ +import { action, computed, observable, runInAction } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { MainViewModal } from '../views/MainViewModal'; +import { DocumentView } from '../views/nodes/DocumentView'; +import './SharingManager.scss'; + +@observer +export class ServerStats extends React.Component<{}> { + public static Instance: ServerStats; + @observable private isOpen = false; // whether the SharingManager modal is open or not + + // private get linkVisible() { + // return this.targetDoc ? this.targetDoc["acl-" + PublicKey] !== SharingPermissions.None : false; + // } + + @action + public open = async () => { + /** + * Populates the list of users. + */ + fetch('/stats').then((res: Response) => res.text().then(action(stats => (this._stats = JSON.parse(stats))))); + + this.isOpen = true; + }; + + public close = action(() => { + this.isOpen = false; + }); + + constructor(props: {}) { + super(props); + ServerStats.Instance = this; + } + + @observable _stats: { [key: string]: any } | undefined; + + /** + * @returns the main interface of the SharingManager. + */ + @computed get sharingInterface() { + return ( +
+ Active users:{this._stats?.socketMap.length} + {this._stats?.socketMap.map((user: any) => ( +

{user.username}

+ ))} +
+ ); + } + + render() { + return ; + } +} -- cgit v1.2.3-70-g09d2 From 1150296b546bb3628c3dac5704150dfb4295434b Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 26 Apr 2023 16:03:49 -0400 Subject: added cheatsheet and shortcut for viewing text shortcuts. changed menu organization slightly for viewability. --- src/client/util/RTFMarkup.tsx | 137 +++++++++++++++++++++ src/client/util/ServerStats.tsx | 3 +- src/client/views/MainView.tsx | 8 +- src/client/views/MainViewModal.tsx | 37 +++--- src/client/views/nodes/DocumentView.tsx | 6 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 + .../views/nodes/formattedText/RichTextRules.ts | 7 ++ 7 files changed, 177 insertions(+), 23 deletions(-) create mode 100644 src/client/util/RTFMarkup.tsx (limited to 'src/client/util/ServerStats.tsx') diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx new file mode 100644 index 000000000..306d151d7 --- /dev/null +++ b/src/client/util/RTFMarkup.tsx @@ -0,0 +1,137 @@ +import { action, computed, observable } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { MainViewModal } from '../views/MainViewModal'; + +@observer +export class RTFMarkup extends React.Component<{}> { + static Instance: RTFMarkup; + @observable private isOpen = false; // whether the SharingManager modal is open or not + + // private get linkVisible() { + // return this.targetDoc ? this.targetDoc["acl-" + PublicKey] !== SharingPermissions.None : false; + // } + + @action + public open = () => (this.isOpen = true); + + @action + public close = () => (this.isOpen = false); + + constructor(props: {}) { + super(props); + RTFMarkup.Instance = this; + } + + @observable _stats: { [key: string]: any } | undefined; + + /** + * @returns the main interface of the SharingManager. + */ + @computed get cheatSheet() { + return ( +
+

+ {`wiki:phrase`} + {` display wikipedia page for entered text (terminate with carriage return)`} +

+

+ {`#tag `} + {` add hashtag metadata to document. e.g, #idea`} +

+

+ {`#, ## ... ###### `} + {` set heading style based on number of '#'s between 1 and 6`} +

+

+ {`#tag `} + {` add hashtag metadata to document. e.g, #idea`} +

+

+ {`>> `} + {` add a sidebar text document inline`} +

+

+ {`\`\` `} + {` create a code snippet block`} +

+

+ {`%% `} + {` restore default styling`} +

+

+ {`%color `} + {` changes text color styling. e.g., %green.`} +

+

+ {`%num `} + {` set font size. e.g., %10 for 10pt font`} +

+

+ {`%eq `} + {` creates an equation block for typeset math`} +

+

+ {`%alt `} + {` switch between primary and alternate text (see bottom right Button for hover options).`} +

+

+ {`%f `} + {` create an inline footnote`} +

+

+ {`%> `} + {` create a bockquote section. Terminate with 2 carriage returns`} +

+

+ {`%( `} + {` start a section of inline elidable text. Terminate the inline text with %)`} +

+

+ {`%q `} + {` start a quoted block of text that’s indented on the left and right. Terminate with %q`} +

+

+ {`%d `} + {` start a block text where the first line is indented`} +

+

+ {`%h `} + {` start a block of text that begins with a hanging indent`} +

+

+ {`%[ `} + {` left justify text`} +

+

+ {`%^ `} + {` center text`} +

+

+ {`%] `} + {` right justify text`} +

+

+ {`[:doctitle]] `} + {` hyperlink to document specified by it’s title`} +

+

+ {`[[fieldname]] `} + {` display value of fieldname`} +

+

+ {`[[fieldname=value]] `} + {` assign value to fieldname of document and display it`} +

+

+ {`[[fieldname:doctitle]] `} + {` show value of fieldname from doc specified by it’s title`} +

+
+ ); + } + + render() { + return ; + } +} diff --git a/src/client/util/ServerStats.tsx b/src/client/util/ServerStats.tsx index 0ab411bff..f84ad8598 100644 --- a/src/client/util/ServerStats.tsx +++ b/src/client/util/ServerStats.tsx @@ -1,8 +1,7 @@ -import { action, computed, observable, runInAction } from 'mobx'; +import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { MainViewModal } from '../views/MainViewModal'; -import { DocumentView } from '../views/nodes/DocumentView'; import './SharingManager.scss'; @observer diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 43f56dd8c..5af9a9f9a 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -14,7 +14,7 @@ import { StrCast } from '../../fields/Types'; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents, Utils } from '../../Utils'; import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager'; import { DocServer } from '../DocServer'; -import { Docs, DocUtils } from '../documents/Documents'; +import { Docs } from '../documents/Documents'; import { CollectionViewType, DocumentType } from '../documents/DocumentTypes'; import { CaptureManager } from '../util/CaptureManager'; import { DocumentManager } from '../util/DocumentManager'; @@ -22,11 +22,12 @@ import { GroupManager } from '../util/GroupManager'; import { HistoryUtil } from '../util/History'; import { Hypothesis } from '../util/HypothesisUtils'; import { ReportManager } from '../util/ReportManager'; +import { RTFMarkup } from '../util/RTFMarkup'; import { ScriptingGlobals } from '../util/ScriptingGlobals'; import { SelectionManager } from '../util/SelectionManager'; +import { ServerStats } from '../util/ServerStats'; import { ColorScheme, SettingsManager } from '../util/SettingsManager'; import { SharingManager } from '../util/SharingManager'; -import { ServerStats } from '../util/ServerStats'; import { SnappingManager } from '../util/SnappingManager'; import { Transform } from '../util/Transform'; import { TimelineMenu } from './animationtimeline/TimelineMenu'; @@ -41,7 +42,7 @@ import { DashboardView } from './DashboardView'; import { DictationOverlay } from './DictationOverlay'; import { DocumentDecorations } from './DocumentDecorations'; import { GestureOverlay } from './GestureOverlay'; -import { TOPBAR_HEIGHT, LEFT_MENU_WIDTH } from './global/globalCssVariables.scss'; +import { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } from './global/globalCssVariables.scss'; import { Colors } from './global/globalEnums'; import { KeyManager } from './GlobalKeyHandler'; import { InkTranscription } from './InkTranscription'; @@ -971,6 +972,7 @@ export class MainView extends React.Component { + diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx index 55dee005d..32997a944 100644 --- a/src/client/views/MainViewModal.tsx +++ b/src/client/views/MainViewModal.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import "./MainViewModal.scss"; +import './MainViewModal.scss'; import { observer } from 'mobx-react'; export interface MainViewOverlayProps { @@ -15,31 +15,38 @@ export interface MainViewOverlayProps { @observer export class MainViewModal extends React.Component { - render() { const p = this.props; const dialogueOpacity = p.dialogueBoxDisplayedOpacity || 1; const overlayOpacity = p.overlayDisplayedOpacity || 0.4; - return !p.isDisplayed ? (null) : ( -
-
+ return !p.isDisplayed ? null : ( +
+
{p.contents}
-
); } -} \ No newline at end of file +} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 38aa8db55..d58a4c199 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -767,6 +767,7 @@ export class DocumentViewInternal extends DocComponent this.props.addDocTab(this.props.Document, (OpenWhere.addRight.toString() + 'KeyValue') as OpenWhere), icon: 'layer-group' }); constantItems.push({ description: 'Export as Zip file', icon: 'download', event: async () => Doc.Zip(this.props.Document) }); constantItems.push({ description: 'Import Zipped file', icon: 'upload', event: ({ x, y }) => this.importDocument() }); (this.rootDoc._viewType !== CollectionViewType.Docking || !Doc.noviceMode) && constantItems.push({ description: 'Share', event: () => SharingManager.Instance.open(this.props.DocumentView()), icon: 'users' }); @@ -774,11 +775,10 @@ export class DocumentViewInternal extends DocComponent this.props.addDocTab(this.props.Document, (OpenWhere.addRight.toString() + 'KeyValue') as OpenWhere), icon: 'layer-group' }); !Doc.noviceMode && helpItems.push({ description: 'Text Shortcuts Ctrl+/', event: () => this.props.addDocTab(Docs.Create.PdfDocument('/assets/cheat-sheet.pdf', { _width: 300, _height: 300 }), OpenWhere.addRight), icon: 'keyboard' }); !Doc.noviceMode && helpItems.push({ description: 'Print Document in Console', event: () => console.log(this.props.Document), icon: 'hand-point-right' }); !Doc.noviceMode && helpItems.push({ description: 'Print DataDoc in Console', event: () => console.log(this.props.Document[DataSym]), icon: 'hand-point-right' }); @@ -825,7 +825,7 @@ export class DocumentViewInternal extends DocComponent, dataDoc: Doc) => void; @@ -858,6 +859,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent (this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight), icon: this.Document._autoHeight ? 'lock' : 'unlock' }); + optionItems.push({ description: `show markdown options`, event: RTFMarkup.Instance.open, icon: 'text' }); !options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'eye' }); this._downX = this._downY = Number.NaN; }; diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index 599f96bca..20ce929ad 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -8,6 +8,7 @@ import { normalizeEmail } from '../../../../fields/util'; import { Utils } from '../../../../Utils'; import { DocServer } from '../../../DocServer'; import { Docs, DocUtils } from '../../../documents/Documents'; +import { RTFMarkup } from '../../../util/RTFMarkup'; import { FormattedTextBox } from './FormattedTextBox'; import { wrappingInputRule } from './prosemirrorPatches'; import { RichTextMenu } from './RichTextMenu'; @@ -228,6 +229,12 @@ export class RichTextRules { return null; }), + // show markup help + new InputRule(new RegExp(/%\?$/), (state, match, start, end) => { + setTimeout(RTFMarkup.Instance.open); + return state.tr.deleteRange(start, end); + }), + // stop using active style new InputRule(new RegExp(/%alt$/), (state, match, start, end) => { setTimeout(() => (this.Document[this.TextBox.props.fieldKey + '-usePath'] = this.Document[this.TextBox.props.fieldKey + '-usePath'] ? undefined : 'alternate')); -- cgit v1.2.3-70-g09d2