diff --git a/app/assets/javascripts/app/app.frontend.js b/app/assets/javascripts/app/app.frontend.js index 80a607ee3..6affad2d1 100644 --- a/app/assets/javascripts/app/app.frontend.js +++ b/app/assets/javascripts/app/app.frontend.js @@ -36,3 +36,7 @@ function parametersFromURL(url) { function isDesktopApplication() { return window && window.process && window.process.type && window.process.versions["electron"]; } + +function isMacApplication() { + return window && window.process && window.process.type && window.process.platform == "darwin"; +} diff --git a/app/assets/javascripts/app/frontend/controllers/editor.js b/app/assets/javascripts/app/frontend/controllers/editor.js index b976d90fb..047264ffa 100644 --- a/app/assets/javascripts/app/frontend/controllers/editor.js +++ b/app/assets/javascripts/app/frontend/controllers/editor.js @@ -50,13 +50,20 @@ angular.module('app.frontend') this.showMenu = false; this.loadTagsString(); + let onReady = () => { + this.noteReady = true; + $timeout(() => { + this.loadPreferences(); + }) + } + let associatedEditor = this.editorForNote(note); if(associatedEditor) { // setting note to not ready will remove the editor from view in a flash, // so we only want to do this if switching between external editors this.noteReady = false; } else { - this.noteReady = true; + onReady(); } if(this.editorComponent && this.editorComponent != associatedEditor) { @@ -71,10 +78,10 @@ angular.module('app.frontend') $timeout(() => { this.enableComponent(associatedEditor); this.editorComponent = associatedEditor; - this.noteReady = true; + onReady(); }) } else { - this.noteReady = true; + onReady(); } if(note.safeText().length == 0 && note.dummy) { @@ -124,6 +131,10 @@ angular.module('app.frontend') this.note.setAppDataItem("prefersPlainEditor", true); this.note.setDirty(true); syncManager.sync(); + + $timeout(() => { + this.reloadFont(); + }) } this.editorComponent = editorComponent; @@ -322,7 +333,73 @@ angular.module('app.frontend') } + /* Resizability */ + this.resizeControl = {}; + + this.onPanelResizeFinish = function(width, left, isMaxWidth) { + if(isMaxWidth) { + authManager.setUserPrefValue("editorWidth", null); + } else { + if(width !== undefined && width !== null) { + authManager.setUserPrefValue("editorWidth", width); + } + } + + if(left !== undefined && left !== null) { + authManager.setUserPrefValue("editorLeft", left); + } + authManager.syncUserPreferences(); + } + + $rootScope.$on("user-preferences-changed", () => { + this.loadPreferences(); + }); + + this.loadPreferences = function() { + this.monospaceFont = authManager.getUserPrefValue("monospaceFont", "monospace"); + + if(!document.getElementById("editor-content")) { + // Elements have not yet loaded due to ng-if around wrapper + return; + } + + this.reloadFont(); + + let width = authManager.getUserPrefValue("editorWidth", null); + if(width !== null) { + this.resizeControl.setWidth(width); + } + + let left = authManager.getUserPrefValue("editorLeft", null); + if(left !== null) { + this.resizeControl.setLeft(left); + } + } + + this.reloadFont = function() { + var editable = document.getElementById("note-text-editor"); + + if(!editable) { + return; + } + + if(this.monospaceFont) { + if(isMacApplication()) { + editable.style.fontFamily = "Menlo, Consolas, 'DejaVu Sans Mono', monospace"; + } else { + editable.style.fontFamily = "monospace"; + } + } else { + editable.style.fontFamily = "inherit"; + } + } + + this.toggleKey = function(key) { + this[key] = !this[key]; + authManager.setUserPrefValue(key, this[key], true); + this.reloadFont(); + } diff --git a/app/assets/javascripts/app/frontend/controllers/notes.js b/app/assets/javascripts/app/frontend/controllers/notes.js index 2f35f5d98..c5660f93d 100644 --- a/app/assets/javascripts/app/frontend/controllers/notes.js +++ b/app/assets/javascripts/app/frontend/controllers/notes.js @@ -33,21 +33,61 @@ angular.module('app.frontend') }) .controller('NotesCtrl', function (authManager, $timeout, $rootScope, modelManager, storageManager) { - this.sortBy = storageManager.getItem("sortBy") || "created_at"; - this.showArchived = storageManager.getBooleanValue("showArchived") || false; - this.sortDescending = this.sortBy != "title"; + this.panelController = {}; + + $rootScope.$on("user-preferences-changed", () => { + this.loadPreferences(); + }); + + this.loadPreferences = function() { + this.sortBy = authManager.getUserPrefValue("sortBy", "created_at"); + this.sortDescending = this.sortBy != "title"; + + this.showArchived = authManager.getUserPrefValue("showArchived", false); + this.hidePinned = authManager.getUserPrefValue("hidePinned", false); + this.hideNotePreview = authManager.getUserPrefValue("hideNotePreview", false); + this.hideDate = authManager.getUserPrefValue("hideDate", false); + this.hideTags = authManager.getUserPrefValue("hideTags", false); + + let width = authManager.getUserPrefValue("notesPanelWidth"); + if(width) { + this.panelController.setWidth(width); + } + } + + this.loadPreferences(); + + this.onPanelResize = function(newWidth) { + authManager.setUserPrefValue("notesPanelWidth", newWidth); + authManager.syncUserPreferences(); + } + + angular.element(document).ready(() => { + this.loadPreferences(); + }); $rootScope.$on("editorFocused", function(){ this.showMenu = false; }.bind(this)) $rootScope.$on("noteDeleted", function() { - this.selectFirstNote(false); + $timeout(this.onNoteRemoval.bind(this)); }.bind(this)) $rootScope.$on("noteArchived", function() { - this.selectFirstNote(false); - }.bind(this)) + $timeout(this.onNoteRemoval.bind(this)); + }.bind(this)); + + + // When a note is removed from the list + this.onNoteRemoval = function() { + let visibleNotes = this.visibleNotes(); + if(this.selectedIndex < visibleNotes.length) { + this.selectNote(visibleNotes[this.selectedIndex]); + } else { + this.selectNote(visibleNotes[visibleNotes.length - 1]); + } + } this.DefaultNotesToDisplayValue = 20; @@ -56,26 +96,39 @@ angular.module('app.frontend') this.notesToDisplay += this.DefaultNotesToDisplayValue } + this.panelTitle = function() { + if(this.noteFilter.text.length) { + return `${this.tag.notes.filter((i) => {return i.visible;}).length} search results`; + } else if(this.tag) { + return `${this.tag.title} notes`; + } + } + this.optionsSubtitle = function() { - var base = "Sorting by"; + var base = ""; if(this.sortBy == "created_at") { - base += " date added"; + base += " Date Added"; } else if(this.sortBy == "updated_at") { - base += " date modifed"; + base += " Date Modifed"; } else if(this.sortBy == "title") { - base += " title"; + base += " Title"; } if(this.showArchived && (!this.tag || !this.tag.archiveTag)) { - base += " | Including archived" + base += " | + Archived" + } + + if(this.hidePinned) { + base += " | – Pinned" } return base; } - this.toggleShowArchived = function() { - this.showArchived = !this.showArchived; - storageManager.setBooleanValue("showArchived", this.showArchived); + this.toggleKey = function(key) { + this[key] = !this[key]; + authManager.setUserPrefValue(key, this[key]); + authManager.syncUserPreferences(); } this.tagDidChange = function(tag, oldTag) { @@ -108,10 +161,14 @@ angular.module('app.frontend') this.selectFirstNote(createNew); } - this.selectFirstNote = function(createNew) { - var visibleNotes = this.sortedNotes.filter(function(note){ + this.visibleNotes = function() { + return this.sortedNotes.filter(function(note){ return note.visible; }); + } + + this.selectFirstNote = function(createNew) { + var visibleNotes = this.visibleNotes(); if(visibleNotes.length > 0) { this.selectNote(visibleNotes[0]); @@ -121,6 +178,7 @@ angular.module('app.frontend') } this.selectNote = function(note) { + if(!note) { return; } this.selectedNote = note; note.conflict_of = null; // clear conflict this.selectionMade()(note); @@ -142,7 +200,7 @@ angular.module('app.frontend') return note.visible; } - if(note.archived && !this.showArchived) { + if((note.archived && !this.showArchived) || (note.pinned && this.hidePinned)) { note.visible = false; return note.visible; } @@ -188,7 +246,8 @@ angular.module('app.frontend') this.setSortBy = function(type) { this.sortBy = type; - storageManager.setItem("sortBy", type); + authManager.setUserPrefValue("sortBy", this.sortBy); + authManager.syncUserPreferences(); } }); diff --git a/app/assets/javascripts/app/frontend/controllers/tags.js b/app/assets/javascripts/app/frontend/controllers/tags.js index e7f686b8e..549649f80 100644 --- a/app/assets/javascripts/app/frontend/controllers/tags.js +++ b/app/assets/javascripts/app/frontend/controllers/tags.js @@ -34,10 +34,30 @@ angular.module('app.frontend') } } }) - .controller('TagsCtrl', function ($rootScope, modelManager, $timeout, componentManager) { + .controller('TagsCtrl', function ($rootScope, modelManager, $timeout, componentManager, authManager) { var initialLoad = true; + this.panelController = {}; + + $rootScope.$on("user-preferences-changed", () => { + this.loadPreferences(); + }); + + this.loadPreferences = function() { + let width = authManager.getUserPrefValue("tagsPanelWidth"); + if(width) { + this.panelController.setWidth(width); + } + } + + this.loadPreferences(); + + this.onPanelResize = function(newWidth) { + authManager.setUserPrefValue("tagsPanelWidth", newWidth); + authManager.syncUserPreferences(); + } + this.componentManager = componentManager; componentManager.registerHandler({identifier: "tags", areas: ["tags-list"], activationHandler: function(component){ diff --git a/app/assets/javascripts/app/services/authManager.js b/app/assets/javascripts/app/services/authManager.js index 4e7f1936f..2c6d4c7e9 100644 --- a/app/assets/javascripts/app/services/authManager.js +++ b/app/assets/javascripts/app/services/authManager.js @@ -298,6 +298,7 @@ angular.module('app.frontend') singletonManager.registerSingleton({content_type: prefsContentType}, (resolvedSingleton) => { console.log("AuthManager received resolved UserPreferences", resolvedSingleton); this.userPreferences = resolvedSingleton; + this.userPreferencesDidChange(); }, () => { // Safe to create. Create and return object. var prefs = new Item({content_type: prefsContentType}); @@ -308,5 +309,28 @@ angular.module('app.frontend') return prefs; }); + this.userPreferencesDidChange = function() { + $rootScope.$broadcast("user-preferences-changed"); + } + + this.syncUserPreferences = function() { + this.userPreferences.setDirty(true); + $rootScope.sync(); + } + + this.getUserPrefValue = function(key, defaultValue) { + if(!this.userPreferences) { return; } + var value = this.userPreferences.getAppDataItem(key); + return (value !== undefined && value != null) ? value : defaultValue; + } + + this.setUserPrefValue = function(key, value, sync) { + if(!this.userPreferences) { console.log("Prefs are null, not setting value", key); return; } + this.userPreferences.setAppDataItem(key, value); + if(sync) { + this.syncUserPreferences(); + } + } + } }); diff --git a/app/assets/javascripts/app/services/directives/views/panelResizer.js b/app/assets/javascripts/app/services/directives/views/panelResizer.js new file mode 100644 index 000000000..3b6d9e87e --- /dev/null +++ b/app/assets/javascripts/app/services/directives/views/panelResizer.js @@ -0,0 +1,201 @@ +class PanelResizer { + + constructor() { + this.restrict = "E"; + this.templateUrl = "frontend/directives/panel-resizer.html"; + this.scope = { + index: "=", + panelId: "=", + onResize: "&", + onResizeFinish: "&", + control: "=", + alwaysVisible: "=", + minWidth: "=", + property: "=", + hoverable: "=", + collapsable: "=" + }; + } + + link(scope, elem, attrs, ctrl) { + scope.elem = elem; + + scope.control.setWidth = function(value) { + scope.setWidth(value, true); + } + + scope.control.setLeft = function(value) { + scope.setLeft(value); + } + } + + controller($scope, $element, modelManager, extensionManager) { + 'ngInject'; + + let panel = document.getElementById($scope.panelId); + if(!panel) { + console.log("Panel not found for", $scope.panelId); + } + let resizerColumn = $element[0]; + let resizerWidth = resizerColumn.offsetWidth; + let minWidth = $scope.minWidth || resizerWidth; + + function getParentRect() { + return panel.parentNode.getBoundingClientRect(); + } + + var pressed = false; + var startWidth = panel.scrollWidth, startX, lastDownX, collapsed, lastWidth = startWidth, startLeft, lastLeft; + let appFrame = document.getElementById("app").getBoundingClientRect(); + + if($scope.alwaysVisible) { + console.log("Adding always visible", $scope.alwaysVisible); + resizerColumn.classList.add("always-visible"); + } + + if($scope.hoverable) { + resizerColumn.classList.add("hoverable"); + } + + $scope.setWidth = function(width, finish) { + if(width < minWidth) { + width = minWidth; + } + + let parentRect = getParentRect(); + + if(width > parentRect.width) { + width = parentRect.width; + } + + if(width == parentRect.width) { + panel.style.width = "100%"; + panel.style.flexBasis = "100%"; + } else { + panel.style.flexBasis = width + "px"; + panel.style.width = width + "px"; + } + + + lastWidth = width; + + if(finish) { + $scope.finishSettingWidth(); + } + } + + $scope.setLeft = function(left) { + panel.style.left = left + "px"; + lastLeft = left; + } + + $scope.finishSettingWidth = function() { + if(!$scope.collapsable) { + return; + } + + + if(lastWidth <= minWidth) { + collapsed = true; + } else { + collapsed = false; + } + if(collapsed) { + resizerColumn.classList.add("collapsed"); + } else { + resizerColumn.classList.remove("collapsed"); + } + } + + resizerColumn.addEventListener("mousedown", function(event){ + pressed = true; + lastDownX = event.clientX; + startWidth = panel.scrollWidth; + startLeft = panel.offsetLeft; + panel.classList.add("no-selection"); + + if($scope.hoverable) { + resizerColumn.classList.add("dragging"); + } + }) + + document.addEventListener("mousemove", function(event){ + if(!pressed) { + return; + } + + event.preventDefault(); + + if($scope.property && $scope.property == 'left') { + handleLeftEvent(event); + } else { + handleWidthEvent(event); + } + }) + + function handleWidthEvent(event) { + var rect = panel.getBoundingClientRect(); + var panelMaxX = rect.left + (startWidth || panel.style.maxWidth); + + var x = event.clientX; + + let deltaX = x - lastDownX; + var newWidth = startWidth + deltaX; + + $scope.setWidth(newWidth, false); + + if($scope.onResize()) { + $scope.onResize()(lastWidth, panel); + } + } + + function handleLeftEvent(event) { + var panelRect = panel.getBoundingClientRect(); + var x = event.clientX; + let deltaX = x - lastDownX; + var newLeft = startLeft + deltaX; + if(newLeft < 0) { + newLeft = 0; + deltaX = -startLeft; + } + + let parentRect = getParentRect(); + + var newWidth = startWidth - deltaX; + if(newWidth < minWidth) { + newWidth = minWidth; + } + + if(newWidth > parentRect.width) { + newWidth = parentRect.width; + } + + + if(newLeft + newWidth > parentRect.width) { + newLeft = parentRect.width - newWidth; + } + + $scope.setLeft(newLeft, false); + $scope.setWidth(newWidth, false); + } + + document.addEventListener("mouseup", function(event){ + if(pressed) { + pressed = false; + resizerColumn.classList.remove("dragging"); + panel.classList.remove("no-selection"); + + let isMaxWidth = lastWidth == getParentRect().width; + + if($scope.onResizeFinish) { + $scope.onResizeFinish()(lastWidth, lastLeft, isMaxWidth); + } + + $scope.finishSettingWidth(); + } + }) + } + +} + +angular.module('app.frontend').directive('panelResizer', () => new PanelResizer); diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index 0860d57be..98b896f70 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -1,21 +1,11 @@ $heading-height: 75px; .editor { flex: 1 50%; - min-width: 300px; display: flex; flex-direction: column; overflow-y: hidden; background-color: white; - &.fullscreen { - width: 100%; - position: absolute; - left: 0px; - top: 0px; - z-index: 200; - padding: 0; - } - .section-menu-bar { flex: 1 0 28px; max-height: 28px; @@ -37,10 +27,6 @@ $heading-height: 75px; height: auto; overflow: visible; - &.fullscreen { - position: relative; - } - > .title { font-size: 18px; font-weight: bold; @@ -103,7 +89,7 @@ $heading-height: 75px; } } -.editor-content { +.editor-content, #editor-content { flex: 1; z-index: 10; overflow-y: hidden; @@ -111,9 +97,7 @@ $heading-height: 75px; display: flex; background-color: white; - &.fullscreen { - padding-top: 0px; - } + position: relative; #editor-iframe { flex: 1; @@ -122,7 +106,6 @@ $heading-height: 75px; .editable { font-family: monospace; - flex: 1; overflow-y: scroll; width: 100%; @@ -132,14 +115,6 @@ $heading-height: 75px; padding-top: 11px; font-size: 17px; resize: none; - - &.fullscreen { - padding: 85px 10%; - max-width: 1200px; - display: inline-block; - margin-left: auto; - margin-right: auto; - } } } diff --git a/app/assets/stylesheets/app/_main.scss b/app/assets/stylesheets/app/_main.scss index 83d9f0bad..39ab8bdb1 100644 --- a/app/assets/stylesheets/app/_main.scss +++ b/app/assets/stylesheets/app/_main.scss @@ -110,10 +110,7 @@ p { $footer-height: 25px; -$section-header-height: 70px; - .app { - // height: 100%; height: calc(100% - #{$footer-height}); width: 100%; display: flex; @@ -136,11 +133,48 @@ $section-header-height: 70px; } } + panel-resizer { + top: 0; + right: 0; + z-index: 1; + width: 8px; + height: 100%; + position: absolute; + cursor: col-resize; + background-color: rgb(224, 224, 224); + opacity: 0; + + &.left { + left: 0; + right: none; + } + + &.always-visible { + opacity: 1; + } + + &.collapsed { + opacity: 1; + } + + &.dragging { + opacity: 1; + } + + &.hoverable { + &:hover { + opacity: 1; + } + } + } + .section { padding-bottom: 0px; height: 100%; max-height: calc(100vh - #{$footer-height}); font-size: 17px; + position: relative; + overflow: hidden; .scrollable { overflow-y: auto; @@ -155,34 +189,40 @@ $section-header-height: 70px; } .section-title-bar { - padding: 20px; - height: $section-header-height; font-weight: bold; font-size: 14px; - > .title { - float: left; - white-space: nowrap; - text-overflow: ellipsis; - width: 80%; - overflow: hidden; + .padded { + padding: 0 14px; } - > .add-button { - float: right; - font-size: 18px; - width: 45px; - height: 24px; - cursor: pointer; - background-color: #e9e9e9; - border-radius: 4px; - font-weight: normal; - text-align: center; - position: absolute; - right: 12px; + .section-title-bar-header { + display: flex; + justify-content: space-between; + align-items: center; + overflow: hidden; - &:hover { - background-color: rgba(#e9e9e9, 0.8); + > .title { + white-space: nowrap; + text-overflow: ellipsis; + width: 80%; + overflow: hidden; + } + + > .add-button { + + font-size: 18px; + width: 45px; + height: 24px; + cursor: pointer; + background-color: #e9e9e9; + border-radius: 4px; + font-weight: normal; + text-align: center; + + &:hover { + background-color: rgba(#e9e9e9, 0.8); + } } } } diff --git a/app/assets/stylesheets/app/_menus.scss b/app/assets/stylesheets/app/_menus.scss index 8e851aad6..4bbfab8af 100644 --- a/app/assets/stylesheets/app/_menus.scss +++ b/app/assets/stylesheets/app/_menus.scss @@ -4,6 +4,11 @@ ul.section-menu-bar { padding-left: 6px; padding-right: 21px; + &.no-h-padding { + padding-left: 0px; + padding-right: 0px; + } + user-select: none; background-color: #f1f1f1; @@ -29,6 +34,7 @@ ul.section-menu-bar { &.full-width { width: 100%; + padding-left: 14px; } &.item-with-subtitle { @@ -43,14 +49,14 @@ ul.section-menu-bar { font-weight: normal; font-size: 12px; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 1; /* number of lines to show */ - $line-height: 18px; - line-height: $line-height; /* fallback */ - max-height: calc(#{$line-height} * 1); /* fallback */ + // overflow: hidden; + // text-overflow: ellipsis; + // display: -webkit-box; + // -webkit-box-orient: vertical; + // -webkit-line-clamp: 1; /* number of lines to show */ + // $line-height: 18px; + // line-height: $line-height; /* fallback */ + // max-height: calc(#{$line-height} * 1); /* fallback */ } } @@ -79,9 +85,15 @@ ul.section-menu-bar { border: none; width: 280px; + &.full-width { + width: 100%; + } + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 50px rgba(0, 0, 0, 0.175); background-clip: padding-box; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; background-color: white; color: $selected-text-color; diff --git a/app/assets/stylesheets/app/_notes.scss b/app/assets/stylesheets/app/_notes.scss index 7dd46dfd7..7075a8b87 100644 --- a/app/assets/stylesheets/app/_notes.scss +++ b/app/assets/stylesheets/app/_notes.scss @@ -1,21 +1,23 @@ -.notes { +#notes-column, .notes { border-left: 1px solid #dddddd; border-right: 1px solid #dddddd; - flex: 1 20%; - max-width: 350px; - min-width: 170px; - + width: 350px; + flex-grow: 0; user-select: none; - $notes-title-bar-height: 148px; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + + .content { + display: flex; + flex-direction: column; + } #notes-title-bar { color: rgba(black, 0.40); padding-top: 16px; - padding-left: 14px; - padding-right: 14px; - height: $notes-title-bar-height; font-weight: normal; font-size: 18px; @@ -25,21 +27,20 @@ } #notes-add-button { - right: 14px; + } #notes-menu-bar { position: relative; - margin: 0 -14px; margin-top: 14px; - height: 45px; + height: auto; width: auto; } .filter-section { clear: left; height: 32px; - margin-top: 20px; + margin-top: 14px; position: relative; .filter-bar { @@ -80,7 +81,7 @@ } .scrollable { - height: calc(100vh - (#{$notes-title-bar-height} + #{$footer-height})); + height: 100%; } .infinite-scroll { diff --git a/app/assets/stylesheets/app/_tags.scss b/app/assets/stylesheets/app/_tags.scss index d0e1e31db..79f0fb0b9 100644 --- a/app/assets/stylesheets/app/_tags.scss +++ b/app/assets/stylesheets/app/_tags.scss @@ -1,21 +1,20 @@ .tags { - flex: 1 10%; - max-width: 180px; - min-width: 100px; width: 180px; - background-color: #f6f6f6; - - user-select: none; + flex-grow: 0; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; $tags-title-bar-height: 55px; #tags-title-bar { - color: black; - height: $tags-title-bar-height; - padding-left: 12px; - padding-right: 12px; - font-size: 12px; - color: rgba(black, 0.8); + color: black; + height: $tags-title-bar-height; + padding-top: 14px; + padding-left: 12px; + padding-right: 12px; + font-size: 12px; + color: rgba(black, 0.8); } #tags-content { @@ -23,9 +22,7 @@ } #tag-add-button { - margin-top: -6px; background-color: #d7d7d7; - float: right; &:hover { background-color: rgba(#d7d7d7, 0.8); diff --git a/app/assets/templates/frontend/directives/panel-resizer.html.haml b/app/assets/templates/frontend/directives/panel-resizer.html.haml new file mode 100644 index 000000000..b2822c8c3 --- /dev/null +++ b/app/assets/templates/frontend/directives/panel-resizer.html.haml @@ -0,0 +1 @@ +.panel-resizer-column diff --git a/app/assets/templates/frontend/editor.html.haml b/app/assets/templates/frontend/editor.html.haml index 9b9ddf714..447265d35 100644 --- a/app/assets/templates/frontend/editor.html.haml +++ b/app/assets/templates/frontend/editor.html.haml @@ -1,8 +1,8 @@ -.section.editor{"ng-class" => "{'fullscreen' : ctrl.fullscreen}"} - #editor-title-bar.section-title-bar{"ng-show" => "ctrl.note && !ctrl.note.errorDecrypting", "ng-class" => "{'fullscreen' : ctrl.fullscreen }"} +.section.editor#editor-column + #editor-title-bar.section-title-bar{"ng-show" => "ctrl.note && !ctrl.note.errorDecrypting"} .title %input.input#note-title-editor{"ng-model" => "ctrl.note.title", "ng-keyup" => "$event.keyCode == 13 && ctrl.saveTitle($event)", - "ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()", + "ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()", "ng-blur" => "ctrl.onNameBlur()", "select-on-click" => "true"} #save-status{"ng-class" => "{'red bold': ctrl.saveError, 'orange bold': ctrl.syncTakingTooLong}", "ng-bind-html" => "ctrl.noteStatus"} @@ -16,26 +16,31 @@ %li{"ng-class" => "{'selected' : ctrl.showMenu}", "click-outside" => "ctrl.showMenu = false;", "is-open" => "ctrl.showMenu"} %label{"ng-click" => "ctrl.showMenu = !ctrl.showMenu; ctrl.showExtensions = false; ctrl.showEditorMenu = false;"} Menu - %ul.dropdown-menu.sectioned-menu{"ng-if" => "ctrl.showMenu"} - %li - %label{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.togglePin()"} - %i.icon.ion-ios-flag - {{ctrl.note.pinned ? "Unpin" : "Pin"}} - %li - %label{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.toggleArchiveNote()"} - %i.icon.ion-ios-box - {{ctrl.note.archived ? "Unarchive" : "Archive"}} - %li - %label{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.deleteNote()"} - %i.icon.ion-trash-b - Delete - %li - %label{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.toggleFullScreen()"} - %i.icon.ion-arrow-expand - Toggle Fullscreen - - %li{"ng-if" => "ctrl.hasDisabledStackComponents()"} - %label{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.restoreDisabledStackComponents()"} Restore Disabled Components + .dropdown-menu.sectioned-menu{"ng-if" => "ctrl.showMenu"} + %ul + .header + .title Note + %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.togglePin()"} + %label + %i.icon.ion-ios-flag + {{ctrl.note.pinned ? "Unpin" : "Pin"}} + %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.toggleArchiveNote()"} + %label + %i.icon.ion-ios-box + {{ctrl.note.archived ? "Unarchive" : "Archive"}} + %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.deleteNote()"} + %label + %i.icon.ion-trash-b + Delete + %li{"ng-if" => "ctrl.hasDisabledComponents()"} + %label{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.restoreDisabledComponents()"} Restore Disabled Components + %ul{"ng-if" => "!ctrl.editor"} + .header + .title Display + %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.toggleKey('monospaceFont')"} + %label + %span.top.mt-5.mr-5{"ng-if" => "ctrl.monospaceFont == true"} ✓ + Monospace Font %li{"ng-class" => "{'selected' : ctrl.showEditorMenu}", "click-outside" => "ctrl.showEditorMenu = false;", "is-open" => "ctrl.showEditorMenu"} %label{"ng-click" => "ctrl.showEditorMenu = !ctrl.showEditorMenu; ctrl.showMenu = false; ctrl.showExtensions = false;"} Editor @@ -45,12 +50,14 @@ %label{"ng-click" => "ctrl.showExtensions = !ctrl.showExtensions; ctrl.showMenu = false; ctrl.showEditorMenu = false;"} Actions %contextual-extensions-menu{"ng-if" => "ctrl.showExtensions", "item" => "ctrl.note"} - .editor-content{"ng-if" => "ctrl.noteReady && !ctrl.note.errorDecrypting", "ng-class" => "{'fullscreen' : ctrl.fullscreen }"} + .editor-content#editor-content{"ng-if" => "ctrl.noteReady && !ctrl.note.errorDecrypting"} + %panel-resizer.left{"panel-id" => "'editor-content'", "on-resize-finish" => "ctrl.onPanelResizeFinish","control" => "ctrl.resizeControl", "min-width" => 300, "property" => "'left'", "hoverable" => "true"} %iframe#editor-iframe{"ng-if" => "ctrl.editorComponent && ctrl.editorComponent.active", "ng-src" => "{{ctrl.componentManager.urlForComponent(ctrl.editorComponent) | trusted}}", "data-component-id" => "{{ctrl.editorComponent.uuid}}", "frameBorder" => "0", "style" => "width: 100%;"} Loading - %textarea.editable#note-text-editor{"ng-if" => "!ctrl.editorComponent", "ng-class" => "{'fullscreen' : ctrl.fullscreen }", "ng-model" => "ctrl.note.text", + %textarea.editable#note-text-editor{"ng-if" => "!ctrl.editorComponent", "ng-model" => "ctrl.note.text", "ng-change" => "ctrl.contentChanged()", "ng-click" => "ctrl.clickedTextArea()", "ng-focus" => "ctrl.onContentFocus()", "dir" => "auto"} {{ctrl.onSystemEditorLoad()}} + %panel-resizer{"panel-id" => "'editor-content'", "on-resize-finish" => "ctrl.onPanelResizeFinish","control" => "ctrl.resizeControl", "min-width" => 300, "hoverable" => "true"} %section.section{"ng-if" => "ctrl.note.errorDecrypting"} diff --git a/app/assets/templates/frontend/home.html.haml b/app/assets/templates/frontend/home.html.haml index bf98088c2..eb2b1f7b4 100644 --- a/app/assets/templates/frontend/home.html.haml +++ b/app/assets/templates/frontend/home.html.haml @@ -1,6 +1,6 @@ .main-ui-view %lock-screen{"ng-if" => "needsUnlock", "on-success" => "onSuccessfulUnlock"} - .app{"ng-if" => "!needsUnlock"} + .app#app{"ng-if" => "!needsUnlock"} %tags-section{"save" => "tagsSave", "add-new" => "tagsAddNew", "will-select" => "tagsWillMakeSelection", "selection-made" => "tagsSelectionMade", "all-tag" => "allTag", "archive-tag" => "archiveTag", "tags" => "tags", "remove-tag" => "removeTag"} diff --git a/app/assets/templates/frontend/notes.html.haml b/app/assets/templates/frontend/notes.html.haml index c5514fa91..1baa45463 100644 --- a/app/assets/templates/frontend/notes.html.haml +++ b/app/assets/templates/frontend/notes.html.haml @@ -1,41 +1,58 @@ -.section.notes +.section.notes#notes-column .content .section-title-bar#notes-title-bar - .title {{ctrl.tag.title}} notes - .add-button#notes-add-button{"ng-click" => "ctrl.createNewNote()"} + - %br - .filter-section - %input.filter-bar{"select-on-click" => "true", "ng-model" => "ctrl.noteFilter.text", "placeholder" => "Search", "ng-change" => "ctrl.filterTextChanged()", "lowercase" => "true"} - #search-clear-button{"ng-if" => "ctrl.noteFilter.text", "ng-click" => "ctrl.noteFilter.text = ''; ctrl.filterTextChanged()"} ✕ - %ul.section-menu-bar#notes-menu-bar - %li.item-with-subtitle{"ng-class" => "{'selected' : ctrl.showMenu}"} - .wrapper{"ng-click" => "ctrl.showMenu = !ctrl.showMenu", "click-outside" => "ctrl.showMenu = false;", "is-open" => "ctrl.showMenu"} - %label Options - .subtitle {{ctrl.optionsSubtitle()}} - - .sectioned-menu.dropdown-menu{"ng-if" => "ctrl.showMenu"} + .padded + .section-title-bar-header + .title {{ctrl.panelTitle()}} + .add-button#notes-add-button{"ng-click" => "ctrl.createNewNote()"} + + .filter-section + %input.filter-bar#search-bar.mousetrap{"select-on-click" => "true", "ng-model" => "ctrl.noteFilter.text", "placeholder" => "Search", "ng-change" => "ctrl.filterTextChanged()", "lowercase" => "true"} + #search-clear-button{"ng-if" => "ctrl.noteFilter.text", "ng-click" => "ctrl.noteFilter.text = ''; ctrl.filterTextChanged()"} ✕ + %ul.section-menu-bar#notes-menu-bar.no-h-padding + %li.item-with-subtitle.full-width{"ng-class" => "{'selected' : ctrl.showMenu}"} + .wrapper{"ng-click" => "ctrl.showMenu = !ctrl.showMenu"} + %label + Options + %span.subtitle {{ctrl.optionsSubtitle()}} + .sectioned-menu.dropdown-menu.full-width{"ng-if" => "ctrl.showMenu"} %ul .header - .title Sort by + .title Sort By %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.selectedSortByCreated()"} %label %span.top.mt-5.mr-5{"ng-if" => "ctrl.sortBy == 'created_at'"} ✓ - By date added + By Date Added %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.selectedSortByUpdated()"} %label %span.top.mt-5.mr-5{"ng-if" => "ctrl.sortBy == 'updated_at'"} ✓ - By date modified + By Date Modified %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.selectedSortByTitle()"} %label %span.top.mt-5.mr-5{"ng-if" => "ctrl.sortBy == 'title'"} ✓ - By title + By Title %ul{"ng-if" => "!ctrl.tag.archiveTag"} .header - .title Archives - %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.toggleShowArchived()"} + .title Display + %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.toggleKey('showArchived')"} %label %span.top.mt-5.mr-5{"ng-if" => "ctrl.showArchived == true"} ✓ - Show archived notes + Show Archived Notes + %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.toggleKey('hidePinned')"} + %label + %span.top.mt-5.mr-5{"ng-if" => "ctrl.hidePinned == true"} ✓ + Hide Pinned Notes + %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.toggleKey('hideNotePreview')"} + %label + %span.top.mt-5.mr-5{"ng-if" => "ctrl.hideNotePreview == true"} ✓ + Hide Note Preview + %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.toggleKey('hideDate')"} + %label + %span.top.mt-5.mr-5{"ng-if" => "ctrl.hideDate == true"} ✓ + Hide Date + %li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.toggleKey('hideTags')"} + %label + %span.top.mt-5.mr-5{"ng-if" => "ctrl.hideTags == true"} ✓ + Hide Tags .scrollable .infinite-scroll#notes-scrollable{"infinite-scroll" => "ctrl.paginate()", "can-load" => "true", "threshold" => "200"} @@ -52,13 +69,15 @@ %i.icon.ion-ios-box %strong.medium Archived - .tags-string{"ng-if" => "ctrl.tag.all"} + .tags-string{"ng-if" => "ctrl.tag.all && !ctrl.hideTags"} .faded {{note.tagsString()}} .name{"ng-if" => "note.title"} {{note.title}} - .note-preview + .note-preview{"ng-if" => "!ctrl.hideNotePreview"} {{note.text}} - .date.faded + .date.faded{"ng-if" => "!ctrl.hideDate"} %span{"ng-if" => "ctrl.sortBy == 'updated_at'"} Modified {{note.updatedAtString() || 'Now'}} %span{"ng-if" => "ctrl.sortBy != 'updated_at'"} {{note.createdAtString() || 'Now'}} + + %panel-resizer{"panel-id" => "'notes-column'", "on-resize-finish" => "ctrl.onPanelResize", "control" => "ctrl.panelController", "hoverable" => "true", "collapsable" => "true"} diff --git a/app/assets/templates/frontend/tags.html.haml b/app/assets/templates/frontend/tags.html.haml index 5a5a4a807..d9cea08ee 100644 --- a/app/assets/templates/frontend/tags.html.haml +++ b/app/assets/templates/frontend/tags.html.haml @@ -2,8 +2,9 @@ %iframe#tags-list-iframe{"ng-if" => "ctrl.component && ctrl.component.active", "ng-src" => "{{ctrl.componentManager.urlForComponent(ctrl.component) | trusted}}", "frameBorder" => "0", "style" => "width: 100%; height: 100%;", "sandbox" => "allow-scripts"} #tags-content.content{"ng-if" => "!(ctrl.component && ctrl.component.active)"} #tags-title-bar.section-title-bar - .title Tags - .add-button#tag-add-button{"ng-click" => "ctrl.clickedAddNewTag()"} + + .section-title-bar-header + .title Tags + .add-button#tag-add-button{"ng-click" => "ctrl.createNewTag()"} + .scrollable .tag{"ng-if" => "ctrl.allTag", "ng-click" => "ctrl.selectTag(ctrl.allTag)", "ng-class" => "{'selected' : ctrl.selectedTag == ctrl.allTag}"} @@ -27,3 +28,5 @@ .tag.faded{"ng-if" => "ctrl.archiveTag", "ng-click" => "ctrl.selectTag(ctrl.archiveTag)", "ng-class" => "{'selected' : ctrl.selectedTag == ctrl.archiveTag}"} .info %input.title{"ng-disabled" => "true", "ng-model" => "ctrl.archiveTag.title"} + + %panel-resizer{"panel-id" => "'tags-column'", "on-resize-finish" => "ctrl.onPanelResize", "control" => "ctrl.panelController", "hoverable" => "true", "collapsable" => "true"}