+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/css/productvideo.css b/app/code/Magento/ProductVideo/view/adminhtml/web/css/productvideo.css
index 7861103573d2d..e2aa3047a6892 100755
--- a/app/code/Magento/ProductVideo/view/adminhtml/web/css/productvideo.css
+++ b/app/code/Magento/ProductVideo/view/adminhtml/web/css/productvideo.css
@@ -1,4 +1,4 @@
-/**
+ /**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
@@ -8,110 +8,254 @@
text-decoration: none;
}
-.image.video-placeholder {
- background-color: #fff;
- font-size: 4rem;
- line-height: inherit;
- color: #ccc;
- overflow: hidden;
- speak: none;
- font-weight: normal;
- -webkit-font-smoothing: antialiased;
- display: inline-block;
- vertical-align: middle;
- text-align: center;
- position: relative;
-}
.image.video-placeholder:before {
- background: url(../images/gallery-sprite.png) no-repeat left bottom;
- content: '';
- position: absolute;
- height: 49px;
- width: 49px;
- left: 50%;
- top: 18px;
- margin-left: -24px;
- opacity: 0.7;
-}
-#add_video_button {
- background: rgba(0,0,0,0);
- width: 100%;
- height: 100%;
- border: 0;
- z-index: 5;
- position: relative;
+ background: url(../images/gallery-sprite.png) no-repeat left bottom;
+ content: '';
+ position: absolute;
+ height: 49px;
+ width: 49px;
+ left: 50%;
+ top: 18px;
+ margin-left: -24px;
+ opacity: 0.7;
+ z-index: 1;
}
+
.video-placeholder .image-placeholder-text {
- font-weight: 400;
+ font-weight: 400;
}
-.admin__field.field-video_base_image .admin__field-control,
+
+.admin__field.field-video_image .admin__field-control,
.admin__field.field-video_small_image .admin__field-control,
-.admin__field.field-video_thumb_image .admin__field-control,
+.admin__field.field-video_thumbnail .admin__field-control,
.admin__field.field-video_swatch_image .admin__field-control,
.admin__field.field-new_video_disabled .admin__field-control {
- width: 82px;
- margin-left: calc( (100%) * .33333333 - 30px );
+ width: 82px;
+ margin-left: calc((100%) * .33333333 - 30px);
}
-.admin__field.field-video_base_image .admin__field-control input,
+
+.admin__field.field-video_image .admin__field-control input,
.admin__field.field-video_small_image .admin__field-control input,
-.admin__field.field-video_thumb_image .admin__field-control input,
+.admin__field.field-video_thumbnail .admin__field-control input,
.admin__field.field-video_swatch_image .admin__field-control input,
.admin__field.field-new_video_disabled .admin__field-control input {
- float: right;
+ float: right;
}
-.admin__field.field-video_base_image .admin__field-label,
+
+.admin__field.field-video_image .admin__field-label,
.admin__field.field-video_small_image .admin__field-label,
-.admin__field.field-video_thumb_image .admin__field-label,
+.admin__field.field-video_thumbnail .admin__field-label,
.admin__field.field-video_swatch_image .admin__field-label,
.admin__field.field-new_video_disabled .admin__field-label {
- width: 200px;
- position: absolute;
- margin-left: calc( (100%) * .33333333 - 30px + 90px );
+ width: 200px;
+ position: absolute;
+ margin-left: calc((100%) * .33333333 - 30px + 90px);
+ left: 0px;
+}
+
+.admin__field.field-video_image .admin__field-label:before,
+.admin__field.field-video_small_image .admin__field-label:before,
+.admin__field.field-video_thumbnail .admin__field-label:before,
+.admin__field.field-video_swatch_image .admin__field-label:before,
+.admin__field.field-new_video_disabled .admin__field-label:before {
+ content: none;
}
-.admin__field.field-video_base_image .admin__field-label span,
+
+.admin__field.field-video_image .admin__field-label span,
.admin__field.field-video_small_image .admin__field-label span,
-.admin__field.field-video_thumb_image .admin__field-label span,
+.admin__field.field-video_thumbnail .admin__field-label span,
.admin__field.field-video_swatch_image .admin__field-label span,
.admin__field.field-new_video_disabled .admin__field-label span {
- float: left;
+ float: left;
}
-.admin__field.field-video_base_image,
+
+.admin__field.field-video_image,
.admin__field.field-video_small_image,
-.admin__field.field-video_thumb_image,
+.admin__field.field-video_thumbnail,
.admin__field.field-video_swatch_image {
- margin-bottom: 20px !important;
+ margin-bottom: 20px !important;
}
+
.admin__field.field-new_video_disabled {
- margin-top: 32px !important;
+ margin-top: 32px !important;
}
-.admin__field.field-video_base_image .admin__field-control {
- position: relative;
+
+.admin__field.field-video_image .admin__field-control {
+ position: relative;
}
-.admin__field.field-video_base_image .admin__field-control:after {
- content: 'Role';
- position: absolute;
- color: #000;
- width: 34px;
- height: 20px;
- left: 1px;
- top: -2px;
- font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
- font-size: 1.4rem;
- font-weight: 600;
+
+.admin__field.field-video_image .admin__field-control:after {
+ content: 'Role';
+ position: absolute;
+ color: #000;
+ width: 34px;
+ height: 20px;
+ left: 1px;
+ top: -2px;
+ font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ font-size: 1.4rem;
+ font-weight: 600;
}
.preview_hidden_image_input_button {
display: none;
}
+
.video-item {
- position: relative;
+ position: relative;
}
+
.video-item:after {
- content: '';
- position: absolute;
- bottom: 0;
- right: 9px;
- background: url(../images/gallery-sprite.png) bottom left;
- width: 49px;
- height: 40px;
-}
\ No newline at end of file
+ content: '';
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ background: url(../images/gallery-sprite.png) bottom left;
+ width: 49px;
+ height: 40px;
+ z-index: 3;
+ left: 0;
+ top: 10px;
+ margin: auto;
+}
+
+.mage-new-video-dialog #new_video_form {
+ width: 65%;
+ float: left;
+}
+
+.mage-new-video-dialog #video-player-preview-location {
+ width: 34.99999%;
+ float: left;
+}
+
+.video-player-container {
+ width: 100%;
+ height: 20vw;
+ margin-bottom: 30px;
+ border: 1px solid #e3e3e3;
+ position: relative;
+}
+
+.video-player-container:after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ margin: auto;
+ width: 93px;
+ height: 60px;
+ background: url(../images/camera.png) no-repeat center;
+ z-index: 1;
+}
+
+.video-information {
+ margin-bottom: 7px;
+ display: none;
+}
+
+.video-information:after {
+ content: " "; /* Older browser do not support empty content */
+ visibility: hidden;
+ display: block;
+ height: 0;
+ clear: both;
+}
+
+.video-information label {
+ font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ font-size: 1.4rem;
+ font-weight: 600;
+ display: block;
+ width: 25%;
+ float: left;
+ text-align: right;
+}
+
+.video-information span {
+ font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ font-size: 1.4rem;
+ font-weight: 300;
+ display: block;
+ width: 74.9999%;
+ float: left;
+ padding-left: 20px;
+}
+
+.product-video {
+ width: 100%;
+ z-index: 20;
+ height: 100%;
+ position: relative;
+}
+
+.image.video-placeholder > button[data-role="add-video-button"],
+.image.video-placeholder > button {
+ width: 100%;
+ height: 100%;
+ border: 0;
+ background: transparent;
+ z-index: 10;
+ position: relative;
+}
+
+.add-video-button-container {
+ float: right;
+ margin-bottom: 10px;
+}
+
+.admin__field.field.field-new_video_screenshot {
+ margin-bottom: 5px;
+}
+
+.admin__field.field.field-new_video_screenshot_preview {
+ margin-bottom: 50px;
+}
+
+.image .action-make-base:after {
+ -webkit-font-smoothing: antialiased;
+ font-size: 1.8rem;
+ line-height: inherit;
+ color: #9e9e9e;
+ content: '\e63b';
+ font-family: 'Admin Icons';
+ vertical-align: middle;
+ display: inline-block;
+ font-weight: normal;
+ overflow: hidden;
+ speak: none;
+ text-align: center;
+ position: absolute;
+ top: -7px;
+ left: -4px;
+}
+
+.image .action-make-base:hover:after {
+ color: #7d7d7d;
+}
+
+.admin__scope-old .gallery .image .action-make-base {
+ border: 0;
+ width: 0;
+ height: 0;
+ position: absolute;
+ margin: 0;
+ bottom: 9px;
+ right: 9px;
+ left: auto;
+ background: transparent;
+}
+
+.image .action-make-base span {
+ display: none;
+}
+
+.admin__scope-old .base-image .image-label {
+ display: block;
+}
+
+.image.base-image:hover .image-label {
+ display: none;
+}
diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/images/camera.png b/app/code/Magento/ProductVideo/view/adminhtml/web/images/camera.png
new file mode 100644
index 0000000000000..468f922ecb12d
Binary files /dev/null and b/app/code/Magento/ProductVideo/view/adminhtml/web/images/camera.png differ
diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js b/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js
new file mode 100644
index 0000000000000..d692aaf4eccf6
--- /dev/null
+++ b/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js
@@ -0,0 +1,534 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+require([
+ 'jquery',
+ 'Magento_Ui/js/modal/alert',
+ 'jquery/ui'
+ ],
+ function ($, alert) {
+ 'use strict';
+
+ var videoRegister = {
+ _register: {},
+
+ /**
+ * Checks, if api is already registered
+ *
+ * @param {String} api
+ * @returns {bool}
+ */
+ isRegistered: function (api) {
+ return this._register[api] !== undefined;
+ },
+
+ /**
+ * Checks, if api is loaded
+ *
+ * @param {String} api
+ * @returns {bool}
+ */
+ isLoaded: function (api) {
+ return this._register[api] !== undefined && this._register[api] === true;
+ },
+
+ /**
+ * Register new video api
+ * @param {String} api
+ * @param {bool} loaded
+ */
+ register: function (api, loaded) {
+ loaded = loaded || false;
+ this._register[api] = loaded;
+ }
+ };
+
+ $.widget('mage.productVideoLoader', {
+
+ /**
+ * @private
+ */
+ _create: function () {
+ switch (this.element.data('type')) {
+ case 'youtube':
+ this.element.videoYoutube();
+ this._player = this.element.data('mageVideoYoutube');
+ break;
+
+ case 'vimeo':
+ this.element.videoVimeo();
+ this._player = this.element.data('mageVideoVimeo');
+ break;
+ default:
+ throw {
+ name: 'Video Error',
+ message: 'Unknown video type',
+
+ /**
+ * Return string
+ */
+ toString: function () {
+ return this.name + ': ' + this.message;
+ }
+ };
+ }
+ },
+
+ /**
+ * Initializes variables
+ * @private
+ */
+ _initialize: function () {
+ this._params = this.element.data('params') || {};
+ this._code = this.element.data('code');
+ this._width = this.element.data('width');
+ this._height = this.element.data('height');
+ this._autoplay = !!this.element.data('autoplay');
+ this._playing = this._autoplay || false;
+
+ this._responsive = this.element.data('responsive') !== false;
+
+ if (this._responsive === true) {
+ this.element.addClass('responsive');
+ }
+
+ this._calculateRatio();
+ },
+
+ /**
+ * Abstract play command
+ */
+ play: function () {
+ this._player.play();
+ },
+
+ /**
+ * Abstract pause command
+ */
+ pause: function () {
+ this._player.pause();
+ },
+
+ /**
+ * Abstract stop command
+ */
+ stop: function () {
+ this._player.stop();
+ },
+
+ /**
+ * Abstract playing command
+ */
+ playing: function () {
+ return this._player.playing();
+ },
+
+ /**
+ * Abstract destroying command
+ */
+ destroy: function () {
+ this._player.destroy();
+ },
+
+ /**
+ * Calculates ratio for responsive videos
+ * @private
+ */
+ _calculateRatio: function () {
+ if (!this._responsive) {
+ return;
+ }
+ this.element.css('paddingBottom', this._height / this._width * 100 + '%');
+ }
+ });
+
+ $.widget('mage.videoYoutube', $.mage.productVideoLoader, {
+
+ /**
+ * Initialization of the Youtube widget
+ * @private
+ */
+ _create: function () {
+ var self = this;
+
+ this._initialize();
+
+ this.element.append('
');
+
+ this._on(window, {
+
+ /**
+ * Youtube state check
+ * @private
+ */
+ 'youtubeapiready': function () {
+ if (self._player !== undefined) {
+ return;
+ }
+
+ if (self._autoplay) {
+ self._params.autoplay = 1;
+ }
+ self._params.rel = 0;
+
+ self._player = new window.YT.Player(self.element.children(':first')[0], {
+ height: self._height,
+ width: self._width,
+ videoId: self._code,
+ playerVars: self._params,
+ events: {
+
+ /**
+ * @private
+ */
+ 'onReady': function onPlayerReady() {
+ self._player.getDuration();
+ },
+
+ /**
+ * State change flag init
+ */
+ onStateChange: function (data) {
+ switch (window.parseInt(data.data, 10)) {
+ case 1:
+ self._playing = true;
+ break;
+ default:
+ self._playing = false;
+ break;
+ }
+
+ self._trigger('statechange', {}, data);
+ }
+ }
+
+ });
+ }
+ });
+
+ this._loadApi();
+ },
+
+ /**
+ * Loads Youtube API and triggers event, when loaded
+ * @private
+ */
+ _loadApi: function () {
+ var element,
+ scriptTag;
+
+ if (videoRegister.isRegistered('youtube')) {
+ if (videoRegister.isLoaded('youtube')) {
+ $(window).trigger('youtubeapiready');
+ }
+
+ return;
+ }
+ videoRegister.register('youtube');
+
+ element = document.createElement('script');
+ scriptTag = document.getElementsByTagName('script')[0];
+
+ element.async = true;
+ element.src = 'https://www.youtube.com/iframe_api';
+ scriptTag.parentNode.insertBefore(element, scriptTag);
+
+ /**
+ * Trigger youtube api ready event
+ */
+ window.onYouTubeIframeAPIReady = function () {
+ $(window).trigger('youtubeapiready');
+ videoRegister.register('youtube', true);
+ };
+ },
+
+ /**
+ * Play command for Youtube
+ */
+ play: function () {
+ this._player.playVideo();
+ this._playing = true;
+ },
+
+ /**
+ * Pause command for Youtube
+ */
+ pause: function () {
+ this._player.pauseVideo();
+ this._playing = false;
+ },
+
+ /**
+ * Stop command for Youtube
+ */
+ stop: function () {
+ this._player.stopVideo();
+ this._playing = false;
+ },
+
+ /**
+ * Playing command for Youtube
+ */
+ playing: function () {
+ return this._playing;
+ },
+
+ /**
+ * stops and unloads player
+ * @private
+ */
+ destroy: function () {
+ this.stop();
+ this._player.destroy();
+ }
+ });
+
+ $.widget('mage.videoVimeo', $.mage.productVideoLoader, {
+
+ /**
+ * Initialize the Vimeo widget
+ * @private
+ */
+ _create: function () {
+ var timestamp,
+ src,
+ additionalParams;
+
+ this._initialize();
+ timestamp = new Date().getTime();
+
+ if (this._autoplay) {
+ additionalParams += '&autoplay=1';
+ }
+
+ src = 'http://player.vimeo.com/video/' +
+ this._code + '?api=1&player_id=vimeo' +
+ this._code +
+ timestamp +
+ additionalParams;
+ this.element.append(
+ $('
')
+ .attr('frameborder', 0)
+ .attr('id', 'vimeo' + this._code + timestamp)
+ .attr('width', this._width)
+ .attr('height', this._height)
+ .attr('src', src)
+ );
+
+ }
+ });
+
+ $.widget('mage.videoData', {
+ options: {
+ youtubeKey: 'AIzaSyDwqDWuw1lra-LnpJL2Mr02DYuFmkuRSns' //sample data, change later!
+ },
+
+ _REQUEST_VIDEO_INFORMATION_TRIGGER: 'update_video_information',
+
+ _UPDATE_VIDEO_INFORMATION_TRIGGER: 'updated_video_information',
+
+ _ERROR_UPDATE_INFORMATION_TRIGGER: 'error_updated_information',
+
+ _videoInformation: null,
+
+ /**
+ * @private
+ */
+ _init: function () {
+ this._onRequestHandler();
+ },
+
+ /**
+ * @private
+ */
+ _onRequestHandler: function () {
+ var url = this.element.val(),
+ self = this,
+ videoInfo,
+ type,
+ id,
+ googleapisUrl;
+
+ if (!url) {
+ //this._onRequestError("Video url is undefined");
+ return;
+ }
+
+ videoInfo = this._validateURL(url);
+
+ if (!videoInfo) {
+ this._onRequestError('Invalid video url');
+
+ return;
+ }
+
+ /**
+ * @private
+ */
+ function _onYouTubeLoaded(data) {
+ var tmp,
+ uploadedFormatted,
+ respData;
+
+ if (data.items.length < 1) {
+ this._onRequestError('Video not found');
+
+ return;
+ }
+ tmp = data.items[0];
+ uploadedFormatted = tmp.snippet.publishedAt.replace('T', ' ').replace(/\..+/g, '');
+ respData = {
+ duration: this._formatYoutubeDuration(tmp.contentDetails.duration),
+ channel: tmp.snippet.channelTitle,
+ channelId: tmp.snippet.channelId,
+ uploaded: uploadedFormatted,
+ title: tmp.snippet.localized.title,
+ description: tmp.snippet.description,
+ thumbnail: tmp.snippet.thumbnails.high.url,
+ videoId: videoInfo.id,
+ videoProvider: videoInfo.type
+ };
+ this._videoInformation = respData;
+ this.element.trigger(this._UPDATE_VIDEO_INFORMATION_TRIGGER, respData);
+ }
+
+ /**
+ * @private
+ */
+ function _onVimeoLoaded(data) {
+ var tmp = data[0],
+ respData;
+
+ if (data.length < 1) {
+ this._onRequestError('Video not found');
+
+ return null;
+ }
+ tmp = data[0];
+ respData = {
+ duration: this._formatVimeoDuration(tmp.duration),
+ channel: tmp['user_name'],
+ channelId: tmp['user_url'],
+ uploaded: tmp['upload_date'],
+ title: tmp.title,
+ description: tmp.description.replace(/( |<([^>]+)>)/ig, ''),
+ thumbnail: tmp['thumbnail_large'],
+ videoId: videoInfo.id,
+ videoProvider: videoInfo.type
+ };
+ this._videoInformation = respData;
+ this.element.trigger(this._UPDATE_VIDEO_INFORMATION_TRIGGER, respData);
+ }
+
+ type = videoInfo.type;
+ id = videoInfo.id;
+
+ if (type === 'youtube') {
+ googleapisUrl = 'https://www.googleapis.com/youtube/v3/videos?id=' +
+ id +
+ '&part=snippet,contentDetails,statistics,status&key=' +
+ this.options.youtubeKey;
+ $.get(googleapisUrl, $.proxy(_onYouTubeLoaded, this));
+ } else if (type === 'vimeo') {
+ $.getJSON('http://www.vimeo.com/api/v2/video/' + id + '.json?callback=?',
+ {
+ format: 'json'
+ },
+ $.proxy(_onVimeoLoaded, self)
+ ).fail(
+ function () {
+ self._onRequestError('Video not found');
+ }
+ );
+ }
+ },
+
+ /**
+ * @private
+ */
+ _onRequestError: function (error) {
+ this._videoInformation = null;
+ this.element.trigger(this._ERROR_UPDATE_INFORMATION_TRIGGER, error);
+ this.element.val('');
+ alert({
+ content: 'Error: "' + error + '"'
+ });
+ },
+
+ /**
+ * @private
+ */
+ _formatYoutubeDuration: function (duration) {
+ var match = duration.match(/PT(\d+H)?(\d+M)?(\d+S)?/),
+ hours = parseInt(match[1], 10) || 0,
+ minutes = parseInt(match[2], 10) || 0,
+ seconds = parseInt(match[3], 10) || 0;
+
+ return this._formatVimeoDuration(hours * 3600 + minutes * 60 + seconds);
+ },
+
+ /**
+ * @private
+ */
+ _formatVimeoDuration: function (seconds) {
+ return (new Date(seconds * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];
+ },
+
+ /**
+ * @private
+ */
+ _parseHref: function (href) {
+ var a = document.createElement('a');
+
+ a.href = href;
+
+ return a;
+ },
+
+ /**
+ * @private
+ */
+ _validateURL: function (href, forceVideo) {
+ var id,
+ type,
+ ampersandPosition;
+
+ if (typeof href !== 'string') {
+ return href;
+ }
+ href = this._parseHref(href);
+
+ if (href.host.match(/youtube\.com/) && href.search) {
+
+ id = href.search.split('v=')[1];
+
+ if (id) {
+ ampersandPosition = id.indexOf('&');
+ type = 'youtube';
+ }
+
+ if (id && ampersandPosition !== -1) {
+ id = id.substring(0, ampersandPosition);
+ }
+
+ } else if (href.host.match(/youtube\.com|youtu\.be/)) {
+ id = href.pathname.replace(/^\/(embed\/|v\/)?/, '').replace(/\/.*/, '');
+ type = 'youtube';
+ } else if (href.host.match(/vimeo\.com/)) {
+ type = 'vimeo';
+ id = href.pathname.replace(/^\/(video\/)?/, '').replace(/\/.*/, '');
+ }
+
+ if ((!id || !type) && forceVideo) {
+ id = href.href;
+ type = 'custom';
+ }
+
+ return id ? {
+ id: id, type: type, s: href.search.replace(/^\?/, '')
+ } : false;
+ }
+ });
+ });
diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js b/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js
index bbddacac644ae..980ac3a2e4ddb 100644
--- a/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js
+++ b/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js
@@ -2,7 +2,6 @@
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-/*jshint browser:true $:true*/
define([
'jquery',
'Magento_Ui/js/modal/alert',
@@ -10,10 +9,165 @@ define([
'Magento_Ui/js/modal/modal',
'mage/translate',
'mage/backend/tree-suggest',
- 'mage/backend/validation'
+ 'mage/backend/validation',
+ 'Magento_ProductVideo/js/get-video-information'
], function ($, alert) {
'use strict';
+ $.widget('mage.createVideoPlayer', {
+ options: {
+ videoId: '',
+ videoProvider: '',
+ container: '.video-player-container',
+ videoClass: 'product-video',
+ reset: false,
+ metaData: {
+ DOM: {
+ title: '.video-information.title span',
+ uploaded: '.video-information.uploaded span',
+ uploader: '.video-information.uploader span',
+ duration: '.video-information.duration span',
+ all: '.video-information span',
+ wrapper: '.video-information'
+ },
+ data: {
+ title: '',
+ uploaded: '',
+ uploader: '',
+ uploaderUrl: '',
+ duration: ''
+ }
+ }
+ },
+
+ /**
+ * @private
+ */
+ _init: function () {
+ if (this.options.reset) {
+ this.reset();
+ } else {
+ this.update();
+ }
+
+ this.element.on('reset', $.proxy(this.reset, this));
+
+ },
+
+ /**
+ * @returns {Boolean}
+ */
+ update: function () {
+ var checkVideoID = $(this.options.container).find('.' + this.options.videoClass).data('code');
+
+ if (checkVideoID && checkVideoID !== this.options.videoId) {
+ this._doUpdate();
+ } else
+ if (checkVideoID && checkVideoID === this.options.videoId) {
+ return false;
+ } else
+ if (!checkVideoID) {
+ this._doUpdate();
+ }
+
+ },
+
+ /**
+ * @private
+ */
+ _doUpdate: function () {
+ this.reset();
+ $(this.options.container).append('
');
+ $(this.options.metaData.DOM.wrapper).show();
+ $(this.options.metaData.DOM.title).text(this.options.metaData.data.title);
+ $(this.options.metaData.DOM.uploaded).text(this.options.metaData.data.uploaded);
+ $(this.options.metaData.DOM.duration).text(this.options.metaData.data.duration);
+
+ if (this.options.videoProvider === 'youtube') {
+ $(this.options.metaData.DOM.uploader).html(
+ '
' +
+ this.options.metaData.data.uploader +
+ ''
+ );
+ } else
+ if (this.options.videoProvider === 'vimeo') {
+ $(this.options.metaData.DOM.uploader).html(
+ '
' + this.options.metaData.data.uploader +
+ '');
+ }
+ $('.' + this.options.videoClass).productVideoLoader();
+
+ },
+
+ /**
+ * Reset
+ */
+ reset: function () {
+ $(this.options.container).find('.' + this.options.videoClass).remove();
+ $(this.options.metaData.DOM.wrapper).hide();
+ $(this.options.metaData.DOM.all).text('');
+
+ }
+ });
+
+ $.widget('mage.updateInputFields', {
+ options: {
+ reset: false,
+ DOM: {
+ urlField: 'input[name="video_url"]',
+ titleField: 'input[name="video_title"]',
+ fileField: '#file_name',
+ descriptionField: 'textarea[name="video_description"]',
+ thumbnailLocation: '.field-new_video_screenshot_preview .admin__field-control'
+ },
+ data: {
+ url: '',
+ title: '',
+ description: '',
+ thumbnail: ''
+ }
+ },
+
+ /**
+ * @private
+ */
+ _init: function () {
+ if (this.options.reset) {
+ this.reset();
+ } else {
+ this.update();
+ }
+ },
+
+ /**
+ * Update
+ */
+ update: function () {
+ $(this.options.DOM.titleField).val(this.options.data.title);
+ $(this.options.DOM.descriptionField).val(this.options.data.description);
+ },
+
+ /**
+ * Reset
+ */
+ reset: function () {
+ $(this.options.DOM.fileField).val('');
+ $(this.options.DOM.urlField).val('');
+ $(this.options.DOM.titleField).val('');
+ $(this.options.DOM.descriptionField).val('');
+ }
+ });
+
/**
*/
$.widget('mage.newVideoDialog', {
@@ -25,14 +179,59 @@ define([
_images: {},
_imageTypes: [
- 'image/jpeg',
- 'image/pjpeg',
- 'image/jpeg',
- 'image/pjpeg',
- 'image/png',
- 'image/gif'
+ '.jpeg',
+ '.pjpeg',
+ '.jpeg',
+ '.jpg',
+ '.pjpeg',
+ '.png',
+ '.gif'
],
+ _imageWidgetSelector: '#media_gallery_content',
+
+ _imageProductGalleryWrapperSelector: '#image-container',
+
+ _videoPreviewInputSelector: '#new_video_screenshot',
+
+ _videoPreviewRemoteSelector: '',
+
+ _videoDisableinputSelector: '#new_video_disabled',
+
+ _videoPreviewImagePointer: '#new_video_screenshot_preview',
+
+ _videoFormSelector: '#new_video_form',
+
+ _itemIdSelector: '#item_id',
+
+ _videoUrlSelector: '[name="video_url"]',
+
+ _videoImageFilenameselector: '#file_name',
+
+ _videoUrlWidget: null,
+
+ _videoInformationBtnSelector: '[name="new_video_get"]',
+
+ _editVideoBtnSelector: '#media_gallery_content .image',
+
+ _deleteGalleryVideoSelector: '[data-role=delete-button]',
+
+ _deleteGalleryVideoSelectorBtn: null,
+
+ _videoInformationGetBtn: null,
+
+ _videoInformationGetUrlField: null,
+
+ _videoInformationGetEditBtn: null,
+
+ _isEditPage: false,
+
+ _onlyVideoPlayer: false,
+
+ _tempPreviewImageData: null,
+
+ _videoPlayerSelector: '.mage-new-video-dialog',
+
/**
* Bind events
* @private
@@ -43,6 +242,119 @@ define([
};
this._on(events);
+
+ this._videoUrlWidget = $(this._videoUrlSelector).videoData();
+ this._videoInformationGetBtn = $(this._videoInformationBtnSelector);
+ this._videoInformationGetUrlField = $(this._videoUrlSelector);
+ this._videoInformationGetEditBtn = $(this._editVideoBtnSelector);
+
+ this._videoInformationGetBtn.on('click', $.proxy(this._onGetVideoInformationClick, this));
+ this._videoInformationGetUrlField.on('focusout', $.proxy(this._onGetVideoInformationFocusOut, this));
+ this._videoUrlWidget.on('updated_video_information', $.proxy(this._onGetVideoInformationSuccess, this));
+ this._videoUrlWidget.on('error_updated_information', $.proxy(this._onGetVideoInformationError, this));
+
+ },
+
+ /**
+ * Fired when user click on button "Get video information"
+ * @private
+ */
+ _onGetVideoInformationClick: function () {
+ this._onlyVideoPlayer = false;
+ this._isEditPage = false;
+ this._videoInformationGetUrlField.videoData();
+ this._videoUrlWidget.trigger('update_video_information');
+ },
+
+ /**
+ * Fired when user do focus out from url field
+ * @private
+ */
+ _onGetVideoInformationFocusOut: function () {
+ this._videoInformationGetUrlField.videoData();
+ this._videoUrlWidget.trigger('update_video_information');
+ },
+
+ /**
+ * Fired when user click Edit Video button
+ * @private
+ */
+ _onGetVideoInformationEditClick: function () {
+ this._onlyVideoPlayer = true;
+ this._isEditPage = true;
+ this._videoInformationGetUrlField.videoData();
+ this._videoUrlWidget.trigger('update_video_information');
+ },
+
+ /**
+ * Fired when successfully received information about the video.
+ * @param {Object} e
+ * @param {Object} data
+ * @private
+ */
+ _onGetVideoInformationSuccess: function (e, data) {
+ var player = $(this._videoPlayerSelector).createVideoPlayer({
+ videoId: data.videoId,
+ videoProvider: data.videoProvider,
+ reset: false,
+ metaData: {
+ DOM: {
+ title: '.video-information.title span',
+ uploaded: '.video-information.uploaded span',
+ uploader: '.video-information.uploader span',
+ duration: '.video-information.duration span',
+ all: '.video-information span',
+ wrapper: '.video-information'
+ },
+ data: {
+ title: data.title,
+ uploaded: data.uploaded,
+ uploader: data.channel,
+ duration: data.duration,
+ uploaderUrl: data.channelId
+ }
+ }
+ });
+
+ if (!this._isEditPage) {
+ player.updateInputFields({
+ reset: false,
+ data: {
+ title: data.title,
+ description: data.description
+ }
+ });
+ this._loadRemotePreview(data.thumbnail);
+ }
+ },
+
+ /**
+ * Load preview from youtube/vimeo
+ * @param {String} sourceUrl
+ * @private
+ */
+ _loadRemotePreview: function (sourceUrl) {
+ var url = this.options.saveRemoteVideoUrl,
+ self = this;
+
+ this._blockActionButtons(true, true);
+ $.ajax({
+ url: url,
+ data: 'remote_image=' + sourceUrl,
+ type: 'post',
+ success: $.proxy(function (result) {
+ this._tempPreviewImageData = result;
+ this._getPreviewImage().attr('src', sourceUrl).show();
+ this._blockActionButtons(false, true);
+ }, self)
+ });
+ },
+
+ /**
+ * Fired when receiving information about the video ended with error
+ * @private
+ */
+ _onGetVideoInformationError: function () {
},
/**
@@ -55,7 +367,7 @@ define([
var tmppost = '.tmp';
if (!name) {
- return null;
+ return name;
}
if (name.endsWith(tmppost)) {
@@ -74,7 +386,7 @@ define([
_setImage: function (file, imageData) {
file = this.__prepareFilename(file);
this._images[file] = imageData;
- $('#media_gallery_content').trigger('addItem', imageData);
+ $(this._imageWidgetSelector).trigger('addItem', imageData);
this.element.trigger('setImage', imageData);
this._addVideoClass(imageData.url);
},
@@ -93,7 +405,7 @@ define([
},
/**
- * Replace image
+ * Replace image (update)
* @param {String} oldFile
* @param {String} newFile
* @param {Object} imageData
@@ -122,11 +434,13 @@ define([
this._setImage(newFile, imageData);
if (oldFile && imageData.oldFile) {
- newImageId = this.findElementId(tmpNewFile),
- fc = $('#item_id').val(),
- suff = 'product[media_gallery][images]' + fc,
- searchsuff = 'input[name="' + suff + '[value_id]"]',
- key = $(searchsuff).val();
+ newImageId = this.findElementId(tmpNewFile);
+ fc = $(this._itemIdSelector).val();
+
+ suff = 'product[media_gallery][images]' + fc;
+
+ searchsuff = 'input[name="' + suff + '[value_id]"]';
+ key = $(searchsuff).val();
if (!key) {
return null;
@@ -153,7 +467,7 @@ define([
return null;
}
- $('#media_gallery_content').trigger('removeItem', imageData);
+ $(this._imageWidgetSelector).trigger('removeItem', imageData);
this.element.trigger('removeImage', imageData);
delete this._images[file];
},
@@ -169,70 +483,83 @@ define([
},
/**
- * Upload local image
+ *
+ * Wrap _uploadFile
* @param {String} file
* @param {String} oldFile
* @param {Function} callback
* @private
*/
_uploadImage: function (file, oldFile, callback) {
- var self = this,
- url = this.options.saveVideoUrl,
- uploadData = {
- files: file,
- url: url
- };
+ var url = this.options.saveVideoUrl,
+ data = {
+ files: file,
+ url: url
+ };
- this._uploadFile('send', uploadData, function (result) {
- var data = JSON.parse(result);
+ this._blockActionButtons(true, true);
+ this._uploadFile(data, $.proxy(function (result) {
+ this._onImageLoaded(result, file, oldFile, callback);
+ this._blockActionButtons(false);
+ }, this));
- if (data && data.errorcode) {
- alert({
- content: data.error
- });
+ },
- return null;
- }
+ /**
+ * @param {String} result
+ * @param {String} file
+ * @param {String} oldFile
+ * @param {Function} callback
+ * @private
+ */
+ _onImageLoaded: function (result, file, oldFile, callback) {
+ var data = JSON.parse(result);
- $.each($('#new_video_form').serializeArray(), function (i, field) {
- data[field.name] = field.value;
+ if (data.errorcode || data.error) {
+ alert({
+ content: data.error
});
- data.disabled = $('#new_video_disabled').prop('checked') ? 1 : 0;
- data['media_type'] = 'external-video';
- data['old_file'] = oldFile;
- oldFile ?
- self._replaceImage(oldFile, data.file, data) :
- self._setImage(data.file, data);
-
- callback.call(0, data);
+
+ return;
+ }
+ $.each($(this._videoFormSelector).serializeArray(), function (i, field) {
+ data[field.name] = field.value;
});
+ data.disabled = $(this._videoDisableinputSelector).attr('checked') ? 1 : 0;
+ data['media_type'] = 'external-video';
+ data.oldFile = oldFile;
+
+ oldFile ?
+ this._replaceImage(oldFile, data.file, data) :
+ this._setImage(data.file, data);
+ callback.call(0, data);
},
/**
- * Upload local file
+ * File uploader
* @private
*/
- _uploadFile: function (method, data, callback) {
- var fu = $('#new_video_screenshot'),
+ _uploadFile: function (data, callback) {
+ var fu = $(this._videoPreviewInputSelector),
tmpInput = document.createElement('input'),
fileUploader = null;
$(tmpInput).attr({
- name: fu.attr('name'),
- value: fu.val(),
- type: 'file',
+ 'name': fu.attr('name'),
+ 'value': fu.val(),
+ 'type': 'file',
'data-ui-ud': fu.attr('data-ui-ud')
}).css('display', 'none');
fu.parent().append(tmpInput);
fileUploader = $(tmpInput).fileupload();
- fileUploader.fileupload(method, data).success(function (result, textStatus, jqXHR) {
+ fileUploader.fileupload('send', data).success(function (result, textStatus, jqXHR) {
tmpInput.remove();
callback.call(null, result, textStatus, jqXHR);
});
},
/**
- * Add video class (gallery items)
+ * Update style
* @param {String} url
* @private
*/
@@ -243,11 +570,11 @@ define([
},
/**
- * Fired when widget initialized
+ * Build widget
* @private
*/
_create: function () {
- var imgs = $('#media_gallery_content').data('images') || [],
+ var imgs = $(this._imageWidgetSelector).data('images') || [],
widget,
uploader,
tmp,
@@ -255,232 +582,256 @@ define([
for (i = 0; i < imgs.length; i++) {
tmp = imgs[i];
- tmp.subclass = 'video-item';
this._images[tmp.file] = tmp;
- this._addVideoClass(tmp.url);
- }
+ if (tmp['media_type'] === 'external-video') {
+ tmp.subclass = 'video-item';
+ this._addVideoClass(tmp.url);
+ }
+ }
+ $('.gallery.ui-sortable').on('openDialog', $.proxy(this._onOpenDialog, this));
this._bind();
+ this.createVideoItemIcons();
widget = this;
- uploader = $('#new_video_screenshot');
+ uploader = $(this._videoPreviewInputSelector);
uploader.on('change', this._onImageInputChange.bind(this));
- this.toggleButtons();
uploader.attr('accept', this._imageTypes.join(','));
+
this.element.modal({
type: 'slide',
modalClass: 'mage-new-video-dialog form-inline',
- title: $.mage.__('Create Video'),
- buttons: [{
- text: $.mage.__('Save'),
- class: 'action-primary video-create-button',
-
- /**
- * Fired when click on Save button
- */
- click: function () {
- var nvs = $('#new_video_screenshot'),
- file = nvs.get(0),
- newVideoForm,
- reqClass = 'required-entry _required';
-
- if (file && file.files && file.files.length) {
- file = file.files[0];
- } else {
- file = null;
- }
-
- if (!file) {
- nvs.addClass(reqClass);
- }
-
- newVideoForm = $('#new_video_form');
- newVideoForm.mage('validation', {
-
- /**
- * Set invalid message
- * @param {jQuery} error
- * @param {jQuery} element
- */
- errorPlacement: function (error, element) {
- error.insertAfter(element);
- }
- }).on('highlight.validate', function () {
- $(this).validation('option');
- });
- newVideoForm.validation();
-
- if (!newVideoForm.valid()) {
- return null;
- }
-
- widget._uploadImage(file, null, function () {
- //uploader.replaceWith(data.file);
- widget._onClose();
- });
- nvs.removeClass(reqClass);
- }
- },
+ title: $.mage.__('New Video'),
+ buttons: [
{
text: $.mage.__('Save'),
- class: 'action-primary video-edit',
-
- /**
- * Fired when video edit
- */
- click: function () {
- var newVideoForm = $('#new_video_form'),
- inputFile,
- flagChecked,
- imageData,
- fileName,
- itemVal,
- mediaFields,
-
- /**
- * Callback for event "modalClose"
- */
- callback = function () {
- widget._onClose();
- };
-
- newVideoForm.mage('validation', {
-
- /**
- * Set invalid message
- * @param {jQuery} error
- * @param {jQuery} element
- */
- errorPlacement: function (error, element) {
- error.insertAfter(element);
- }
- }).on('highlight.validate', function () {
- $(this).validation('option');
- });
- newVideoForm.validation();
-
- if (!newVideoForm.valid()) {
- return null;
- }
-
- inputFile = uploader;
- itemVal = $('#item_id').val();
- mediaFields = $('input[name*="' + itemVal + '"]');
- $.each(mediaFields, function (itmp, el) {
- var start = el.name.indexOf(itemVal) + itemVal.length + 1,
- fieldName = el.name.substring(start, el.name.length - 1),
- fieldItem = $('#' + fieldName);
-
- if (fieldItem.length > 0) {
- $('input[name*="' + itemVal + '[' + fieldName + ']"]').val(fieldItem.val());
- }
- });
- flagChecked = $('#new_video_disabled').prop('checked') ? 1 : 0;
- $('input[name*="' + itemVal + '[disabled]"]').val(flagChecked);
-
- if (flagChecked) {
- $('[name*="' + itemVal + '"]').siblings('.image-fade').css('visibility', 'visible');
- } else {
- $('[name*="' + itemVal + '"]').siblings('.image-fade').css('visibility', 'hidden');
- }
-
- imageData = widget._getImage($('#file_name').val());
- fileName = $('#new_video_screenshot').get(0).files[0];
- uploader.replaceWith(inputFile);
-
- if (!fileName) {
- callback.call(0, imageData);
- widget._replaceImage(imageData.file, imageData.file, imageData);
- } else {
- widget._uploadImage(fileName, imageData.file, callback);
- }
- }
+ class: 'action-primary video-create-button',
+ click: $.proxy(widget._onCreate, widget)
+ },
+ {
+ text: $.mage.__('Cancel'),
+ class: 'video-cancel-button',
+ click: $.proxy(widget._onCancel, widget)
},
{
text: $.mage.__('Delete'),
- class: 'action-primary video-delete-button',
-
- /**
- * Fired when click on delete image button
- */
- click: function () {
- var removed = $('[name*="' + $('#item_id').val() + '[removed]"]');
-
- widget._onClose();
- removed.val(1);
- removed.parent().hide();
- }
+ class: 'video-delete-button',
+ click: $.proxy(widget._onDelete, widget)
},
{
- text: $.mage.__('Cancel'),
- class: 'video-cancel-button',
-
- /**
- * Fired when click on Close dialog button
- * @param {Event} e
- */
- click: function (e) {
- widget._onClose(e);
- }
- }],
+ text: $.mage.__('Save'),
+ class: 'action-primary video-edit',
+ click: $.proxy(widget._onUpdate, widget)
+ }
+ ],
/**
- * Open widged action
+ * @returns {null}
*/
opened: function () {
- var file = $('#file_name').val(),
- imageData;
+ var roles, file, modalTitleElement, imageData;
$('#video_url').focus();
- $('button[data-role="close-panel"]').click();
+ roles = $('.video_image_role');
+ roles.prop('disabled', false);
+ file = $('#file_name').val();
+ widget._onGetVideoInformationEditClick();
+ modalTitleElement = $('.modal-title');
if (!file) {
+ widget._blockActionButtons(true);
+ roles.prop('checked', $('.image.item:not(.removed)').length < 1);
+ modalTitleElement.text($.mage.__('New Video'));
+ widget._isEditPage = false;
+
return null;
}
+ modalTitleElement.text($.mage.__('Edit Video'));
+ widget._isEditPage = true;
imageData = widget._getImage(file);
widget._onPreview(null, imageData.url, false);
},
/**
- * Closed widged action
+ * Closed
*/
closed: function () {
- var newVideoForm = $('#new_video_form');
+ widget._onClose();
+ widget.createVideoItemIcons();
+ }
+ });
+ this.toggleButtons();
+ },
- if (widget._previewImage) {
- widget._previewImage.remove();
- widget._previewImage = null;
- }
+ /**
+ * @param {String} status
+ * @private
+ */
+ _blockActionButtons: function (status) {
+ $('.page-actions-buttons').find('button.video-create-button').attr('disabled', status);
+ },
- $(newVideoForm).trigger('reset');
- $(newVideoForm).find('input[type="hidden"][name!="form_key"]').val('');
- $('input[name*="' + $('#item_id').val() + '"]').parent().removeClass('active');
+ /**
+ * Check form
+ * @returns {*}
+ */
+ isValid: function () {
+ var videoForm = $(this._videoFormSelector);
- try {
- newVideoForm.validation('clearError');
- } catch (e) {
+ videoForm.mage('validation', {
- }
+ /**
+ * @param {jQuery} error
+ * @param {jQuery} element
+ */
+ errorPlacement: function (error, element) {
+ error.insertAfter(element);
+ }
+ }).on('highlight.validate', function () {
+ $(this).validation('option');
+ });
+ videoForm.validation();
+
+ return videoForm.valid();
+ },
+
+ /**
+ * Create video item icons
+ */
+ createVideoItemIcons: function () {
+ var $imageWidget = $(this._imageWidgetSelector).find('.product-image.video-item'),
+ $productGalleryWrapper = $(this._imageProductGalleryWrapperSelector).find('.product-image.video-item');
+
+ $imageWidget.parent().addClass('video-item');
+ $productGalleryWrapper.parent().addClass('video-item');
+ $imageWidget.removeClass('video-item');
+ $productGalleryWrapper.removeClass('video-item');
+ },
+
+ /**
+ * Fired when click on create video
+ * @private
+ */
+ _onCreate: function () {
+ var nvs = $(this._videoPreviewInputSelector),
+ file = nvs.get(0),
+ reqClass = 'required-entry _required';
+
+ if (file && file.files && file.files.length) {
+ file = file.files[0];
+ } else {
+ file = null;
+ }
+
+ if (!file && !this._tempPreviewImageData) {
+ nvs.addClass(reqClass);
+ }
+
+ if (!this.isValid()) {
+ return;
+ }
+
+ if (this._tempPreviewImageData) {
+ this._onImageLoaded(this._tempPreviewImageData, null, null, $.proxy(this.close, this));
+ } else {
+ this._uploadImage(file, null, $.proxy(function () {
+ this.close();
+ }, this));
+ }
+
+ nvs.removeClass(reqClass);
+ },
+
+ /**
+ * Fired when click on update video
+ * @private
+ */
+ _onUpdate: function () {
+ var inputFile, itemId, _inputSelector, mediaFields, imageData, flagChecked, fileName, callback;
+
+ if (!this.isValid()) {
+ return;
+ }
+ imageData = this.imageData;
+ inputFile = $(this._videoPreviewInputSelector);
+ itemId = $(this._itemIdSelector).val();
+ itemId = itemId.slice(1, itemId.length - 1);
+ _inputSelector = '[name*="[' + itemId + ']"]';
+ mediaFields = $('input' + _inputSelector);
+ $.each(mediaFields, function (i, el) {
+ var elName = el.name,
+ start = elName.indexOf(itemId) + itemId.length + 2,
+ fieldName = elName.substring(start, el.name.length - 1),
+ _field = $('#' + fieldName),
+ _tmp;
+
+ if (_field.length > 0) {
+ _tmp = _inputSelector.slice(0, _inputSelector.length - 2) + '[' + fieldName + ']"]';
+ $(_tmp).val(_field.val());
+ imageData[fieldName] = _field.val();
}
});
+ flagChecked = $(this._videoDisableinputSelector).attr('checked') ? 1 : 0;
+ $('input[name*="' + itemId + '][disabled]"]').val(flagChecked);
+ $(_inputSelector).siblings('.image-fade').css('visibility', flagChecked ? 'visible' : 'hidden');
+ imageData.disabled = flagChecked;
+
+ if (this._tempPreviewImageData) {
+ this._onImageLoaded(this._tempPreviewImageData, null, imageData.file, $.proxy(this.close, this));
+
+ return;
+ }
+ fileName = inputFile.get(0).files;
+
+ if (!fileName || !fileName.length) {
+ fileName = null;
+ }
+ inputFile.replaceWith(inputFile);
+
+ callback = $.proxy(function () {
+ this.close();
+ }, this);
+
+ if (fileName) {
+ this._uploadImage(fileName, imageData.file, callback);
+ } else {
+ this._replaceImage(imageData.file, imageData.file, imageData);
+ callback(0, imageData);
+ }
+ },
+
+ /**
+ * Fired when clicked on cancel
+ * @private
+ */
+ _onCancel: function () {
+ this.close();
+ },
+
+ /**
+ * Fired when clicked on delete
+ * @private
+ */
+ _onDelete: function () {
+ var filename = this.element.find(this._videoImageFilenameselector).val();
+
+ this._removeImage(filename);
+ this.close();
},
/**
- * Read image from local
* @param {String} file
* @param {Function} callback
* @private
*/
_readPreviewLocal: function (file, callback) {
- var fr;
+ var fr = new FileReader;
if (!window.FileReader) {
- return null;
+ return;
}
- fr = new FileReader;
-
/**
- * Fired when image loaded
+ * On load end
*/
fr.onloadend = function () {
callback(fr.result);
@@ -489,41 +840,63 @@ define([
},
/**
- * Fired when preview input change
+ * Image file input handler
* @private
*/
_onImageInputChange: function () {
- var file = document.getElementById('new_video_screenshot').files[0];
-
- if (!file) {
- return null;
+ var jFile = $(this._videoPreviewInputSelector),
+ file = jFile[0],
+ val = jFile.val(),
+ prev = this._getPreviewImage(),
+ ext = '.' + val.split('.').pop();
+
+ if (!val) {
+ return;
}
-
+ ext = ext ? ext.toLowerCase() : '';
+
+ if (
+ ext.length < 2 ||
+ this._imageTypes.indexOf(ext.toLowerCase()) === -1 ||
+ !file.files ||
+ !file.files.length
+
+ ) {
+ prev.remove();
+ this._previewImage = null;
+ jFile.val('');
+
+ return;
+ } // end if
+ file = file.files[0];
+ this._tempPreviewImageData = null;
this._onPreview(null, file, true);
},
/**
- * Fired when image loaded
- * @param {bool} error
+ * Change Preview
+ * @param {String} error
* @param {String} src
- * @param {bool} local
+ * @param {Boolean} local
* @private
*/
_onPreview: function (error, src, local) {
- var img = this._getPreviewImage(),
+ var img, renderImage;
- /**
- * Callback
- * @param {String} source
- */
- renderImage = function (source) {
- img.attr({
- 'src': source
- }).show();
- };
+ img = this._getPreviewImage();
+
+ /**
+ * Callback
+ * @param {String} source
+ */
+ renderImage = function (source) {
+ img.attr({
+ 'src': source
+ }).show();
+ };
if (error) {
- return null;
+ return;
}
if (!local) {
@@ -534,7 +907,8 @@ define([
},
/**
- * Get preview image DOM instance
+ *
+ * Return preview image imstance
* @returns {null}
* @private
*/
@@ -542,34 +916,58 @@ define([
if (!this._previewImage) {
this._previewImage = $(document.createElement('img')).css({
- 'width': '145px',
+ 'width': '100%',
'display': 'none',
'src': ''
});
- $(this._previewImage).insertAfter('#new_video_screenshot_preview');
+ $(this._previewImage).insertAfter(this._videoPreviewImagePointer);
+ $(this._previewImage).attr('data-role', 'video_preview_image');
}
return this._previewImage;
},
/**
- * Fired when dialog close
+ * Close slideout dialog
+ */
+ close: function () {
+ this.element.trigger('closeModal');
+ },
+
+ /**
+ * Close dialog wrap
* @private
*/
_onClose: function () {
- $('#new-video').modal('closeModal');
+ var newVideoForm;
+
+ this.imageData = null;
+
+ if (this._previewImage) {
+ this._previewImage.remove();
+ this._previewImage = null;
+ }
+ this._tempPreviewImageData = null;
+ $(this._videoPlayerSelector).trigger('reset');
+ newVideoForm = this.element.find(this._videoFormSelector);
+
+ $(newVideoForm).find('input[type="hidden"][name!="form_key"]').val('');
+ $('input[name*="' + $(this._itemIdSelector).val() + '"]').parent().removeClass('active');
+
+ try {
+ newVideoForm.validation('clearError');
+ } catch (e) {}
+ newVideoForm.trigger('reset');
},
/**
* Find element by fileName
* @param {String} file
- * @returns {*}
*/
findElementId: function (file) {
var elem = $('.image.item').find('input[value="' + file + '"]');
if (!elem) {
-
return null;
}
@@ -585,17 +983,13 @@ define([
self = this,
containers;
- if (!data) {
- throw new Error('You need use _getImae');
- }
-
- if (data.length > 0) {
- containers = $('.video-placeholder').siblings('input');
+ if (data && data.length > 0) {
+ containers = $('.image-placeholder').siblings('input');
$.each(containers, function (i, el) {
var start = el.name.indexOf('[') + 1,
end = el.name.indexOf(']'),
imageType = el.name.substring(start, end),
- imageCheckbox = $('input[value="' + imageType + '"]');
+ imageCheckbox = $(self._videoFormSelector + ' input[value="' + imageType + '"]');
self._changeRole(imageType, imageCheckbox.attr('checked'), imageData);
});
@@ -617,36 +1011,90 @@ define([
}
if (!needCheked) {
-
return null;
}
- $('#media_gallery_content').trigger('setImageType', {
+ $(this._imageWidgetSelector).trigger('setImageType', {
type: imageType,
imageData: isEnabled ? imageData : null
});
},
/**
- * Register Items event listeners
+ * On open dialog
+ * @param {Object} e
+ * @param {Object} imageData
+ * @private
+ */
+ _onOpenDialog: function (e, imageData) {
+ var formFields, flagChecked, file;
+
+ if (imageData['media_type'] === 'external-video') {
+ this.imageData = imageData;
+ $('.video-create-button').hide();
+ $('.video-delete-button').show();
+ $('.video-edit').show();
+ $('.mage-new-video-dialog').createVideoPlayer({
+ reset: true
+ }).createVideoPlayer('reset');
+
+ formFields = $(this._videoFormSelector).find('.edited-data');
+
+ $.each(formFields, function (i, field) {
+ $(field).val(imageData[field.name]);
+ });
+
+ flagChecked = imageData.disabled > 0;
+ $(this._videoDisableinputSelector).prop('checked', flagChecked);
+
+ file = $('#file_name').val(imageData.file);
+
+ $.each($('.video_image_role'), function () {
+ $(this).prop('checked', false).prop('disabled', false);
+ });
+
+ $.each($('.image-placeholder').siblings('input:hidden'), function () {
+ var start, end, imageRole;
+
+ if ($(this).val() === file.val()) {
+ start = this.name.indexOf('[') + 1;
+ end = this.name.length - 1;
+ imageRole = this.name.substring(start, end);
+ $('#new_video_form input[value="' + imageRole + '"]').prop('checked', true);
+ }
+ });
+ }
+
+ },
+
+ /**
+ * Toggle buttons
*/
toggleButtons: function () {
- $('.video-placeholder').click(function () {
+ var self = this;
+
+ $('.video-placeholder, .add-video-button-container > button').click(function () {
$('.video-create-button').show();
$('.video-delete-button').hide();
$('.video-edit').hide();
- $('.modal-title').html('New video');
+ $('.mage-new-video-dialog').createVideoPlayer({
+ reset: true
+ }).createVideoPlayer('reset').updateInputFields({
+ reset: true
+ }).updateInputFields('reset');
});
- $(document).on('click', '.item.image', function () {
+ $(document).on('click', '#media_gallery_content .item.video-item', function () {
$('.video-create-button').hide();
$('.video-delete-button').show();
$('.video-edit').show();
- $('.modal-title').html('Edit video');
+ $('.mage-new-video-dialog').createVideoPlayer({
+ reset: true
+ }).createVideoPlayer('reset');
});
- $(document).on('click', '.item.image', function () {
+ $(document).on('click', '#media_gallery_content .item.video-item:not(.removed)', function () {
var flagChecked,
file,
- formFields = $('#new_video_form').find('.edited-data'),
+ formFields = $(self._videoFormSelector).find('.edited-data'),
container = $(this);
$.each(formFields, function (i, field) {
@@ -654,32 +1102,31 @@ define([
});
flagChecked = container.find('input[name*="disabled"]').val() > 0;
- $('#new_video_disabled').prop('checked', flagChecked);
+ $(self._videoDisableinputSelector).attr('checked', flagChecked);
file = $('#file_name').val(container.find('input[name*="file"]').val());
+
$.each($('.video_image_role'), function () {
$(this).prop('checked', false).prop('disabled', false);
});
- $.each($('.video-placeholder').siblings('input:hidden'), function () {
- var start,
- end,
- imageRole;
- if ($(this).val() !== file.val()) {
+ $.each($('.image-placeholder').siblings('input:hidden'), function () {
+ var start, end, imageRole;
+ if ($(this).val() !== file.val()) {
return null;
}
- start = this.name.indexOf('[') + 1,
- end = this.name.length - 1,
- imageRole = this.name.substring(start, end);
+
+ start = this.name.indexOf('[') + 1;
+ end = this.name.length - 1;
+ imageRole = this.name.substring(start, end);
$('input[value="' + imageRole + '"]').prop('checked', true);
});
});
}
});
- $('.video-create-button').on('click', function () {
- $('#media_gallery_content').find('.video-item').parent().addClass('video-item');
- });
+
+ $('#group-fields-image-management > legend > span').text('Images and Videos');
return $.mage.newVideoDialog;
});
diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/js/video-modal.js b/app/code/Magento/ProductVideo/view/adminhtml/web/js/video-modal.js
index 77221c35d1b37..f7e0e72de69c1 100644
--- a/app/code/Magento/ProductVideo/view/adminhtml/web/js/video-modal.js
+++ b/app/code/Magento/ProductVideo/view/adminhtml/web/js/video-modal.js
@@ -30,21 +30,27 @@ define([
*/
_bind: function () {
$(this.element).on('click', this.showModal.bind(this));
+ $('.gallery.ui-sortable').on('openDialog', $.proxy(this._onOpenDialog, this));
+ },
+
+ /**
+ * Open dialog for external video
+ * @private
+ */
+ _onOpenDialog: function (e, imageData) {
+
+ if (imageData['media_type'] !== 'external-video') {
+ return;
+ }
+ this.showModal();
},
/**
* Fired on trigger "openModal"
*/
showModal: function () {
- var videoimgRoleInput = $('.video_image_role');
$('#new-video').modal('openModal');
- videoimgRoleInput.prop('disabled', false);
- $('#new_video_form')[0].reset();
-
- if ($('.image.item').length < 1) {
- videoimgRoleInput.prop('checked', true);
- }
}
}
);
diff --git a/app/code/Magento/ProductVideo/view/frontend/layout/catalog_product_view.xml b/app/code/Magento/ProductVideo/view/frontend/layout/catalog_product_view.xml
new file mode 100644
index 0000000000000..340d82d4adac4
--- /dev/null
+++ b/app/code/Magento/ProductVideo/view/frontend/layout/catalog_product_view.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/ProductVideo/view/frontend/requirejs-config.js b/app/code/Magento/ProductVideo/view/frontend/requirejs-config.js
new file mode 100644
index 0000000000000..956dd40b89e31
--- /dev/null
+++ b/app/code/Magento/ProductVideo/view/frontend/requirejs-config.js
@@ -0,0 +1,13 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*eslint no-unused-vars: 0*/
+var config = {
+ map: {
+ '*': {
+ fotoramaAddVideoEvents: 'Magento_ProductVideo/js/fotorama-add-video-events',
+ loadPlayer: 'Magento_ProductVideo/js/load-player'
+ }
+ }
+};
diff --git a/app/code/Magento/ProductVideo/view/frontend/templates/product/view/gallery.phtml b/app/code/Magento/ProductVideo/view/frontend/templates/product/view/gallery.phtml
new file mode 100644
index 0000000000000..192a3f18e2cc6
--- /dev/null
+++ b/app/code/Magento/ProductVideo/view/frontend/templates/product/view/gallery.phtml
@@ -0,0 +1,79 @@
+
+
+
+
diff --git a/app/code/Magento/ProductVideo/view/frontend/web/css/product-video.css b/app/code/Magento/ProductVideo/view/frontend/web/css/product-video.css
new file mode 100644
index 0000000000000..0198f8c98ecb9
--- /dev/null
+++ b/app/code/Magento/ProductVideo/view/frontend/web/css/product-video.css
@@ -0,0 +1,75 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+.fotorama-video-container.video-unplayed:after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ background: url(../img/gallery-sprite.png) bottom right;
+ width: 100px;
+ height: 100px;
+ left: 0;
+ top: 12px;
+ margin: auto;
+}
+.fotorama-video-container .magnify-lens {
+ display: none !important;
+}
+.fotorama-video-container.video-unplayed:hover img {
+ opacity: 0.6;
+}
+.fotorama-video-container.video-unplayed:hover:after {
+ transform: scale(1.25);
+}
+.video-thumb-icon:after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ background: url(../img/gallery-sprite.png) bottom left;
+ width: 49px;
+ height: 40px;
+ left: 0;
+ top: 10px;
+ margin: auto;
+}
+.video-timing {
+ width: auto;
+ height: 30px;
+ background: rgba(0, 0, 0, 0.75);
+ padding: 0 17px;
+ color: #fff;
+ position: absolute;
+ right: 0;
+ line-height: 2;
+ transition: 0.3s;
+ bottom: -30px;
+}
+.video-timing.fadeIn {
+ bottom: 0;
+}
+.product-video {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ height: 85%;
+ margin-top: 15%;
+}
+.product-video iframe {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 9999;
+}
+.fotorama__arr.hidden-video {
+ z-index: -1;
+}
+.fotorama__video-close {
+ bottom: 89%;
+ top: auto;
+}
diff --git a/app/code/Magento/ProductVideo/view/frontend/web/img/gallery-sprite.png b/app/code/Magento/ProductVideo/view/frontend/web/img/gallery-sprite.png
new file mode 100644
index 0000000000000..c2a8a9a2a76e7
Binary files /dev/null and b/app/code/Magento/ProductVideo/view/frontend/web/img/gallery-sprite.png differ
diff --git a/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js
new file mode 100644
index 0000000000000..e19d635a72b36
--- /dev/null
+++ b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js
@@ -0,0 +1,559 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+require(['jquery', 'jquery/ui', 'catalogGallery'], function ($) {
+ 'use strict';
+
+ /**
+ * @private
+ */
+ function parseHref(href) {
+ var a = document.createElement('a');
+
+ a.href = href;
+
+ return a;
+ }
+
+ /**
+ * @private
+ */
+ function parseURL(href, forceVideo) {
+ var id,
+ type,
+ ampersandPosition;
+
+ /**
+ * Get youtube ID
+ * @param {String} srchref
+ * @returns {{}}
+ */
+ function _getYoutubeId(srchref) {
+ var srcid = srchref.search.split('v=')[1];
+
+ if (srcid) {
+ ampersandPosition = srcid.indexOf('&');
+
+ if (ampersandPosition === -1) {
+ return srcid;
+ }
+
+ srcid = srcid.substring(0, ampersandPosition);
+ }
+
+ return srcid;
+ }
+
+ if (typeof href !== 'string') {
+ return href;
+ }
+
+ href = parseHref(href);
+
+ if (href.host.match(/youtube\.com/) && href.search) {
+ id = href.search.split('v=')[1];
+
+ if (id) {
+ id = _getYoutubeId(id);
+ type = 'youtube';
+ }
+ } else if (href.host.match(/youtube\.com|youtu\.be/)) {
+ id = href.pathname.replace(/^\/(embed\/|v\/)?/, '').replace(/\/.*/, '');
+ type = 'youtube';
+ } else if (href.host.match(/vimeo\.com/)) {
+ type = 'vimeo';
+ id = href.pathname.replace(/^\/(video\/)?/, '').replace(/\/.*/, '');
+ }
+
+ if ((!id || !type) && forceVideo) {
+ id = href.href;
+ type = 'custom';
+ }
+
+ return id ? {
+ id: id, type: type, s: href.search.replace(/^\?/, '')
+ } : false;
+ }
+
+ //create AddFotoramaVideoEvents widget
+ $.widget('mage.AddFotoramaVideoEvents', {
+ options: {
+ VideoData: '',
+ VideoSettings: ''
+ },
+
+ PV: 'product-video', // [CONST]
+ VID: 'video', // [CONST]
+ VI: 'vimeo', // [CONST]
+ FTVC: 'fotorama__video-close',
+ FTAR: 'fotorama__arr',
+ Base: 0, //on check for video is base this setting become true if there is any video with base role
+ MobileMaxWidth: 767,
+ GP: 'gallery-placeholder', //gallery placeholder class is needed to find and erase