};
}]);
-
- // Controller used to reply to and add new comments
- ngApp.controller('CommentReplyController', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
- const MarkdownIt = require("markdown-it");
- const md = new MarkdownIt({html: true});
- let vm = this;
-
- vm.saveComment = function () {
- let pageId = $scope.comment.pageId || $scope.pageId;
- let comment = $scope.comment.text;
- if (!comment) {
- return events.emit('warning', trans('errors.empty_comment'));
- }
- let commentHTML = md.render($scope.comment.text);
- let serviceUrl = `/ajax/page/${pageId}/comment/`;
- let httpMethod = 'post';
- let reqObj = {
- text: comment,
- html: commentHTML
- };
-
- if ($scope.isEdit === true) {
- // this will be set when editing the comment.
- serviceUrl = `/ajax/page/${pageId}/comment/${$scope.comment.id}`;
- httpMethod = 'put';
- } else if ($scope.isReply === true) {
- // if its reply, get the parent comment id
- reqObj.parent_id = $scope.parentId;
- }
- $http[httpMethod](window.baseUrl(serviceUrl), reqObj).then(resp => {
- if (!isCommentOpSuccess(resp)) {
- return;
- }
- // hide the comments first, and then retrigger the refresh
- if ($scope.isEdit) {
- updateComment($scope.comment, resp.data);
- $scope.$emit('evt.comment-success', $scope.comment.id);
- } else {
- $scope.comment.text = '';
- if ($scope.isReply === true && $scope.parent.sub_comments) {
- $scope.parent.sub_comments.push(resp.data.comment);
- } else {
- $scope.$emit('evt.new-comment', resp.data.comment);
- }
- $scope.$emit('evt.comment-success', null, true);
- }
- $scope.comment.is_hidden = true;
- $timeout(function() {
- $scope.comment.is_hidden = false;
- });
-
- events.emit('success', trans(resp.data.message));
-
- }, checkError);
-
- };
-
- function checkError(response) {
- let msg = null;
- if (isCommentOpSuccess(response)) {
- // all good
- return;
- } else if (response.data) {
- msg = response.data.message;
- } else {
- msg = trans('errors.comment_add');
- }
- if (msg) {
- events.emit('success', msg);
- }
- }
- }]);
-
- // Controller used to delete comments
- ngApp.controller('CommentDeleteController', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
- let vm = this;
-
- vm.delete = function(comment) {
- $http.delete(window.baseUrl(`/ajax/comment/${comment.id}`)).then(resp => {
- if (!isCommentOpSuccess(resp)) {
- return;
- }
- updateComment(comment, resp.data, $timeout, true);
- }, function (resp) {
- if (isCommentOpSuccess(resp)) {
- events.emit('success', trans('entities.comment_deleted'));
- } else {
- events.emit('error', trans('error.comment_delete'));
- }
- });
- };
- }]);
-
- // Controller used to fetch all comments for a page
- ngApp.controller('CommentListController', ['$scope', '$http', '$timeout', '$location', function ($scope, $http, $timeout, $location) {
- let vm = this;
- $scope.errors = {};
- // keep track of comment levels
- $scope.level = 1;
- vm.totalCommentsStr = trans('entities.comments_loading');
- vm.permissions = {};
- vm.trans = window.trans;
-
- $scope.$on('evt.new-comment', function (event, comment) {
- // add the comment to the comment list.
- vm.comments.push(comment);
- ++vm.totalComments;
- setTotalCommentMsg();
- event.stopPropagation();
- event.preventDefault();
- });
-
- vm.canEditDelete = function (comment, prop) {
- if (!comment.active) {
- return false;
- }
- let propAll = prop + '_all';
- let propOwn = prop + '_own';
-
- if (vm.permissions[propAll]) {
- return true;
- }
-
- if (vm.permissions[propOwn] && comment.created_by.id === vm.current_user_id) {
- return true;
- }
-
- return false;
- };
-
- vm.canComment = function () {
- return vm.permissions.comment_create;
- };
-
- // check if there are is any direct linking
- let linkedCommentId = $location.search().cm;
-
- $timeout(function() {
- $http.get(window.baseUrl(`/ajax/page/${$scope.pageId}/comments/`)).then(resp => {
- if (!isCommentOpSuccess(resp)) {
- // just show that no comments are available.
- vm.totalComments = 0;
- setTotalCommentMsg();
- return;
- }
- vm.comments = resp.data.comments;
- vm.totalComments = +resp.data.total;
- vm.permissions = resp.data.permissions;
- vm.current_user_id = resp.data.user_id;
- setTotalCommentMsg();
- if (!linkedCommentId) {
- return;
- }
- $timeout(function() {
- // wait for the UI to render.
- focusLinkedComment(linkedCommentId);
- });
- }, checkError);
- });
-
- function setTotalCommentMsg () {
- if (vm.totalComments === 0) {
- vm.totalCommentsStr = trans('entities.no_comments');
- } else if (vm.totalComments === 1) {
- vm.totalCommentsStr = trans('entities.one_comment');
- } else {
- vm.totalCommentsStr = trans('entities.x_comments', {
- numComments: vm.totalComments
- });
- }
- }
-
- function focusLinkedComment(linkedCommentId) {
- let comment = angular.element('#' + linkedCommentId);
- if (comment.length === 0) {
- return;
- }
-
- window.setupPageShow.goToText(linkedCommentId);
- }
-
- function checkError(response) {
- let msg = null;
- if (isCommentOpSuccess(response)) {
- // all good
- return;
- } else if (response.data) {
- msg = response.data.message;
- } else {
- msg = trans('errors.comment_list');
- }
- if (msg) {
- events.emit('success', msg);
- }
- }
- }]);
-
- function updateComment(comment, resp, $timeout, isDelete) {
- comment.text = resp.comment.text;
- comment.updated = resp.comment.updated;
- comment.updated_by = resp.comment.updated_by;
- comment.active = resp.comment.active;
- if (isDelete && !resp.comment.active) {
- comment.html = trans('entities.comment_deleted');
- } else {
- comment.html = resp.comment.html;
- }
- if (!$timeout) {
- return;
- }
- comment.is_hidden = true;
- $timeout(function() {
- comment.is_hidden = false;
- });
- }
-
- function isCommentOpSuccess(resp) {
- if (resp && resp.data && resp.data.status === 'success') {
- return true;
- }
- return false;
- }
};
}
}
}]);
-
- ngApp.directive('commentReply', [function () {
- return {
- restrict: 'E',
- templateUrl: 'comment-reply.html',
- scope: {
- pageId: '=',
- parentId: '=',
- parent: '='
- },
- link: function (scope, element) {
- scope.isReply = true;
- element.find('textarea').focus();
- scope.$on('evt.comment-success', function (event) {
- // no need for the event to do anything more.
- event.stopPropagation();
- event.preventDefault();
- scope.closeBox();
- });
-
- scope.closeBox = function () {
- element.remove();
- scope.$destroy();
- };
- }
- };
- }]);
-
- ngApp.directive('commentEdit', [function () {
- return {
- restrict: 'E',
- templateUrl: 'comment-reply.html',
- scope: {
- comment: '='
- },
- link: function (scope, element) {
- scope.isEdit = true;
- element.find('textarea').focus();
- scope.$on('evt.comment-success', function (event, commentId) {
- // no need for the event to do anything more.
- event.stopPropagation();
- event.preventDefault();
- if (commentId === scope.comment.id && !scope.isNew) {
- scope.closeBox();
- }
- });
-
- scope.closeBox = function () {
- element.remove();
- scope.$destroy();
- };
- }
- };
- }]);
-
-
- ngApp.directive('commentReplyLink', ['$document', '$compile', function ($document, $compile) {
- return {
- scope: {
- comment: '='
- },
- link: function (scope, element, attr) {
- element.on('$destroy', function () {
- element.off('click');
- scope.$destroy();
- });
-
- element.on('click', function (e) {
- e.preventDefault();
- var $container = element.parents('.comment-actions').first();
- if (!$container.length) {
- console.error('commentReplyLink directive should be placed inside a container with class comment-box!');
- return;
- }
- if (attr.noCommentReplyDupe) {
- removeDupe();
- }
-
- compileHtml($container, scope, attr.isReply === 'true');
- });
- }
- };
-
- function compileHtml($container, scope, isReply) {
- let lnkFunc = null;
- if (isReply) {
- lnkFunc = $compile('<comment-reply page-id="comment.pageId" parent-id="comment.id" parent="comment"></comment-reply>');
- } else {
- lnkFunc = $compile('<comment-edit comment="comment"></comment-add>');
- }
- var compiledHTML = lnkFunc(scope);
- $container.append(compiledHTML);
- }
-
- function removeDupe() {
- let $existingElement = $document.find('.comments-list comment-reply, .comments-list comment-edit');
- if (!$existingElement.length) {
- return;
- }
-
- $existingElement.remove();
- }
- }]);
-
- ngApp.directive('commentDeleteLink', ['$window', function ($window) {
- return {
- controller: 'CommentDeleteController',
- scope: {
- comment: '='
- },
- link: function (scope, element, attr, ctrl) {
-
- element.on('click', function(e) {
- e.preventDefault();
- var resp = $window.confirm(trans('entities.comment_delete_confirm'));
- if (!resp) {
- return;
- }
-
- ctrl.delete(scope.comment);
- });
- }
- };
- }]);
};
--- /dev/null
+const MarkdownIt = require("markdown-it");
+const md = new MarkdownIt({ html: true });
+
+var template = `
+<div class="comment-editor" v-cloak>
+<form novalidate>
+ <textarea name="markdown" rows="3" v-model="comment.text" :placeholder="trans('entities.comment_placeholder')"></textarea>
+ <input type="hidden" v-model="comment.pageId" name="comment.pageId" :value="pageId">
+ <button type="button" v-if="isReply || isEdit" class="button muted" v-on:click="closeBox">{{ trans('entities.comment_cancel') }}</button>
+ <button type="submit" class="button pos" v-on:click.prevent="saveComment">{{ trans('entities.comment_save') }}</button>
+</form>
+</div>
+`;
+
+const props = {
+ pageId: {},
+ commentObj: {},
+ isReply: {
+ default: false,
+ type: Boolean
+ }, isEdit: {
+ default: false,
+ type: Boolean
+ }
+};
+
+function data() {
+ let comment = {
+ text: ''
+ };
+
+ if (this.isReply) {
+ comment.page_id = this.commentObj.page_id;
+ comment.id = this.commentObj.id;
+ } else if (this.isEdit) {
+ comment = this.commentObj;
+ }
+
+ return {
+ comment: comment,
+ trans: trans
+ };
+}
+
+const methods = {
+ saveComment: function (event) {
+ let pageId = this.comment.page_id || this.pageId;
+ let commentText = this.comment.text;
+ if (!commentText) {
+ return this.$events.emit('error', trans('errors.empty_comment'))
+ }
+ let commentHTML = md.render(commentText);
+ let serviceUrl = `/ajax/page/${pageId}/comment/`;
+ let httpMethod = 'post';
+ let reqObj = {
+ text: commentText,
+ html: commentHTML
+ };
+
+ if (this.isEdit === true) {
+ // this will be set when editing the comment.
+ serviceUrl = `/ajax/page/${pageId}/comment/${this.comment.id}`;
+ httpMethod = 'put';
+ } else if (this.isReply === true) {
+ // if its reply, get the parent comment id
+ reqObj.parent_id = this.comment.id;
+ }
+ $http[httpMethod](window.baseUrl(serviceUrl), reqObj).then(resp => {
+ if (!isCommentOpSuccess(resp)) {
+ this.$events.emit('error', getErrorMsg(resp));
+ return;
+ }
+ // hide the comments first, and then retrigger the refresh
+ if (this.isEdit) {
+ this.$emit('comment-edited', event, resp.data.comment);
+ } else {
+ this.comment.text = '';
+ this.$emit('comment-added', event);
+ if (this.isReply === true) {
+ this.$emit('comment-replied', event, resp.data.comment);
+ } else {
+ this.$parent.$emit('new-comment', event, resp.data.comment);
+ }
+ }
+ this.$events.emit('success', resp.data.message);
+ }).catch(err => {
+ this.$events.emit('error', trans('errors.comment_add'))
+ });
+ },
+ closeBox: function (event) {
+ this.$emit('editor-removed', event);
+ }
+};
+
+const computed = {};
+
+function isCommentOpSuccess(resp) {
+ if (resp && resp.data && resp.data.status === 'success') {
+ return true;
+ }
+ return false;
+}
+
+function getErrorMsg(response) {
+ if (response.data) {
+ return response.data.message;
+ } else {
+ return trans('errors.comment_add');
+ }
+}
+
+module.exports = { name: 'comment-reply', template, data, props, methods, computed };
+
--- /dev/null
+const commentReply = require('./comment-reply');
+
+const template = `
+<div class="comment-box">
+ <div class='page-comment' :id="commentId">
+ <div class="user-image">
+ <img :src="comment.created_by.avatar_url" alt="user avatar">
+ </div>
+ <div class="comment-container">
+ <div class="comment-header">
+ <a :href="comment.created_by.profile_url">{{comment.created_by.name}}</a>
+ </div>
+ <div v-html="comment.html" v-if="comment.active" class="comment-body" v-bind:class="{ 'comment-inactive' : !comment.active }">
+
+ </div>
+ <div v-if="!comment.active" class="comment-body comment-inactive">
+ {{ trans('entities.comment_deleted') }}
+ </div>
+ <div class="comment-actions">
+ <ul>
+ <li v-if="(level < 4 && canComment)">
+ <a href="#" comment="comment" v-on:click.prevent="replyComment">{{ trans('entities.comment_reply') }}</a>
+ </li>
+ <li v-if="canEditOrDelete('update')">
+ <a href="#" comment="comment" v-on:click.prevent="editComment">{{ trans('entities.comment_edit') }}</a>
+ </li>
+ <li v-if="canEditOrDelete('delete')">
+ <a href="#" comment="comment" v-on:click.prevent="deleteComment">{{ trans('entities.comment_delete') }}</a>
+ </li>
+ <li>{{ trans('entities.comment_create') }}
+ <a :title="comment.created.day_time_str" :href="commentHref">{{comment.created.diff}}</a>
+ </li>
+ <li v-if="comment.updated">
+ <span :title="comment.updated.day_time_str">{{trans('entities.comment_updated_text', { updateDiff: comment.updated.diff }) }}
+ <a :href="comment.updated_by.profile_url">{{comment.updated_by.name}}</a>
+ </span>
+ </li>
+ </ul>
+ </div>
+ <div v-if="showEditor">
+ <comment-reply :page-id="comment.page_id" :comment-obj="comment"
+ v-on:editor-removed.stop.prevent="hideComment"
+ v-on:comment-replied.stop="commentReplied(...arguments)"
+ v-on:comment-edited.stop="commentEdited(...arguments)"
+ v-on:comment-added.stop="commentAdded"
+ :is-reply="isReply" :is-edit="isEdit">
+ </comment-reply>
+ </div>
+ <comment v-for="(comment, index) in comments" :initial-comment="comment" :index="index"
+ :level="nextLevel" :key="comment.id" :permissions="permissions" :current-user-id="currentUserId"
+ v-on:comment-added.stop="commentAdded"></comment>
+
+ </div>
+ </div>
+</div>
+`;
+
+const props = ['initialComment', 'index', 'level', 'permissions', 'currentUserId'];
+
+function data() {
+ return {
+ trans: trans,
+ comments: [],
+ showEditor: false,
+ comment: this.initialComment,
+ nextLevel: this.level + 1
+ };
+}
+
+const methods = {
+ deleteComment: function () {
+ var resp = window.confirm(trans('entities.comment_delete_confirm'));
+ if (!resp) {
+ return;
+ }
+ this.$http.delete(window.baseUrl(`/ajax/comment/${this.comment.id}`)).then(resp => {
+ if (!isCommentOpSuccess(resp)) {
+ this.$events.emit('error', trans('error.comment_delete'));
+ return;
+ }
+ this.$events.emit('success', trans('entities.comment_deleted'));
+ this.comment = resp.data.comment;
+ }).catch(err => {
+ this.$events.emit('error', trans('error.comment_delete'));
+ });
+ },
+ replyComment: function () {
+ this.toggleEditor(false);
+ },
+ editComment: function () {
+ this.toggleEditor(true);
+ },
+ hideComment: function () {
+ this.showEditor = false;
+ },
+ toggleEditor: function (isEdit) {
+ this.showEditor = false;
+ this.isEdit = isEdit;
+ this.isReply = !isEdit;
+ this.showEditor = true;
+ },
+ commentReplied: function (event, comment) {
+ this.comments.push(comment);
+ this.showEditor = false;
+ },
+ commentEdited: function (event, comment) {
+ this.comment = comment;
+ this.showEditor = false;
+ },
+ commentAdded: function (event, comment) {
+ // this is to handle non-parent child relationship
+ // we want to make it go up.
+ this.$emit('comment-added', event);
+ },
+ canEditOrDelete: function (prop) {
+ if (!this.comment.active) {
+ return false;
+ }
+
+ if (!this.permissions) {
+ return false;
+ }
+
+ let propAll = 'comment_' + prop + '_all';
+ let propOwn = 'comment_' + prop + '_own';
+
+ if (this.permissions[propAll]) {
+ return true;
+ }
+
+ if (this.permissions[propOwn] && this.comment.created_by.id === this.currentUserId) {
+ return true;
+ }
+
+ return false;
+ },
+ canComment: function () {
+ if (!this.permissions) {
+ return false;
+ }
+ return this.permissions.comment_create === true;
+ }
+};
+
+const computed = {
+ commentId: function () {
+ return `comment-${this.comment.page_id}-${this.comment.id}`;
+ },
+ commentHref: function () {
+ return `#?cm=${this.commentId}`;
+ }
+};
+
+function mounted() {
+ if (this.comment.sub_comments && this.comment.sub_comments.length) {
+ // set this so that we can render the next set of sub comments.
+ this.comments = this.comment.sub_comments;
+ }
+}
+
+function isCommentOpSuccess(resp) {
+ if (resp && resp.data && resp.data.status === 'success') {
+ return true;
+ }
+ return false;
+}
+
+module.exports = {
+ name: 'comment',
+ template, data, props, methods, computed, mounted, components: {
+ commentReply
+ }
+};
+
--- /dev/null
+const comment = require('./components/comments/comment');
+const commentReply = require('./components/comments/comment-reply');
+
+let data = {
+ totalCommentsStr: trans('entities.comments_loading'),
+ comments: [],
+ permissions: null,
+ currentUserId: null,
+ trans: trans,
+ commentCount: 0
+};
+
+let methods = {
+ commentAdded: function () {
+ ++this.totalComments;
+ }
+}
+
+let computed = {
+ totalComments: {
+ get: function () {
+ return this.commentCount;
+ },
+ set: function (value) {
+ this.commentCount = value;
+ if (value === 0) {
+ this.totalCommentsStr = trans('entities.no_comments');
+ } else if (value === 1) {
+ this.totalCommentsStr = trans('entities.one_comment');
+ } else {
+ this.totalCommentsStr = trans('entities.x_comments', {
+ numComments: value
+ });
+ }
+ }
+ },
+ canComment: function () {
+ if (!this.permissions) {
+ return false;
+ }
+ return this.permissions.comment_create === true;
+ }
+}
+
+function mounted() {
+ this.pageId = Number(this.$el.getAttribute('page-id'));
+ let linkedCommentId = getUrlParameter('cm');
+ this.$http.get(window.baseUrl(`/ajax/page/${this.pageId}/comments/`)).then(resp => {
+ if (!isCommentOpSuccess(resp)) {
+ // just show that no comments are available.
+ vm.totalComments = 0;
+ this.$events.emit('error', getErrorMsg(resp));
+ return;
+ }
+ this.comments = resp.data.comments;
+ this.totalComments = +resp.data.total;
+ this.permissions = resp.data.permissions;
+ this.currentUserId = resp.data.user_id;
+ if (!linkedCommentId) {
+ return;
+ }
+
+ // adding a setTimeout to give the comment list some time to render
+ // before focusing the comment.
+ setTimeout(function() {
+ focusLinkedComment(linkedCommentId);
+ });
+ }).catch(err => {
+ this.$events.emit('error', trans('errors.comment_list'));
+ });
+}
+
+function isCommentOpSuccess(resp) {
+ if (resp && resp.data && resp.data.status === 'success') {
+ return true;
+ }
+ return false;
+}
+
+function getErrorMsg(response) {
+ if (response.data) {
+ return response.data.message;
+ } else {
+ return trans('errors.comment_add');
+ }
+}
+
+function created() {
+ this.$on('new-comment', function (event, comment) {
+ this.comments.push(comment);
+ })
+}
+
+function beforeDestroy() {
+ this.$off('new-comment');
+}
+
+function getUrlParameter(name) {
+ name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
+ var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
+ var results = regex.exec(location.hash);
+ return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
+}
+
+function focusLinkedComment(linkedCommentId) {
+ let comment = document.getElementById(linkedCommentId);
+ if (comment && comment.length !== 0) {
+ window.setupPageShow.goToText(linkedCommentId);
+ }
+}
+
+module.exports = {
+ data, methods, mounted, computed, components: {
+ comment, commentReply
+ },
+ created, beforeDestroy
+};
\ No newline at end of file
'image-manager': require('./image-manager'),
'tag-manager': require('./tag-manager'),
'attachment-manager': require('./attachment-manager'),
+ 'page-comments': require('./page-comments')
};
window.vues = {};
// Comments
'comment_list' => 'An error occurred while fetching the comments.',
'cannot_add_comment_to_draft' => 'You cannot add comments to a draft.',
- 'comment_add' => 'An error occurred while adding the comment.',
+ 'comment_add' => 'An error occurred while adding / updating the comment.',
'comment_delete' => 'An error occurred while deleting the comment.',
'empty_comment' => 'Cannot add an empty comment.',
+++ /dev/null
-<div class="comment-editor" ng-controller="CommentReplyController as vm" ng-cloak>
- <form novalidate>
- <textarea name="markdown" rows="3" ng-model="comment.text" placeholder="{{ trans('entities.comment_placeholder') }}"></textarea>
- <input type="hidden" ng-model="comment.pageId" name="comment.pageId" value="{{$pageId}}" ng-init="comment.pageId = {{$pageId }}">
- <button type="button" ng-if="::(isReply || isEdit)" class="button muted" ng-click="closeBox()">{{ trans('entities.comment_cancel') }}</button>
- <button type="submit" class="button pos" ng-click="vm.saveComment()">{{ trans('entities.comment_save') }}</button>
- </form>
-</div>
-
-@if($errors->has('markdown'))
- <div class="text-neg text-small">{{ $errors->first('markdown') }}</div>
-@endif
\ No newline at end of file
-<script type="text/ng-template" id="comment-list-item.html">
- @include('comments/list-item')
-</script>
-<script type="text/ng-template" id="comment-reply.html">
- @include('comments/comment-reply', ['pageId' => $pageId])
-</script>
-<div ng-controller="CommentListController as vm" ng-init="pageId = <?= $page->id ?>" class="comments-list" ng-cloak>
-<h3>@{{vm.totalCommentsStr}}</h3>
-<hr>
- <div class="comment-box" ng-repeat="comment in vm.comments track by comment.id">
- <div ng-include src="'comment-list-item.html'">
-
- </div>
- </div>
- <div ng-if="::vm.canComment()">
- @include('comments/comment-reply', ['pageId' => $pageId])
- </div>
+<div id="page-comments" page-id="<?= $page->id ?>" class="comments-list" v-cloak>
+ <h3>@{{totalCommentsStr}}</h3>
+ <hr>
+ <comment v-for="(comment, index) in comments" :initial-comment="comment" :index="index" :level=1
+ v-on:comment-added.stop="commentAdded"
+ :current-user-id="currentUserId" :key="comment.id" :permissions="permissions"></comment>
+ <div v-if="canComment">
+ <comment-reply v-on:comment-added.stop="commentAdded" :page-id="<?= $page->id ?>">
+ </comment-reply>
+ </div>
</div>
\ No newline at end of file
+++ /dev/null
-<div class='page-comment' id="comment-@{{::pageId}}-@{{::comment.id}}">
- <div class="user-image">
- <img ng-src="@{{::comment.created_by.avatar_url}}" alt="user avatar">
- </div>
- <div class="comment-container">
- <div class="comment-header">
- <a href="@{{::comment.created_by.profile_url}}">@{{ ::comment.created_by.name }}</a>
- </div>
- <div ng-bind-html="comment.html" ng-if="::comment.active" class="comment-body" ng-class="!comment.active ? 'comment-inactive' : ''">
-
- </div>
- <div ng-if="::!comment.active" class="comment-body comment-inactive">
- {{ trans('entities.comment_deleted') }}
- </div>
- <div class="comment-actions">
- <ul ng-if="!comment.is_hidden">
- <li ng-if="::(level < 3 && vm.canComment())"><a href="#" comment-reply-link no-comment-reply-dupe="true" comment="comment" is-reply="true">{{ trans('entities.comment_reply') }}</a></li>
- <li ng-if="::vm.canEditDelete(comment, 'comment_update')"><a href="#" comment-reply-link no-comment-reply-dupe="true" comment="comment" >{{ trans('entities.comment_edit') }}</a></li>
- <li ng-if="::vm.canEditDelete(comment, 'comment_delete')"><a href="#" comment-delete-link comment="comment" >{{ trans('entities.comment_delete') }}</a></li>
- <li>{{ trans('entities.comment_create') }} <a title="@{{::comment.created.day_time_str}}" href="#?cm=comment-@{{::pageId}}-@{{::comment.id}}">@{{::comment.created.diff}}</a></li>
- <li ng-if="::comment.updated"><span title="@{{::comment.updated.day_time_str}}">@{{ ::vm.trans('entities.comment_updated_text', { updateDiff: comment.updated.diff }) }}
- <a href="@{{::comment.updated_by.profile_url}}">@{{::comment.updated_by.name}}</a></span></li>
- </ul>
- </div>
- <div class="comment-box" ng-repeat="comment in comments = comment.sub_comments track by comment.id" ng-init="level = level + 1">
- <div ng-include src="'comment-list-item.html'">
- </div>
- </div>
- </div>
-</div>
\ No newline at end of file