From 63cf2c8f6942575e4b6e284980af393d8b8532b2 Mon Sep 17 00:00:00 2001 From: Denis Shakhov Date: Wed, 1 Jan 2014 15:47:12 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B2=D1=81=D1=82=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BC=D0=B5=D0=B4=D0=B8=D0=B0=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/frontend/common/js/media.js | 541 +++++++++++------- .../skin/developer/assets/css/modals.css | 17 +- .../modal.upload_image.gallery.item.tpl | 2 - .../modals/modal.upload_image.gallery.tpl | 120 ++-- .../developer/modals/modal.upload_image.tpl | 17 +- 5 files changed, 418 insertions(+), 279 deletions(-) diff --git a/application/frontend/common/js/media.js b/application/frontend/common/js/media.js index 02e7ab15..b04d9141 100644 --- a/application/frontend/common/js/media.js +++ b/application/frontend/common/js/media.js @@ -1,5 +1,5 @@ /** - * Фотосет + * Работа с медиа файлами * * @module ls/media * @@ -10,302 +10,427 @@ var ls = ls || {}; -ls.media =( function ($) { - - var _defaultsFileupload = { - url: aRouter['ajax']+"media/upload/", - sequentialUploads: false, - singleFileUploads: true, - limitConcurrentUploads: 3 - }; - +ls.media = (function ($) { + /** + * Дефолтные опции + * + * @private + */ var _defaults = { target_type: '', target_id: '', target_tmp: '', - fileupload: _defaultsFileupload - }; - - this.mode='insert'; - - this.setMode = function(mode) { - this.mode=mode; - this.showSettingsMode(); - }; - - this.showSettingsMode = function($item) { - $('.js-media-settings-mode').hide(); - /** - * Показываем только если есть выделенные элементы - */ - if (this.getSelected().length) { - $('#media-settings-mode-'+this.mode).show(); - $item=$item || this.getCurrent(); - /** - * Выставляем настройки по вставке медиа - */ - var $select=$('select[name=size]').html(''); - var sizes=$item.data('mediaImageSizes'); - $.each(sizes,function(k,v){ - /** - * Расчитываем пропорциональную высоту изображения - */ - var height=v.h; - if (!v.h) { - height=parseInt(v.w*$item.data('mediaHeight')/$item.data('mediaWidth')); - } - $select.append(''); - }); + // Настройки загрузчика + fileupload: { + url: null, + sequentialUploads: false, + singleFileUploads: true, + limitConcurrentUploads: 3 + }, + // Селекторы + selectors: { + gallery: { + upload_area: '.js-media-upload-area', + upload_input: '.js-media-upload-file', + file_list: '.js-media-upload-gallery-list', + file: '.js-media-upload-gallery-item' + }, + button_insert: '.js-media-insert', + button_insert_photoset: '.js-media-insert-photoset' + }, + // Классы + classes: { + selected: 'is-selected' + }, + // Роуты + routers: { + upload: aRouter['ajax'] + "media/upload/", + remove_file: aRouter['ajax'] + "media/remove-file/", + load_gallery: aRouter['ajax'] + "media/load-gallery/", + generate_target_tmp: aRouter['ajax'] + "media/generate-target-tmp/", + submit_insert: aRouter['ajax'] + "media/submit-insert/", + submit_photoset: aRouter['ajax'] + "media/submit-create-photoset/" + }, + // HTML + html: { + progress: '
' } }; - this.hideSettingsMode = function() { - $('.js-media-settings-mode').hide(); - }; - - this.initUpload = function(options) { - this.options = $.extend(true, {}, _defaults, options); - - this.options.target_tmp=this.options.target_tmp ? this.options.target_tmp : $.cookie('media_target_tmp_'+this.options.target_type); - if (!this.options.target_id && !this.options.target_tmp) { - ls.media.generateTargetTmp(this.options.target_type); - } - - var params=this.options.fileupload; - params.formData=$.extend({}, params.formData || {}, { - security_ls_key: LIVESTREET_SECURITY_KEY, - target_type: this.options.target_type, - target_id: this.options.target_id, - target_tmp: this.options.target_tmp - }); - $.each(params.formData,function(k,v){ - if (v==null) { - params.formData[k]=''; - } - }); - $('.js-media-upload-file').fileupload(params); - - - $('.js-media-upload-file').bind('fileuploadadd',function(e,data) { - ls.media.addPreload(data); - }); - $('.js-media-upload-file').bind('fileuploaddone',function(e,data) { - if (data.result.bStateError) { - ls.media.addFileError(data.context,data.result); - } else { - ls.media.addFile(data.context,data.result); - } - }); - $('.js-media-upload-file').bind('fileuploadprogress',function(e,data) { - data.context.html(parseInt(data.loaded / data.total * 100, 10)+'%'); - }); - - this.loadGallery(); - this.bindFileEvents(); - }; - - + this.mode = 'insert'; /** * Инициализация */ - this.init = function() { + this.init = function(options) { + this.options = $.extend(true, {}, _defaults, options); + this.elements = { + uploadArea: $(this.options.selectors.gallery.upload_area), + uploadInput: $(this.options.selectors.gallery.upload_input), + buttonInsert: $(this.options.selectors.button_insert), + buttonInsertPhotoset: $(this.options.selectors.button_insert_photoset), + gallery: { + fileList: $(this.options.selectors.gallery.file_list) + } + }; + + this.setMode('insert'); + + this.options.target_tmp = this.options.target_tmp ? this.options.target_tmp : $.cookie('media_target_tmp_' + this.options.target_type); + if ( ! this.options.target_id && ! this.options.target_tmp ) { + ls.media.generateTargetTmp(this.options.target_type); + } + + // Настройки загрузчика + this.options.fileupload.url = this.options.fileupload.url || this.options.routers.upload; + this.options.fileupload.dropZone = this.options.fileupload.dropZone || this.elements.uploadArea; + this.options.fileupload.formData = $.extend({}, this.options.fileupload.formData || {}, { + security_ls_key: LIVESTREET_SECURITY_KEY, + target_type: this.options.target_type, + target_id: this.options.target_id, + target_tmp: this.options.target_tmp + }); + + $.each(this.options.fileupload.formData, function(k, v) { + if (v === null) this.options.fileupload.formData[k] = ''; + }); + + this.elements.uploadInput.fileupload(this.options.fileupload); + + this.elements.uploadInput.bind({ + fileuploadadd: function(e, data) { + ls.media.addPreload(data); + }, + fileuploaddone: function(e, data) { + ls.media[data.result.bStateError ? 'onUploadError' : 'onUploadDone'](data.context, data.result); + }, + fileuploadprogress: function(e, data) { + data.context.html(this.options.html.progress); + }.bind(this) + }); + + // Ивенты вставки в редактор + this.elements.buttonInsert.on('click', function () { + var params = { + align: $('#media-settings-mode-insert').find('select[name=align]').val(), + size: $('#media-settings-mode-insert').find('select[name=size]').val() + } + + this.insert(this.options.routers.submit_insert, params); + }.bind(this)); + + this.elements.buttonInsertPhotoset.on('click', function () { + console.log('asdf') + var params = { + use_thumbs: $('#media-settings-mode-create-photoset').find('input[name=use_thumbs]').val(), + show_caption: $('#media-settings-mode-create-photoset').find('input[name=show_caption]').val() + } + + this.insert(this.options.routers.submit_photoset, params); + }.bind(this)); + + // Перемещение галереи из одного таба в другой + $('.js-tab-show-gallery').on('tabbeforeactivate',function(event,tab){ + $('#upload-gallery-image').appendTo($('#' + tab.options.target).find('.modal-content')); + ls.media.setMode($(event.target).data('mediaMode')); + }); + + // Сохранение настроек файла + $('.js-media-detail-area .js-input-title').on('blur', function(e) { + this.saveDataFile($(e.currentTarget).attr('name'),$(e.currentTarget).val()); + }.bind(this)); + + this.loadImageList(); + this.bindFileEvents(); }; + /** + * + */ + this.setMode = function(mode) { + this.mode = mode; + this.showSettingsMode(); + }; + + /** + * Показывает блок с информацией об активном файле + * + * @param {Object} $item Выделенный файл + */ + this.showSettingsMode = function($item) { + $('.js-media-settings-mode').hide(); + + /* Показываем только если есть выделенные элементы */ + if (this.getSelected().length) { + $('#media-settings-mode-' + this.mode).show(); + $item = $item || this.getCurrent(); + + /* Выставляем настройки по вставке медиа */ + var $select = $('select[name=size]').html(''); + var sizes = $item.data('mediaImageSizes'); + + $.each(sizes, function(k, v) { + /* Расчитываем пропорциональную высоту изображения */ + var height = v.h; + + if ( ! height ) { + height = parseInt(v.w * $item.data('mediaHeight') / $item.data('mediaWidth')); + } + + $select.append(''); + }); + } + }; + + /** + * + */ + this.hideSettingsMode = function() { + $('.js-media-settings-mode').hide(); + }; + + /** + * Удаление активного файла + */ this.removeCurrentFile = function() { - var $item=this.getCurrent(); + var $item = this.getCurrent(); + if ($item.length) { return this.removeFile($item.data('mediaId')); } + return false; }; + /** + * Удаление файла + * + * @param {Number} id + */ this.removeFile = function(id) { - $this=this; - ls.ajax.load(aRouter['ajax']+"media/remove-file/", { id: id }, function(result) { - $('.js-media-upload-gallery-item[data-media-id='+id+']').fadeOut(500,function(){ + var _this = this; + + ls.ajax.load(this.options.routers.remove_file, { id: id }, function(result) { + $(_this.options.selectors.gallery.file + '[data-media-id=' + id + ']').fadeOut(500, function() { $(this).remove(); - if ($itemNext=$this.searchNextSelected()) { - $this.setCurrent($itemNext,true); + if ($itemNext = _this.searchNextSelected()) { + _this.setCurrent($itemNext, true); } else { - $this.hideDetail(); + _this.hideDetail(); } + + if ($(_this.options.selectors.gallery.file).length === 0) _this.showEmptyAlert(); }); }); }; - this.loadGallery = function() { - $('.js-media-upload-gallery-list').addClass('loader'); - ls.ajax.load(aRouter['ajax']+"media/load-gallery/", { target_type: this.options.target_type, target_id: this.options.target_id, target_tmp: this.options.target_tmp }, function(result) { - $('.js-media-upload-gallery-list').removeClass('loader'); - $('.js-media-upload-gallery-list').html(result.sTemplate); - }); - }; + /** + * Подгрузка списка файлов + */ + this.loadImageList = function() { + this.elements.gallery.fileList.empty().addClass( ls.options.classes.states.loading ); - this.generateTargetTmp = function(type) { - ls.ajax.load(aRouter['ajax']+"media/generate-target-tmp/", { type: type }, function(result) { - if (result.sTmpKey) { - this.options.target_tmp=result.sTmpKey; - } + ls.ajax.load(this.options.routers.load_gallery, {target_type: this.options.target_type, target_id: this.options.target_id, target_tmp: this.options.target_tmp }, function(result) { + this.elements.gallery.fileList.removeClass( ls.options.classes.states.loading ).html(result.sTemplate); + this[result.sTemplate ? 'hideEmptyAlert' : 'showEmptyAlert'](); }.bind(this)); }; - this.addPreload = function(data) { - data.context=$(''); - $('.js-media-upload-gallery-list').prepend(data.context); + /** + * + */ + this.generateTargetTmp = function(type) { + ls.ajax.load(this.options.routers.generate_target_tmp, { type: type }, function(result) { + if (result.sTmpKey) this.options.target_tmp = result.sTmpKey; + }.bind(this)); }; + /** + * Индикация загрузки изображения + */ + this.addPreload = function(data) { + this.hideEmptyAlert(); + data.context = $(''); + this.elements.gallery.fileList.prepend(data.context); + }; + + /** + * Выделение изображений + */ this.bindFileEvents = function() { - $('.js-media-upload-gallery-list').on('click','.js-media-upload-gallery-item',function(e){ - var $item=$(e.currentTarget); - var allowMany=(this.mode=='create-photoset' || e.ctrlKey || e.metaKey); - if ($item.hasClass('active')) { - /** - * Снимаем выделение с текущего - */ - $item.removeClass('active').removeClass('is-selected'); - /** - * Делаем активным другой выделенный элемент - */ - if ($itemNext=this.searchNextSelected($item)) { + this.elements.gallery.fileList.on('click', this.options.selectors.gallery.file, function(e){ + var $item = $(e.currentTarget); + var allowMany = (this.mode == 'create-photoset' || e.ctrlKey || e.metaKey); + + if ($item.hasClass(ls.options.classes.states.active)) { + /* Снимаем выделение с текущего */ + $item.removeClass(ls.options.classes.states.active).removeClass(this.options.classes.selected); + + /* Делаем активным другой выделенный элемент */ + if ($itemNext = this.searchNextSelected($item)) { this.setCurrent($itemNext,true); } else { this.hideDetail(); } } else { - /** - * Делаем текущим и показываем детальную информацию - */ + /* Делаем текущим и показываем детальную информацию */ this.setCurrent($item,allowMany); } }.bind(this)); }; - this.addFile = function(context,response) { - /** - * Завершение загрузки файла - */ - var $item=$(response.sTemplateFile); - context.replaceWith($item); - this.setSelected($item,true); + /** + * + */ + this.showEmptyAlert = function(data) { + $('#media-empty').show(); + $('.js-media-item-info').hide(); }; - this.addFileError = function(context,response) { - /** - * Помечаем файл как ошибочный (глюк при загрузке) - */ + /** + * + */ + this.hideEmptyAlert = function(data) { + $('#media-empty').hide(); + $('.js-media-item-info').show(); + }; + + /** + * Завершение загрузки файла + */ + this.onUploadDone = function(context, response) { + var $item = $(response.sTemplateFile); + context.replaceWith($item); + this.setSelected($item, true); + }; + + /** + * Помечаем файл как ошибочный (глюк при загрузке) + */ + this.onUploadError = function(context, response) { ls.msg.error(response.sMsgTitle,response.sMsg); context.html('ERROR'); }; - this.searchNextSelected = function($itemOld) { - var $item=$('.js-media-upload-gallery-item.is-selected:first'); - if ($item.length==0) { - return false; - } + /** + * Ищет файл для выделения + */ + this.searchNextSelected = function() { + var $item = $(this.options.selectors.gallery.file + '.' + this.options.classes.selected + ':first'); + if ($item.length === 0) return false; return $item; }; - this.setCurrent = function($item,allowMany) { - $('.js-media-upload-gallery-item.active').removeClass('active'); - $item.addClass('active'); - this.setSelected($item,allowMany); - /** - * Показываем детальную информацию - */ + /** + * Помечает файл как активный + * + * @param {Object} $item Помечаемый файл + * @param {Boolean} allowMany Выделение нескольких файлов + */ + this.setCurrent = function($item, allowMany) { + $(this.options.selectors.gallery.file + '.' + ls.options.classes.states.active).removeClass(ls.options.classes.states.active); + $item.addClass(ls.options.classes.states.active); + this.setSelected($item, allowMany); this.showDetail($item); }; + /** + * Получает активный файл + * + * @return {Object} Активный файл + */ this.getCurrent = function() { - return $('.js-media-upload-gallery-item.active'); + return $(this.options.selectors.gallery.file + '.' + ls.options.classes.states.active); }; - this.setSelected = function($item,allowMany) { - if (!allowMany) { - this.getSelected().removeClass('is-selected'); + /** + * Выделяет файл + * + * @param {Object} $item Выделяемый файл + * @param {Boolean} allowMany Выделение нескольких файлов + */ + this.setSelected = function($item, allowMany) { + if ( ! allowMany ) { + this.getSelected().removeClass(this.options.classes.selected); } - $item.addClass('is-selected'); - /** - * Если нет еще нет активного элемента, то делаем активным текущий - */ - if (this.getCurrent().length==0) { - this.setCurrent($item,allowMany); + + $item.addClass(this.options.classes.selected); + + /* Если нет еще нет активного элемента, то делаем активным текущий */ + if (this.getCurrent().length === 0) { + this.setCurrent($item, allowMany); } }; + /** + * Получает выделенные файлы + * + * @return {Array} Список выделенных файлов + */ this.getSelected = function() { - return $('.js-media-upload-gallery-item.is-selected'); + return $(this.options.selectors.gallery.file + '.' + this.options.classes.selected); }; + /** + * + */ + this.saveDataFile = function(name, value) { + var $item = this.getCurrent(); + + if ($item.length) { + var id = $item.data('mediaId'); + + ls.ajax.load(aRouter['ajax']+"media/save-data-file/", { name: name, value: value, id: id }, function(result) { + $(this.options.selectors.gallery.file + '[data-media-id=' + id + ']').data('mediaData' + name.charAt(0).toUpperCase() + name.slice(1), value); + }); + } + }; + + /** + * + */ this.showDetail = function($item) { $('.js-media-detail-preview').attr('src',$item.data('mediaPreview')); $('.js-media-detail-name').html($item.data('mediaFileName')); $('.js-media-detail-date').html($item.data('mediaDateAdd')); $('.js-media-detail-dimensions').html($item.data('mediaWidth')+' × '+$item.data('mediaHeight')); $('.js-media-detail-file-size').html(parseInt($item.data('mediaFileSize')/1024)+'kB'); + $('.js-media-detail-area .js-input-title').val($item.data('mediaDataTitle')); $('.js-media-detail-area').show(); this.showSettingsMode($item); }; + /** + * + */ this.hideDetail = function() { $('.js-media-detail-area').hide(); this.hideSettingsMode(); }; - this.submitInsert = function() { - var $aItems=this.getSelected(); - if (!$aItems.length) { - return false; - } - /** - * Формируем список ID элементов - */ - var aIds=[]; - $aItems.each(function(k,v){ - var $item=$(v); - aIds.push($item.data('mediaId')); - }); - var params={ - ids: aIds, - align: $('#media-settings-mode-insert').find('select[name=align]').val(), - size: $('#media-settings-mode-insert').find('select[name=size]').val() - } + /** + * Вставка файлов в редактор + */ + this.insert = function(url, params) { + var $aItems = this.getSelected(); - ls.ajax.load(aRouter['ajax']+"media/submit-insert/", params, function(result) { - if (result.bStateError) { - ls.msg.error(result.sMsgTitle,result.sMsg); - } else { - $.markItUp({ - replaceWith: result.sTextResult - }); - $('#modal-image-upload').modal('hide'); - } - }); - }; + if ( ! $aItems.length ) return false; - this.submitCreatePhotoset = function() { - var $aItems=this.getSelected(); - if (!$aItems.length) { - return false; - } - /** - * Формируем список ID элементов - */ - var aIds=[]; - $aItems.each(function(k,v){ - var $item=$(v); - aIds.push($item.data('mediaId')); - }); - var params={ + var aIds = []; + var _params = { ids: aIds - } + }; - ls.ajax.load(aRouter['ajax']+"media/submit-create-photoset/", params, function(result) { + /* Формируем список ID элементов */ + $aItems.each(function(k, v) { + var $item = $(v); + aIds.push($item.data('mediaId')); + }); + + ls.ajax.load(url, $.extend(true, {}, _params, params), function(result) { if (result.bStateError) { ls.msg.error(result.sMsgTitle,result.sMsg); } else { diff --git a/application/frontend/skin/developer/assets/css/modals.css b/application/frontend/skin/developer/assets/css/modals.css index 6ff23e51..282169fe 100644 --- a/application/frontend/skin/developer/assets/css/modals.css +++ b/application/frontend/skin/developer/assets/css/modals.css @@ -59,8 +59,8 @@ } /* Manager */ -.modal-upload-image-gallery { overflow: hidden; } -.modal-upload-image-gallery-list { overflow: auto; width: 68%; margin-right: 2%; max-height: 354px; float: left; } +.modal-upload-image-gallery { overflow: hidden; min-height: 150px; } +.modal-upload-image-gallery-list { overflow: auto; width: 68%; min-height: 150px; margin-right: 2%; max-height: 354px; float: left; } .modal-upload-image-gallery-list-item { position: relative; cursor: pointer; @@ -72,16 +72,25 @@ .modal-upload-image-gallery-list-item img { vertical-align: top; width: 100px; height: 100px; } .modal-upload-image-gallery-list-item:hover { border-color: #eee; } +/* Progress bar */ +.modal-upload-image-gallery-list-item .progress { + width: 100px; + height: 100px; + line-height: 100px; + text-align: center; + background-color: #f5f5f5; +} + /* Selected */ .modal-upload-image-gallery-list-item.is-selected { border-color: #D5CE3D; } /* Active */ .modal-upload-image-gallery-list-item.is-selected.active { border-color: #7979FC; } -.modal-upload-image-gallery-list-item.is-selected.active .modal-upload-image-gallery-list-item-checkbox {background: #7979FC; } +.modal-upload-image-gallery-list-item.is-selected.active .modal-upload-image-gallery-list-item-checkbox { background: #7979FC; } /* Checkbox */ .modal-upload-image-gallery-list-item input { display: none; } -.modal-upload-image-gallery-list-item.is-selected .modal-upload-image-gallery-list-item-checkbox { position: absolute; right: 0; bottom: 0; width: 20px; height: 20px; background: #D5CE3D; cursor: pointer; } +.modal-upload-image-gallery-list-item.is-selected .modal-upload-image-gallery-list-item-checkbox { display: none; position: absolute; right: 0; bottom: 0; width: 20px; height: 20px; background: #D5CE3D; cursor: pointer; } .modal-upload-image-gallery-list-item.is-selected input:checked + .modal-upload-image-gallery-list-item-checkbox { background: #000; } /* Info */ diff --git a/application/frontend/skin/developer/modals/modal.upload_image.gallery.item.tpl b/application/frontend/skin/developer/modals/modal.upload_image.gallery.item.tpl index 8323bda8..21673751 100755 --- a/application/frontend/skin/developer/modals/modal.upload_image.gallery.item.tpl +++ b/application/frontend/skin/developer/modals/modal.upload_image.gallery.item.tpl @@ -2,8 +2,6 @@ * Добавление медиа-файла / Список изображений / Блок с изображением * * @styles css/modals.css - * - * TODO: Передавать сюда объект изображения вместо отдельных переменных *}