From b88a8d241619003537f64014a354cb523d6cc297 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 24 Jul 2014 14:59:53 -0400 Subject: [PATCH] FIX: Clicking navigation pills a second time should refresh the list you're looking at. --- .../initializers/inject-app-events.js.es6 | 6 ++- app/assets/javascripts/discourse/lib/url.js | 13 ++---- .../discourse/mixins/url-refresh.js.es6 | 19 ++++++++ .../views/discovery-categories.js.es6 | 4 +- .../discourse/views/discovery-top.js.es6 | 4 +- .../discourse/views/discovery-topics.js.es6 | 11 +---- .../discourse/views/poster-expansion.js.es6 | 46 ++++++++++--------- 7 files changed, 60 insertions(+), 43 deletions(-) create mode 100644 app/assets/javascripts/discourse/mixins/url-refresh.js.es6 diff --git a/app/assets/javascripts/discourse/initializers/inject-app-events.js.es6 b/app/assets/javascripts/discourse/initializers/inject-app-events.js.es6 index 6a11fd729d6..ea701a6771d 100644 --- a/app/assets/javascripts/discourse/initializers/inject-app-events.js.es6 +++ b/app/assets/javascripts/discourse/initializers/inject-app-events.js.es6 @@ -1,13 +1,15 @@ export default { name: "inject-app-events", initialize: function(container, application) { - var AppEvents = Ember.Object.extend(Ember.Evented); - application.register('app-events:main', AppEvents, { singleton: true }); + var appEvents = Ember.Object.createWithMixins(Ember.Evented); + application.register('app-events:main', appEvents, { instantiate: false }); application.inject('controller', 'appEvents', 'app-events:main'); application.inject('component', 'appEvents', 'app-events:main'); application.inject('route', 'appEvents', 'app-events:main'); application.inject('view', 'appEvents', 'app-events:main'); application.inject('model', 'appEvents', 'app-events:main'); + + Discourse.URL.appEvents = appEvents; } }; diff --git a/app/assets/javascripts/discourse/lib/url.js b/app/assets/javascripts/discourse/lib/url.js index 6805ddb259c..d9062be681a 100644 --- a/app/assets/javascripts/discourse/lib/url.js +++ b/app/assets/javascripts/discourse/lib/url.js @@ -145,8 +145,10 @@ Discourse.URL = Em.Object.createWithMixins({ // TODO: Extract into rules we can inject into the URL handler if (this.navigatedToHome(oldPath, path)) { return; } - if (path.match(/^\/?users\/[^\/]+$/)) { - path += "/activity"; + if (oldPath === path) { + // If navigating to the same path send an app event. Views can watch it + // and tell their controllers to refresh + this.appEvents.trigger('url:refresh'); } return this.handleURL(path); @@ -244,12 +246,7 @@ Discourse.URL = Em.Object.createWithMixins({ var homepage = Discourse.Utilities.defaultHomepage(); if (window.history && window.history.pushState && path === "/" && (oldPath === "/" || oldPath === "/" + homepage)) { - // refresh the list - switch (homepage) { - case "top" : { this.controllerFor('discovery/top').send('refresh'); break; } - case "categories": { this.controllerFor('discovery/categories').send('refresh'); break; } - default: { this.controllerFor('discovery/topics').send('refresh'); break; } - } + this.appEvents.trigger('url:refresh'); return true; } diff --git a/app/assets/javascripts/discourse/mixins/url-refresh.js.es6 b/app/assets/javascripts/discourse/mixins/url-refresh.js.es6 new file mode 100644 index 00000000000..389f60c76da --- /dev/null +++ b/app/assets/javascripts/discourse/mixins/url-refresh.js.es6 @@ -0,0 +1,19 @@ +// A Mixin that a view can use to listen for 'url:refresh' when +// it is on screen, and will send an action to the controller to +// refresh its data. +// +// This is useful if you want to get around Ember's default +// behavior of not refreshing when navigating to the same place. +export default Em.Mixin.create({ + _initURLRefresh: function() { + this.appEvents.on('url:refresh', this, '_urlRefresh'); + }.on('didInsertElement'), + + _tearDownURLRefresh: function() { + this.appEvents.off('url:refresh', this, '_urlRefresh'); + }.on('willDestroyElement'), + + _urlRefresh: function() { + this.get('controller').send('refresh'); + } +}); diff --git a/app/assets/javascripts/discourse/views/discovery-categories.js.es6 b/app/assets/javascripts/discourse/views/discovery-categories.js.es6 index 688c999ca69..8ec083e5399 100644 --- a/app/assets/javascripts/discourse/views/discovery-categories.js.es6 +++ b/app/assets/javascripts/discourse/views/discovery-categories.js.es6 @@ -1,4 +1,6 @@ -export default Discourse.View.extend({ +import UrlRefresh from 'discourse/mixins/url-refresh'; + +export default Discourse.View.extend(UrlRefresh, { orderingChanged: function(){ if (this.get("controller.ordering")) { diff --git a/app/assets/javascripts/discourse/views/discovery-top.js.es6 b/app/assets/javascripts/discourse/views/discovery-top.js.es6 index 95433a05722..a50fbcd77df 100644 --- a/app/assets/javascripts/discourse/views/discovery-top.js.es6 +++ b/app/assets/javascripts/discourse/views/discovery-top.js.es6 @@ -1 +1,3 @@ -export default Discourse.View.extend(Discourse.ScrollTop); +import UrlRefresh from 'discourse/mixins/url-refresh'; + +export default Discourse.View.extend(Discourse.ScrollTop, UrlRefresh); diff --git a/app/assets/javascripts/discourse/views/discovery-topics.js.es6 b/app/assets/javascripts/discourse/views/discovery-topics.js.es6 index ccb7ae91532..2885f09e00a 100644 --- a/app/assets/javascripts/discourse/views/discovery-topics.js.es6 +++ b/app/assets/javascripts/discourse/views/discovery-topics.js.es6 @@ -1,13 +1,6 @@ -/** - This view handles rendering of a list of topics under discovery, with support - for loading more as well as remembering your scroll position. +import UrlRefresh from 'discourse/mixins/url-refresh'; - @class DiscoveryTopicsView - @extends Discourse.View - @namespace Discourse - @module Discourse -**/ -export default Discourse.View.extend(Discourse.LoadMore, { +export default Discourse.View.extend(Discourse.LoadMore, UrlRefresh, { eyelineSelector: '.topic-list-item', actions: { diff --git a/app/assets/javascripts/discourse/views/poster-expansion.js.es6 b/app/assets/javascripts/discourse/views/poster-expansion.js.es6 index 6bb871ae748..89c10476950 100644 --- a/app/assets/javascripts/discourse/views/poster-expansion.js.es6 +++ b/app/assets/javascripts/discourse/views/poster-expansion.js.es6 @@ -5,27 +5,8 @@ export default Discourse.View.extend({ classNameBindings: ['controller.visible::hidden', 'controller.showBadges'], _setup: function() { - var self = this, - width = this.$().width(); - - this.appEvents.on('poster:expand', function(target) { - if (!target) { return; } - Em.run.schedule('afterRender', function() { - if (target) { - var position = target.offset(); - if (position) { - position.left += target.width() + 10; - - var overage = ($(window).width() - 50) - (position.left + width); - if (overage < 0) { - position.left += overage; - position.top += target.height() + 5; - } - self.$().css(position); - } - } - }); - }); + var self = this; + this.appEvents.on('poster:expand', this, '_posterExpand'); $('html').off(clickOutsideEventName).on(clickOutsideEventName, function(e) { if (self.get('controller.visible')) { @@ -40,9 +21,30 @@ export default Discourse.View.extend({ }); }.on('didInsertElement'), + _posterExpand: function(target) { + if (!target) { return; } + var self = this, + width = this.$().width(); + Em.run.schedule('afterRender', function() { + if (target) { + var position = target.offset(); + if (position) { + position.left += target.width() + 10; + + var overage = ($(window).width() - 50) - (position.left + width); + if (overage < 0) { + position.left += overage; + position.top += target.height() + 5; + } + self.$().css(position); + } + } + }); + }, + _removeEvents: function() { $('html').off(clickOutsideEventName); - this.appEvents.off('poster:expand'); + this.appEvents.off('poster:expand', this, '_posterExpand'); }.on('willDestroyElement') });