mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Merge pull request #6108 from mixonic/no-rerender-selectors
Unify mobile state in JS, drop resize
This commit is contained in:
commit
9437b8eeef
15 changed files with 96 additions and 121 deletions
|
@ -4,26 +4,6 @@ export default Ember.Component.extend({
|
|||
tagName: 'section',
|
||||
classNames: ['gh-view', 'content-view-container'],
|
||||
|
||||
previewIsHidden: false,
|
||||
|
||||
resizeService: Ember.inject.service(),
|
||||
|
||||
_resizeListener: null,
|
||||
|
||||
calculatePreviewIsHidden: function () {
|
||||
if (this.$('.content-preview').length) {
|
||||
this.set('previewIsHidden', !this.$('.content-preview').is(':visible'));
|
||||
}
|
||||
},
|
||||
|
||||
didInsertElement: function () {
|
||||
this._super(...arguments);
|
||||
this._resizeListener = Ember.run.bind(this, this.calculatePreviewIsHidden);
|
||||
this.get('resizeService').on('debouncedDidResize', this._resizeListener);
|
||||
this.calculatePreviewIsHidden();
|
||||
},
|
||||
|
||||
willDestroy: function () {
|
||||
this.get('resizeService').off('debouncedDidResize', this._resizeListener);
|
||||
}
|
||||
mediaQueries: Ember.inject.service(),
|
||||
previewIsHidden: Ember.computed.reads('mediaQueries.maxWidth900')
|
||||
});
|
||||
|
|
|
@ -10,12 +10,12 @@ closes the mobile menu
|
|||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
import mobileQuery from 'ghost/utils/mobile';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: ['gh-menu-toggle'],
|
||||
|
||||
isMobile: false,
|
||||
mediaQueries: Ember.inject.service(),
|
||||
isMobile: Ember.computed.reads('mediaQueries.isMobile'),
|
||||
maximise: false,
|
||||
|
||||
iconClass: Ember.computed('maximise', 'isMobile', function () {
|
||||
|
@ -26,18 +26,6 @@ export default Ember.Component.extend({
|
|||
}
|
||||
}),
|
||||
|
||||
didInsertElement: function () {
|
||||
this.set('isMobile', mobileQuery.matches);
|
||||
this.set('mqListener', Ember.run.bind(this, function (mql) {
|
||||
this.set('isMobile', mql.matches);
|
||||
}));
|
||||
mobileQuery.addListener(this.get('mqListener'));
|
||||
},
|
||||
|
||||
willDestroyElement: function () {
|
||||
mobileQuery.removeListener(this.get('mqListener'));
|
||||
},
|
||||
|
||||
click: function () {
|
||||
if (this.get('isMobile')) {
|
||||
this.sendAction('mobileAction');
|
||||
|
|
|
@ -18,6 +18,9 @@ export default Ember.Component.extend({
|
|||
|
||||
config: Ember.inject.service(),
|
||||
|
||||
mediaQueries: Ember.inject.service(),
|
||||
isMobile: Ember.computed.reads('mediaQueries.maxWidth600'),
|
||||
|
||||
title: Ember.computed('tag.isNew', function () {
|
||||
if (this.get('tag.isNew')) {
|
||||
return 'New Tag';
|
||||
|
|
|
@ -6,16 +6,18 @@ export default Ember.Component.extend({
|
|||
classNames: ['view-container'],
|
||||
classNameBindings: ['isMobile'],
|
||||
|
||||
mobileWidth: 600,
|
||||
mediaQueries: Ember.inject.service(),
|
||||
|
||||
tags: null,
|
||||
selectedTag: null,
|
||||
|
||||
isMobile: false,
|
||||
isMobile: Ember.computed.reads('mediaQueries.maxWidth600'),
|
||||
isEmpty: Ember.computed.equal('tags.length', 0),
|
||||
|
||||
resizeService: Ember.inject.service('resize-service'),
|
||||
|
||||
_resizeListener: null,
|
||||
init: function () {
|
||||
this._super(...arguments);
|
||||
Ember.run.schedule('actions', this, this.fireMobileChangeActions);
|
||||
},
|
||||
|
||||
displaySettingsPane: Ember.computed('isEmpty', 'selectedTag', 'isMobile', function () {
|
||||
const isEmpty = this.get('isEmpty'),
|
||||
|
@ -36,25 +38,9 @@ export default Ember.Component.extend({
|
|||
return true;
|
||||
}),
|
||||
|
||||
toggleMobile: function () {
|
||||
let width = Ember.$(window).width();
|
||||
|
||||
if (width < this.get('mobileWidth')) {
|
||||
this.set('isMobile', true);
|
||||
this.sendAction('enteredMobile');
|
||||
} else {
|
||||
this.set('isMobile', false);
|
||||
fireMobileChangeActions: Ember.observer('isMobile', function () {
|
||||
if (!this.get('isMobile')) {
|
||||
this.sendAction('leftMobile');
|
||||
}
|
||||
},
|
||||
|
||||
didInitAttrs: function () {
|
||||
this._resizeListener = Ember.run.bind(this, this.toggleMobile);
|
||||
this.get('resizeService').on('debouncedDidResize', this._resizeListener);
|
||||
this.toggleMobile();
|
||||
},
|
||||
|
||||
willDestroyElement: function () {
|
||||
this.get('resizeService').off('debouncedDidResize', this._resizeListener);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
|
@ -7,10 +7,6 @@ export default Ember.Controller.extend({
|
|||
|
||||
tagController: inject.controller('settings.tags.tag'),
|
||||
|
||||
// set at controller level because it's shared by routes and components
|
||||
mobileWidth: 600,
|
||||
|
||||
isMobile: false,
|
||||
selectedTag: alias('tagController.tag'),
|
||||
|
||||
tagListFocused: equal('keyboardFocus', 'tagList'),
|
||||
|
@ -31,17 +27,12 @@ export default Ember.Controller.extend({
|
|||
}),
|
||||
|
||||
actions: {
|
||||
enteredMobile: function () {
|
||||
this.set('isMobile', true);
|
||||
},
|
||||
|
||||
leftMobile: function () {
|
||||
this.set('isMobile', false);
|
||||
|
||||
let firstTag = this.get('tags.firstObject');
|
||||
// redirect to first tag if possible so that you're not left with
|
||||
// tag settings blank slate when switching from portrait to landscape
|
||||
if (this.get('tags.length') && !this.get('tagController.tag')) {
|
||||
this.transitionToRoute('settings.tags.tag', this.get('tags.firstObject'));
|
||||
if (firstTag && !this.get('tagController.tag')) {
|
||||
this.transitionToRoute('settings.tags.tag', firstTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
import Ember from 'ember';
|
||||
import mobileQuery from 'ghost/utils/mobile';
|
||||
|
||||
// Routes that extend MobileIndexRoute need to implement
|
||||
// desktopTransition, a function which is called when
|
||||
// the user resizes to desktop levels.
|
||||
export default Ember.Route.extend({
|
||||
desktopTransition: Ember.K,
|
||||
_callDesktopTransition: null,
|
||||
|
||||
activate: function attachDesktopTransition() {
|
||||
this._super();
|
||||
mobileQuery.addListener(this.desktopTransitionMQ);
|
||||
},
|
||||
mediaQueries: Ember.inject.service(),
|
||||
|
||||
deactivate: function removeDesktopTransition() {
|
||||
this._super();
|
||||
mobileQuery.removeListener(this.desktopTransitionMQ);
|
||||
},
|
||||
|
||||
setDesktopTransitionMQ: Ember.on('init', function () {
|
||||
var self = this;
|
||||
this.set('desktopTransitionMQ', function desktopTransitionMQ() {
|
||||
if (!mobileQuery.matches) {
|
||||
self.desktopTransition();
|
||||
activate: function () {
|
||||
this._callDesktopTransition = () => {
|
||||
if (!this.get('mediaQueries.isMobile')) {
|
||||
this.desktopTransition();
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
Ember.addObserver(this, 'mediaQueries.isMobile', this._callDesktopTransition);
|
||||
},
|
||||
|
||||
deactivate: function () {
|
||||
if (this._callDesktopTransition) {
|
||||
Ember.removeObserver(this, 'mediaQueries.isMobile', this._callDesktopTransition);
|
||||
this._callDesktopTransition = null;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
import Ember from 'ember';
|
||||
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
||||
import MobileIndexRoute from 'ghost/routes/mobile-index-route';
|
||||
import mobileQuery from 'ghost/utils/mobile';
|
||||
|
||||
export default MobileIndexRoute.extend(AuthenticatedRouteMixin, {
|
||||
noPosts: false,
|
||||
|
||||
mediaQueries: Ember.inject.service(),
|
||||
isMobile: Ember.computed.reads('mediaQueries.isMobile'),
|
||||
|
||||
// Transition to a specific post if we're not on mobile
|
||||
beforeModel: function () {
|
||||
if (!mobileQuery.matches) {
|
||||
if (!this.get('isMobile')) {
|
||||
return this.goToPost();
|
||||
}
|
||||
},
|
||||
|
||||
setupController: function (controller, model) {
|
||||
/*jshint unused:false*/
|
||||
setupController: function (controller) {
|
||||
controller.set('noPosts', this.get('noPosts'));
|
||||
},
|
||||
|
||||
|
|
|
@ -3,13 +3,11 @@ import AuthenticatedRoute from 'ghost/routes/authenticated';
|
|||
|
||||
export default AuthenticatedRoute.extend({
|
||||
|
||||
// HACK: ugly way of changing behaviour when on mobile
|
||||
beforeModel: function () {
|
||||
const firstTag = this.modelFor('settings.tags').get('firstObject'),
|
||||
mobileWidth = this.controllerFor('settings.tags').get('mobileWidth'),
|
||||
viewportWidth = Ember.$(window).width();
|
||||
mediaQueries: Ember.inject.service(),
|
||||
|
||||
if (firstTag && viewportWidth > mobileWidth) {
|
||||
beforeModel: function () {
|
||||
let firstTag = this.modelFor('settings.tags').get('firstObject');
|
||||
if (firstTag && !this.get('mediaQueries.maxWidth600')) {
|
||||
this.transitionTo('settings.tags.tag', firstTag);
|
||||
}
|
||||
}
|
||||
|
|
46
core/client/app/services/media-queries.js
Normal file
46
core/client/app/services/media-queries.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
const MEDIA_QUERIES = {
|
||||
maxWidth600: '(max-width: 600px)',
|
||||
isMobile: '(max-width: 800px)',
|
||||
maxWidth900: '(max-width: 900px)',
|
||||
maxWidth1000: '(max-width: 1000px)'
|
||||
};
|
||||
|
||||
export default Ember.Service.extend({
|
||||
init: function () {
|
||||
this._super(...arguments);
|
||||
this._handlers = [];
|
||||
this.loadQueries(MEDIA_QUERIES);
|
||||
},
|
||||
|
||||
loadQueries: function (queries) {
|
||||
Object.keys(queries).forEach(key => {
|
||||
this.loadQuery(key, queries[key]);
|
||||
});
|
||||
},
|
||||
|
||||
loadQuery: function (key, queryString) {
|
||||
let query = window.matchMedia(queryString);
|
||||
|
||||
this.set(key, query.matches);
|
||||
|
||||
let handler = Ember.run.bind(this, () => {
|
||||
let lastValue = this.get(key);
|
||||
let newValue = query.matches;
|
||||
if (lastValue !== newValue) {
|
||||
this.set(key, query.matches);
|
||||
}
|
||||
});
|
||||
query.addListener(handler);
|
||||
this._handlers.push([query, handler]);
|
||||
},
|
||||
|
||||
willDestroy: function () {
|
||||
this._handlers.forEach(([query, handler]) => {
|
||||
query.removeListener(handler);
|
||||
});
|
||||
this._super(...arguments);
|
||||
}
|
||||
|
||||
});
|
|
@ -7,7 +7,7 @@
|
|||
</section>
|
||||
</header>
|
||||
|
||||
{{#gh-tags-management-container mobileWidth=mobileWidth tags=tags selectedTag=selectedTag enteredMobile="enteredMobile" leftMobile="leftMobile" as |container|}}
|
||||
{{#gh-tags-management-container tags=tags selectedTag=selectedTag enteredMobile="enteredMobile" leftMobile="leftMobile" as |container|}}
|
||||
{{#gh-infinite-scroll
|
||||
fetch="loadNextPage"
|
||||
isLoading=isLoading
|
||||
|
|
|
@ -1 +1 @@
|
|||
{{gh-tag-settings-form tag=tag setProperty=(action "setProperty") openModal="openModal" isMobile=isMobile}}
|
||||
{{gh-tag-settings-form tag=tag setProperty=(action "setProperty") openModal="openModal"}}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export default matchMedia('(max-width: 800px)');
|
|
@ -23,13 +23,6 @@ module.exports = function (environment) {
|
|||
authenticationRoute: 'signin',
|
||||
routeAfterAuthentication: 'posts',
|
||||
routeIfAlreadyAuthenticated: 'posts'
|
||||
},
|
||||
|
||||
resizeServiceDefaults: {
|
||||
debounceTimeout: 100,
|
||||
heightSensitive: false,
|
||||
widthSensitive: true,
|
||||
injectionFactories: []
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
"ember-disable-proxy-controllers": "^1.0.0",
|
||||
"ember-export-application-global": "^1.0.3",
|
||||
"ember-myth": "0.1.1",
|
||||
"ember-resize": "0.0.10",
|
||||
"ember-simple-auth": "1.0.0",
|
||||
"ember-sinon": "0.2.1",
|
||||
"ember-watson": "^0.6.4",
|
||||
|
|
|
@ -7,10 +7,6 @@ import {
|
|||
import hbs from 'htmlbars-inline-precompile';
|
||||
import Ember from 'ember';
|
||||
|
||||
const resizeStub = Ember.Service.extend(Ember.Evented, {
|
||||
|
||||
});
|
||||
|
||||
describeComponent(
|
||||
'gh-tags-management-container',
|
||||
'Integration: Component: gh-tags-management-container',
|
||||
|
@ -18,13 +14,7 @@ describeComponent(
|
|||
integration: true
|
||||
},
|
||||
function () {
|
||||
beforeEach(function () {
|
||||
this.register('service:resize-service', resizeStub);
|
||||
this.inject.service('resize-service', {as: 'resize-service'});
|
||||
});
|
||||
|
||||
it('renders', function () {
|
||||
this.set('mobileWidth', 600);
|
||||
this.set('tags', []);
|
||||
this.set('selectedTag', null);
|
||||
this.on('enteredMobile', function () {
|
||||
|
@ -35,7 +25,7 @@ describeComponent(
|
|||
});
|
||||
|
||||
this.render(hbs`
|
||||
{{#gh-tags-management-container mobileWidth=mobileWidth tags=tags selectedTag=selectedTag enteredMobile="enteredMobile" leftMobile="leftMobile"}}{{/gh-tags-management-container}}
|
||||
{{#gh-tags-management-container tags=tags selectedTag=selectedTag enteredMobile="enteredMobile" leftMobile="leftMobile"}}{{/gh-tags-management-container}}
|
||||
`);
|
||||
expect(this.$()).to.have.length(1);
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue