From 7dbfa2fde01fc1078458eec2f764c9936ef10f6f Mon Sep 17 00:00:00 2001 From: Aman Harwara Date: Wed, 29 Sep 2021 23:21:48 +0530 Subject: [PATCH] feat(preferences): Tools segment (#657) --- .../javascripts/preferences/panes/General.tsx | 2 + .../panes/general-segments/Tools.tsx | 86 ++++++++++++ .../panes/general-segments/index.ts | 1 + .../javascripts/views/editor/editor-view.pug | 36 ----- .../javascripts/views/editor/editor_view.ts | 126 +++++++----------- 5 files changed, 140 insertions(+), 111 deletions(-) create mode 100644 app/assets/javascripts/preferences/panes/general-segments/Tools.tsx diff --git a/app/assets/javascripts/preferences/panes/General.tsx b/app/assets/javascripts/preferences/panes/General.tsx index 2598b7a98..b4fa9ad8e 100644 --- a/app/assets/javascripts/preferences/panes/General.tsx +++ b/app/assets/javascripts/preferences/panes/General.tsx @@ -3,6 +3,7 @@ import { AppState } from '@/ui_models/app_state'; import { FunctionComponent } from 'preact'; import { PreferencesPane } from '../components'; import { ErrorReporting } from './general-segments'; +import { Tools } from './general-segments/Tools'; interface GeneralProps { appState: AppState; @@ -11,6 +12,7 @@ interface GeneralProps { export const General: FunctionComponent = (props) => ( + ); diff --git a/app/assets/javascripts/preferences/panes/general-segments/Tools.tsx b/app/assets/javascripts/preferences/panes/general-segments/Tools.tsx new file mode 100644 index 000000000..3cd46b114 --- /dev/null +++ b/app/assets/javascripts/preferences/panes/general-segments/Tools.tsx @@ -0,0 +1,86 @@ +import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator'; +import { Switch } from '@/components/Switch'; +import { + PreferencesGroup, + PreferencesSegment, + Subtitle, + Text, + Title, +} from '@/preferences/components'; +import { WebApplication } from '@/ui_models/application'; +import { PrefKey } from '@standardnotes/snjs'; +import { observer } from 'mobx-react-lite'; +import { FunctionalComponent } from 'preact'; +import { useState } from 'preact/hooks'; + +type Props = { + application: WebApplication; +}; + +export const Tools: FunctionalComponent = observer( + ({ application }: Props) => { + const [monospaceFont, setMonospaceFont] = useState(() => + application.getPreference(PrefKey.EditorMonospaceEnabled) + ); + const [marginResizers, setMarginResizers] = useState(() => + application.getPreference(PrefKey.EditorResizersEnabled) + ); + const [spellcheck, setSpellcheck] = useState(() => + application.getPreference(PrefKey.EditorSpellcheck) + ); + + const toggleMonospaceFont = () => { + setMonospaceFont(!monospaceFont); + application.setPreference(PrefKey.EditorMonospaceEnabled, !monospaceFont); + }; + + const toggleMarginResizers = () => { + setMarginResizers(!marginResizers); + application.setPreference(PrefKey.EditorResizersEnabled, !marginResizers); + }; + + const toggleSpellcheck = () => { + setSpellcheck(!spellcheck); + application.setPreference(PrefKey.EditorSpellcheck, !spellcheck); + }; + + return ( + + + Tools +
+
+
+ Monospace Font + Toggles the font style in the Plain Text editor. +
+ +
+ +
+
+ Margin Resizers + Allows left and right editor margins to be resized. +
+ +
+ +
+
+ Spellcheck + + May degrade performance, especially with long notes. Available + in the Plain Text editor and most specialty editors. + +
+ +
+
+
+
+ ); + } +); diff --git a/app/assets/javascripts/preferences/panes/general-segments/index.ts b/app/assets/javascripts/preferences/panes/general-segments/index.ts index 619f11e36..dd28d7a2c 100644 --- a/app/assets/javascripts/preferences/panes/general-segments/index.ts +++ b/app/assets/javascripts/preferences/panes/general-segments/index.ts @@ -1 +1,2 @@ export * from './ErrorReporting'; +export * from './Tools'; diff --git a/app/assets/javascripts/views/editor/editor-view.pug b/app/assets/javascripts/views/editor/editor-view.pug index d0fe2249c..8c7724f55 100644 --- a/app/assets/javascripts/views/editor/editor-view.pug +++ b/app/assets/javascripts/views/editor/editor-view.pug @@ -59,42 +59,6 @@ .sn-component(ng-if='self.note') #editor-menu-bar.sk-app-bar.no-edges .left - .sk-app-bar-item( - click-outside=`self.setMenuState('showOptionsMenu', false)`, - is-open='self.state.showOptionsMenu', - ng-class="{'selected' : self.state.showOptionsMenu}", - ng-click="self.toggleMenu('showOptionsMenu')" - ) - .sk-label Options - .sk-menu-panel.dropdown-menu(ng-if='self.state.showOptionsMenu') - .sk-menu-panel-section - .sk-menu-panel-header - .sk-menu-panel-header-title Global Display - menu-row( - action="self.selectedMenuItem(true); self.toggleWebPrefKey(self.prefKeyMonospace)" - circle="self.state.monospaceFont ? 'success' : 'neutral'", - desc="'Toggles the font style for the default editor'", - disabled='self.state.editorComponent', - label="'Monospace Font'", - subtitle="self.state.editorComponent ? 'Not available with editor extensions' : null" - ) - menu-row( - action="self.selectedMenuItem(true); self.toggleWebPrefKey(self.prefKeySpellcheck)" - circle="self.state.spellcheck ? 'success' : 'neutral'", - desc="'Toggles spellcheck for the default editor'", - disabled='self.state.editorComponent', - label="'Spellcheck'", - subtitle=` - self.state.editorComponent - ? 'Not available with editor extensions' - : (self.state.isDesktop ? 'May degrade editor performance' : null) - `) - menu-row( - action="self.selectedMenuItem(true); self.toggleWebPrefKey(self.prefKeyMarginResizers)" - circle="self.state.marginResizersEnabled ? 'success' : 'neutral'", - desc="'Allows for editor left and right margins to be resized'", - label="'Margin Resizers'" - ) .sk-app-bar-item( click-outside=`self.setMenuState('showEditorMenu', false)` is-open='self.state.showEditorMenu', diff --git a/app/assets/javascripts/views/editor/editor_view.ts b/app/assets/javascripts/views/editor/editor_view.ts index 2c3e346af..9d6c282d8 100644 --- a/app/assets/javascripts/views/editor/editor_view.ts +++ b/app/assets/javascripts/views/editor/editor_view.ts @@ -1,6 +1,4 @@ -import { - STRING_SAVING_WHILE_DOCUMENT_HIDDEN, -} from './../../strings'; +import { STRING_SAVING_WHILE_DOCUMENT_HIDDEN } from './../../strings'; import { Editor } from '@/ui_models/editor'; import { WebApplication } from '@/ui_models/application'; import { PanelPuppet, WebDirective } from '@/types'; @@ -61,7 +59,6 @@ type EditorState = { isDesktop?: boolean; syncTakingTooLong: boolean; showActionsMenu: boolean; - showOptionsMenu: boolean; showEditorMenu: boolean; showHistoryMenu: boolean; spellcheck: boolean; @@ -202,7 +199,7 @@ class EditorViewCtrl extends PureViewCtrl { }); this.autorun(() => { this.setState({ - showProtectedWarning: this.appState.notes.showProtectedWarning + showProtectedWarning: this.appState.notes.showProtectedWarning, }); }); } @@ -216,7 +213,6 @@ class EditorViewCtrl extends PureViewCtrl { spellcheck: true, syncTakingTooLong: false, showActionsMenu: false, - showOptionsMenu: false, showEditorMenu: false, showHistoryMenu: false, noteStatus: undefined, @@ -272,11 +268,11 @@ class EditorViewCtrl extends PureViewCtrl { async handleEditorNoteChange() { this.cancelPendingSetStatus(); const note = this.editor.note; - const showProtectedWarning = note.protected && !this.application.hasProtectionSources(); + const showProtectedWarning = + note.protected && !this.application.hasProtectionSources(); this.setShowProtectedWarning(showProtectedWarning); await this.setState({ showActionsMenu: false, - showOptionsMenu: false, showEditorMenu: false, showHistoryMenu: false, noteStatus: undefined, @@ -364,12 +360,7 @@ class EditorViewCtrl extends PureViewCtrl { } closeAllMenus(exclude?: string) { - const allMenus = [ - 'showOptionsMenu', - 'showEditorMenu', - 'showActionsMenu', - 'showHistoryMenu', - ]; + const allMenus = ['showEditorMenu', 'showActionsMenu', 'showHistoryMenu']; const menuState: any = {}; for (const candidate of allMenus) { if (candidate !== exclude) { @@ -591,7 +582,7 @@ class EditorViewCtrl extends PureViewCtrl { } clickedTextArea() { - this.setMenuState('showOptionsMenu', false); + this.closeAllMenus(); } // eslint-disable-next-line @typescript-eslint/no-empty-function @@ -607,12 +598,6 @@ class EditorViewCtrl extends PureViewCtrl { this.lastEditorFocusEventSource = undefined; } - selectedMenuItem(hide: boolean) { - if (hide) { - this.setMenuState('showOptionsMenu', false); - } - } - setShowProtectedWarning(show: boolean) { this.appState.notes.setShowProtectedWarning(show); } @@ -757,13 +742,10 @@ class EditorViewCtrl extends PureViewCtrl { /** @components */ registerComponentHandler() { - this.unregisterComponent = this.application.componentManager!.registerHandler( - { + this.unregisterComponent = + this.application.componentManager!.registerHandler({ identifier: 'editor', - areas: [ - ComponentArea.EditorStack, - ComponentArea.Editor, - ], + areas: [ComponentArea.EditorStack, ComponentArea.Editor], contextRequestHandler: (componentUuid) => { const currentEditor = this.state.editorComponent; if ( @@ -778,8 +760,7 @@ class EditorViewCtrl extends PureViewCtrl { this.closeAllMenus(); } }, - } - ); + }); } async reloadStackComponents() { @@ -809,9 +790,8 @@ class EditorViewCtrl extends PureViewCtrl { } async toggleStackComponentForCurrentItem(component: SNComponent) { - const hidden = this.application.componentManager!.isComponentHidden( - component - ); + const hidden = + this.application.componentManager!.isComponentHidden(component); if (hidden || !component.active) { this.application.componentManager!.setComponentHidden(component, false); await this.associateComponentWithCurrentNote(component); @@ -844,16 +824,14 @@ class EditorViewCtrl extends PureViewCtrl { } registerKeyboardShortcuts() { - this.removeTrashKeyObserver = this.application - .io - .addKeyObserver({ - key: KeyboardKey.Backspace, - notTags: ['INPUT', 'TEXTAREA'], - modifiers: [KeyboardModifier.Meta], - onKeyDown: () => { - this.deleteNote(false); - }, - }); + this.removeTrashKeyObserver = this.application.io.addKeyObserver({ + key: KeyboardKey.Backspace, + notTags: ['INPUT', 'TEXTAREA'], + modifiers: [KeyboardModifier.Meta], + onKeyDown: () => { + this.deleteNote(false); + }, + }); } setScrollPosition() { @@ -883,39 +861,37 @@ class EditorViewCtrl extends PureViewCtrl { const editor = document.getElementById( ElementIds.NoteTextEditor )! as HTMLInputElement; - this.removeTabObserver = this.application - .io - .addKeyObserver({ - element: editor, - key: KeyboardKey.Tab, - onKeyDown: (event) => { - if (document.hidden || this.note.locked || event.shiftKey) { - return; - } - event.preventDefault(); - /** Using document.execCommand gives us undo support */ - const insertSuccessful = document.execCommand( - 'insertText', - false, - '\t' - ); - if (!insertSuccessful) { - /** document.execCommand works great on Chrome/Safari but not Firefox */ - const start = editor.selectionStart!; - const end = editor.selectionEnd!; - const spaces = ' '; - /** Insert 4 spaces */ - editor.value = - editor.value.substring(0, start) + - spaces + - editor.value.substring(end); - /** Place cursor 4 spaces away from where the tab key was pressed */ - editor.selectionStart = editor.selectionEnd = start + 4; - } - this.editorValues.text = editor.value; - this.save(this.note, copyEditorValues(this.editorValues), true); - }, - }); + this.removeTabObserver = this.application.io.addKeyObserver({ + element: editor, + key: KeyboardKey.Tab, + onKeyDown: (event) => { + if (document.hidden || this.note.locked || event.shiftKey) { + return; + } + event.preventDefault(); + /** Using document.execCommand gives us undo support */ + const insertSuccessful = document.execCommand( + 'insertText', + false, + '\t' + ); + if (!insertSuccessful) { + /** document.execCommand works great on Chrome/Safari but not Firefox */ + const start = editor.selectionStart!; + const end = editor.selectionEnd!; + const spaces = ' '; + /** Insert 4 spaces */ + editor.value = + editor.value.substring(0, start) + + spaces + + editor.value.substring(end); + /** Place cursor 4 spaces away from where the tab key was pressed */ + editor.selectionStart = editor.selectionEnd = start + 4; + } + this.editorValues.text = editor.value; + this.save(this.note, copyEditorValues(this.editorValues), true); + }, + }); editor.addEventListener('scroll', this.setScrollPosition); editor.addEventListener('input', this.resetScrollPosition);