Upgrade to new Plugin API + backwards compatibility
This commit is contained in:
parent
7f1dd78822
commit
8085462c00
|
@ -0,0 +1,103 @@
|
||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"jasmine": true,
|
||||||
|
"node": true,
|
||||||
|
"mocha": true,
|
||||||
|
"browser": true,
|
||||||
|
"builtin": true
|
||||||
|
},
|
||||||
|
ecmaVersion: 7,
|
||||||
|
"globals":
|
||||||
|
{"Ember":true,
|
||||||
|
"jQuery":true,
|
||||||
|
"$":true,
|
||||||
|
"RSVP":true,
|
||||||
|
"Discourse":true,
|
||||||
|
"Em":true,
|
||||||
|
"PreloadStore":true,
|
||||||
|
"Handlebars":true,
|
||||||
|
"I18n":true,
|
||||||
|
"bootbox":true,
|
||||||
|
"module":true,
|
||||||
|
"moduleFor":true,
|
||||||
|
"moduleForComponent":true,
|
||||||
|
"Pretender":true,
|
||||||
|
"sandbox":true,
|
||||||
|
"controllerFor":true,
|
||||||
|
"test":true,
|
||||||
|
"ok":true,
|
||||||
|
"not":true,
|
||||||
|
"expect":true,
|
||||||
|
"equal":true,
|
||||||
|
"visit":true,
|
||||||
|
"andThen":true,
|
||||||
|
"click":true,
|
||||||
|
"currentPath":true,
|
||||||
|
"currentRouteName":true,
|
||||||
|
"currentURL":true,
|
||||||
|
"fillIn":true,
|
||||||
|
"keyEvent":true,
|
||||||
|
"triggerEvent":true,
|
||||||
|
"count":true,
|
||||||
|
"exists":true,
|
||||||
|
"visible":true,
|
||||||
|
"invisible":true,
|
||||||
|
"asyncRender":true,
|
||||||
|
"selectDropdown":true,
|
||||||
|
"asyncTestDiscourse":true,
|
||||||
|
"fixture":true,
|
||||||
|
"find":true,
|
||||||
|
"sinon":true,
|
||||||
|
"moment":true,
|
||||||
|
"start":true,
|
||||||
|
"_":true,
|
||||||
|
"alert":true,
|
||||||
|
"containsInstance":true,
|
||||||
|
"deepEqual":true,
|
||||||
|
"notEqual":true,
|
||||||
|
"define":true,
|
||||||
|
"require":true,
|
||||||
|
"requirejs":true,
|
||||||
|
"hasModule":true,
|
||||||
|
"Blob":true,
|
||||||
|
"File":true},
|
||||||
|
"rules": {
|
||||||
|
"block-scoped-var": 2,
|
||||||
|
"dot-notation": 0,
|
||||||
|
"eqeqeq": [
|
||||||
|
2,
|
||||||
|
"allow-null"
|
||||||
|
],
|
||||||
|
"guard-for-in": 2,
|
||||||
|
"no-bitwise": 2,
|
||||||
|
"no-caller": 2,
|
||||||
|
"no-cond-assign": 0,
|
||||||
|
"no-debugger": 2,
|
||||||
|
"no-empty": 0,
|
||||||
|
"no-eval": 2,
|
||||||
|
"no-extend-native": 2,
|
||||||
|
"no-extra-parens": 0,
|
||||||
|
"no-irregular-whitespace": 2,
|
||||||
|
"no-iterator": 2,
|
||||||
|
"no-loop-func": 2,
|
||||||
|
"no-multi-str": 2,
|
||||||
|
"no-new": 2,
|
||||||
|
"no-plusplus": 0,
|
||||||
|
"no-proto": 2,
|
||||||
|
"no-script-url": 2,
|
||||||
|
"no-sequences": 2,
|
||||||
|
"no-shadow": 2,
|
||||||
|
"no-undef": 2,
|
||||||
|
"no-unused-vars": 2,
|
||||||
|
"no-with": 2,
|
||||||
|
"no-this-before-super": 2,
|
||||||
|
"semi": 2,
|
||||||
|
"strict": 0,
|
||||||
|
"valid-typeof": 2,
|
||||||
|
"wrap-iife": [
|
||||||
|
2,
|
||||||
|
"inside"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"parser": "babel-eslint"
|
||||||
|
}
|
|
@ -4,18 +4,165 @@ import { Button } from 'discourse/components/post-menu';
|
||||||
import Topic from 'discourse/models/topic';
|
import Topic from 'discourse/models/topic';
|
||||||
import User from 'discourse/models/user';
|
import User from 'discourse/models/user';
|
||||||
import TopicStatus from 'discourse/views/topic-status';
|
import TopicStatus from 'discourse/views/topic-status';
|
||||||
import computed from 'ember-addons/ember-computed-decorators';
|
|
||||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||||
|
import { withPluginApi } from 'discourse/lib/plugin-api';
|
||||||
|
|
||||||
|
function clearAccepted(topic) {
|
||||||
|
const posts = topic.get('postStream.posts');
|
||||||
|
posts.forEach(post => {
|
||||||
|
if (post.get('post_number') > 1 ) {
|
||||||
|
post.set('accepted_answer',false);
|
||||||
|
post.set('can_accept_answer',true);
|
||||||
|
post.set('can_unaccept_answer',false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function unacceptPost(post) {
|
||||||
|
if (!post.get('can_unaccept_answer')) { return; }
|
||||||
|
const topic = post.topic;
|
||||||
|
|
||||||
|
post.setProperties({
|
||||||
|
can_accept_answer: true,
|
||||||
|
can_unaccept_answer: false,
|
||||||
|
accepted_answer: false
|
||||||
|
});
|
||||||
|
topic.set('accepted_answer', undefined);
|
||||||
|
|
||||||
|
Discourse.ajax("/solution/unaccept", {
|
||||||
|
type: 'POST',
|
||||||
|
data: { id: post.get('id') }
|
||||||
|
}).catch(popupAjaxError);
|
||||||
|
}
|
||||||
|
|
||||||
|
function acceptPost(post) {
|
||||||
|
const topic = post.topic;
|
||||||
|
|
||||||
|
clearAccepted(topic);
|
||||||
|
|
||||||
|
post.setProperties({
|
||||||
|
can_unaccept_answer: true,
|
||||||
|
can_accept_answer: false,
|
||||||
|
accepted_answer: true
|
||||||
|
});
|
||||||
|
|
||||||
|
topic.setProperties({
|
||||||
|
username: post.get('username'),
|
||||||
|
post_number: post.get('post_number')
|
||||||
|
});
|
||||||
|
|
||||||
|
Discourse.ajax("/solution/accept", {
|
||||||
|
type: 'POST',
|
||||||
|
data: { id: post.get('.id') }
|
||||||
|
}).catch(popupAjaxError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code for older discourse installs for backwards compatibility
|
||||||
|
function oldPluginCode() {
|
||||||
|
PostView.reopen({
|
||||||
|
classNameBindings: ['post.accepted_answer:accepted-answer']
|
||||||
|
});
|
||||||
|
|
||||||
|
PostMenuComponent.registerButton(function(visibleButtons){
|
||||||
|
var position = 0;
|
||||||
|
|
||||||
|
var canAccept = this.get('post.can_accept_answer');
|
||||||
|
var canUnaccept = this.get('post.can_unaccept_answer');
|
||||||
|
var accepted = this.get('post.accepted_answer');
|
||||||
|
var isOp = Discourse.User.currentProp("id") === this.get('post.topic.user_id');
|
||||||
|
|
||||||
|
if (!accepted && canAccept && !isOp) {
|
||||||
|
// first hidden position
|
||||||
|
if (this.get('collapsed')) { return; }
|
||||||
|
position = visibleButtons.length - 2;
|
||||||
|
}
|
||||||
|
if (canAccept) {
|
||||||
|
visibleButtons.splice(position,0,new Button('acceptAnswer', 'solved.accept_answer', 'check-square-o', {className: 'unaccepted'}));
|
||||||
|
}
|
||||||
|
if (canUnaccept || accepted) {
|
||||||
|
var locale = canUnaccept ? 'solved.unaccept_answer' : 'solved.accepted_answer';
|
||||||
|
visibleButtons.splice(position,0,new Button(
|
||||||
|
'unacceptAnswer',
|
||||||
|
locale,
|
||||||
|
'check-square',
|
||||||
|
{className: 'accepted fade-out', prefixHTML: '<span class="accepted-text">' + I18n.t('solved.solution') + '</span>'})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
PostMenuComponent.reopen({
|
||||||
|
acceptedChanged: function() {
|
||||||
|
this.rerender();
|
||||||
|
}.observes('post.accepted_answer'),
|
||||||
|
|
||||||
|
clickUnacceptAnswer() {
|
||||||
|
unacceptPost(this.get('post'));
|
||||||
|
},
|
||||||
|
|
||||||
|
clickAcceptAnswer() {
|
||||||
|
acceptPost(this.get('post'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function initializeWithApi(api) {
|
||||||
|
const currentUser = api.getCurrentUser();
|
||||||
|
|
||||||
|
api.includePostAttributes('can_accept_answer', 'can_unaccept_answer', 'accepted_answer');
|
||||||
|
|
||||||
|
api.addPostMenuButton('solved', attrs => {
|
||||||
|
const canAccept = attrs.can_accept_answer;
|
||||||
|
const canUnaccept = attrs.can_unaccept_answer;
|
||||||
|
const accepted = attrs.accepted_answer;
|
||||||
|
const isOp = currentUser && currentUser.id === attrs.user_id;
|
||||||
|
const position = (!accepted && canAccept && !isOp) ? 'second-last-hidden' : 'first';
|
||||||
|
|
||||||
|
if (canAccept) {
|
||||||
|
return {
|
||||||
|
action: 'acceptAnswer',
|
||||||
|
icon: 'check-square-o',
|
||||||
|
className: 'unaccepted',
|
||||||
|
title: 'solved.accept_answer',
|
||||||
|
position
|
||||||
|
};
|
||||||
|
} else if (canUnaccept || accepted) {
|
||||||
|
const title = canUnaccept ? 'solved.unaccept_answer' : 'solved.accepted_answer';
|
||||||
|
return {
|
||||||
|
action: 'unacceptAnswer',
|
||||||
|
icon: 'check-square',
|
||||||
|
title,
|
||||||
|
className: 'accepted fade-out',
|
||||||
|
position,
|
||||||
|
beforeButton(h) {
|
||||||
|
return h('span.accepted-text', I18n.t('solved.solution'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
api.attachWidgetAction('post', 'acceptAnswer', function() {
|
||||||
|
const post = this.model;
|
||||||
|
const current = post.get('topic.postStream.posts').filterProperty('accepted_answer');
|
||||||
|
acceptPost(post);
|
||||||
|
|
||||||
|
current.forEach(p => this.appEvents.trigger('post-stream:refresh', { id: p.id }));
|
||||||
|
});
|
||||||
|
|
||||||
|
api.attachWidgetAction('post', 'unacceptAnswer', function() {
|
||||||
|
unacceptPost(this.model);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'extend-for-solved-button',
|
name: 'extend-for-solved-button',
|
||||||
initialize: function() {
|
initialize() {
|
||||||
|
|
||||||
Topic.reopen({
|
Topic.reopen({
|
||||||
// keeping this here cause there is complex localization
|
// keeping this here cause there is complex localization
|
||||||
acceptedAnswerHtml: function(){
|
acceptedAnswerHtml: function() {
|
||||||
const username = this.get('accepted_answer.username');
|
const username = this.get('accepted_answer.username');
|
||||||
var postNumber = this.get('accepted_answer.post_number');
|
const postNumber = this.get('accepted_answer.post_number');
|
||||||
|
|
||||||
if (!username || !postNumber) {
|
if (!username || !postNumber) {
|
||||||
return "";
|
return "";
|
||||||
|
@ -33,7 +180,7 @@ export default {
|
||||||
|
|
||||||
TopicStatus.reopen({
|
TopicStatus.reopen({
|
||||||
statuses: function(){
|
statuses: function(){
|
||||||
var results = this._super();
|
const results = this._super();
|
||||||
if (this.topic.has_accepted_answer) {
|
if (this.topic.has_accepted_answer) {
|
||||||
results.push({
|
results.push({
|
||||||
openTag: 'span',
|
openTag: 'span',
|
||||||
|
@ -46,90 +193,6 @@ export default {
|
||||||
}.property()
|
}.property()
|
||||||
});
|
});
|
||||||
|
|
||||||
PostView.reopen({
|
withPluginApi('0.1', initializeWithApi, { noApi: oldPluginCode });
|
||||||
classNameBindings: ['post.accepted_answer:accepted-answer']
|
|
||||||
});
|
|
||||||
|
|
||||||
PostMenuComponent.registerButton(function(visibleButtons){
|
|
||||||
var position = 0;
|
|
||||||
|
|
||||||
var canAccept = this.get('post.can_accept_answer');
|
|
||||||
var canUnaccept = this.get('post.can_unaccept_answer');
|
|
||||||
var accepted = this.get('post.accepted_answer');
|
|
||||||
var isOp = User.currentProp("id") === this.get('post.topic.user_id');
|
|
||||||
|
|
||||||
if (!accepted && canAccept && !isOp) {
|
|
||||||
// first hidden position
|
|
||||||
if (this.get('collapsed')) { return; }
|
|
||||||
position = visibleButtons.length - 2;
|
|
||||||
}
|
|
||||||
if (canAccept) {
|
|
||||||
visibleButtons.splice(position,0,new Button('acceptAnswer', 'solved.accept_answer', 'check-square-o', {className: 'unaccepted'}));
|
|
||||||
}
|
|
||||||
if (canUnaccept || accepted) {
|
|
||||||
var locale = canUnaccept ? 'solved.unaccept_answer' : 'solved.accepted_answer';
|
|
||||||
visibleButtons.splice(position,0,new Button(
|
|
||||||
'unacceptAnswer',
|
|
||||||
locale,
|
|
||||||
'check-square',
|
|
||||||
{className: 'accepted fade-out', prefixHTML: '<span class="accepted-text">' + I18n.t('solved.solution') + '</span>'})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
PostMenuComponent.reopen({
|
|
||||||
acceptedChanged: function(){
|
|
||||||
this.rerender();
|
|
||||||
}.observes('post.accepted_answer'),
|
|
||||||
|
|
||||||
clickUnacceptAnswer: function(){
|
|
||||||
if (!this.get('post.can_unaccept_answer')) { return; }
|
|
||||||
|
|
||||||
this.set('post.can_accept_answer', true);
|
|
||||||
this.set('post.can_unaccept_answer', false);
|
|
||||||
this.set('post.accepted_answer', false);
|
|
||||||
this.set('post.topic.accepted_answer', undefined);
|
|
||||||
|
|
||||||
Discourse.ajax("/solution/unaccept", {
|
|
||||||
type: 'POST',
|
|
||||||
data: {
|
|
||||||
id: this.get('post.id')
|
|
||||||
}
|
|
||||||
}).catch(popupAjaxError);
|
|
||||||
},
|
|
||||||
|
|
||||||
clearAcceptedAnswer: function(){
|
|
||||||
const posts = this.get('post.topic.postStream.posts');
|
|
||||||
posts.forEach(function(post){
|
|
||||||
if (post.get('post_number') > 1 ) {
|
|
||||||
post.set('accepted_answer',false);
|
|
||||||
post.set('can_accept_answer',true);
|
|
||||||
post.set('can_unaccept_answer',false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
clickAcceptAnswer: function(){
|
|
||||||
|
|
||||||
this.clearAcceptedAnswer();
|
|
||||||
|
|
||||||
this.set('post.can_unaccept_answer', true);
|
|
||||||
this.set('post.can_accept_answer', false);
|
|
||||||
this.set('post.accepted_answer', true);
|
|
||||||
|
|
||||||
this.set('post.topic.accepted_answer', {
|
|
||||||
username: this.get('post.username'),
|
|
||||||
post_number: this.get('post.post_number')
|
|
||||||
});
|
|
||||||
|
|
||||||
Discourse.ajax("/solution/accept", {
|
|
||||||
type: 'POST',
|
|
||||||
data: {
|
|
||||||
id: this.get('post.id')
|
|
||||||
}
|
|
||||||
}).catch(popupAjaxError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -207,20 +207,21 @@ after_initialize do
|
||||||
topic = (topic_view && topic_view.topic) || object.topic
|
topic = (topic_view && topic_view.topic) || object.topic
|
||||||
|
|
||||||
if topic
|
if topic
|
||||||
scope.can_accept_answer?(topic) &&
|
return scope.can_accept_answer?(topic) && object.post_number > 1 && !accepted_answer
|
||||||
object.post_number > 1 && !accepted_answer
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_unaccept_answer
|
def can_unaccept_answer
|
||||||
topic = (topic_view && topic_view.topic) || object.topic
|
topic = (topic_view && topic_view.topic) || object.topic
|
||||||
if topic
|
if topic
|
||||||
scope.can_accept_answer?(topic) && post_custom_fields["is_accepted_answer"]
|
return scope.can_accept_answer?(topic) && (post_custom_fields["is_accepted_answer"] == 'true')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def accepted_answer
|
def accepted_answer
|
||||||
post_custom_fields["is_accepted_answer"]
|
post_custom_fields["is_accepted_answer"] == 'true'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue