/** This view renders a menu below a post. It uses buffered rendering for performance. @class PostMenuView @extends Discourse.View @namespace Discourse @module Discourse **/ // Helper class for rendering a button var Button = function(action, label, icon, opts) { this.action = action; this.label = label; if (typeof icon === "object") { this.opts = icon; } else { this.icon = icon; } this.opts = this.opts || opts || {}; }; Button.prototype.render = function(buffer) { buffer.push(""); }; var hiddenButtons; export default Discourse.View.extend({ tagName: 'section', classNames: ['post-menu-area', 'clearfix'], shouldRerender: Discourse.View.renderIfChanged( 'post.deleted_at', 'post.flagsAvailable.@each', 'post.reply_count', 'post.showRepliesBelow', 'post.can_delete', 'post.bookmarked', 'post.shareUrl', 'post.topic.deleted_at', 'post.replies.length', 'post.wiki', 'collapsed'), _collapsedByDefault: function() { this.set('collapsed', true); }.on('init'), render: function(buffer) { var post = this.get('post'); buffer.push(""); }, // Delegate click actions click: function(e) { var $target = $(e.target), action = $target.data('action') || $target.parent().data('action'); if (!action) return; var handler = this["click" + action.capitalize()]; if (!handler) return; handler.call(this, this.get('post')); }, // Replies Button renderReplies: function(post, buffer) { if (!post.get('showRepliesBelow')) return; var reply_count = post.get('reply_count'); buffer.push(""); }, renderButtons: function(post, buffer) { var self = this, allButtons = [], visibleButtons = []; if (typeof hiddenButtons === "undefined") { if (!Em.isEmpty(Discourse.SiteSettings.post_menu_hidden_items)) { hiddenButtons = Discourse.SiteSettings.post_menu_hidden_items.split('|'); } else { hiddenButtons = []; } } var yours = post.get('yours'); Discourse.SiteSettings.post_menu.split("|").forEach(function(i) { var creator = self["buttonFor" + i.replace(/\+/, '').capitalize()]; if (creator) { var button = creator.call(self, post); if (button) { allButtons.push(button); if ((yours && button.opts.alwaysShowYours) || (post.get('wiki') && button.opts.alwaysShowWiki) || (hiddenButtons.indexOf(i) === -1)) { visibleButtons.push(button); } } } }); // Only show ellipsis if there is more than one button hidden if (!this.get('collapsed') || (allButtons.length <= visibleButtons.length + 1)) { visibleButtons = allButtons; } else { visibleButtons.splice(visibleButtons.length - 1, 0, this.buttonForShowMoreActions(post)); } buffer.push('
'); visibleButtons.forEach(function (b) { b.render(buffer); }); buffer.push("
"); }, clickReplies: function() { if (this.get('post.replies.length') > 0) { this.set('post.replies', []); } else { this.get('post').loadReplies(); } }, // Delete button buttonForDelete: function(post) { var label, icon; if (post.get('post_number') === 1) { // If it's the first post, the delete/undo actions are related to the topic var topic = post.get('topic'); if (topic.get('deleted_at')) { if (!topic.get('details.can_recover')) { return; } label = "topic.actions.recover"; icon = "undo"; } else { if (!topic.get('details.can_delete')) { return; } label = "topic.actions.delete"; icon = "trash-o"; } } else { // The delete actions target the post iteself if (post.get('deleted_at') || post.get('user_deleted')) { if (!post.get('can_recover')) { return; } label = "post.controls.undelete"; icon = "undo"; } else { if (!post.get('can_delete')) { return; } label = "post.controls.delete"; icon = "trash-o"; } } var action = (icon === 'trash-o') ? 'delete' : 'recover'; var opts; if (icon === "trash-o"){ opts = {className: 'delete'}; } return new Button(action, label, icon, opts); }, clickRecover: function(post) { this.get('controller').send('recoverPost', post); }, clickDelete: function(post) { this.get('controller').send('deletePost', post); }, // Like button buttonForLike: function(post) { if (!post.get('actionByName.like.can_act')) return; return new Button('like', 'post.controls.like', 'heart', {className: 'like'}); }, clickLike: function(post) { this.get('controller').send('likePost', post); }, // Flag button buttonForFlag: function(post) { if (Em.isEmpty(post.get('flagsAvailable'))) return; return new Button('flag', 'post.controls.flag', 'flag'); }, clickFlag: function(post) { this.get('controller').send('showFlags', post); }, // Edit button buttonForEdit: function(post) { if (!post.get('can_edit')) return; return new Button('edit', 'post.controls.edit', 'pencil', { alwaysShowYours: true, alwaysShowWiki: true }); }, clickEdit: function(post) { this.get('controller').send('editPost', post); }, // Share button buttonForShare: function(post) { return new Button('share', 'post.controls.share', 'link', {shareUrl: post.get('shareUrl')}); }, // Reply button buttonForReply: function() { if (!this.get('controller.model.details.can_create_post')) return; var options = {className: 'create'}; if(!Discourse.Mobile.mobileView) { options.textLabel = 'topic.reply.title'; } return new Button('reply', 'post.controls.reply', 'reply', options); }, clickReply: function(post) { this.get('controller').send('replyToPost', post); }, // Bookmark button buttonForBookmark: function(post) { if (!Discourse.User.current()) return; var iconClass = 'read-icon', buttonClass = 'bookmark', tooltip = 'bookmarks.not_bookmarked'; if (post.get('bookmarked')) { iconClass += ' bookmarked'; buttonClass += ' bookmarked'; tooltip = 'bookmarks.created'; } return new Button('bookmark', tooltip, {className: buttonClass, innerHTML: "
"}); }, clickBookmark: function(post) { this.get('controller').send('toggleBookmark', post); }, buttonForAdmin: function() { if (!Discourse.User.currentProp('canManageTopic')) { return; } return new Button('admin', 'post.controls.admin', 'wrench'); }, renderAdminPopup: function(post, buffer) { if (!Discourse.User.currentProp('canManageTopic')) { return; } var wikiText = post.get('wiki') ? I18n.t('post.controls.unwiki') : I18n.t('post.controls.wiki'); buffer.push('

' + I18n.t('admin_title') + '

'); }, clickAdmin: function() { var $adminMenu = this.$('.post-admin-menu'); this.set('adminMenu', $adminMenu); $adminMenu.show(); }, clickToggleWiki: function() { this.get('controller').send('toggleWiki', this.get('post')); }, buttonForShowMoreActions: function() { return new Button('showMoreActions', 'show_more', 'ellipsis-h'); }, clickShowMoreActions: function() { this.set('collapsed', false); } });