mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Mobile Interactions
closes #3018 - split clientold mobile interactions into their respective Ember routes/views - create PostsView and SettingsView with mobile interactions - place interactions for the publish bar into ApplicationRoute on init
This commit is contained in:
parent
968e339a1e
commit
54eda5c03c
6 changed files with 181 additions and 61 deletions
|
@ -1,9 +1,24 @@
|
||||||
import ShortcutsRoute from 'ghost/mixins/shortcuts-route';
|
import ShortcutsRoute from 'ghost/mixins/shortcuts-route';
|
||||||
|
import mobileUtils from 'ghost/utils/mobile-utils';
|
||||||
|
|
||||||
var ApplicationRoute = Ember.Route.extend(ShortcutsRoute, {
|
var ApplicationRoute = Ember.Route.extend(ShortcutsRoute, {
|
||||||
shortcuts: {
|
shortcuts: {
|
||||||
'esc': 'closePopups'
|
'esc': 'closePopups'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mobileInteractions: function () {
|
||||||
|
var responsiveAction = mobileUtils.responsiveAction;
|
||||||
|
|
||||||
|
Ember.run.scheduleOnce('afterRender', document, function () {
|
||||||
|
// ### Toggle the sidebar menu
|
||||||
|
$('[data-off-canvas]').on('click', function (event) {
|
||||||
|
responsiveAction(event, '(max-width: 650px)', function () {
|
||||||
|
$('body').toggleClass('off-canvas');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}.on('init'),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
closePopups: function () {
|
closePopups: function () {
|
||||||
this.get('popover').closePopovers();
|
this.get('popover').closePopovers();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<section class="content-view-container">
|
<section class="content-list js-content-list">
|
||||||
<section class="content-list js-content-list">
|
|
||||||
<header class="floatingheader">
|
<header class="floatingheader">
|
||||||
<section class="content-filter">
|
<section class="content-filter">
|
||||||
<small>All Posts</small>
|
<small>All Posts</small>
|
||||||
|
@ -30,8 +29,7 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ol>
|
</ol>
|
||||||
{{/view}}
|
{{/view}}
|
||||||
</section>
|
</section>
|
||||||
<section class="content-preview js-content-preview">
|
<section class="content-preview js-content-preview">
|
||||||
{{outlet}}
|
{{outlet}}
|
||||||
</section>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<div class="wrapper">
|
<aside class="settings-sidebar" role="complementary">
|
||||||
<aside class="settings-sidebar" role="complementary">
|
|
||||||
<header>
|
<header>
|
||||||
<h1 class="title">Settings</h1>
|
<h1 class="title">Settings</h1>
|
||||||
</header>
|
</header>
|
||||||
|
@ -20,9 +19,8 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<section class="settings-content active">
|
<section class="settings-content active">
|
||||||
{{outlet}}
|
{{outlet}}
|
||||||
</section>
|
</section>
|
||||||
</div>
|
|
||||||
|
|
48
ghost/admin/utils/mobile-utils.js
Normal file
48
ghost/admin/utils/mobile-utils.js
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*global DocumentTouch,FastClick*/
|
||||||
|
var hasTouchScreen,
|
||||||
|
smallScreen,
|
||||||
|
initFastClick,
|
||||||
|
responsiveAction;
|
||||||
|
|
||||||
|
// Taken from "Responsive design & the Guardian" with thanks to Matt Andrews
|
||||||
|
// Added !window._phantom so that the functional tests run as though this is not a touch screen.
|
||||||
|
// In future we can do something more advanced here for testing both touch and non touch
|
||||||
|
hasTouchScreen = function () {
|
||||||
|
return !window._phantom &&
|
||||||
|
(
|
||||||
|
('ontouchstart' in window) ||
|
||||||
|
(window.DocumentTouch && document instanceof DocumentTouch)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
smallScreen = function () {
|
||||||
|
if (window.matchMedia('(max-width: 1000px)').matches) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
initFastClick = function () {
|
||||||
|
Ember.run.scheduleOnce('afterRender', null, function () {
|
||||||
|
FastClick.attach(document.body);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
responsiveAction = function responsiveAction(event, mediaCondition, cb) {
|
||||||
|
if (!window.matchMedia(mediaCondition).matches) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
cb();
|
||||||
|
};
|
||||||
|
|
||||||
|
export { hasTouchScreen, smallScreen };
|
||||||
|
export default {
|
||||||
|
hasTouchScreen: hasTouchScreen,
|
||||||
|
smallScreen: smallScreen,
|
||||||
|
initFastClick: initFastClick,
|
||||||
|
responsiveAction: responsiveAction
|
||||||
|
};
|
30
ghost/admin/views/posts.js
Normal file
30
ghost/admin/views/posts.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import mobileUtils from 'ghost/utils/mobile-utils';
|
||||||
|
|
||||||
|
var PostsView = Ember.View.extend({
|
||||||
|
classNames: ['content-view-container'],
|
||||||
|
tagName: 'section',
|
||||||
|
|
||||||
|
mobileInteractions: function () {
|
||||||
|
var responsiveAction = mobileUtils.responsiveAction;
|
||||||
|
|
||||||
|
Ember.run.scheduleOnce('afterRender', this, function () {
|
||||||
|
// ### Show content preview when swiping left on content list
|
||||||
|
$('.manage').on('click', '.content-list ol li', function (event) {
|
||||||
|
responsiveAction(event, '(max-width: 800px)', function () {
|
||||||
|
$('.content-list').animate({right: '100%', left: '-100%', 'margin-right': '15px'}, 300);
|
||||||
|
$('.content-preview').animate({right: '0', left: '0', 'margin-left': '0'}, 300);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### Hide content preview
|
||||||
|
$('.manage').on('click', '.content-preview .button-back', function (event) {
|
||||||
|
responsiveAction(event, '(max-width: 800px)', function () {
|
||||||
|
$('.content-list').animate({right: '0', left: '0', 'margin-right': '0'}, 300);
|
||||||
|
$('.content-preview').animate({right: '-100%', left: '100%', 'margin-left': '15px'}, 300);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}.on('didInsertElement'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default PostsView;
|
31
ghost/admin/views/settings.js
Normal file
31
ghost/admin/views/settings.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import mobileUtils from 'ghost/utils/mobile-utils';
|
||||||
|
|
||||||
|
var SettingsView = Ember.View.extend({
|
||||||
|
classNames: ['wrapper'],
|
||||||
|
|
||||||
|
mobileInteractions: function () {
|
||||||
|
var responsiveAction = mobileUtils.responsiveAction;
|
||||||
|
|
||||||
|
Ember.run.scheduleOnce('afterRender', this, function () {
|
||||||
|
// ### Show settings options page when swiping left on settings menu link
|
||||||
|
$('.settings').on('click', '.settings-menu li', function (event) {
|
||||||
|
responsiveAction(event, '(max-width: 800px)', function () {
|
||||||
|
$('.settings-sidebar').animate({right: '100%', left: '-102%', 'margin-right': '15px'}, 300);
|
||||||
|
$('.settings-content').animate({right: '0', left: '0', 'margin-left': '0'}, 300);
|
||||||
|
$('.settings-content .button-back, .settings-content .button-save').css('display', 'inline-block');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ### Hide settings options page
|
||||||
|
$('.settings').on('click', '.settings-content .button-back', function (event) {
|
||||||
|
responsiveAction(event, '(max-width: 800px)', function () {
|
||||||
|
$('.settings-sidebar').animate({right: '0', left: '0', 'margin-right': '0'}, 300);
|
||||||
|
$('.settings-content').animate({right: '-100%', left: '100%', 'margin-left': '15'}, 300);
|
||||||
|
$('.settings-content .button-back, .settings-content .button-save').css('display', 'none');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}.on('didInsertElement')
|
||||||
|
});
|
||||||
|
|
||||||
|
export default SettingsView;
|
Loading…
Add table
Reference in a new issue