define([ 'require', 'debug', 'lib/panzoom', 'lib/orientation', 'MediaFrame', 'lib/bind', 'attach', 'view', 'gaia-header' ], function (require) { 'use strict'; var debug = require('debug')('view:preview-gallery'); var addPanAndZoomHandlers = require('lib/panzoom'); var orientation = require('lib/orientation'); var MediaFrame = require('MediaFrame'); var bind = require('lib/bind'); var attach = require('attach'); var View = require('view'); require('gaia-header'); var SWIPE_DISTANCE_THRESHOLD = window.innerWidth / 3; var SWIPE_VELOCITY_THRESHOLD = 1; var SWIPE_DURATION = 150; var FADE_IN_DURATION = 450; return View.extend({ name: 'preview-gallery', className: 'offscreen', initialize: function () { debug('initialized'); }, render: function () { this.el.innerHTML = this.template(); this.els.frameContainer = this.find('.js-frame-container'); this.els.previewMenu = this.find('.js-preview-menu'); this.els.mediaFrame = this.find('.js-media-frame'); this.els.countText = this.find('.js-count-text'); this.els.options = this.find('.js-options'); this.els.header = this.find('.js-header'); this.els.share = this.find('.js-share'); window.dispatchEvent(new CustomEvent('lazyload', { detail: this.el })); this.configure(); delete this.template; debug('rendered'); return this.bindEvents(); }, bindEvents: function () { bind(this.el, 'tap', this.onTap); bind(this.els.header, 'action', this.firer('click:back')); bind(this.els.options, 'click', this.onButtonClick); bind(this.els.share, 'click', this.onButtonClick); bind(this.els.mediaFrame, 'wheel', this.onFrameWheel); return this; }, configure: function () { this.currentIndex = this.lastIndex = 0; this.frame = new MediaFrame(this.els.mediaFrame, true, this.maxPreviewSize); this.frame.video.onloading = this.onVideoLoading; this.frame.video.onplaying = this.onVideoPlaying; this.frame.video.onpaused = this.onVideoPaused; addPanAndZoomHandlers(this.frame, this.swipeCallback); }, template: function () { return '
' + '' + '

Preview

' + '' + '' + '
' + '
' + '
' + '
' + '
' + '
'; }, onTap: function () { if (this.videoPlaying) { return; } var isShown = this.els.previewMenu.classList.contains('visible'); if (isShown) { this.previewMenuFadeOut(); } else { this.previewMenuFadeIn(); } }, previewMenuFadeIn: function () { this.els.previewMenu.classList.add('visible'); }, previewMenuFadeOut: function () { this.els.previewMenu.classList.remove('visible'); }, onFrameWheel: function (event) { if (event.deltaMode !== event.DOM_DELTA_PAGE || event.deltaY) { return; } if (this.videoPlaying) { this.onVideoPaused(); } if (event.deltaX > 0) { this.emit('swipe', 'left'); } else if (event.deltaX < 0) { this.emit('swipe', 'right'); } }, swipeCallback: function (swipeAmount, swipeVelocity) { var self = this; if (swipeVelocity === undefined) { this.els.frameContainer.style.transform = 'translate(' + swipeAmount + 'px, 0)'; return; } var direction, translation; if (swipeAmount > 0 && swipeVelocity > 0 && this.currentIndex > 1 && (swipeAmount > SWIPE_DISTANCE_THRESHOLD || swipeVelocity > SWIPE_VELOCITY_THRESHOLD)) { direction = 'right'; translation = '100%'; } else if (swipeAmount <= 0 && swipeVelocity <= 0 && this.currentIndex < this.lastIndex && (swipeAmount < -SWIPE_DISTANCE_THRESHOLD || swipeVelocity < -SWIPE_VELOCITY_THRESHOLD)) { direction = 'left'; translation = '-100%'; } if (!direction) { animate('transform', 'translate(0,0)', SWIPE_DURATION); return; } if (this.videoPlaying) { this.onVideoPaused(); } animate('transform', 'translate(' + translation + ', 0)', SWIPE_DURATION, function () { self.emit('swipe', direction); window.requestAnimationFrame(function () { self.els.frameContainer.style.opacity = 0; self.els.frameContainer.style.transform = 'translate(0,0)'; window.requestAnimationFrame(function () { animate('opacity', 1, FADE_IN_DURATION); }); }); }); function animate(property, value, duration, done) { var e = self.els.frameContainer; e.addEventListener('transitionend', onTransitionEnd); e.style.transitionProperty = property; e.style.transitionDuration = duration + 'ms'; e.style[property] = value; function onTransitionEnd() { e.removeEventListener('transitionend', onTransitionEnd); delete e.style.transitionProperty; delete e.style.transitionDuration; if (done) { done(); } } } }, onButtonClick: function (e, el) { if (this.videoPlaying) { return; } el = el || e.currentTarget; var name = el.getAttribute('name'); if (this.optionsMenuContainer) { this.hideOptionsMenu(); } this.emit('click:' + name, e); e.stopPropagation(); }, open: function () { window.addEventListener('resize', this.onResize); orientation.unlock(); this.previewMenuFadeIn(); this.el.classList.remove('offscreen'); }, close: function () { window.removeEventListener('resize', this.onResize); orientation.lock(); this.previewMenuFadeOut(); this.el.classList.add('offscreen'); this.frame.clear(); }, updateCountText: function (current, total) { this.currentIndex = current; this.lastIndex = total; this.els.countText.textContent = current + '/' + total; this.els.mediaFrame.setAttribute('data-l10n-id', 'media-frame'); this.els.mediaFrame.setAttribute('data-l10n-args', JSON.stringify({ total: total, current: current })); }, onResize: function () { this.frame.resize(); if (this.frame.displayingVideo) { this.frame.video.setPlayerSize(); } }, showImage: function (image) { this.frame.displayImage(image.blob, image.width, image.height, image.preview, image.rotation, image.mirrored); }, showVideo: function (video) { this.frame.displayVideo(video.blob, video.poster.blob, video.poster.width / video.poster.height, video.rotation); }, onVideoLoading: function () { this.emit('loadingvideo', 'loadingVideo'); }, onVideoPlaying: function () { if (this.videoPlaying) { return; } this.videoPlaying = true; this.previewMenuFadeOut(); this.emit('playingvideo'); }, onVideoPaused: function () { if (!this.videoPlaying) { return; } this.videoPlaying = false; this.previewMenuFadeIn(); }, showOptionsMenu: function () { this.optionsMenuContainer = document.createElement('div'); this.optionsMenuContainer.innerHTML = this.optionTemplate(); this.el.appendChild(this.optionsMenuContainer); this.el.classList.add('action-menu'); this.menu = this.find('.js-menu'); var cancelButton = this.find('.js-cancel'); bind(cancelButton, 'click', this.hideOptionsMenu); if (this.menu) { attach.on(this.menu, 'click', '.js-btn', this.onButtonClick); } }, hideOptionsMenu: function () { if (this.optionsMenuContainer) { this.el.classList.remove('action-menu'); this.optionsMenuContainer.parentElement.removeChild(this.optionsMenuContainer); this.optionsMenuContainer = null; } }, optionTemplate: function () { return '
' + '
Options
' + '' + '' + '' + '' + '' + '
'; } }); });