Add custom post icons to PluginAPI
This commit is contained in:
parent
9b8871d7dd
commit
f9722f8598
|
@ -161,7 +161,9 @@ function methodMissing() {
|
||||||
"and your plugin needs to be updated.");
|
"and your plugin needs to be updated.");
|
||||||
};
|
};
|
||||||
|
|
||||||
['reopen', 'registerButton'].forEach(function(m) { RemovedObject.prototype[m] = methodMissing; });
|
Discourse.RemovedObject = RemovedObject;
|
||||||
|
|
||||||
|
['reopen', 'registerButton', 'on', 'off'].forEach(function(m) { RemovedObject.prototype[m] = methodMissing; });
|
||||||
|
|
||||||
['discourse/views/post', 'discourse/components/post-menu'].forEach(function(moduleName) {
|
['discourse/views/post', 'discourse/components/post-menu'].forEach(function(moduleName) {
|
||||||
define(moduleName, [], function() { return new RemovedObject(moduleName); });
|
define(moduleName, [], function() { return new RemovedObject(moduleName); });
|
||||||
|
|
|
@ -1,77 +1,2 @@
|
||||||
import { setting } from 'discourse/lib/computed';
|
const removed = new Discourse.RemovedObject('discourse/components/poster-name');
|
||||||
|
export default removed;
|
||||||
const PosterNameComponent = Em.Component.extend({
|
|
||||||
classNames: ['names', 'trigger-user-card'],
|
|
||||||
displayNameOnPosts: setting('display_name_on_posts'),
|
|
||||||
|
|
||||||
// sanitize name for comparison
|
|
||||||
sanitizeName(name){
|
|
||||||
return name.toLowerCase().replace(/[\s_-]/g,'');
|
|
||||||
},
|
|
||||||
|
|
||||||
render(buffer) {
|
|
||||||
const post = this.get('post');
|
|
||||||
|
|
||||||
if (post) {
|
|
||||||
const username = post.get('username'),
|
|
||||||
primaryGroupName = post.get('primary_group_name'),
|
|
||||||
url = post.get('usernameUrl');
|
|
||||||
|
|
||||||
var linkClass = 'username',
|
|
||||||
name = post.get('name');
|
|
||||||
|
|
||||||
if (post.get('staff')) { linkClass += ' staff'; }
|
|
||||||
if (post.get('admin')) { linkClass += ' admin'; }
|
|
||||||
if (post.get('moderator')) { linkClass += ' moderator'; }
|
|
||||||
if (post.get('new_user')) { linkClass += ' new-user'; }
|
|
||||||
|
|
||||||
if (!Em.isEmpty(primaryGroupName)) {
|
|
||||||
linkClass += ' ' + primaryGroupName;
|
|
||||||
}
|
|
||||||
// Main link
|
|
||||||
buffer.push("<span class='" + linkClass + "'><a href='" + url + "' data-auto-route='true' data-user-card='" + username + "'>" + username + "</a>");
|
|
||||||
|
|
||||||
// Add a glyph if we have one
|
|
||||||
const glyph = this.posterGlyph(post);
|
|
||||||
if (!Em.isEmpty(glyph)) {
|
|
||||||
buffer.push(glyph);
|
|
||||||
}
|
|
||||||
buffer.push("</span>");
|
|
||||||
|
|
||||||
// Are we showing full names?
|
|
||||||
if (name && this.get('displayNameOnPosts') && (this.sanitizeName(name) !== this.sanitizeName(username))) {
|
|
||||||
name = Discourse.Utilities.escapeExpression(name);
|
|
||||||
buffer.push("<span class='full-name'><a href='" + url + "' data-auto-route='true' data-user-card='" + username + "'>" + name + "</a></span>");
|
|
||||||
}
|
|
||||||
|
|
||||||
// User titles
|
|
||||||
let title = post.get('user_title');
|
|
||||||
if (!Em.isEmpty(title)) {
|
|
||||||
|
|
||||||
title = Discourse.Utilities.escapeExpression(title);
|
|
||||||
buffer.push('<span class="user-title">');
|
|
||||||
if (Em.isEmpty(primaryGroupName)) {
|
|
||||||
buffer.push(title);
|
|
||||||
} else {
|
|
||||||
buffer.push("<a href='/groups/" + post.get('primary_group_name') + "' class='user-group'>" + title + "</a>");
|
|
||||||
}
|
|
||||||
buffer.push("</span>");
|
|
||||||
}
|
|
||||||
|
|
||||||
PosterNameComponent.trigger('renderedName', buffer, post);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Overwrite this to give a user a custom font awesome glyph.
|
|
||||||
posterGlyph(post) {
|
|
||||||
if(post.get('moderator')) {
|
|
||||||
const desc = I18n.t('user.moderator_tooltip');
|
|
||||||
return '<i class="fa fa-shield" title="' + desc + '" alt="' + desc + '"></i>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Support for event triggering
|
|
||||||
PosterNameComponent.reopenClass(Em.Evented);
|
|
||||||
|
|
||||||
export default PosterNameComponent;
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { addDecorator } from 'discourse/widgets/post-cooked';
|
import { addDecorator } from 'discourse/widgets/post-cooked';
|
||||||
import ComposerEditor from 'discourse/components/composer-editor';
|
import ComposerEditor from 'discourse/components/composer-editor';
|
||||||
|
import { addPosterIcon } from 'discourse/widgets/poster-name';
|
||||||
|
|
||||||
let _decorateId = 0;
|
let _decorateId = 0;
|
||||||
function decorate(klass, evt, cb) {
|
function decorate(klass, evt, cb) {
|
||||||
|
@ -18,21 +19,61 @@ class PluginApi {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* decorateCooked(callback)
|
||||||
|
*
|
||||||
|
* Used for decorating the `cooked` content of a post after it is rendered using
|
||||||
|
* jQuery.
|
||||||
|
*
|
||||||
|
* `callback` will be called when it is time to decorate with a jQuery selector.
|
||||||
|
*
|
||||||
|
* For example, to add a yellow background to all posts you could do this:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* api.decorateCooked($elem => $elem.css({ backgroundColor: 'yellow' }));
|
||||||
|
* ```
|
||||||
|
**/
|
||||||
decorateCooked(cb) {
|
decorateCooked(cb) {
|
||||||
addDecorator(cb);
|
addDecorator(cb);
|
||||||
decorate(ComposerEditor, 'previewRefreshed', cb);
|
decorate(ComposerEditor, 'previewRefreshed', cb);
|
||||||
decorate(this.container.lookupFactory('view:user-stream'), 'didInsertElement', cb);
|
decorate(this.container.lookupFactory('view:user-stream'), 'didInsertElement', cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addPosterIcon(callback)
|
||||||
|
*
|
||||||
|
* This function can be used to add an icon with a link that will be displayed
|
||||||
|
* beside a poster's name. The `callback` is called with the post's user custom
|
||||||
|
* fields, and will render an icon if it receives an object back.
|
||||||
|
*
|
||||||
|
* The returned object can have the following attributes:
|
||||||
|
*
|
||||||
|
* icon (required) the font awesome icon to render
|
||||||
|
* className (optional) a css class to apply to the icon
|
||||||
|
* url (optional) where to link the icon
|
||||||
|
* title (optional) the tooltip title for the icon on hover
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* api.addPosterIcon(cfs => {
|
||||||
|
* if (cfs.customer) {
|
||||||
|
* return { icon: 'user', className: 'customer', title: 'customer' };
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
**/
|
||||||
|
addPosterIcon(cb) {
|
||||||
|
addPosterIcon(cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _pluginv01;
|
let _pluginv01;
|
||||||
|
|
||||||
export function getPluginApi(version) {
|
export function getPluginApi(version) {
|
||||||
if (version === "0.1") {
|
if (version === "0.1") {
|
||||||
if (!_pluginv01) {
|
if (!_pluginv01) {
|
||||||
_pluginv01 = new PluginApi(version, Discourse.__container__);
|
_pluginv01 = new PluginApi(version, Discourse.__container__);
|
||||||
}
|
}
|
||||||
return _pluginv01;
|
return _pluginv01;
|
||||||
|
} else {
|
||||||
|
throw `Plugin API v${version} is not supported`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ export default function transformPost(currentUser, site, post, prevPost, nextPos
|
||||||
postAtts.linkCounts = post.link_counts;
|
postAtts.linkCounts = post.link_counts;
|
||||||
postAtts.actionCode = post.action_code;
|
postAtts.actionCode = post.action_code;
|
||||||
postAtts.actionCodeWho = post.action_code_who;
|
postAtts.actionCodeWho = post.action_code_who;
|
||||||
|
postAtts.userCustomFields = post.user_custom_fields;
|
||||||
|
|
||||||
const showPMMap = topic.archetype === 'private_message' && post.post_number === 1;
|
const showPMMap = topic.archetype === 'private_message' && post.post_number === 1;
|
||||||
if (showPMMap) {
|
if (showPMMap) {
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
{{#link-to 'user' user}}
|
{{#link-to 'user' user}}
|
||||||
{{avatar user imageSize="extra_large"}}
|
{{avatar user imageSize="extra_large"}}
|
||||||
<div class="details clearfix">
|
<div class="details clearfix">
|
||||||
{{poster-name post=user}}
|
<div class='username'>{{user.username}}</div>
|
||||||
</div>
|
</div>
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
<div class='earned'>
|
<div class='earned'>
|
||||||
|
|
|
@ -6,6 +6,11 @@ function sanitizeName(name){
|
||||||
return name.toLowerCase().replace(/[\s_-]/g,'');
|
return name.toLowerCase().replace(/[\s_-]/g,'');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _callbacks = [];
|
||||||
|
export function addPosterIcon(cb) {
|
||||||
|
_callbacks.push(cb);
|
||||||
|
}
|
||||||
|
|
||||||
export default createWidget('poster-name', {
|
export default createWidget('poster-name', {
|
||||||
tagName: 'div.names.trigger-user-card',
|
tagName: 'div.names.trigger-user-card',
|
||||||
|
|
||||||
|
@ -56,6 +61,25 @@ export default createWidget('poster-name', {
|
||||||
contents.push(h('span.user-title', titleContents));
|
contents.push(h('span.user-title', titleContents));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cfs = attrs.userCustomFields;
|
||||||
|
if (cfs) {
|
||||||
|
_callbacks.forEach(cb => {
|
||||||
|
const result = cb(cfs);
|
||||||
|
if (result) {
|
||||||
|
|
||||||
|
let iconBody = iconNode(result.icon);
|
||||||
|
if (result.url) {
|
||||||
|
iconBody = h('a', { attributes: { href: result.url } }, iconBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
contents.push(h('span',
|
||||||
|
{ className: result.className,
|
||||||
|
attributes: { title: result.title }
|
||||||
|
},
|
||||||
|
iconBody));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue