diff --git a/ember/app/components/back-button.js b/ember/app/components/back-button.js index e36306575..4be9abef0 100755 --- a/ember/app/components/back-button.js +++ b/ember/app/components/back-button.js @@ -3,7 +3,8 @@ import Ember from 'ember'; export default Ember.Component.extend({ classNames: ['back-button'], classNameBindings: ['active'], - active: Ember.computed.or('target.paneShowing', 'target.panePinned'), + + active: Ember.computed.or('target.paneIsShowing', 'target.paneIsPinned'), mouseEnter: function() { this.get('target').send('showPane'); @@ -18,9 +19,9 @@ export default Ember.Component.extend({ this.get('target').send('transitionFromBackButton'); this.set('target', null); }, + togglePinned: function() { this.get('target').send('togglePinned'); } } - }); diff --git a/ember/app/controllers/index.js b/ember/app/controllers/index.js deleted file mode 100644 index 23c4e618b..000000000 --- a/ember/app/controllers/index.js +++ /dev/null @@ -1,142 +0,0 @@ -import Ember from 'ember'; - -import DiscussionResult from '../models/discussion-result'; -import PostResult from '../models/post-result'; -import PaneableMixin from '../mixins/paneable'; - -export default Ember.ArrayController.extend(Ember.Evented, PaneableMixin, { - - needs: ['application', 'composer'], - - count: function() { - return this.get('model.length'); - }.property('model.@each'), - - queryParams: ['sort', 'show', {searchQuery: 'q'}, 'filter'], - sort: 'recent', - show: 'discussions', - filter: '', - - searchQuery: '', - - sortOptions: [ - {sort: 'recent', label: 'Recent'}, - {sort: 'replies', label: 'Replies'}, - {sort: 'newest', label: 'Newest'}, - {sort: 'oldest', label: 'Oldest'}, - ], - - terminalPostType: function() { - return ['newest', 'oldest'].indexOf(this.get('sort')) !== -1 ? 'start' : 'last'; - }.property('sort'), - - countType: function() { - return this.get('sort') === 'replies' ? 'replies' : 'unread'; - }.property('sort'), - - discussionsCount: function() { - return this.get('model.length'); - }.property('@each'), - - resultsLoading: false, - - start: 0, - - moreResults: function() { - return !! this.get('meta.moreUrl'); - }.property('meta.moreUrl'), - - meta: null, - - getResults: function(start) { - var sort = this.get('sort'); - // var order = this.get('order'); - var order; - var show = this.get('show'); - var searchQuery = this.get('searchQuery'); - - if (sort === 'newest') { - sort = 'created'; - order = 'desc'; - } else if (sort === 'oldest') { - sort = 'created'; - } - else if (sort === 'recent') { - sort = ''; - } - else if (sort === 'replies') { - order = 'desc'; - } - - var params = { - sort: (order === 'desc' ? '-' : '')+sort, - q: searchQuery, - start: start - }; - - if (show === 'posts') { - if (searchQuery) { - params.include = 'relevantPosts'; - } else if (sort === 'created') { - params.include = 'startPost,startUser'; - } else { - params.include = 'lastPost,lastUser'; - } - } - - return this.store.find('discussion', params).then(function(discussions) { - var results = Ember.A(); - discussions.forEach(function(discussion) { - var relevantPosts = Ember.A(); - // discussion.get('relevantPosts.content').forEach(function(post) { - // relevantPosts.pushObject(PostResult.create(post)); - // }); - results.pushObject(DiscussionResult.create({ - content: discussion, - relevantPosts: relevantPosts, - lastPost: PostResult.create(discussion.get('lastPost')), - startPost: PostResult.create(discussion.get('startPost')) - })); - results.set('meta', discussions.get('meta')); - }); - return results; - }); - }, - - actions: { - loadMore: function() { - var self = this; - this.set('start', this.get('length')); - this.set('resultsLoading', true); - - this.getResults(this.get('start')).then(function(results) { - self.get('model').addObjects(results); - self.set('meta', results.get('meta')); - self.set('resultsLoading', false); - }); - }, - - transitionFromBackButton: function() { - this.transitionToRoute('index'); - } - }, - - searchQueryDidChange: function() { - this.get('controllers.application').set('searchQuery', this.get('searchQuery')); - this.get('controllers.application').set('searchActive', !! this.get('searchQuery')); - - var sortOptions = this.get('sortOptions'); - - if (this.get('searchQuery') && sortOptions[0].sort !== 'relevance') { - sortOptions.unshiftObject({sort: 'relevance', label: 'Relevance'}); - } - else if ( ! this.get('searchQuery') && sortOptions[0].sort === 'relevance') { - sortOptions.shiftObject(); - } - }.observes('searchQuery'), - - paramsDidChange: function() { - this.set('start', 0); - }.observes('show', 'sort', 'searchQuery') - -}); diff --git a/ember/app/controllers/index/index.js b/ember/app/controllers/index/index.js index e2128002e..5f9a88ef5 100644 --- a/ember/app/controllers/index/index.js +++ b/ember/app/controllers/index/index.js @@ -1,5 +1,108 @@ import Ember from 'ember'; -export default Ember.ArrayController.extend({ - needs: ['application'] +import DiscussionResult from '../../models/discussion-result'; +import PostResult from '../../models/post-result'; + +export default Ember.Controller.extend({ + needs: ['application'], + + queryParams: ['sort', 'show', {searchQuery: 'q'}, 'filter'], + sort: 'recent', + show: 'discussions', + filter: '', + searchQuery: '', + + meta: null, + resultsLoading: false, + + sortOptions: [ + {key: 'recent', label: 'Recent', sort: 'recent'}, + {key: 'replies', label: 'Replies', sort: '-replies'}, + {key: 'newest', label: 'Newest', sort: '-created'}, + {key: 'oldest', label: 'Oldest', sort: 'created'}, + ], + + terminalPostType: function() { + return ['newest', 'oldest'].indexOf(this.get('sort')) !== -1 ? 'start' : 'last'; + }.property('sort'), + + countType: function() { + return this.get('sort') === 'replies' ? 'replies' : 'unread'; + }.property('sort'), + + moreResults: function() { + return !!this.get('meta.moreUrl'); + }.property('meta.moreUrl'), + + getResults: function(start) { + var searchQuery = this.get('searchQuery'); + var sort = this.get('sort'); + var sortOptions = this.get('sortOptions'); + var sortOption = sortOptions.findBy('key', sort) || sortOptions.objectAt(0); + + var params = { + sort: sortOption.sort, + q: searchQuery, + start: start + }; + + if (this.get('show') === 'posts') { + if (searchQuery) { + params.include = 'relevantPosts'; + } else if (sort === 'created') { + params.include = 'startPost,startUser'; + } else { + params.include = 'lastPost,lastUser'; + } + } + + return this.store.find('discussion', params).then(function(discussions) { + var results = Ember.A(); + discussions.forEach(function(discussion) { + var relevantPosts = Ember.A(); + // discussion.get('relevantPosts.content').forEach(function(post) { + // relevantPosts.pushObject(PostResult.create(post)); + // }); + results.pushObject(DiscussionResult.create({ + content: discussion, + relevantPosts: relevantPosts, + lastPost: PostResult.create(discussion.get('lastPost')), + startPost: PostResult.create(discussion.get('startPost')) + })); + results.set('meta', discussions.get('meta')); + }); + return results; + }); + }, + + searchQueryDidChange: function() { + this.get('controllers.application').set('searchQuery', this.get('searchQuery')); + this.get('controllers.application').set('searchActive', !! this.get('searchQuery')); + + var sortOptions = this.get('sortOptions'); + + if (this.get('searchQuery') && sortOptions[0].sort !== 'relevance') { + sortOptions.unshiftObject({key: 'relevance', label: 'Relevance', sort: 'relevance'}); + } else if (!this.get('searchQuery') && sortOptions[0].sort === 'relevance') { + sortOptions.shiftObject(); + } + }.observes('searchQuery'), + + paramsDidChange: function() { + if (this.get('model')) { + this.send('refresh'); + } + }.observes('sort', 'show', 'searchQuery'), + + actions: { + loadMore: function() { + var controller = this; + this.set('resultsLoading', true); + this.getResults(this.get('model.length')).then(function(results) { + controller.get('model').addObjects(results); + controller.set('meta', results.get('meta')); + controller.set('resultsLoading', false); + }); + } + } }); diff --git a/ember/app/mixins/paneable.js b/ember/app/mixins/paneable.js index 8d1dc076d..fa24f6169 100644 --- a/ember/app/mixins/paneable.js +++ b/ember/app/mixins/paneable.js @@ -17,7 +17,25 @@ export default Ember.Mixin.create({ // Whether or not the pane is always visible on screen, even when the // mouse is taken away. - panePinned: false, + panePinned: localStorage.getItem('panePinned'), + + // Disable the paneable behaviour completely, regardless of if it is + // paned, showing, or pinned. + paneDisabled: false, + + paneIsShowing: function() { + return this.get('paned') && this.get('paneShowing') && !this.get('paneDisabled'); + }.property('paned', 'paneShowing', 'paneDisabled'), + + paneIsPinned: function() { + return this.get('paned') && this.get('panePinned') && !this.get('paneDisabled'); + }.property('paned', 'panePinned', 'paneDisabled'), + + // Tell the application controller when we pin/unpin the pane so that + // other parts of the interface can respond appropriately. + paneIsPinnedChanged: function() { + this.set('controllers.application.panePinned', this.get('paneIsPinned')); + }.observes('paneIsPinned'), actions: { showPane: function() { @@ -35,13 +53,7 @@ export default Ember.Mixin.create({ }, togglePinned: function() { - this.toggleProperty('panePinned'); + localStorage.setItem('panePinned', this.toggleProperty('panePinned') || ''); } - }, - - // Tell the application controller when we pin/unpin the pane so that - // other parts of the interface can respond appropriately. - panePinnedChanged: function() { - this.set('controllers.application.panePinned', this.get('paned') && this.get('panePinned')); - }.observes('paned', 'panePinned') -}); \ No newline at end of file + } +}); diff --git a/ember/app/routes/index.js b/ember/app/routes/index.js deleted file mode 100644 index 0235bec30..000000000 --- a/ember/app/routes/index.js +++ /dev/null @@ -1,35 +0,0 @@ -import Ember from 'ember'; - -export default Ember.Route.extend({ - - setupController: function(controller, model) { - controller.set('model', model); - - if ( ! model.get('length')) { - controller.set('resultsLoading', true); - - controller.getResults().then(function(results) { - controller - .set('resultsLoading', false) - .set('meta', results.get('meta')) - .set('model.content', results); - }); - } - }, - - model: function() { - var model = Ember.ArrayProxy.create(); - - return Ember.RSVP.resolve(model); - }, - - actions: { - queryParamsDidChange: function() { - var self = this; - Ember.run.scheduleOnce('afterRender', function() { - self.refresh(); - }); - } - } - -}); diff --git a/ember/app/routes/index/index.js b/ember/app/routes/index/index.js deleted file mode 100644 index 2e236f42c..000000000 --- a/ember/app/routes/index/index.js +++ /dev/null @@ -1,21 +0,0 @@ -import Ember from 'ember'; - -import AddCssClassToBodyMixin from '../../mixins/add-css-class-to-body'; - -export default Ember.Route.extend(AddCssClassToBodyMixin, { - - // When we enter the discussions list view, we no longer want the - // discussions list to be in pane mode. - setupController: function(controller, model) { - this.controllerFor('index').set('paned', false); - this.controllerFor('index').set('paneShowing', false); - this._super(controller, model); - }, - - actions: { - didTransition: function() { - // @todo only if it's not a new discussion - this.controllerFor('composer').send('minimize'); - } - } -}); diff --git a/ember/app/styles/flarum/index.less b/ember/app/styles/flarum/index.less index d4a36822b..61c2662fe 100644 --- a/ember/app/styles/flarum/index.less +++ b/ember/app/styles/flarum/index.less @@ -143,8 +143,6 @@ // When the pane is pinned, move the other page content inwards .global-main, .global-footer { - .transition(margin-left 0.2s); - .with-pane & { margin-left: @index-pane-width; & .container { @@ -154,8 +152,6 @@ } } .global-header .container { - .transition(width 0.2s); - .with-pane & { width: 100%; } diff --git a/ember/app/templates/application.hbs b/ember/app/templates/application.hbs index 42e35ff08..da3c32a6e 100644 --- a/ember/app/templates/application.hbs +++ b/ember/app/templates/application.hbs @@ -1,4 +1,4 @@ -