diff --git a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 index c429d6b4a2a..86fe0c0bd85 100644 --- a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 +++ b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 @@ -1,6 +1,8 @@ import { addDecorator } from 'discourse/widgets/post-cooked'; import ComposerEditor from 'discourse/components/composer-editor'; import { addPosterIcon } from 'discourse/widgets/poster-name'; +import { addButton } from 'discourse/widgets/post-menu'; +import { includeAttributes } from 'discourse/lib/transform-post'; let _decorateId = 0; function decorate(klass, evt, cb) { @@ -17,6 +19,12 @@ class PluginApi { constructor(version, container) { this.version = version; this.container = container; + + this._currentUser = container.lookup('current-user:main'); + } + + getCurrentUser() { + return this._currentUser; } /** @@ -64,6 +72,20 @@ class PluginApi { addPosterIcon(cb) { addPosterIcon(cb); } + + attachWidgetAction(widget, actionName, fn) { + const widgetClass = this.container.lookupFactory(`widget:${widget}`); + widgetClass.prototype[actionName] = fn; + } + + includePostAttributes(...attributes) { + includeAttributes(...attributes); + } + + addPostMenuButton(name, callback) { + addButton(name, callback); + } + } let _pluginv01; diff --git a/app/assets/javascripts/discourse/lib/transform-post.js.es6 b/app/assets/javascripts/discourse/lib/transform-post.js.es6 index 89e28db4da7..5eed4be23b8 100644 --- a/app/assets/javascripts/discourse/lib/transform-post.js.es6 +++ b/app/assets/javascripts/discourse/lib/transform-post.js.es6 @@ -10,6 +10,12 @@ function actionDescription(action, acted, count) { } } +const _additionalAttributes = []; + +export function includeAttributes(...attributes) { + attributes.forEach(a => _additionalAttributes.push(a)); +} + export function transformBasicPost(post) { // Note: it can be dangerous to not use `get` in Ember code, but this is significantly // faster and has tests to confirm it works. We only call `get` when the property is a CP @@ -189,5 +195,7 @@ export default function transformPost(currentUser, site, post, prevPost, nextPos postAtts.canDelete = !postAtts.isDeleted && postAtts.canDelete; } + _additionalAttributes.forEach(a => postAtts[a] = post[a]); + return postAtts; } diff --git a/app/assets/javascripts/discourse/widgets/post-menu.js.es6 b/app/assets/javascripts/discourse/widgets/post-menu.js.es6 index 571891f15cb..41d65a08f85 100644 --- a/app/assets/javascripts/discourse/widgets/post-menu.js.es6 +++ b/app/assets/javascripts/discourse/widgets/post-menu.js.es6 @@ -19,6 +19,11 @@ function animateHeart($elem, start, end, complete) { } const _builders = {}; +const _extraButtons = {}; + +export function addButton(name, builder) { + _extraButtons[name] = builder; +} function registerButton(name, builder) { _builders[name] = builder; @@ -246,6 +251,39 @@ export default createWidget('post-menu', { visibleButtons.splice(visibleButtons.length - 1, 0, showMore); } + Object.keys(_extraButtons).forEach(k => { + const builder = _extraButtons[k]; + if (builder) { + const buttonAtts = builder(attrs, this.state, this.siteSettings); + if (buttonAtts) { + const { position, beforeButton } = buttonAtts; + delete buttonAtts.position; + + let button = this.attach('button', buttonAtts); + + if (beforeButton) { + button = h('span', [beforeButton(h), button]); + } + + if (button) { + switch(position) { + case 'first': + visibleButtons.unshift(button); + break; + case 'second-last-hidden': + if (!state.collapsed) { + visibleButtons.splice(visibleButtons.length-2, 0, button); + } + break; + default: + visibleButtons.push(button); + break; + } + } + } + } + }); + const postControls = []; const repliesButton = this.attachButton('replies', attrs); diff --git a/app/assets/javascripts/discourse/widgets/post.js.es6 b/app/assets/javascripts/discourse/widgets/post.js.es6 index 4163553153d..17314acabec 100644 --- a/app/assets/javascripts/discourse/widgets/post.js.es6 +++ b/app/assets/javascripts/discourse/widgets/post.js.es6 @@ -379,7 +379,6 @@ export default createWidget('post', { const likeAction = post.get('likeAction'); if (likeAction && likeAction.get('canToggle')) { - const promise = likeAction.togglePromise(post); this.scheduleRerender(); return promise; diff --git a/app/assets/javascripts/discourse/widgets/widget.js.es6 b/app/assets/javascripts/discourse/widgets/widget.js.es6 index 26df22bce83..38c31cd2f40 100644 --- a/app/assets/javascripts/discourse/widgets/widget.js.es6 +++ b/app/assets/javascripts/discourse/widgets/widget.js.es6 @@ -75,6 +75,7 @@ export default class Widget { this.siteSettings = container.lookup('site-settings:main'); this.currentUser = container.lookup('current-user:main'); this.store = container.lookup('store:main'); + this.appEvents = container.lookup('app-events:main'); } defaultState() {