Using new like handler for comments
authorAlexander Ebert <ebert@woltlab.com>
Tue, 26 Jan 2016 14:32:27 +0000 (15:32 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 26 Jan 2016 14:32:27 +0000 (15:32 +0100)
com.woltlab.wcf/templates/__commentJavaScript.tpl
com.woltlab.wcf/templates/commentList.tpl
com.woltlab.wcf/templates/commentResponseList.tpl
wcfsetup/install/files/js/WCF.Comment.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Like/Handler.js
wcfsetup/install/files/style/ui/comment.scss

index 3ebedce8ffdfd3c8d26b3a420db1ceb16c0c187f..4c64c0daac5b1c74627ecac3cb1192aabc4b93d8 100644 (file)
                
                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')}
index 4a7e8602561b84472d08cc7e1fa8f15485c6fba0..a52cef6f3b73ef8a3aaee09a7fde9aa6dc18411f 100644 (file)
@@ -1,6 +1,6 @@
 {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}">
index fe86d2fb19fd994cf86f068ba7e9a33dbd45d52a..39f9634953651f2e4959f71bfc15d7b077b59f18 100644 (file)
@@ -1,5 +1,5 @@
 {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}">
index 6831fd87875892e65ee398de30399ad916b0256f..10dcba0537e14ed6688876455e7190e5a01d93f8 100644 (file)
@@ -890,93 +890,7 @@ WCF.Comment.Handler = Class.extend({
        }
 });
 
-/**
- * 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) { }
-});
index 311ba61a77a51cf83e6345dfdb320f182b3064f7..729c3e6bee05ac3d65366ef3c5e0747e1177afbb 100644 (file)
@@ -25,7 +25,7 @@ define(
        /**
         * @constructor
         */
-       function UiLikeHandler(objectType, options) { this.init(objectType, options); };
+       function UiLikeHandler(objectType, options) { this.init(objectType, options); }
        UiLikeHandler.prototype = {
                /**
                 * Initializes the like handler.
@@ -42,7 +42,11 @@ define(
                        this._details = new ObjectMap();
                        this._objectType = objectType;
                        this._options = Core.extend({
+                               // settings
+                               badgeClassNames: '',
                                isSingleItem: false,
+                               markListItemAsActive: false,
+                               renderAsButton: true,
                                
                                // permissions
                                canDislike: false,
@@ -52,6 +56,7 @@ define(
                                
                                // selectors
                                badgeContainerSelector: '.messageHeader .messageHeadline > p',
+                               buttonAppendToSelector: '',
                                buttonBeforeSelector: '.messageFooterButtons > .toTopLink',
                                containerSelector: '',
                                summarySelector: '.messageFooterNotes'
@@ -125,7 +130,7 @@ define(
                        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);
@@ -134,16 +139,19 @@ define(
                                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);
@@ -155,18 +163,19 @@ define(
                 * 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>';
@@ -174,7 +183,13 @@ define(
                        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;
                },
@@ -275,14 +290,17 @@ define(
                _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');
                        }
                },
                
index 5378a959651ea480b3d94e4019780510783dd506..013ebdb1501be91c27c181f3437076f646269da0 100644 (file)
                                margin-top: 20px;
                        }
                }
+               
+               .wcfLikeCounter {
+                       @extend .wcfFontSmall;
+               }
        }
        
        .commentResponseList {