From c5460b7d3fb9afd65d3538f91a0a3943cb1aeb69 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Tue, 25 Aug 2015 12:50:19 -0400 Subject: [PATCH] FEATURE: Full height hamburger menu - Rename `site-map` to `hamburger-menu` - Includes acceptance tests --- .../components/hamburger-category.js.es6 | 13 ++++ .../components/hamburger-menu.js.es6 | 77 +++++++++++++++++++ .../discourse/controllers/application.js.es6 | 19 ++++- .../controllers/site-map-category.js.es6 | 10 --- .../discourse/controllers/site-map.js.es6 | 46 ----------- .../discourse/lib/keyboard-shortcuts.js.es6 | 7 +- .../sniff-capabilities.js.es6 | 1 + .../discourse/routes/application.js.es6 | 7 +- .../discourse/templates/application.hbs | 2 + .../components/hamburger-category.hbs | 9 +++ .../hamburger-menu.hbs} | 41 ++++------ .../discourse/templates/header.hbs | 28 +++---- .../modal/keyboard-shortcuts-help.hbs | 2 +- app/assets/javascripts/vendor.js | 1 + .../stylesheets/common/base/hamburger.scss | 64 +++++++++++++++ .../stylesheets/common/base/header.scss | 32 -------- config/locales/client.ar.yml | 4 +- config/locales/client.bs_BA.yml | 4 +- config/locales/client.cs.yml | 4 +- config/locales/client.da.yml | 4 +- config/locales/client.de.yml | 4 +- config/locales/client.en.yml | 4 +- config/locales/client.es.yml | 4 +- config/locales/client.fa_IR.yml | 4 +- config/locales/client.fi.yml | 4 +- config/locales/client.fr.yml | 4 +- config/locales/client.he.yml | 4 +- config/locales/client.it.yml | 4 +- config/locales/client.ja.yml | 4 +- config/locales/client.ko.yml | 4 +- config/locales/client.nb_NO.yml | 4 +- config/locales/client.nl.yml | 4 +- config/locales/client.pl_PL.yml | 4 +- config/locales/client.pt.yml | 4 +- config/locales/client.pt_BR.yml | 4 +- config/locales/client.ro.yml | 4 +- config/locales/client.ru.yml | 4 +- config/locales/client.sq.yml | 4 +- config/locales/client.sv.yml | 4 +- config/locales/client.te.yml | 4 +- config/locales/client.tr_TR.yml | 4 +- config/locales/client.uk.yml | 2 +- config/locales/client.zh_CN.yml | 4 +- config/locales/client.zh_TW.yml | 4 +- .../hamburger-menu-staff-test.js.es6 | 13 ++++ .../acceptance/hamburger-menu-test.js.es6 | 39 ++++++++++ .../acceptance/header-anonymous-test.js.es6 | 9 --- .../acceptance/header-test-staff.js.es6 | 7 -- .../acceptance/login-required-test.js.es6 | 2 +- .../components/keyboard-shortcuts-test.js.es6 | 2 +- .../controllers/site-map-category-test.js.es6 | 26 ------- .../controllers/site-map-test.js.es6 | 77 ------------------- ...e_fixtures.js.es6 => site-fixtures.js.es6} | 0 test/javascripts/helpers/qunit-helpers.js.es6 | 2 +- test/javascripts/helpers/site-settings.js | 1 + test/javascripts/test_helper.js | 2 +- .../assets/javascripts/jquery.detect_swipe.js | 72 +++++++++++++++++ 57 files changed, 399 insertions(+), 322 deletions(-) create mode 100644 app/assets/javascripts/discourse/components/hamburger-category.js.es6 create mode 100644 app/assets/javascripts/discourse/components/hamburger-menu.js.es6 delete mode 100644 app/assets/javascripts/discourse/controllers/site-map-category.js.es6 delete mode 100644 app/assets/javascripts/discourse/controllers/site-map.js.es6 create mode 100644 app/assets/javascripts/discourse/templates/components/hamburger-category.hbs rename app/assets/javascripts/discourse/templates/{site-map.hbs => components/hamburger-menu.hbs} (55%) create mode 100644 app/assets/stylesheets/common/base/hamburger.scss create mode 100644 test/javascripts/acceptance/hamburger-menu-staff-test.js.es6 create mode 100644 test/javascripts/acceptance/hamburger-menu-test.js.es6 delete mode 100644 test/javascripts/controllers/site-map-category-test.js.es6 delete mode 100644 test/javascripts/controllers/site-map-test.js.es6 rename test/javascripts/fixtures/{site_fixtures.js.es6 => site-fixtures.js.es6} (100%) create mode 100644 vendor/assets/javascripts/jquery.detect_swipe.js diff --git a/app/assets/javascripts/discourse/components/hamburger-category.js.es6 b/app/assets/javascripts/discourse/components/hamburger-category.js.es6 new file mode 100644 index 00000000000..63b08fd70ee --- /dev/null +++ b/app/assets/javascripts/discourse/components/hamburger-category.js.es6 @@ -0,0 +1,13 @@ +import computed from 'ember-addons/ember-computed-decorators'; + +export default Ember.Component.extend({ + tagName: 'li', + classNames: ['category-link'], + + @computed('category.unreadTopics', 'category.newTopics') + unreadTotal(unreadTopics, newTopics) { + return parseInt(unreadTopics, 10) + parseInt(newTopics, 10); + }, + + showTopicCount: Ember.computed.not('currentUser') +}); diff --git a/app/assets/javascripts/discourse/components/hamburger-menu.js.es6 b/app/assets/javascripts/discourse/components/hamburger-menu.js.es6 new file mode 100644 index 00000000000..b4b2a33ad7f --- /dev/null +++ b/app/assets/javascripts/discourse/components/hamburger-menu.js.es6 @@ -0,0 +1,77 @@ +import { default as computed, on } from 'ember-addons/ember-computed-decorators'; + +export default Ember.Component.extend({ + classNameBindings: ['visible::slideright'], + elementId: 'hamburger-menu', + + @computed() + showKeyboardShortcuts() { + return !Discourse.Mobile.mobileView && !this.capabilities.touch; + }, + + @computed() + showMobileToggle() { + return Discourse.Mobile.mobileView || (this.siteSettings.enable_mobile_theme && this.capabilities.touch); + }, + + @computed() + mobileViewLinkTextKey() { + return Discourse.Mobile.mobileView ? "desktop_view" : "mobile_view"; + }, + + @computed() + faqUrl() { + return this.siteSettings.faq_url ? this.siteSettings.faq_url : Discourse.getURL('/faq'); + }, + + @on('didInsertElement') + _bindEvents() { + this.$().on('click.discourse-hamburger', 'a', () => { + this.set('visible', false); + }); + + $('body').on('keydown.discourse-hambuger', (e) => { + if (e.which === 27) { + this.set('visible', false); + } + }); + + if (this.capabilities.touch) { + $('body').on('swipeleft.discourse-hamburger', () => this.set('visible', true)); + $('body').on('swiperight.discourse-hamburger', () => this.set('visible', false)); + } + }, + + @on('willDestroyElement') + _removeEvents() { + this.$().off('click.discourse-hamburger'); + $('body').off('keydown.discourse-hambuger'); + $('body').off('swipeleft.discourse-hamburger'); + $('body').off('swiperight.discourse-hamburger'); + }, + + @computed() + categories() { + const hideUncategorized = !this.siteSettings.allow_uncategorized_topics; + const showSubcatList = this.siteSettings.show_subcategory_list; + const isStaff = Discourse.User.currentProp('staff'); + + return Discourse.Category.list().reject((c) => { + if (showSubcatList && c.get('parent_category_id')) { return true; } + if (hideUncategorized && c.get('isUncategorizedCategory') && !isStaff) { return true; } + return false; + }); + }, + + actions: { + close() { + this.set('visible', false); + }, + keyboardShortcuts() { + this.sendAction('showKeyboardAction'); + }, + toggleMobileView() { + Discourse.Mobile.toggleMobileView(); + } + } +}); diff --git a/app/assets/javascripts/discourse/controllers/application.js.es6 b/app/assets/javascripts/discourse/controllers/application.js.es6 index 2f0b4cec5f3..472bba31520 100644 --- a/app/assets/javascripts/discourse/controllers/application.js.es6 +++ b/app/assets/javascripts/discourse/controllers/application.js.es6 @@ -1,16 +1,27 @@ +import computed from 'ember-addons/ember-computed-decorators'; + export default Ember.Controller.extend({ showTop: true, showFooter: false, styleCategory: null, + hamburgerVisible: false, - canSignUp: function() { + @computed + canSignUp() { return !Discourse.SiteSettings.invite_only && Discourse.SiteSettings.allow_new_registrations && !Discourse.SiteSettings.enable_sso; - }.property(), + }, - loginRequired: function() { + @computed + loginRequired() { return Discourse.SiteSettings.login_required && !Discourse.User.current(); - }.property() + }, + + actions: { + toggleHamburgerMenu() { + this.toggleProperty('hamburgerVisible'); + } + } }); diff --git a/app/assets/javascripts/discourse/controllers/site-map-category.js.es6 b/app/assets/javascripts/discourse/controllers/site-map-category.js.es6 deleted file mode 100644 index 0fcce87f972..00000000000 --- a/app/assets/javascripts/discourse/controllers/site-map-category.js.es6 +++ /dev/null @@ -1,10 +0,0 @@ -export default Ember.Controller.extend({ - needs: ['site-map'], - - unreadTotal: function() { - return parseInt(this.get('model.unreadTopics'), 10) + - parseInt(this.get('model.newTopics'), 10); - }.property('model.unreadTopics', 'model.newTopics'), - - showTopicCount: Em.computed.not('currentUser') -}); diff --git a/app/assets/javascripts/discourse/controllers/site-map.js.es6 b/app/assets/javascripts/discourse/controllers/site-map.js.es6 deleted file mode 100644 index 61192eb575d..00000000000 --- a/app/assets/javascripts/discourse/controllers/site-map.js.es6 +++ /dev/null @@ -1,46 +0,0 @@ -import { url } from 'discourse/lib/computed'; - -export default Ember.ArrayController.extend({ - needs: ['application', 'header'], - - showBadgesLink: function(){return Discourse.SiteSettings.enable_badges;}.property(), - showAdminLinks: Em.computed.alias('currentUser.staff'), - - faqUrl: function() { - return Discourse.SiteSettings.faq_url ? Discourse.SiteSettings.faq_url : Discourse.getURL('/faq'); - }.property(), - - badgesUrl: url('/badges'), - - showKeyboardShortcuts: function(){ - return !Discourse.Mobile.mobileView && !this.capabilities.touch; - }.property(), - - showMobileToggle: function(){ - return Discourse.Mobile.mobileView || (Discourse.SiteSettings.enable_mobile_theme && this.capabilities.touch); - }.property(), - - mobileViewLinkTextKey: function() { - return Discourse.Mobile.mobileView ? "desktop_view" : "mobile_view"; - }.property(), - - categories: function() { - var hideUncategorized = !this.siteSettings.allow_uncategorized_topics, - showSubcatList = this.siteSettings.show_subcategory_list, - isStaff = Discourse.User.currentProp('staff'); - return Discourse.Category.list().reject(function(c) { - if (showSubcatList && c.get('parent_category_id')) { return true; } - if (hideUncategorized && c.get('isUncategorizedCategory') && !isStaff) { return true; } - return false; - }); - }.property(), - - actions: { - keyboardShortcuts: function(){ - this.get('controllers.application').send('showKeyboardShortcutsHelp'); - }, - toggleMobileView: function() { - Discourse.Mobile.toggleMobileView(); - } - } -}); diff --git a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 index 2075a57ce69..d611ca53006 100644 --- a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 +++ b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 @@ -45,7 +45,7 @@ const PATH_BINDINGS = { 'k': 'selectUp', 'u': 'goBack', '/': 'showSearch', - '=': 'showSiteMap', // open site map menu + '=': 'toggleHamburgerMenu', 'p': 'showCurrentUser', // open current user menu 'ctrl+f': 'showBuiltinSearch', 'command+f': 'showBuiltinSearch', @@ -172,9 +172,8 @@ export default { return false; }, - showSiteMap() { - $('#site-map').click(); - $('#site-map-dropdown a:first').focus(); + toggleHamburgerMenu() { + this.container.lookup('controller:application').send('toggleHamburgerMenu'); }, showCurrentUser() { diff --git a/app/assets/javascripts/discourse/pre-initializers/sniff-capabilities.js.es6 b/app/assets/javascripts/discourse/pre-initializers/sniff-capabilities.js.es6 index 90a722de9a0..c6834980500 100644 --- a/app/assets/javascripts/discourse/pre-initializers/sniff-capabilities.js.es6 +++ b/app/assets/javascripts/discourse/pre-initializers/sniff-capabilities.js.es6 @@ -28,5 +28,6 @@ export default { application.register('capabilities:main', caps, { instantiate: false }); application.inject('view', 'capabilities', 'capabilities:main'); application.inject('controller', 'capabilities', 'capabilities:main'); + application.inject('component', 'capabilities', 'capabilities:main'); } }; diff --git a/app/assets/javascripts/discourse/routes/application.js.es6 b/app/assets/javascripts/discourse/routes/application.js.es6 index a923dd17975..a8ede91294e 100644 --- a/app/assets/javascripts/discourse/routes/application.js.es6 +++ b/app/assets/javascripts/discourse/routes/application.js.es6 @@ -13,7 +13,6 @@ function unlessReadOnly(method) { } const ApplicationRoute = Discourse.Route.extend(OpenComposer, { - siteTitle: setting('title'), actions: { @@ -134,12 +133,12 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, { }); }, - deleteSpammer: function (user) { + deleteSpammer(user) { this.send('closeModal'); user.deleteAsSpammer(function() { window.location.reload(); }); }, - checkEmail: function (user) { + checkEmail(user) { user.checkEmail(); }, @@ -150,7 +149,7 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, { this.render(w, {into: 'modal/topic-bulk-actions', outlet: 'bulkOutlet', controller: factory ? controllerName : 'topic-bulk-actions'}); }, - createNewTopicViaParams: function(title, body, category_id, category) { + createNewTopicViaParams(title, body, category_id, category) { this.openComposerWithParams(this.controllerFor('discovery/topics'), title, body, category_id, category); } }, diff --git a/app/assets/javascripts/discourse/templates/application.hbs b/app/assets/javascripts/discourse/templates/application.hbs index 9d92d2063f2..3a3eb195586 100644 --- a/app/assets/javascripts/discourse/templates/application.hbs +++ b/app/assets/javascripts/discourse/templates/application.hbs @@ -18,3 +18,5 @@ {{render "modal"}} {{render "topic-entrance"}} {{render "composer"}} + +{{hamburger-menu visible=hamburgerVisible showKeyboardAction="showKeyboardShortcutsHelp"}} diff --git a/app/assets/javascripts/discourse/templates/components/hamburger-category.hbs b/app/assets/javascripts/discourse/templates/components/hamburger-category.hbs new file mode 100644 index 00000000000..9204b3d42d9 --- /dev/null +++ b/app/assets/javascripts/discourse/templates/components/hamburger-category.hbs @@ -0,0 +1,9 @@ +{{category-link category allowUncategorized="true"}} + +{{#if unreadTotal}} + {{unreadTotal}} +{{/if}} + +{{#if showTopicCount}} + {{category.topic_count}} +{{/if}} diff --git a/app/assets/javascripts/discourse/templates/site-map.hbs b/app/assets/javascripts/discourse/templates/components/hamburger-menu.hbs similarity index 55% rename from app/assets/javascripts/discourse/templates/site-map.hbs rename to app/assets/javascripts/discourse/templates/components/hamburger-menu.hbs index 99af0489cbd..58e2b1150ed 100644 --- a/app/assets/javascripts/discourse/templates/site-map.hbs +++ b/app/assets/javascripts/discourse/templates/components/hamburger-menu.hbs @@ -1,16 +1,17 @@ -
+{{#if visible}} + {{fa-icon 'times'}}
+ +
+{{/if}} diff --git a/app/assets/javascripts/discourse/templates/header.hbs b/app/assets/javascripts/discourse/templates/header.hbs index 42b2323f6a6..a05d8930e2b 100644 --- a/app/assets/javascripts/discourse/templates/header.hbs +++ b/app/assets/javascripts/discourse/templates/header.hbs @@ -12,9 +12,9 @@ {{/unless}} {{#if view.renderDropdowns}} - {{plugin-outlet "header-before-dropdowns"}} - {{render "search"}} {{render "notifications" notifications}} - - {{#if view.renderSiteMap}} - {{render "site-map"}} - {{/if}} - {{render "user-dropdown"}} {{/if}} diff --git a/app/assets/javascripts/discourse/templates/modal/keyboard-shortcuts-help.hbs b/app/assets/javascripts/discourse/templates/modal/keyboard-shortcuts-help.hbs index 38167ba221e..f07392a4b2a 100644 --- a/app/assets/javascripts/discourse/templates/modal/keyboard-shortcuts-help.hbs +++ b/app/assets/javascripts/discourse/templates/modal/keyboard-shortcuts-help.hbs @@ -25,7 +25,7 @@