summaryrefslogtreecommitdiffstats
path: root/client/components
diff options
context:
space:
mode:
authorMaxime Quandalle <maxime@quandalle.com>2015-05-26 20:30:01 +0200
committerMaxime Quandalle <maxime@quandalle.com>2015-05-26 20:34:56 +0200
commit40c2411f2a1ce0bbd177f377828f9d6700112b06 (patch)
treebf1f7ab8d94fe3e0edfcde817961d6954c11af4d /client/components
parent1b4fcc67f4ec94ed53a2f86ad6889e551f00815e (diff)
downloadwekan-40c2411f2a1ce0bbd177f377828f9d6700112b06.tar.gz
wekan-40c2411f2a1ce0bbd177f377828f9d6700112b06.tar.bz2
wekan-40c2411f2a1ce0bbd177f377828f9d6700112b06.zip
Implement a new system to handle "escape actions"
The new EscapeActions object decide what to do when the user press the Escape key (such as closing a opened popup or inlined form). This commit also re-introduced the sidebar current view as a sidebar component local state.
Diffstat (limited to 'client/components')
-rw-r--r--client/components/boards/router.js8
-rw-r--r--client/components/cards/details.jade3
-rw-r--r--client/components/forms/inlinedform.js22
-rw-r--r--client/components/main/editor.js (renamed from client/components/main/rendered.js)32
-rw-r--r--client/components/main/events.js8
-rw-r--r--client/components/main/templates.html2
-rw-r--r--client/components/sidebar/sidebar.jade6
-rw-r--r--client/components/sidebar/sidebar.js29
8 files changed, 84 insertions, 26 deletions
diff --git a/client/components/boards/router.js b/client/components/boards/router.js
index 9c5bee35..80fadd9e 100644
--- a/client/components/boards/router.js
+++ b/client/components/boards/router.js
@@ -39,7 +39,7 @@ Router.route('/boards/:boardId/:slug/:cardId', {
template: 'board',
onAfterAction: function() {
Tracker.nonreactive(function() {
- if (! Session.get('currentCard') && typeof Sidebar !== 'undefined') {
+ if (! Session.get('currentCard') && Sidebar) {
Sidebar.hide();
}
});
@@ -55,3 +55,9 @@ Router.route('/boards/:boardId/:slug/:cardId', {
return Boards.findOne(this.params.boardId);
}
});
+
+// Close the card details pane by pressing escape
+EscapeActions.register(50,
+ function() { return ! Session.equals('currentCard', null); },
+ function() { Utils.goBoardId(Session.get('currentBoard')); }
+);
diff --git a/client/components/cards/details.jade b/client/components/cards/details.jade
index 55cc4b9e..b77c3961 100644
--- a/client/components/cards/details.jade
+++ b/client/components/cards/details.jade
@@ -26,7 +26,8 @@ template(name="cardDetails")
h3 Description
+inlinedForm(classNames="js-card-description")
i.fa.fa-times.js-close-inlined-form
- textarea(autofocus)= description
+ +editor(autofocus=true)
+ = description
button(type="submit") {{_ 'edit'}}
else
.js-open-inlined-form
diff --git a/client/components/forms/inlinedform.js b/client/components/forms/inlinedform.js
index 2e2b2eba..200a6f9d 100644
--- a/client/components/forms/inlinedform.js
+++ b/client/components/forms/inlinedform.js
@@ -15,7 +15,9 @@
// We can only have one inlined form element opened at a time
// XXX Could we avoid using a global here ? This is used in Mousetrap
// keyboard.js
-currentlyOpenedForm = new ReactiveVar(null);
+var currentlyOpenedForm = new ReactiveVar(null);
+
+var inlinedFormEscapePriority = 30;
BlazeComponent.extendComponent({
template: function() {
@@ -32,9 +34,10 @@ BlazeComponent.extendComponent({
open: function() {
// Close currently opened form, if any
- if (currentlyOpenedForm.get() !== null) {
- currentlyOpenedForm.get().close();
- }
+ // if (currentlyOpenedForm.get() !== null) {
+ // currentlyOpenedForm.get().close();
+ // }
+ EscapeActions.executeLowerThan(inlinedFormEscapePriority);
this.isOpen.set(true);
currentlyOpenedForm.set(this);
},
@@ -46,7 +49,8 @@ BlazeComponent.extendComponent({
},
getValue: function() {
- return this.isOpen.get() && this.find('textarea,input[type=text]').value;
+ var input = this.find('textarea,input[type=text]');
+ return this.isOpen.get() && input && input.value;
},
saveValue: function() {
@@ -66,7 +70,7 @@ BlazeComponent.extendComponent({
'keydown form input, keydown form textarea': function(evt) {
if (evt.keyCode === 27) {
evt.preventDefault();
- this.close();
+ EscapeActions.executeLowest();
}
},
@@ -91,3 +95,9 @@ BlazeComponent.extendComponent({
}];
}
}).register('inlinedForm');
+
+// Press escape to close the currently opened inlinedForm
+EscapeActions.register(inlinedFormEscapePriority,
+ function() { return currentlyOpenedForm.get() !== null; },
+ function() { currentlyOpenedForm.get().close(); }
+);
diff --git a/client/components/main/rendered.js b/client/components/main/editor.js
index 787e8225..95a8dc5d 100644
--- a/client/components/main/rendered.js
+++ b/client/components/main/editor.js
@@ -1,5 +1,9 @@
-Template.editor.rendered = function() {
- this.$('textarea').textcomplete([
+var dropdownMenuIsOpened = false;
+
+Template.editor.onRendered(function() {
+ var $textarea = this.$('textarea');
+
+ $textarea.textcomplete([
// Emojies
{
match: /\B:([\-+\w]*)$/,
@@ -37,4 +41,26 @@ Template.editor.rendered = function() {
index: 1
}
]);
-};
+
+ // Since commit d474017 jquery-textComplete automatically closes a potential
+ // opened dropdown menu when the user press Escape. This behavior conflicts
+ // with our EscapeActions system, but it's too complicated and hacky to
+ // monkey-pach textComplete to disable it -- I tried. Instead we listen to
+ // 'open' and 'hide' events, and create a ghost escapeAction when the dropdown
+ // is opened (and rely on textComplete to execute the actual action).
+ $textarea.on({
+ 'textComplete:show': function() {
+ dropdownMenuIsOpened = true;
+ },
+ 'textComplete:hide': function() {
+ Tracker.afterFlush(function() {
+ dropdownMenuIsOpened = false;
+ });
+ }
+ });
+});
+
+EscapeActions.register(10,
+ function() { return dropdownMenuIsOpened; },
+ function() {}
+);
diff --git a/client/components/main/events.js b/client/components/main/events.js
deleted file mode 100644
index beb90c5e..00000000
--- a/client/components/main/events.js
+++ /dev/null
@@ -1,8 +0,0 @@
-Template.editor.events({
- // Pressing Ctrl+Enter should submit the form.
- 'keydown textarea': function(event) {
- if (event.keyCode === 13 && (event.metaKey || event.ctrlKey)) {
- $(event.currentTarget).parents('form:first').submit();
- }
- }
-});
diff --git a/client/components/main/templates.html b/client/components/main/templates.html
index e9be0f93..4828663a 100644
--- a/client/components/main/templates.html
+++ b/client/components/main/templates.html
@@ -12,7 +12,7 @@
</template>
<template name="editor">
- <textarea class="{{class}}" placeholder="{{_ 'comment-placeholder'}}" id="{{id}}" tabindex="1">{{> UI.contentBlock }}</textarea>
+ <textarea class="{{class}}" placeholder="{{_ 'comment-placeholder'}}" id="{{id}}" autofocus="{{autofocus}}">{{> UI.contentBlock}}</textarea>
</template>
<template name="viewer">{{#markdown}}{{#emoji}}{{#mentions}}{{> UI.contentBlock }}{{/mentions}}{{/emoji}}{{/markdown}}</template>
diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade
index 07cd777c..07d6bbcf 100644
--- a/client/components/sidebar/sidebar.jade
+++ b/client/components/sidebar/sidebar.jade
@@ -4,11 +4,7 @@ template(name="sidebar")
class="{{#if isTongueHidden}}is-hidden{{/if}}")
i.fa.fa-chevron-left
.sidebar-content.js-board-sidebar-content.js-perfect-scrollbar
- //- XXX https://github.com/peerlibrary/meteor-blaze-components/issues/30
- if Filter.isActive
- +filterSidebar
- else
- +homeSidebar
+ +Template.dynamic(template=getViewTemplate)
template(name='homeSidebar')
+membersWidget
diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js
index 6e45b5cf..729bc42b 100644
--- a/client/components/sidebar/sidebar.js
+++ b/client/components/sidebar/sidebar.js
@@ -1,3 +1,7 @@
+var defaultView = 'home';
+
+Sidebar = null;
+
BlazeComponent.extendComponent({
template: function() {
return 'sidebar';
@@ -9,9 +13,14 @@ BlazeComponent.extendComponent({
onCreated: function() {
this._isOpen = new ReactiveVar(! Session.get('currentCard'));
+ this._view = new ReactiveVar(defaultView);
Sidebar = this;
},
+ onDestroyed: function() {
+ Sidebar = null;
+ },
+
isOpen: function() {
return this._isOpen.get();
},
@@ -43,7 +52,20 @@ BlazeComponent.extendComponent({
},
isTongueHidden: function() {
- return this.isOpen() && Filter.isActive();
+ return this.isOpen() && this.getView() !== defaultView;
+ },
+
+ getView: function() {
+ return this._view.get();
+ },
+
+ setView: function(view) {
+ view = view || defaultView;
+ this._view.set(view);
+ },
+
+ getViewTemplate: function() {
+ return this.getView() + 'Sidebar';
},
onRendered: function() {
@@ -74,3 +96,8 @@ BlazeComponent.extendComponent({
}]);
}
}).register('sidebar');
+
+EscapeActions.register(40,
+ function() { return Sidebar && Sidebar.getView() !== defaultView; },
+ function() { Sidebar.setView(defaultView); }
+);