From f2f49a5e96ec634f67e1b4ec9c57ab52abb8d86d Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Fri, 19 Feb 2016 14:22:36 -0500 Subject: [PATCH] Ability to add text to a poster name icon --- .../discourse/lib/plugin-api.js.es6 | 32 +++++++++++++- .../discourse/widgets/poster-name.js.es6 | 43 ++++--------------- .../discourse/widgets/widget.js.es6 | 22 +++++++++- app/models/concerns/has_custom_fields.rb | 1 - 4 files changed, 60 insertions(+), 38 deletions(-) diff --git a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 index 086a23fd4..506cc0ffd 100644 --- a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 +++ b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 @@ -1,10 +1,11 @@ +import { iconNode } from 'discourse/helpers/fa-icon'; 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'; import { addToolbarCallback } from 'discourse/components/d-editor'; import { addWidgetCleanCallback } from 'discourse/components/mount-widget'; +import { decorateWidget } from 'discourse/widgets/widget'; let _decorateId = 0; function decorate(klass, evt, cb) { @@ -82,7 +83,34 @@ class PluginApi { * ``` **/ addPosterIcon(cb) { - addPosterIcon(cb); + decorateWidget('poster-name:after', (h, attrs) => { + const result = cb(attrs.userCustomFields, attrs); + if (result) { + let iconBody; + + if (result.icon) { + iconBody = iconNode(result.icon); + } else if (result.emoji) { + iconBody = result.emoji.split('|').map(emoji => { + const src = Discourse.Emoji.urlFor(emoji); + return h('img', { className: 'emoji', attributes: { src } }); + }); + } + + if (result.text) { + iconBody = [iconBody, result.text]; + } + + if (result.url) { + iconBody = h('a', { attributes: { href: result.url } }, iconBody); + } + + + return h('span', + { className: result.className, attributes: { title: result.title } }, + iconBody); + } + }); } attachWidgetAction(widget, actionName, fn) { diff --git a/app/assets/javascripts/discourse/widgets/poster-name.js.es6 b/app/assets/javascripts/discourse/widgets/poster-name.js.es6 index 393cd418a..c9b2a45ab 100644 --- a/app/assets/javascripts/discourse/widgets/poster-name.js.es6 +++ b/app/assets/javascripts/discourse/widgets/poster-name.js.es6 @@ -6,11 +6,6 @@ function sanitizeName(name){ return name.toLowerCase().replace(/[\s_-]/g,''); } -const _callbacks = []; -export function addPosterIcon(cb) { - _callbacks.push(cb); -} - export default createWidget('poster-name', { tagName: 'div.names.trigger-user-card', @@ -61,35 +56,15 @@ export default createWidget('poster-name', { contents.push(h('span.user-title', titleContents)); } - const cfs = attrs.userCustomFields; - if (cfs) { - _callbacks.forEach(cb => { - const result = cb(cfs, attrs); - if (result) { - - let iconBody; - - if (result.icon) { - iconBody = iconNode(result.icon); - } else if (result.emoji) { - iconBody = result.emoji.split('|').map(emoji => { - const src = Discourse.Emoji.urlFor(emoji); - return h('img', { className: 'emoji', attributes: { src } }); - }); - } - - if (result.url) { - iconBody = h('a', { attributes: { href: result.url } }, iconBody); - } - - contents.push(h('span', - { className: result.className, - attributes: { title: result.title } - }, - iconBody)); - } - }); - } + // const cfs = attrs.userCustomFields; + // if (cfs) { + // _callbacks.forEach(cb => { + // const result = cb(cfs, attrs); + // if (result) { + // + // } + // }); + // } return contents; } }); diff --git a/app/assets/javascripts/discourse/widgets/widget.js.es6 b/app/assets/javascripts/discourse/widgets/widget.js.es6 index 38c31cd2f..56c025fde 100644 --- a/app/assets/javascripts/discourse/widgets/widget.js.es6 +++ b/app/assets/javascripts/discourse/widgets/widget.js.es6 @@ -14,6 +14,18 @@ export function renderedKey(key) { delete _dirty[key]; } +const _decorators = {}; + +export function decorateWidget(widgetName, cb) { + _decorators[widgetName] = _decorators[widgetName] || []; + _decorators[widgetName].push(cb); +} + +function applyDecorators(name, type, attrs, state) { + const decorators = _decorators[`${name}:${type}`] || []; + return decorators.map(d => d(h, attrs, state)); +} + function drawWidget(builder, attrs, state) { const properties = {}; @@ -44,7 +56,14 @@ function drawWidget(builder, attrs, state) { attributes.title = I18n.t(this.title); } - return h(this.tagName || 'div', properties, this.html(attrs, state)); + let contents = this.html(attrs, state); + if (this.name) { + const beforeContents = applyDecorators(this.name, 'before', attrs, state) || []; + const afterContents = applyDecorators(this.name, 'after', attrs, state) || []; + contents = beforeContents.concat(contents).concat(afterContents); + } + + return h(this.tagName || 'div', properties, contents); } export function createWidget(name, opts) { @@ -54,6 +73,7 @@ export function createWidget(name, opts) { _registry[name] = result; } + opts.name = name; opts.html = opts.html || emptyContent; opts.draw = drawWidget; diff --git a/app/models/concerns/has_custom_fields.rb b/app/models/concerns/has_custom_fields.rb index 1e1f3869a..f1c3ec286 100644 --- a/app/models/concerns/has_custom_fields.rb +++ b/app/models/concerns/has_custom_fields.rb @@ -107,7 +107,6 @@ module HasCustomFields end end - end def reload(options = nil)