From 16f9c277a1916f60e36a2e2a6698542ca124e895 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Sat, 4 Oct 2014 14:06:44 +0200 Subject: [PATCH] Added comment presenters --- TODO | 5 - public_html/css/comments.css | 92 +++++++++ public_html/css/core.css | 5 + public_html/css/post-list.css | 39 ++-- public_html/css/post.css | 2 - public_html/index.html | 4 +- .../js/Presenters/CommentListPresenter.js | 28 --- .../Presenters/GlobalCommentListPresenter.js | 110 ++++++++++ public_html/js/Presenters/PagerPresenter.js | 5 +- .../js/Presenters/PostCommentListPresenter.js | 194 ++++++++++++++++++ .../js/Presenters/PostListPresenter.js | 22 +- public_html/js/Presenters/PostPresenter.js | 21 +- .../js/Presenters/UserListPresenter.js | 15 +- public_html/js/Router.js | 2 +- public_html/js/Util.js | 6 + public_html/templates/comment-form.tpl | 17 ++ public_html/templates/comment-list-item.tpl | 53 +++++ .../templates/global-comment-list-item.tpl | 8 + public_html/templates/global-comment-list.tpl | 6 + public_html/templates/post-comment-list.tpl | 13 ++ public_html/templates/post-list-item.tpl | 4 +- public_html/templates/post.tpl | 3 + public_html/templates/user-list-item.tpl | 4 +- 23 files changed, 577 insertions(+), 81 deletions(-) create mode 100644 public_html/css/comments.css delete mode 100644 public_html/js/Presenters/CommentListPresenter.js create mode 100644 public_html/js/Presenters/GlobalCommentListPresenter.js create mode 100644 public_html/js/Presenters/PostCommentListPresenter.js create mode 100644 public_html/templates/comment-form.tpl create mode 100644 public_html/templates/comment-list-item.tpl create mode 100644 public_html/templates/global-comment-list-item.tpl create mode 100644 public_html/templates/global-comment-list.tpl create mode 100644 public_html/templates/post-comment-list.tpl diff --git a/TODO b/TODO index 49a7410d..0fbcbcea 100644 --- a/TODO +++ b/TODO @@ -51,11 +51,6 @@ everything related to tags: - tag edit history everything related to comments: - - adding comments - - listing comments in post view - - listing comments in comment list view - - deleting - - editing - markdown - score diff --git a/public_html/css/comments.css b/public_html/css/comments.css new file mode 100644 index 00000000..41ac6de7 --- /dev/null +++ b/public_html/css/comments.css @@ -0,0 +1,92 @@ +.comment-form { + margin: 1em 0 2em; +} + +.comment-form .preview { + background: lemonchiffon; + padding: 0.5em; + margin-bottom: 1em; + box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.5) inset; + display: none; +} + +.comments ul { + list-style-type: none; + margin: 1em 0; + padding: 0; +} + +.comment { + margin: 0 0 1em 0; + padding: 0; +} + +.comment .body, +.comment .avatar { + display: inline-block; +} + +.comment .avatar { + margin-right: 0.5em; + vertical-align: top; +} + +.comment .content { + margin-top: 0.25em; +} + +.comment .header { + line-height: 16pt; + vertical-align: middle; +} +.comment .date { + color: silver; + font-size: 80%; + padding-left: 0.5em; +} +.comment .header .ops a { + color: silver; + font-size: 80%; +} +.comment .header .ops a:before { + content: '['; +} +.comment .header .ops a:after { + content: ']'; +} + +#global-comment-list { + text-align: center; +} +#global-comment-list .pagination-content { + text-align: left; +} +#global-comment-list .comments>ul { + margin-top: 0; +} +#global-comment-list ul.posts { + list-style-type: none; + margin: 0; + padding: 0; +} +#global-comment-list ul.posts>li>*:last-child:after { + display: block; + content: ''; + clear: left; +} +#global-comment-list ul.posts>li { + margin-bottom: 2em; +} +#global-comment-list .post { + float: left; +} +#global-comment-list .comment-add, +#global-comment-list h1 { + display: none; +} +#global-comment-list .comments { + float: left; +} +#global-comment-list .post-small a { + margin: 0 1em 0 0; +} diff --git a/public_html/css/core.css b/public_html/css/core.css index fbfe881b..707e82dd 100644 --- a/public_html/css/core.css +++ b/public_html/css/core.css @@ -9,6 +9,11 @@ body { overflow-y: scroll; } +h1 { + font-weight: normal; + font-size: 30px; +} + h2 { font-variant: small-caps; font-weight: normal; diff --git a/public_html/css/post-list.css b/public_html/css/post-list.css index 2e20f632..37cc1079 100644 --- a/public_html/css/post-list.css +++ b/public_html/css/post-list.css @@ -23,32 +23,33 @@ justify-content: center; } -#post-list .posts li a { - display: block; +.post-small a { + display: inline-block; margin: 0.4em; border: 1px solid #999; z-index: 1; position: relative; } -#post-list .posts li img { +.post-small img { display: block; } -#post-list .posts li a:focus, -#post-list .posts li a:hover { +.post-small a:focus, +.post-small a:hover { background: #afe; border-color: #5da; box-shadow: 0 0 0 2px #5da; outline: 0; } -#post-list .posts li a:focus img, -#post-list .posts li a:hover img { +.post-small a:focus img, +.post-small a:hover img { opacity: .9; } -#post-list .posts li a .info { +.post-small a .info { display: none; + text-align: center; position: absolute; bottom: 0; left: 0; @@ -56,16 +57,22 @@ background: #5da; color: black; } -#post-list .posts li a .info li { +.post-small a .info ul { + list-style-type: none; + padding: 0; + margin: 0; +} +.post-small a .info li { display: inline-block; margin: 0.1em 0.5em; + padding: 0; } -#post-list .posts li a:focus .info, -#post-list .posts li a:hover .info { +.post-small a:focus .info, +.post-small a:hover .info { display: block; } -#post-list .posts li:not(.post-type-image) a:before { +.post-small:not(.post-type-image) a:before { display: block; content: ''; z-index: 2; @@ -78,7 +85,7 @@ border-left: 50px solid transparent; } -#post-list .posts li:not(.post-type-image) a:after { +.post-small:not(.post-type-image) a:after { display: block; content: '...'; z-index: 3; @@ -93,13 +100,13 @@ color: white; font-size: 15px; } -#post-list .posts li.post-type-youtube a:after { +.post-small.post-type-youtube a:after { font-size: 13px; content: 'youtube'; } -#post-list .posts li.post-type-video a:after { +.post-small.post-type-video a:after { content: 'video'; } -#post-list .posts li.post-type-flash a:after { +.post-small.post-type-flash a:after { content: 'flash'; } diff --git a/public_html/css/post.css b/public_html/css/post.css index 863000db..b3e1f011 100644 --- a/public_html/css/post.css +++ b/public_html/css/post.css @@ -16,8 +16,6 @@ #post-view-wrapper #sidebar h1 { margin-top: 1.5em; - font-weight: normal; - font-size: 30px; } #post-view-wrapper #sidebar h1:first-of-type { diff --git a/public_html/index.html b/public_html/index.html index 377b499d..35801ddc 100644 --- a/public_html/index.html +++ b/public_html/index.html @@ -33,6 +33,7 @@ + @@ -96,7 +97,8 @@ - + + diff --git a/public_html/js/Presenters/CommentListPresenter.js b/public_html/js/Presenters/CommentListPresenter.js deleted file mode 100644 index 566ce38b..00000000 --- a/public_html/js/Presenters/CommentListPresenter.js +++ /dev/null @@ -1,28 +0,0 @@ -var App = App || {}; -App.Presenters = App.Presenters || {}; - -App.Presenters.CommentListPresenter = function( - jQuery, - topNavigationPresenter) { - - var $el = jQuery('#content'); - - function init(args, loaded) { - topNavigationPresenter.select('comments'); - topNavigationPresenter.changeTitle('Comments'); - render(); - loaded(); - } - - function render() { - $el.html('Comment list placeholder'); - } - - return { - init: init, - render: render, - }; - -}; - -App.DI.register('commentListPresenter', ['jQuery', 'topNavigationPresenter'], App.Presenters.CommentListPresenter); diff --git a/public_html/js/Presenters/GlobalCommentListPresenter.js b/public_html/js/Presenters/GlobalCommentListPresenter.js new file mode 100644 index 00000000..7f4786f2 --- /dev/null +++ b/public_html/js/Presenters/GlobalCommentListPresenter.js @@ -0,0 +1,110 @@ +var App = App || {}; +App.Presenters = App.Presenters || {}; + +App.Presenters.GlobalCommentListPresenter = function( + _, + jQuery, + util, + promise, + pagerPresenter, + topNavigationPresenter) { + + var $el; + var listTemplate; + var itemTemplate; + var postTemplate; + + function init(args, loaded) { + $el = jQuery('#content'); + topNavigationPresenter.select('comments'); + + promise.wait( + util.promiseTemplate('global-comment-list'), + util.promiseTemplate('global-comment-list-item'), + util.promiseTemplate('post-list-item')) + .then(function(listHtml, listItemHtml, postItemHtml) + { + listTemplate = _.template(listHtml); + itemTemplate = _.template(listItemHtml); + postTemplate = _.template(postItemHtml); + + render(); + loaded(); + + pagerPresenter.init({ + baseUri: '#/comments', + backendUri: '/comments', + $target: $el.find('.pagination-target'), + updateCallback: function(data, clear) { + renderPosts(data.entities, clear); + }, + }, + function() { + onArgsChanged(args); + }); + }) + .fail(function() { console.log(new Error(arguments)); }); + } + + + function reinit(args, loaded) { + loaded(); + onArgsChanged(args); + } + + function onArgsChanged(args) { + var searchArgs = util.parseComplexRouteArgs(args.searchArgs); + pagerPresenter.reinit({ + page: searchArgs.page, + searchParams: { + query: searchArgs.query, + order: searchArgs.order}}); + } + + function deinit() { + pagerPresenter.deinit(); + } + + function render() { + $el.html(listTemplate()); + } + + function renderPosts(data, clear) { + var $target = $el.find('.posts'); + + if (clear) { + $target.empty(); + } + + _.each(data, function(data) { + var post = data.post; + var comments = data.comments; + + var $post = jQuery('
  • ' + itemTemplate({ + post: post, + postTemplate: postTemplate, + }) + '
  • '); + + var presenter = App.DI.get('postCommentListPresenter'); + + presenter.init({ + post: post, + comments: comments, + $target: $post.find('.post-comments-target'), + }, function() { + presenter.render(); + }); + + $target.append($post); + }); + } + + return { + init: init, + reinit: reinit, + deinit: deinit, + render: render, + }; +}; + +App.DI.register('globalCommentListPresenter', ['_', 'jQuery', 'util', 'promise', 'pagerPresenter', 'topNavigationPresenter'], App.Presenters.GlobalCommentListPresenter); diff --git a/public_html/js/Presenters/PagerPresenter.js b/public_html/js/Presenters/PagerPresenter.js index 898f3a25..62a7ec86 100644 --- a/public_html/js/Presenters/PagerPresenter.js +++ b/public_html/js/Presenters/PagerPresenter.js @@ -100,9 +100,8 @@ App.Presenters.PagerPresenter = function( return util.compileComplexRouteArgs( baseUri, _.extend( - {}, - pager.getSearchParams(), - {page: pager.getPage()})); + {page: pager.getPage()}, + pager.getSearchParams())); } function syncUrl() { diff --git a/public_html/js/Presenters/PostCommentListPresenter.js b/public_html/js/Presenters/PostCommentListPresenter.js new file mode 100644 index 00000000..a02d2894 --- /dev/null +++ b/public_html/js/Presenters/PostCommentListPresenter.js @@ -0,0 +1,194 @@ +var App = App || {}; +App.Presenters = App.Presenters || {}; + +App.Presenters.PostCommentListPresenter = function( + _, + jQuery, + util, + promise, + api, + auth, + topNavigationPresenter, + messagePresenter) { + + var $el; + var commentListTemplate; + var commentListItemTemplate; + var commentFormTemplate; + var privileges; + + var post; + var comments = []; + + function init(args, loaded) { + $el = args.$target; + post = args.post; + comments = args.comments || []; + + privileges = { + canListComments: auth.hasPrivilege(auth.privileges.listComments), + canAddComments: auth.hasPrivilege(auth.privileges.addComments), + editOwnComments: auth.hasPrivilege(auth.privileges.editOwnComments), + editAllComments: auth.hasPrivilege(auth.privileges.editAllComments), + deleteOwnComments: auth.hasPrivilege(auth.privileges.deleteOwnComments), + deleteAllComments: auth.hasPrivilege(auth.privileges.deleteAllComments), + }; + + promise.wait( + util.promiseTemplate('post-comment-list'), + util.promiseTemplate('comment-list-item'), + util.promiseTemplate('comment-form'), + comments.length === 0 ? api.get('/comments/' + args.post.id) : null) + .then(function( + commentListHtml, + commentListItemHtml, + commentFormHtml, + commentsResponse) + { + commentListTemplate = _.template(commentListHtml); + commentListItemTemplate = _.template(commentListItemHtml); + commentFormTemplate = _.template(commentFormHtml); + if (commentsResponse) { + comments = commentsResponse.json.data; + } + + render(); + loaded(); + }) + .fail(function() { console.log(new Error(arguments)); }); + } + + function render() { + $el.html(commentListTemplate( + _.extend( + { + commentListItemTemplate: commentListItemTemplate, + commentFormTemplate: commentFormTemplate, + formatRelativeTime: util.formatRelativeTime, + formatMarkdown: util.formatMarkdown, + comments: comments, + post: post, + }, + privileges))); + + $el.find('.comment-add form button[type=submit]').click(function(e) { commentFormSubmitted(e, null); }); + renderComments(comments, true); + } + + function renderComments(comments, clear) { + var $target = $el.find('.comments'); + var $targetList = $el.find('ul'); + + if (comments.length > 0) { + $target.show(); + } else { + $target.hide(); + } + + if (clear) { + $targetList.empty(); + } + + _.each(comments, function(comment) { + renderComment($targetList, comment); + }); + } + + function renderComment($targetList, comment) { + var $item = jQuery('
  • ' + commentListItemTemplate({ + comment: comment, + formatRelativeTime: util.formatRelativeTime, + formatMarkdown: util.formatMarkdown, + canEditComment: auth.isLoggedIn(comment.user.name) ? privileges.editOwnComments : privileges.editAllComments, + canDeleteComment: auth.isLoggedIn(comment.user.name) ? privileges.deleteOwnComments : privileges.deleteAllComments, + }) + '
  • '); + $targetList.append($item); + $item.find('a.edit').click(function(e) { + e.preventDefault(); + editCommentStart($item, comment); + }); + $item.find('a.delete').click(function(e) { + e.preventDefault(); + deleteComment($item, comment); + }); + } + + function commentFormSubmitted(e, comment) { + e.preventDefault(); + var $button = jQuery(e.target); + var $form = $button.parents('form'); + var sender = $button.val(); + if (sender === 'preview') { + previewComment($form); + } else { + submitComment($form, comment); + } + } + + function previewComment($form) { + var $preview = $form.find('.preview'); + $preview.slideUp('fast', function() { + $preview.html(util.formatMarkdown($form.find('textarea').val())); + $preview.slideDown('fast'); + }); + } + + function submitComment($form, commentToEdit) { + $form.find('.preview').slideUp(); + var $textarea = $form.find('textarea'); + + var data = {text: $textarea.val()}; + var p; + if (commentToEdit) { + p = promise.wait(api.put('/comments/' + commentToEdit.id, data)); + } else { + p = promise.wait(api.post('/comments/' + post.id, data)); + } + + p.then(function(response) { + $textarea.val(''); + var comment = response.json; + + if (commentToEdit) { + $form.slideUp(function() { + $form.remove(); + }); + comments = _.map(comments, function(c) { return c.id === commentToEdit.id ? comment : c; }); + } else { + comments.push(comment); + } + renderComments(comments, true); + }).fail(function(response) { + window.alert(response.json && response.json.error || response); + }); + } + + function editCommentStart($item, comment) { + if ($item.find('.comment-form').length > 0) { + return; + } + var $form = jQuery(commentFormTemplate({title: 'Edit comment', text: comment.text})); + $item.find('.body').append($form); + $item.find('form button[type=submit]').click(function(e) { commentFormSubmitted(e, comment); }); + } + + function deleteComment($item, comment) { + if (!window.confirm('Are you sure you want to delete this comment?')) { + return; + } + promise.wait(api.delete('/comments/' + comment.id)) + .then(function(response) { + comments = _.filter(comments, function(c) { return c.id !== comment.id; }); + renderComments(comments, true); + }).fail(function(response) { + window.alert(response.json && response.json.error || response); + }); + } + + return { + init: init, + render: render, + }; +}; + +App.DI.register('postCommentListPresenter', ['_', 'jQuery', 'util', 'promise', 'api', 'auth', 'topNavigationPresenter', 'messagePresenter'], App.Presenters.PostCommentListPresenter); diff --git a/public_html/js/Presenters/PostListPresenter.js b/public_html/js/Presenters/PostListPresenter.js index 8a046775..44db2976 100644 --- a/public_html/js/Presenters/PostListPresenter.js +++ b/public_html/js/Presenters/PostListPresenter.js @@ -44,14 +44,17 @@ App.Presenters.PostListPresenter = function( }, }, function() { - reinit(args, function() {}); + onArgsChanged(args); }); }); } function reinit(args, loaded) { loaded(); + onArgsChanged(args); + } + function onArgsChanged(args) { searchArgs = util.parseComplexRouteArgs(args.searchArgs); pagerPresenter.reinit({ page: searchArgs.page, @@ -84,18 +87,15 @@ App.Presenters.PostListPresenter = function( function renderPosts(posts, clear) { var $target = $el.find('.posts'); - var all = ''; - _.each(posts, function(post) { - all += itemTemplate({ - post: post, - }); - }); - if (clear) { - $target.html(all); - } else { - $target.append(all); + $target.empty(); } + + _.each(posts, function(post) { + $target.append(jQuery('
  • ' + itemTemplate({ + post: post, + }) + '
  • ')); + }); } function searchInputKeyPressed(e) { diff --git a/public_html/js/Presenters/PostPresenter.js b/public_html/js/Presenters/PostPresenter.js index 44b4eede..1740c215 100644 --- a/public_html/js/Presenters/PostPresenter.js +++ b/public_html/js/Presenters/PostPresenter.js @@ -10,6 +10,8 @@ App.Presenters.PostPresenter = function( auth, router, keyboard, + presenterManager, + postCommentListPresenter, topNavigationPresenter, messagePresenter) { @@ -122,6 +124,10 @@ App.Presenters.PostPresenter = function( $el.find('.post-edit-wrapper form').submit(editFormSubmitted); attachSidebarEvents(); + + presenterManager.initPresenters([ + [postCommentListPresenter, _.extend({post: post}, {$target: $el.find('#post-comments-target')})]], + function() { }); } function renderSidebar() { @@ -354,4 +360,17 @@ App.Presenters.PostPresenter = function( }; -App.DI.register('postPresenter', ['_', 'jQuery', 'util', 'promise', 'api', 'auth', 'router', 'keyboard', 'topNavigationPresenter', 'messagePresenter'], App.Presenters.PostPresenter); +App.DI.register('postPresenter', [ + '_', + 'jQuery', + 'util', + 'promise', + 'api', + 'auth', + 'router', + 'keyboard', + 'presenterManager', + 'postCommentListPresenter', + 'topNavigationPresenter', + 'messagePresenter'], + App.Presenters.PostPresenter); diff --git a/public_html/js/Presenters/UserListPresenter.js b/public_html/js/Presenters/UserListPresenter.js index a67f7daa..1dfd073a 100644 --- a/public_html/js/Presenters/UserListPresenter.js +++ b/public_html/js/Presenters/UserListPresenter.js @@ -72,19 +72,16 @@ App.Presenters.UserListPresenter = function( function renderUsers(users, clear) { var $target = $el.find('.users'); - var all = ''; + if (clear) { + $target.empty(); + } + _.each(users, function(user) { - all += itemTemplate({ + $target.append(jQuery('
  • ' + itemTemplate({ user: user, formatRelativeTime: util.formatRelativeTime, - }); + }) + '
  • ')); }); - - if (clear) { - $target.html(all); - } else { - $target.append(all); - } } function orderLinkClicked(e) { diff --git a/public_html/js/Router.js b/public_html/js/Router.js index dd2c6ae7..5fda740b 100644 --- a/public_html/js/Router.js +++ b/public_html/js/Router.js @@ -40,7 +40,7 @@ App.Router = function(pathJs, _, jQuery, promise, util, appState, presenterManag inject('#/user/:userName(/:tab)', 'userPresenter'); inject('#/posts(/:searchArgs)', 'postListPresenter'); inject('#/post(/:postNameOrId)', 'postPresenter'); - inject('#/comments(/:searchArgs)', 'commentListPresenter'); + inject('#/comments(/:searchArgs)', 'globalCommentListPresenter'); inject('#/tags(/:searchArgs)', 'tagListPresenter'); inject('#/help', 'helpPresenter'); setRoot('#/home'); diff --git a/public_html/js/Util.js b/public_html/js/Util.js index 8cc02e02..b40c341d 100644 --- a/public_html/js/Util.js +++ b/public_html/js/Util.js @@ -183,12 +183,18 @@ App.Util = function(_, jQuery, promise) { }); } + function formatMarkdown(text) { + //todo + return text; + } + return { promiseTemplate: promiseTemplate, parseComplexRouteArgs: parseComplexRouteArgs, compileComplexRouteArgs: compileComplexRouteArgs, formatRelativeTime: formatRelativeTime, formatFileSize: formatFileSize, + formatMarkdown: formatMarkdown, enableExitConfirmation: enableExitConfirmation, disableExitConfirmation: disableExitConfirmation, isExitConfirmationEnabled: isExitConfirmationEnabled, diff --git a/public_html/templates/comment-form.tpl b/public_html/templates/comment-form.tpl new file mode 100644 index 00000000..a06e69cf --- /dev/null +++ b/public_html/templates/comment-form.tpl @@ -0,0 +1,17 @@ +
    + +

    <%= title %>

    + +
    + +
    +
    + +
    +
    + +
    +   + +
    +
    diff --git a/public_html/templates/comment-list-item.tpl b/public_html/templates/comment-list-item.tpl new file mode 100644 index 00000000..35fe3bfe --- /dev/null +++ b/public_html/templates/comment-list-item.tpl @@ -0,0 +1,53 @@ +
    +
    + <% if (comment.user.name) { %> + + <% } %> + + <%= comment.user.name || 'Anonymous user' %> + + <% if (comment.user.name) { %> + + <% } %> +
    + +
    +
    + + <% if (comment.user.name) { %> + + <% } %> + + <%= comment.user.name || 'Anonymous user' %> + + <% if (comment.user.name) { %> + + <% } %> + + + + <%= formatRelativeTime(comment.creationTime) %> + + + + <% if (canEditComment) { %> + edit + <% } %> + + <% if (canDeleteComment) { %> + delete + <% } %> + +
    + +
    + <%= formatMarkdown(comment.text) %> +
    +
    +
    diff --git a/public_html/templates/global-comment-list-item.tpl b/public_html/templates/global-comment-list-item.tpl new file mode 100644 index 00000000..55f9baac --- /dev/null +++ b/public_html/templates/global-comment-list-item.tpl @@ -0,0 +1,8 @@ +
    +
    + <%= postTemplate({post: post}) %> +
    + +
    +
    +
    diff --git a/public_html/templates/global-comment-list.tpl b/public_html/templates/global-comment-list.tpl new file mode 100644 index 00000000..c9a4cabb --- /dev/null +++ b/public_html/templates/global-comment-list.tpl @@ -0,0 +1,6 @@ +
    +
    +
      +
    +
    +
    diff --git a/public_html/templates/post-comment-list.tpl b/public_html/templates/post-comment-list.tpl new file mode 100644 index 00000000..0130400e --- /dev/null +++ b/public_html/templates/post-comment-list.tpl @@ -0,0 +1,13 @@ +<% if (canListComments && comments.length) { %> +
    +

    Comments

    + +
    +<% } %> + +<% if (canAddComments) { %> +
    + <%= commentFormTemplate({title: 'Add comment'}) %> +
    +<% } %> diff --git a/public_html/templates/post-list-item.tpl b/public_html/templates/post-list-item.tpl index 1628fc03..0d94a4d8 100644 --- a/public_html/templates/post-list-item.tpl +++ b/public_html/templates/post-list-item.tpl @@ -1,4 +1,4 @@ -
  • +
    @@ -25,4 +25,4 @@
    <% } %> -
  • + diff --git a/public_html/templates/post.tpl b/public_html/templates/post.tpl index bc2c6d8c..015e480c 100644 --- a/public_html/templates/post.tpl +++ b/public_html/templates/post.tpl @@ -230,6 +230,9 @@ <%= postContentTemplate({post: post}) %> +
    +
    + <% if (privileges.canViewHistory) { %>
    <%= historyTemplate({ diff --git a/public_html/templates/user-list-item.tpl b/public_html/templates/user-list-item.tpl index 91900441..ca36dcfd 100644 --- a/public_html/templates/user-list-item.tpl +++ b/public_html/templates/user-list-item.tpl @@ -1,4 +1,4 @@ -
  • +
    <%= user.name %> @@ -15,4 +15,4 @@ Last seen: <%= formatRelativeTime(user.lastLoginTime) %>
  • - +