Slide 1

Slide 1 text

LAZY LOADING VIDEOS IN EMBER.JS ! @sugarpirate_ " @poteto # $ https://github.com/poteto/ember-lazy-video BOSTON EMBER.JS – 15TH JAN 2015

Slide 2

Slide 2 text

WHY BOTHER?

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

% INSPIRATION

Slide 6

Slide 6 text

“Maybe I could replace the iFrame with a thumbnail image?”

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

LAZY LOADING

Slide 10

Slide 10 text

& SERVICE

Slide 11

Slide 11 text

// services/lazy-video-provider.js import Ember from 'ember'; import youtube from 'ember-lazy-video/lazy-video-providers/youtube'; import vimeo from 'ember-lazy-video/lazy-video-providers/vimeo'; var YOUTUBE_REGEX = /^[a-zA-Z0-9_-]{11}$/; var VIMEO_REGEX = /^[\d]+$/; export default Ember.Object.extend({ youtube: youtube, vimeo: vimeo, getUrl: function(provider, endpoint, videoId, opts) { var params; opts = (typeof opts === "undefined") ? {} : opts; params = Ember.$.param(opts); return this._getProvider(provider, videoId)[endpoint](videoId) + '?' + params; }, getThumbnailUrl: function(provider, videoId) { return this._getProvider(provider, videoId).thumbnailUrl(videoId); }, ...

Slide 12

Slide 12 text

_getProvider: function(providerName, videoId) { var provider; if (!providerName && videoId) { if (VIMEO_REGEX.test(videoId)) { providerName = 'vimeo'; } if (YOUTUBE_REGEX.test(videoId)) { providerName = 'youtube'; } } provider = this.get(providerName); Ember.assert('Couldn\'t determine provider from `videoId` or the provider supplied was invalid: ' + providerName, provider); return provider; } });

Slide 13

Slide 13 text

& PROVIDERS

Slide 14

Slide 14 text

// lazy-video-providers/youtube.js import Ember from 'ember'; export default { apiUrl: function(videoId) { return '//gdata.youtube.com/feeds/api/videos/' + videoId; }, embedUrl: function(videoId) { return '//www.youtube.com/embed/' + videoId; }, thumbnailUrl: function(videoId) { return Ember.RSVP.resolve('//img.youtube.com/vi/' + videoId + '/maxresdefault.jpg'); } };

Slide 15

Slide 15 text

// lazy-video-providers/vimeo.js import Ember from 'ember'; export default { apiUrl: function(videoId) { return '//vimeo.com/api/oembed.json?url=http%3//vimeo.com/' + videoId; }, embedUrl: function(videoId) { return '//player.vimeo.com/video/' + videoId; }, thumbnailUrl: function(videoId) { var apiUrl = this.apiUrl(videoId); return new Ember.RSVP.Promise(function(resolve, reject) { Ember.$.getJSON(apiUrl).then(function(res) { resolve(res.thumbnail_url); }); }); } };

Slide 16

Slide 16 text

& INITIALIZER

Slide 17

Slide 17 text

// initializers/lazy-video.js import LazyVideoProviders from 'ember-lazy-video/services/lazy-video-providers'; export default { name: 'flash-messages', initialize: function(container, application){ application.register('service:lazy-video-providers', LazyVideoProviders, { singleton: true }); application.inject('component:lazy-video', 'providers', 'service:lazy-video-providers'); } };

Slide 18

Slide 18 text

& COMPONENT

Slide 19

Slide 19 text

// components/lazy-video.js import Ember from 'ember'; var on = Ember.on; var get = Ember.get; var set = Ember.set; export default Ember.Component.extend({ provider: null, isDisplayed: false, videoTitle: null, videoId: null, classNames: [ ‘lazyLoadContainer' ], attributeBindings: [ 'style' ], videoThumbnail: null, click: function() { this.set('isDisplayed', true); }, videoSrc: Ember.computed('provider', 'videoId', function() { var providers = get(this, 'providers'); var provider = get(this, 'provider'); var videoId = get(this, 'videoId'); return providers.getUrl(provider, 'embedUrl', videoId, { autoplay: 1 }); }), _getVideoThumbnail: on('didInsertElement', function() { var providers = get(this, 'providers'); var provider = get(this, 'provider'); var videoId = get(this, 'videoId'); var _this = this; providers.getThumbnailUrl(provider, videoId).then(function(res) { set(_this, 'videoThumbnail', res); }); }), style: Ember.computed('videoThumbnail', function() { var thumbnail = get(this, 'videoThumbnail'); return 'background-image: url(' + thumbnail + ')'; }) });

Slide 20

Slide 20 text

& TEMPLATE

Slide 21

Slide 21 text

{{#if isDisplayed}} {{else}} {{#if template}} {{yield}} {{else}}
...
{{/if}} {{/if}}

Slide 22

Slide 22 text

& USAGE {{lazy-video provider="youtube" videoId="gvdf5n-zI14"}} {{lazy-video provider="vimeo" videoId="51771300"}}

Slide 23

Slide 23 text

JS BIN TO EMBER ADDON

Slide 24

Slide 24 text

' DEMO http://emberjs.jsbin.com/qaribi/24

Slide 25

Slide 25 text

( INSTALL $ npm install ember-lazy-video --save

Slide 26

Slide 26 text

$ CONTRIBUTE https://github.com/poteto/ember-lazy-video

Slide 27

Slide 27 text

) READ https://medium.com/delightful-ui-for-ember-apps/ lazy-loading-videos-in-ember-7504a4abe34f

Slide 28

Slide 28 text

THANKS! # $ https://github.com/poteto/ember-lazy-video BOSTON EMBER.JS – 15TH JAN 2015 ! @sugarpirate_ " @poteto