Combining Liquid Fire and ember-gestures


#1

Hello,

I’m scratching my head about how it’s possible to initiate liquid fire slide transition by swiping on a mobile.

One problem is, that ember-gestures are always working on components. Since I’ve got no “fullscreen” component, the swipe events fire only when swiping over a specific component (say in the bottom right corner).

Furthermore, I don’t know how to initiate a liquid fire transition from code (instead from a template).

I have a route page/:page_id. Its template is:

{{#liquid-bind model use="betweenModel" as |currentModel|}}
  <h3>{{model.title}}</h3>
{{/liquid-bind}}

Together with the custom transition “betweenModel” the pages slide left or right depending on the target page:

export default function() {
  if (this.oldValue.get('id') < this.newValue.get('id')) {
    // toLeft.
    return this.lookup('toLeft').apply(this);
  }
  else {
    // toRight.
    return this.lookup('toRight').apply(this);
  }
}

Now I want to be able to swipe through pages in the same way on a mobile.

Has anyone done this before?

Thank you
haggis


#2

you can do this with a little bit of not too complex wiring which I will walk you through on Slack if you like. Ping me (@runspired) in the ember-gestures channel.


#3

Hello @jthoburn,

thanks for your kind offer!

I just got it working by myself. I’m just unsure if it is the best way to do it:

  1. Create a gestures service to hold the swipeLeft and swipeRight state
  2. Create a component which wraps everything in your application template and listens to the swipe events
  3. Inject the service into the app-wrapper component. Toggle the services swipe states each time one of these events occur
  4. Inject the service also wherever you need to react to the swipe events
  5. Observe the services state variables and do your task

ember g service gestures

gestures/service.js:

import Ember from 'ember';

export default Ember.Service.extend({
  swipeLeftToggle: false,
  swipeRightToggle: false,

  swipeLeftObserver: Ember.observer('swipeLeftToggle', function() {
    this.toggleProperty('_swipeLeft');
  }),

  swipeRightObserver: Ember.observer('swipeRightToggle', function() {
    this.toggleProperty('_swipeRight');
  }),

  _swipeLeft: true,
  pulseSwipeLeft: Ember.computed.oneWay('_swipeLeft').readOnly(),

  _swipeRight: true,
  pulseSwipeRight: Ember.computed.oneWay('_swipeRight').readOnly(),
});

ember g component app-wrapper

application/template.hbs:

{{#app-wrapper}}
    {{outlet}}
{{/app-wrapper}}

components/app-wrapper/component.js:

import RecognizerMixin from 'ember-gestures/mixins/recognizers';
import Ember from 'ember';

export default Ember.Component.extend(RecognizerMixin, {
  gestures: Ember.inject.service(),
  recognizers: 'swipe',

  swipeLeft() {
    this.toggleProperty('gestures.swipeLeftToggle');
  },

  swipeRight() {
    this.toggleProperty('gestures.swipeRightToggle');
  }
});

page/controller.js:

import Ember from 'ember';

export default Ember.Controller.extend({
  gestures: Ember.inject.service(),

  swipeLeftBinding: 'gestures.pulseSwipeLeft',
  swipeLeftObserver: Ember.observer('swipeLeft', function() {
    let nextModel = this.store.peekRecord('page', parseInt(this.get('model.id')) + 1);
    if (nextModel !== null) {
      this.transitionToRoute('/page/' + nextModel.get('id'));
    }
  }),

  swipeRightBinding: 'gestures.pulseSwipeRight',
  swipeRightObserver: Ember.observer('swipeRight', function() {
    let prevModel = this.store.peekRecord('page', parseInt(this.get('model.id')) - 1);
    if (prevModel !== null) {
      this.transitionToRoute('/page/' + prevModel.get('id'));
    }
  })
});

Edit: I also tried it with the swipeUp and swipeDown events. However, they were never fired. Nevermind, I don’t need them atm.


#4

For swipeUp and swipeDown events, change the value recognizers ‘swipe’ to ‘vertical-swipe’ in the component. However, I haven’t found how to cumulate both vertical & horizontal swipe.