new {if $commentHandlerClass|isset}{@$commentHandlerClass}{else}WCF.Comment.Handler{/if}('{$commentContainerID}', '{@$__wcf->getUserProfileHandler()->getAvatar()->getImageTag(48)}', '{@$__wcf->getUserProfileHandler()->getAvatar()->getImageTag(32)}');
{if MODULE_LIKE && $commentList->getCommentManager()->supportsLike() && $__wcf->getSession()->getPermission('user.like.canViewLike')}
- new WCF.Comment.Like({if $__wcf->getUser()->userID && $__wcf->getSession()->getPermission('user.like.canLike')}1{else}0{/if}, {@LIKE_ENABLE_DISLIKE}, false, {@LIKE_ALLOW_FOR_OWN_CONTENT});
- new WCF.Comment.Response.Like({if $__wcf->getUser()->userID && $__wcf->getSession()->getPermission('user.like.canLike')}1{else}0{/if}, {@LIKE_ENABLE_DISLIKE}, false, {@LIKE_ALLOW_FOR_OWN_CONTENT});
+ require(['WoltLab/WCF/Ui/Like/Handler'], function(UiLikeHandler) {
+ var canDislike = {if LIKE_ENABLE_DISLIKE}true{else}false{/if};
+ var canLike = {if $__wcf->getUser()->userID && $__wcf->getSession()->getPermission('user.like.canLike')}true{else}false{/if};
+ var canLikeOwnContent = {if LIKE_ALLOW_FOR_OWN_CONTENT}true{else}false{/if};
+
+ new UiLikeHandler('com.woltlab.wcf.comment', {
+ // settings
+ badgeClassNames: 'separatorLeft',
+ markListItemAsActive: true,
+ renderAsButton: false,
+
+ // permissions
+ canDislike: canDislike,
+ canLike: canLike,
+ canLikeOwnContent: canLikeOwnContent,
+ canViewSummary: false,
+
+ // selectors
+ badgeContainerSelector: '.commentContent:not(.commentResponseContent) > .containerHeadline > h3',
+ buttonAppendToSelector: '.commentContent .buttonList',
+ containerSelector: '.comment',
+ summarySelector: ''
+ });
+
+ new UiLikeHandler('com.woltlab.wcf.comment.response', {
+ // settings
+ badgeClassNames: 'separatorLeft',
+ markListItemAsActive: true,
+ renderAsButton: false,
+
+ // permissions
+ canDislike: canDislike,
+ canLike: canLike,
+ canLikeOwnContent: canLikeOwnContent,
+ canViewSummary: false,
+
+ // selectors
+ badgeContainerSelector: '.commentResponseContent > .containerHeadline > h3',
+ buttonAppendToSelector: '.commentContent .buttonList',
+ containerSelector: '.commentResponse',
+ summarySelector: ''
+ });
+ });
{/if}
{if $commentList->getCommentManager()->supportsReport() && $__wcf->session->getPermission('user.profile.canReportContent')}
{if !$commentManager|isset}{assign var='commentManager' value=$commentList->getCommentManager()}{/if}
{foreach from=$commentList item=comment}
- <li class="comment jsComment" data-comment-id="{@$comment->commentID}" data-object-type="com.woltlab.wcf.comment" data-like-liked="{if $likeData[comment][$comment->commentID]|isset}{@$likeData[comment][$comment->commentID]->liked}{/if}" data-like-likes="{if $likeData[comment][$comment->commentID]|isset}{@$likeData[comment][$comment->commentID]->likes}{else}0{/if}" data-like-dislikes="{if $likeData[comment][$comment->commentID]|isset}{@$likeData[comment][$comment->commentID]->dislikes}{else}0{/if}" data-like-users='{if $likeData[comment][$comment->commentID]|isset}{ {implode from=$likeData[comment][$comment->commentID]->getUsers() item=likeUser}"{@$likeUser->userID}": { "username": "{$likeUser->username|encodeJSON}" }{/implode} }{else}{ }{/if}' data-can-edit="{if $comment->isEditable()}true{else}false{/if}" data-can-delete="{if $comment->isDeletable()}true{else}false{/if}" data-responses="{@$comment->responses}" data-last-response-time="{@$comment->getLastResponseTime()}" data-user-id="{@$comment->userID}">
+ <li class="comment jsComment" data-object-id="{@$comment->commentID}" data-comment-id="{@$comment->commentID}" data-object-type="com.woltlab.wcf.comment" data-like-liked="{if $likeData[comment][$comment->commentID]|isset}{@$likeData[comment][$comment->commentID]->liked}{/if}" data-like-likes="{if $likeData[comment][$comment->commentID]|isset}{@$likeData[comment][$comment->commentID]->likes}{else}0{/if}" data-like-dislikes="{if $likeData[comment][$comment->commentID]|isset}{@$likeData[comment][$comment->commentID]->dislikes}{else}0{/if}" data-like-users='{if $likeData[comment][$comment->commentID]|isset}{ {implode from=$likeData[comment][$comment->commentID]->getUsers() item=likeUser}"{@$likeUser->userID}": { "username": "{$likeUser->username|encodeJSON}" }{/implode} }{else}{ }{/if}' data-can-edit="{if $comment->isEditable()}true{else}false{/if}" data-can-delete="{if $comment->isDeletable()}true{else}false{/if}" data-responses="{@$comment->responses}" data-last-response-time="{@$comment->getLastResponseTime()}" data-user-id="{@$comment->userID}">
<div class="box48">
{if $comment->userID}
<a href="{link controller='User' object=$comment->getUserProfile()}{/link}" title="{$comment->getUserProfile()->username}">
{foreach from=$responseList item=response}
- <li class="commentResponse jsCommentResponse" data-response-id="{@$response->responseID}" data-object-type="com.woltlab.wcf.comment.response" data-like-liked="{if $likeData[response][$response->responseID]|isset}{@$likeData[response][$response->responseID]->liked}{/if}" data-like-likes="{if $likeData[response][$response->responseID]|isset}{@$likeData[response][$response->responseID]->likes}{else}0{/if}" data-like-dislikes="{if $likeData[response][$response->responseID]|isset}{@$likeData[response][$response->responseID]->dislikes}{else}0{/if}" data-like-users='{if $likeData[response][$response->responseID]|isset}{ {implode from=$likeData[response][$response->responseID]->getUsers() item=likeUser}"{@$likeUser->userID}": { "username": "{$likeUser->username|encodeJSON}" }{/implode} }{else}{ }{/if}' data-can-edit="{if $response->isEditable()}true{else}false{/if}" data-can-delete="{if $response->isDeletable()}true{else}false{/if}" data-user-id="{@$response->userID}">
+ <li class="commentResponse jsCommentResponse" data-object-id="{@$response->responseID}" data-response-id="{@$response->responseID}" data-object-type="com.woltlab.wcf.comment.response" data-like-liked="{if $likeData[response][$response->responseID]|isset}{@$likeData[response][$response->responseID]->liked}{/if}" data-like-likes="{if $likeData[response][$response->responseID]|isset}{@$likeData[response][$response->responseID]->likes}{else}0{/if}" data-like-dislikes="{if $likeData[response][$response->responseID]|isset}{@$likeData[response][$response->responseID]->dislikes}{else}0{/if}" data-like-users='{if $likeData[response][$response->responseID]|isset}{ {implode from=$likeData[response][$response->responseID]->getUsers() item=likeUser}"{@$likeUser->userID}": { "username": "{$likeUser->username|encodeJSON}" }{/implode} }{else}{ }{/if}' data-can-edit="{if $response->isEditable()}true{else}false{/if}" data-can-delete="{if $response->isDeletable()}true{else}false{/if}" data-user-id="{@$response->userID}">
<div class="box32">
{if $response->userID}
<a href="{link controller='User' object=$response->getUserProfile()}{/link}" title="{$response->getUserProfile()->username}">
}
});
-/**
- * Like support for comments
- *
- * @see WCF.Like
- */
-WCF.Comment.Like = WCF.Like.extend({
- /**
- * @see WCF.Like._getContainers()
- */
- _getContainers: function() {
- return $('.commentList > li.comment');
- },
-
- /**
- * @see WCF.Like._getObjectID()
- */
- _getObjectID: function(containerID) {
- return this._containers[containerID].data('commentID');
- },
-
- /**
- * @see WCF.Like._buildWidget()
- */
- _buildWidget: function(containerID, likeButton, dislikeButton, badge, summary) {
- this._containers[containerID].find('.containerHeadline:eq(0) > h3').append(badge);
-
- if (this._canLike) {
- likeButton.appendTo(this._containers[containerID].find('ul.buttonList:eq(0)'));
- dislikeButton.appendTo(this._containers[containerID].find('ul.buttonList:eq(0)'));
- }
- },
-
- /**
- * @see WCF.Like._getWidgetContainer()
- */
- _getWidgetContainer: function(containerID) {},
-
- /**
- * @see WCF.Like._addWidget()
- */
- _addWidget: function(containerID, widget) {}
-});
-
/**
* Namespace for comment responses
*/
WCF.Comment.Response = { };
-
-/**
- * Like support for comments responses.
- *
- * @see WCF.Like
- */
-WCF.Comment.Response.Like = WCF.Like.extend({
- /**
- * @see WCF.Like._addWidget()
- */
- _addWidget: function(containerID, widget) { },
-
- /**
- * @see WCF.Like._buildWidget()
- */
- _buildWidget: function(containerID, likeButton, dislikeButton, badge, summary) {
- this._containers[containerID].find('.containerHeadline:eq(0) > h3').append(badge);
-
- if (this._canLike) {
- likeButton.appendTo(this._containers[containerID].find('ul.buttonList:eq(0)'));
- dislikeButton.appendTo(this._containers[containerID].find('ul.buttonList:eq(0)'));
- }
- },
-
- /**
- * @see WCF.Like._getContainers()
- */
- _getContainers: function() {
- return $('.commentResponseList > li.commentResponse');
- },
-
- /**
- * @see WCF.Like._getObjectID()
- */
- _getObjectID: function(containerID) {
- return this._containers[containerID].data('responseID');
- },
-
- /**
- * @see WCF.Like._getWidgetContainer()
- */
- _getWidgetContainer: function(containerID) { }
-});
/**
* @constructor
*/
- function UiLikeHandler(objectType, options) { this.init(objectType, options); };
+ function UiLikeHandler(objectType, options) { this.init(objectType, options); }
UiLikeHandler.prototype = {
/**
* Initializes the like handler.
this._details = new ObjectMap();
this._objectType = objectType;
this._options = Core.extend({
+ // settings
+ badgeClassNames: '',
isSingleItem: false,
+ markListItemAsActive: false,
+ renderAsButton: true,
// permissions
canDislike: false,
// selectors
badgeContainerSelector: '.messageHeader .messageHeadline > p',
+ buttonAppendToSelector: '',
buttonBeforeSelector: '.messageFooterButtons > .toTopLink',
containerSelector: '',
summarySelector: '.messageFooterNotes'
if (badgeContainer !== null) {
badge = elCreate('a');
badge.href = '#';
- badge.className = 'wcfLikeCounter jsTooltip';
+ badge.className = 'wcfLikeCounter jsTooltip' + (this._options.badgeClassNames ? ' ' + this._options.badgeClassNames : '');
badge.addEventListener('click', this._showSummary.bind(this, element));
badgeContainer.appendChild(badge);
this._updateBadge(element);
}
- var insertPosition, userId = elAttr(element, 'data-user-id');
- if (this._options.canLikeOwnContent || WCF.User.userID === userId) {
- insertPosition = elBySel(this._options.buttonBeforeSelector, element);
- if (insertPosition !== null) {
+ if (WCF.User.userID != elData(element, 'user-id') || this._options.canLikeOwnContent) {
+ var appendTo = (this._options.buttonAppendToSelector) ? elBySel(this._options.buttonAppendToSelector, element) : null;
+ var insertPosition = (this._options.buttonBeforeSelector) ? elBySel(this._options.buttonBeforeSelector, element) : null;
+ if (insertPosition === null && appendTo === null) {
+ throw new Error("Unable to find insert location for like/dislike buttons.");
+ }
+ else {
// like button
- elementData.likeButton = this._createButton(element, insertPosition, true);
+ elementData.likeButton = this._createButton(element, true, insertPosition, appendTo);
// dislike button
if (this._options.canDislike) {
- elementData.dislikeButton = this._createButton(element, insertPosition, false);
+ elementData.dislikeButton = this._createButton(element, false, insertPosition, appendTo);
}
this._updateActiveState(element);
* Creates a like or dislike button.
*
* @param {Element} element container element
- * @param {Element} insertBefore insert button before given element
* @param {boolean} isLike false if this is a dislike button
+ * @param {Element?} insertBefore insert button before given element
+ * @param {Element?} appendTo append button to given element
* @return {Element} button element
*/
- _createButton: function(element, insertBefore, isLike) {
+ _createButton: function(element, isLike, insertBefore, appendTo) {
var title = Language.get('wcf.like.button.' + (isLike ? 'like' : 'dislike'));
var listItem = elCreate('li');
listItem.className = 'wcf' + (isLike ? 'Like' : 'Dislike') + 'Button';
var button = elCreate('a');
- button.className = 'button jsTooltip';
+ button.className = 'jsTooltip' + (this._options.renderAsButton ? ' button' : '');
button.href = '#';
button.title = title;
button.innerHTML = '<span class="icon icon16 fa-thumbs-o-' + (isLike ? 'up' : 'down') + '" /> <span class="invisible">' + title + '</span>';
button.setAttribute('data-type', (isLike ? 'like' : 'dislike'));
listItem.appendChild(button);
- insertBefore.parentNode.insertBefore(listItem, insertBefore);
+
+ if (insertBefore) {
+ insertBefore.parentNode.insertBefore(listItem, insertBefore);
+ }
+ else {
+ appendTo.appendChild(listItem);
+ }
return button;
},
_updateActiveState: function(element) {
var data = this._containers.get(element);
- if (data.dislikeButton !== null) data.dislikeButton.classList.remove('active');
- data.likeButton.classList.remove('active');
+ var dislikeTarget = (this._options.markListItemAsActive) ? data.dislikeButton.parentNode : data.dislikeButton;
+ var likeTarget = (this._options.markListItemAsActive) ? data.likeButton.parentNode : data.likeButton;
+
+ if (data.dislikeButton !== null) dislikeTarget.classList.remove('active');
+ likeTarget.classList.remove('active');
if (data.liked === 1) {
- data.likeButton.classList.add('active');
+ likeTarget.classList.add('active');
}
else if (data.liked === -1 && data.dislikeButton !== null) {
- data.dislikeButton.classList.add('active');
+ dislikeTarget.classList.add('active');
}
},
margin-top: 20px;
}
}
+
+ .wcfLikeCounter {
+ @extend .wcfFontSmall;
+ }
}
.commentResponseList {