From 06b8f0ad6aa3fa540e9bdb9485fca7df61b1c0c2 Mon Sep 17 00:00:00 2001 From: Max G Date: Tue, 7 Jul 2020 04:04:55 +0000 Subject: [PATCH] Added privacy policy Updated marketing Added some keyboard shortcuts Added settings page Added accent theming Added beta 2FA --- client/src/App.vue | 6 + client/src/Helpers.js | 4 + client/src/assets/semantic-helper.css | 75 ++++- client/src/assets/squire.js | 80 ++++-- .../src/components/AttachmentDisplayCard.vue | 1 - client/src/components/FastFilters.vue | 6 +- client/src/components/GlobalSiteMenu.vue | 146 +++++----- .../src/components/LoadingIconComponent.vue | 4 +- client/src/components/LoginFormComponent.vue | 75 ++++- client/src/components/LogoComponent.vue | 80 ++++++ client/src/components/NoteInputPanel.vue | 138 ++++++--- .../src/components/NoteTitleDisplayCard.vue | 78 ++++-- client/src/components/SearchInput.vue | 9 +- client/src/mixins/SquireButtonFunctions.js | 104 +++++-- client/src/pages/HelpPage.vue | 30 +- client/src/pages/HomePage.vue | 39 ++- client/src/pages/LoginPage.vue | 2 +- client/src/pages/NotesPage.vue | 127 ++++----- client/src/pages/QuickPage.vue | 9 +- client/src/pages/SettingsPage.vue | 182 ++++++++++++ client/src/router/index.js | 7 + client/src/stores/mainStore.js | 1 + package-lock.json | 265 ++++++++++++++++++ package.json | 4 +- server/helpers/Auth.js | 139 +++++++++ server/index.js | 6 +- server/models/Note.js | 10 +- server/models/User.js | 113 ++++++-- server/routes/userController.js | 50 ++-- 29 files changed, 1428 insertions(+), 362 deletions(-) create mode 100644 client/src/components/LogoComponent.vue create mode 100644 client/src/pages/SettingsPage.vue diff --git a/client/src/App.vue b/client/src/App.vue index 77c9509..fdc8225 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -97,6 +97,12 @@ export default { //Detect if user is on a mobile browser and set a flag in store this.$store.commit('detectIsUserOnMobile') + //Set Main theme color + const accentColor = localStorage.getItem('main-accent') + if(accentColor){ + document.documentElement.style.setProperty('--main-accent', accentColor) + } + //Set color theme based on local storage const themeNumber = localStorage.getItem('nightMode') if(themeNumber != null){ diff --git a/client/src/Helpers.js b/client/src/Helpers.js index c789180..0b22d71 100644 --- a/client/src/Helpers.js +++ b/client/src/Helpers.js @@ -4,6 +4,10 @@ const helpers = {} helpers.timeAgo = (time) => { + if(time == null){ + time = Math.round(time/1000) + } + if(time.toString().length >= 13){ time = Math.round(time/1000) } diff --git a/client/src/assets/semantic-helper.css b/client/src/assets/semantic-helper.css index bc0189f..c79cc46 100644 --- a/client/src/assets/semantic-helper.css +++ b/client/src/assets/semantic-helper.css @@ -18,7 +18,8 @@ :root { - --main-accent: #16ab39; + /*main accent for all buttons, icons and logos*/ + --main-accent: #21BA45; /*theme colors */ --body_bg_color: #f5f6f7; @@ -105,7 +106,7 @@ div.ui.basic.green.label { background-color: var(--small_element_bg_color) !important; } .ui.basic.button, .ui.basic.buttons .button { - background-color: var(--small_element_bg_color) !important; + background-color: var(--small_element_bg_color); color: var(--text_color) !important; border: 1px solid; border-color: var(--dark_border_color) !important; @@ -125,6 +126,24 @@ div.ui.basic.green.label { color: var(--text_color) !important; border-color: var(--dark_border_color) !important; } +/*Overwrites for modifiable theme color */ +i.green.icon.icon.icon.icon { + color: var(--main-accent); +} +.ui.green.buttons, .ui.green.button, .ui.green.button:hover { + background-color: var(--main-accent); +} +.ui.basic.green.button, .ui.basic.green.buttons .button:hover, .ui.basic.green.button:hover, .ui.basic.green.button:focus { + box-shadow: var(--main-accent) 0px 0px 0px 1px inset; +} +.ui.green.labels .label, .ui.ui.ui.green.label { + background-color: var(--main-accent); + border-color: var(--main-accent); +} +.ui.grid > .green.row, .ui.grid > .green.column, .ui.grid > .row > .green.column { + background-color: var(--main-accent); +} + /* OVERWRITE DEFAULT SEMANTIC STYLES FOR CUSTOM/NIGHT MODES*/ /*// @@ -235,7 +254,7 @@ div.ui.basic.green.label { /*border-bottom: 1px solid #ccc;*/ scrollbar-width: none; scrollbar-color: transparent transparent; - caret-color: #21BA45; + caret-color: var(--main-accent); } .squire-box::selection, .squire-box::-moz-selection { @@ -253,7 +272,7 @@ div.ui.basic.green.label { cursor: pointer; } .night-mode .note-card-text i:not(.icon), - .night-mode .squire-box i { + .night-mode .squire-box i:not(.icon) { background-color: rgba(255, 255, 255, 0.2); } @@ -322,9 +341,55 @@ div.ui.basic.green.label { font-family: 'Icons'; content: "\f058"; - color: #21BA45; + color: var(--main-accent); opacity: 1; } + + .note-title-display-card .divide, + .squire-box .divide { + width: 100%; + display: inline-block; + height: 2px; + background-color: var(--main-accent); + } + + table { + width: 100%; + border-collapse: collapse; + } + + th, td { + border: 1px solid #ddd; + border-bottom: 1px solid #ddd; + font-weight: normal; + } +/* table:hover th, table:hover td { + border: 1px solid black; + }*/ + + th, td { + padding: 3px; + text-align: left; + } + + .t-table { + width: 100%; + display: inline-block; + border: 1px solid black; + } + + .t-table > span, + .t-table > div { + display: flex; /* aligns all child elements (flex items) in a row */ + } + + .t-table > span > span, + .t-table > div > div { + flex: 1; /* distributes space on the line equally among items */ + border: 1px solid #DDD; + } + + /* adjust checkboxes for mobile. Make them a little bigger, easier to click */ @media only screen and (max-width: 740px) { diff --git a/client/src/assets/squire.js b/client/src/assets/squire.js index ec63d88..65b7484 100644 --- a/client/src/assets/squire.js +++ b/client/src/assets/squire.js @@ -1096,6 +1096,9 @@ var moveRangeBoundariesUpTree = function ( range, startMax, endMax, root ) { } while ( true ) { + if ( endContainer === endMax || endContainer === root ) { + break; + } if ( maySkipBR && endContainer.nodeType !== TEXT_NODE && endContainer.childNodes[ endOffset ] && @@ -1103,9 +1106,7 @@ var moveRangeBoundariesUpTree = function ( range, startMax, endMax, root ) { endOffset += 1; maySkipBR = false; } - if ( endContainer === endMax || - endContainer === root || - endOffset !== getLength( endContainer ) ) { + if ( endOffset !== getLength( endContainer ) ) { break; } parent = endContainer.parentNode; @@ -1117,6 +1118,20 @@ var moveRangeBoundariesUpTree = function ( range, startMax, endMax, root ) { range.setEnd( endContainer, endOffset ); }; +var moveRangeBoundaryOutOf = function ( range, nodeName, root ) { + var parent = getNearest( range.endContainer, root, 'A' ); + if ( parent ) { + var clone = range.cloneRange(); + parent = parent.parentNode; + moveRangeBoundariesUpTree( clone, parent, parent, root ); + if ( clone.endContainer === parent ) { + range.setStart( clone.endContainer, clone.endOffset ); + range.setEnd( clone.endContainer, clone.endOffset ); + } + } + return range; +}; + // Returns the first block at least partially contained by the range, // or null if no block is contained by the range. var getStartBlockOfRange = function ( range, root ) { @@ -1285,10 +1300,13 @@ var onKey = function ( event ) { if ( event.altKey ) { modifiers += 'alt-'; } if ( event.ctrlKey ) { modifiers += 'ctrl-'; } if ( event.metaKey ) { modifiers += 'meta-'; } + if ( event.shiftKey ) { modifiers += 'shift-'; } } // However, on Windows, shift-delete is apparently "cut" (WTF right?), so - // we want to let the browser handle shift-delete. - if ( event.shiftKey ) { modifiers += 'shift-'; } + // we want to let the browser handle shift-delete in this situation. + if ( isWin && event.shiftKey && key === 'delete' ) { + modifiers += 'shift-'; + } key = modifiers + key; @@ -1465,12 +1483,7 @@ var handleEnter = function ( self, shiftKey, range ) { // just play it safe and insert a
. if ( !block || shiftKey || /^T[HD]$/.test( block.nodeName ) ) { // If inside an , move focus out - parent = getNearest( range.endContainer, root, 'A' ); - if ( parent ) { - parent = parent.parentNode; - moveRangeBoundariesUpTree( range, parent, parent, root ); - range.collapse( false ); - } + moveRangeBoundaryOutOf( range, 'A', root ); insertNodeInRange( range, self.createElement( 'BR' ) ); range.collapse( false ); self.setSelection( range ); @@ -1821,16 +1834,45 @@ if ( !isMac ) { }; } +const changeIndentationLevel = function ( methodIfInQuote, methodIfInList ) { + return function ( self, event ) { + event.preventDefault(); + var path = self.getPath(); + if ( /(?:^|>)BLOCKQUOTE/.test( path ) || + !/(?:^|>)[OU]L/.test( path ) ) { + self[ methodIfInQuote ](); + } else { + self[ methodIfInList ](); + } + }; +}; + +const toggleList = function ( listRegex, methodIfNotInList ) { + return function ( self, event ) { + event.preventDefault(); + var path = self.getPath(); + if ( !listRegex.test( path ) ) { + self[ methodIfNotInList ](); + } else { + self.removeList(); + } + }; +}; + keyHandlers[ ctrlKey + 'b' ] = mapKeyToFormat( 'B' ); keyHandlers[ ctrlKey + 'i' ] = mapKeyToFormat( 'I' ); keyHandlers[ ctrlKey + 'u' ] = mapKeyToFormat( 'U' ); keyHandlers[ ctrlKey + 'shift-7' ] = mapKeyToFormat( 'S' ); keyHandlers[ ctrlKey + 'shift-5' ] = mapKeyToFormat( 'SUB', { tag: 'SUP' } ); keyHandlers[ ctrlKey + 'shift-6' ] = mapKeyToFormat( 'SUP', { tag: 'SUB' } ); -keyHandlers[ ctrlKey + 'shift-8' ] = mapKeyTo( 'makeUnorderedList' ); -keyHandlers[ ctrlKey + 'shift-9' ] = mapKeyTo( 'makeOrderedList' ); -keyHandlers[ ctrlKey + '[' ] = mapKeyTo( 'decreaseQuoteLevel' ); -keyHandlers[ ctrlKey + ']' ] = mapKeyTo( 'increaseQuoteLevel' ); +keyHandlers[ ctrlKey + 'shift-8' ] = + toggleList( /(?:^|>)UL/, 'makeUnorderedList' ); +keyHandlers[ ctrlKey + 'shift-9' ] = + toggleList( /(?:^|>)OL/, 'makeOrderedList' ); +keyHandlers[ ctrlKey + '[' ] = + changeIndentationLevel( 'decreaseQuoteLevel', 'decreaseListLevel' ); +keyHandlers[ ctrlKey + ']' ] = + changeIndentationLevel( 'increaseQuoteLevel', 'increaseListLevel' ); keyHandlers[ ctrlKey + 'd' ] = mapKeyTo( 'toggleCode' ); keyHandlers[ ctrlKey + 'y' ] = mapKeyTo( 'redo' ); keyHandlers[ ctrlKey + 'z' ] = mapKeyTo( 'undo' ); @@ -4417,6 +4459,12 @@ proto.insertHTML = function ( html, isPaste ) { this._docWasChanged(); } range.collapse( false ); + + // After inserting the fragment, check whether the cursor is inside + // an element and if so if there is an equivalent cursor + // position after the element. If there is, move it there. + moveRangeBoundaryOutOf( range, 'A', root ); + this._ensureBottomLine(); } @@ -4947,4 +4995,4 @@ if ( typeof exports === 'object' ) { } } -}( document ) ); \ No newline at end of file +}( document ) ); diff --git a/client/src/components/AttachmentDisplayCard.vue b/client/src/components/AttachmentDisplayCard.vue index 1b27f0a..d9f565d 100644 --- a/client/src/components/AttachmentDisplayCard.vue +++ b/client/src/components/AttachmentDisplayCard.vue @@ -182,7 +182,6 @@ openNote(){ const noteId = this.item.note_id this.$router.push('/notes/open/'+noteId) - this.$bus.$emit('open_note', noteId) }, openEditAttachments(){ const noteId = this.item.note_id diff --git a/client/src/components/FastFilters.vue b/client/src/components/FastFilters.vue index cc80673..bb3296c 100644 --- a/client/src/components/FastFilters.vue +++ b/client/src/components/FastFilters.vue @@ -24,9 +24,9 @@ } }, beforeMount(){ - this.$bus.$on('reset_fast_filters', () => { - this.orderString = 'Order by Last Edited' - }) + // this.$bus.$on('reset_fast_filters', () => { + // this.orderString = 'Order by Last Edited' + // }) }, methods:{ displayString(){ diff --git a/client/src/components/GlobalSiteMenu.vue b/client/src/components/GlobalSiteMenu.vue index 1f2ff4e..50915da 100644 --- a/client/src/components/GlobalSiteMenu.vue +++ b/client/src/components/GlobalSiteMenu.vue @@ -19,9 +19,10 @@ bottom: 0; } .menu-logo-display { - width: 25px; - margin: 5px 0 0 42px; + width: 27px; + margin: 5px 0 0 41px; display: inline-block; + height: auto; } .menu-item { @@ -79,15 +80,17 @@ background-color: var(--small_element_bg_color); border-bottom: 1px solid; border-color: var(--border_color); - padding: 5px 1rem 5px; + /*padding: 5px 1rem 5px;*/ + display: flex; + justify-content: space-around; } .place-holder { width: 100%; height: 50px; } - .top-menu-bar img { - width: 30px; - height: 30px; + .logo-display { + width: 27px; + height: auto; } .version-display { position: absolute; @@ -101,6 +104,19 @@ cursor: pointer; } + .mobile-button { + display: inline-block; + font-size: 2em; + padding: 6px 3px 5px; + cursor: pointer; + } + .mobile-button.active { + background-color: transparent; + } + .mobile-button i { + margin: 0; + } +