1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-07-08 01:14:24 +03:00
ifhub.club/application/frontend/components/comment/js/comments.js
2016-12-27 15:57:29 +07:00

399 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Комментарии
*
* @module ls/comments
*
* @license GNU General Public License, version 2
* @copyright 2013 OOO "ЛС-СОФТ" {@link http://livestreetcms.com}
* @author Denis Shakhov <denis.shakhov@gmail.com>
*/
(function($) {
"use strict";
$.widget( "livestreet.lsComments", $.livestreet.lsComponent, {
/**
* Дефолтные опции
*/
options: {
// Ссылки
urls: {
// Добавление комментария
add: null,
// Подгрузка новых комментариев
load: null,
// Показать/скрыть комментарий
hide: aRouter.ajax + 'comment/delete/',
// Обновление текста комментария
text: aRouter.ajax + 'comment/load/',
// Обновление комментария
update: aRouter.ajax + 'comment/update/'
},
// Селекторы
selectors: {
comment: '.js-comment',
comment_wrapper: '.js-comment-wrapper',
form: '.js-comment-form',
// Блок с превью текста
preview: '.js-comment-preview',
// Кнопка свернуть/развернуть все
fold_all_toggle: '.js-comments-fold-all-toggle',
// Заголовок
title: '.js-comments-title',
// Кнопка "Оставить комментарий"
reply_root: '.js-comment-reply-root',
// Блок с комментариями
comment_list: '.js-comment-list',
// Подписаться на новые комментарии
subscribe: '.js-comments-subscribe',
// Сообщение о пустом списке
empty: '.js-comments-empty'
},
// Использовать визуальный редактор или нет
wysiwyg: null,
// Включить/выключить функцию сворачивания
folding: true,
// Показать/скрыть форму по умолчанию
show_form: false,
// Ajax параметры
params: {},
i18n: {
fold_all: '@comments.folding.fold_all',
unfold_all: '@comments.folding.unfold_all',
subscribe: '@comments.subscribe',
unsubscribe: '@comments.unsubscribe',
comments: '@comments.comments_declension'
}
},
/**
* Конструктор
*
* @constructor
* @private
*/
_create: function () {
var _this = this;
this._super();
this.initComments( this.getComments() );
this.getForm().lsCommentForm({
urls: {
text: this.option( 'urls.text' ),
add: this.option( 'urls.add' ),
update: this.option( 'urls.update' )
},
comments: this.element
});
this._currentComment = $();
// Получаем ID объекта к которому оставлен комментарий
this._targetId = this.element.data( 'target-id' );
// Получаем тип объекта
this._targetType = this.element.data( 'target-type' );
// ID последнего добавленного комментария
this.setLastCommentId( this.element.data('comment-last-id') );
this.elements.reply_root.on( 'click' + this.eventNamespace, function ( event ) {
event.preventDefault();
_this.getForm().lsCommentForm( 'show', 0 );
});
if ( ! this.option( 'show_form' ) ) this.getForm().hide();
//
// ЭКШНБАР
//
// Сворачивание
if ( this.options.folding ) {
this.elements.fold_all_toggle.on( 'click' + this.eventNamespace, this.foldAllToggle.bind( this ) );
}
// Подписаться/отписаться от новых комментариев
this.elements.subscribe.on( 'click' + this.eventNamespace, this.subscribeToggle.bind(this));
},
/**
* Подписаться/отписаться от комментариев
*/
subscribeToggle: function() {
var isActive = this.elements.subscribe.hasClass('active');
ls.subscribe.toggle( this._targetType + '_new_comment', this._targetId, '', ! isActive );
if ( isActive ) {
this.elements.subscribe.removeClass( 'active' ).text( this._i18n('subscribe') );
} else {
this.elements.subscribe.addClass( 'active' ).text( this._i18n('unsubscribe') );
}
},
/**
* Свернуть/развернуть все ветки комментариев
*/
foldAllToggle: function() {
this[ this.elements.fold_all_toggle.hasClass( 'active' ) ? 'unfoldAll' : 'foldAll' ]();
},
/**
* Сворачивает все ветки комментариев
*/
foldAll: function() {
this.getComments().lsComment( 'fold' );
this.elements.fold_all_toggle.addClass( 'active' ).text( this._i18n('unfold_all') );
},
/**
* Разворачивает все ветки комментариев
*/
unfoldAll: function() {
this.getComments().lsComment( 'unfold' );
this.elements.fold_all_toggle.removeClass( 'active' ).text( this._i18n('fold_all') );
},
/**
* Подгрузка новых комментариев
*/
load: function( commentSelfId, flush, callback ) {
flush = typeof flush === 'undefined' ? true : flush;
var params = {
target_id: this._targetId,
target_type: this._targetType,
last_comment_id: this.getLastCommentId(),
self_comment_id: commentSelfId || undefined,
use_paging: false
};
this._load( 'load', params, function( response ) {
var commentsLoaded = response.comments,
countLoaded = commentsLoaded.length;
// Убираем подсветку у новых комментариев
if ( flush ) this.getCommentsNew().lsComment( 'notNew' );
// Скрываем сообщение о пустом списке
if ( ~ this.getComments().length && countLoaded ) this.elements.empty.hide();
// Вставляем новые комментарии
$.each( commentsLoaded, function( index, item ) {
var comment = this.initComments( $( $.trim( item.html ) ) );
this.elements.comment = this.elements.comment.add( comment );
this.insert( comment, item.id, item.parent_id );
}.bind( this ));
// Обновляем данные
if ( countLoaded && response.last_comment_id ) {
this.setLastCommentId( response.last_comment_id );
// Обновляем кол-во комментариев в заголовке
this.elements.title.text( this._i18n( 'comments', this.getComments().length ) );
}
// Разворачиваем все ветки если идет просто подгрузка комментариев
// или если при добавления комментария текущим пользователем
// помимо этого комментария подгружаются еще и ранее добавленные комментарии
if ( this.options.folding && ( ( ! commentSelfId && countLoaded ) || ( commentSelfId && countLoaded - 1 > 0 ) ) ) {
this.unfoldAll();
}
// Прокручиваем к комментарию который оставил текущий пользователь
if ( commentSelfId ) {
this.getForm().lsCommentForm( 'hide' );
this.scrollToComment( this.getCommentById( commentSelfId ) );
}
if ( $.isFunction( callback ) ) callback.call( this );
});
this._trigger('loaded');
},
/**
* Вставка комментария
*
* @param {jQuery} comment Комментарий
* @param {Number} commentId ID добавляемого комментария
* @param {Number} commentParentId (optional) ID родительского комментария
*/
insert: function( comment, commentId, commentParentId ) {
var commentWrapper = $( '<div class="ls-comment-wrapper js-comment-wrapper" data-id="' + commentId + '"></div>' ).append( comment );
this.elements.comment_list.show();
if ( commentParentId ) {
// Получаем обертку родительского комментария
var wrapper = $( this.options.selectors.comment_wrapper + '[data-id=' + commentParentId + ']');
// Проверяем чтобы уровень вложенности комментариев был не больше значения заданного в конфиге
if (wrapper.parentsUntil(this.elements.comment_list).length == ls.registry.get('comment_max_tree')) {
wrapper = wrapper.parent(this.options.selectors.comment_wrapper);
}
wrapper.append( commentWrapper );
} else {
this.elements.comment_list.append( commentWrapper );
}
},
/**
* Сбрасывает текущий комментарий
*/
resetCommentCurrent: function() {
if ( this._currentComment.length ) this._currentComment.lsComment( 'notCurrent' );
this._currentComment = $();
},
/**
* Получает текущий комментарий
*
* @return {jQuery} Текущий комментарий
*/
getCommentCurrent: function() {
return this._currentComment;
},
/**
* Устанавливает текущий комментарий
*
* @param {Object} comment
*/
setCommentCurrent: function( comment ) {
if ( this.getCommentCurrent().is( comment ) ) return;
if ( this.getCommentCurrent().length ) {
this.getCommentCurrent().lsComment( 'notCurrent' );
}
comment.lsComment( 'markAsCurrent' );
this._currentComment = comment;
},
/**
* Прокрутка к комментарию
*
* @param {jQuery} comment Комментарий
*/
scrollToComment: function( comment ) {
this.setCommentCurrent( comment );
$.scrollTo( comment, 1000, { offset: -250 } );
},
/**
* Получает форму комментирования
*
* @return {jQuery} Форма комментирования
*/
getForm: function() {
return this.elements.form;
},
/**
* Получает комментарии
*
* @return {Array} Массив с комментариями
*/
getComments: function() {
return this.elements.comment;
},
/**
* Добавляет комментарий в массив с другими
*
* @param {jQuery} comments Комментарии
*/
addComments: function( comments ) {
this.elements.comment = this.elements.comment.add( comments );
},
/**
* Получает комментарий по его ID
*
* @param {Number} commentId ID комментария
* @return {jQuery} Комментарий
*/
getCommentById: function( commentId ) {
if ( ! commentId ) return;
for ( var i = 0, len = this.getComments().length; i < len; i++ ) {
if ( $( this.getComments()[ i ] ).lsComment( 'getId' ) == commentId ) {
return $( this.getComments()[ i ] );
}
};
return $();
},
/**
* Удаляет комментарий по его ID
*
* @param {Number} commentId ID комментария
*/
removeCommentById: function( commentId ) {
var _this = this;
this.elements.comment = this.getComments().filter(function () {
var comment = $( this );
if ( comment.lsComment( 'getId' ) == commentId ) {
if ( comment.lsComment( 'isCurrent' ) ) _this.resetCommentCurrent();
comment.lsComment( 'destroy' );
return false;
}
return true;
});
},
/**
* Получает новые комментарии
*
* @return {Array} Массив с новыми комментариями
*/
getCommentsNew: function() {
return this.getComments().filter(function () {
return $( this ).lsComment( 'isNew' );
});
},
/**
* Иниц-ия комментариев
*
* @param {jQuery} comments Комментарии
*/
initComments: function( comments ) {
return comments.lsComment({
comments: this.element,
folding: this.options.folding
});
},
/**
* Получает ID последнего добавленного комментария
*/
getLastCommentId: function() {
return this._commentLastId;
},
/**
* Устанавливает ID последнего добавленного комментария
*
* @param {Number} id ID комментария
*/
setLastCommentId: function( id ) {
this._commentLastId = id;
},
});
})(jQuery);