work in progress
This commit is contained in:
commit
43f40c9825
|
@ -0,0 +1,5 @@
|
|||
{{#if topic.accepted_answer}}
|
||||
<p class="solved">
|
||||
<i class='fa-check-square fa accepted'></i> Solved by <a data-user-card="{{topic.accepted_answer.username}}">{{topic.accepted_answer.username}}</a> in <a href="{{acceptedAnswerPath}}">post #{{topic.accepted_answer.post_number}}</a>
|
||||
</p>
|
||||
{{/if}}
|
|
@ -0,0 +1,101 @@
|
|||
import PostMenuView from 'discourse/views/post-menu';
|
||||
import PostView from 'discourse/views/post';
|
||||
import { Button } from 'discourse/views/post-menu';
|
||||
import Topic from 'discourse/models/topic';
|
||||
|
||||
export default {
|
||||
name: 'extend-for-solved-button',
|
||||
initialize: function() {
|
||||
|
||||
Topic.reopen({
|
||||
// keeping this here cause there is complex localization
|
||||
acceptedAnswerHtml: function(){
|
||||
return I18n.t("")
|
||||
}.property('accepted_answer')
|
||||
});
|
||||
|
||||
PostView.reopen({
|
||||
classNameBindings: ['post.accepted_answer:accepted-answer']
|
||||
});
|
||||
|
||||
PostMenuView.registerButton(function(visibleButtons){
|
||||
if (this.get('post.can_accept_answer')) {
|
||||
visibleButtons.splice(0,0,new Button('acceptAnswer', 'accepted_answer.accept_answer', 'check-square-o', {className: 'unaccepted'}));
|
||||
}
|
||||
if (this.get('post.can_unaccept_answer')) {
|
||||
visibleButtons.splice(0,0,new Button('unacceptAnswer', 'accepted_answer.unaccept_answer', 'check-square', {className: 'accepted'}));
|
||||
}
|
||||
});
|
||||
|
||||
PostMenuView.reopen({
|
||||
acceptedChanged: function(){
|
||||
this.rerender();
|
||||
}.observes('post.accepted_answer'),
|
||||
|
||||
clickUnacceptAnswer: function(){
|
||||
this.set('post.can_accept_answer', true);
|
||||
this.set('post.can_unaccept_answer', false);
|
||||
this.set('post.topic.has_accepted_answer', false);
|
||||
|
||||
Discourse.ajax("/solution/unaccept", {
|
||||
type: 'POST',
|
||||
data: {
|
||||
id: this.get('post.id')
|
||||
}
|
||||
}).then(function(){
|
||||
//
|
||||
}).catch(function(error){
|
||||
var message = I18n.t("generic_error");
|
||||
try {
|
||||
message = $.parseJSON(error.responseText).errors;
|
||||
} catch (e) {
|
||||
// nothing we can do
|
||||
}
|
||||
bootbox.alert(message);
|
||||
});
|
||||
},
|
||||
|
||||
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')
|
||||
}
|
||||
}).then(function(){
|
||||
//
|
||||
}).catch(function(error){
|
||||
var message = I18n.t("generic_error");
|
||||
try {
|
||||
message = $.parseJSON(error.responseText).errors;
|
||||
} catch (e) {
|
||||
// nothing we can do
|
||||
}
|
||||
bootbox.alert(message);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
|
@ -0,0 +1,15 @@
|
|||
.post-controls .accepted, .fa.accepted {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.topic-post.accepted-answer .topic-body {
|
||||
background-color: #E9FFE0;
|
||||
}
|
||||
|
||||
.cooked .solved {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0px;
|
||||
padding: 4px 10px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: #E9FFE0;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
en:
|
||||
site_settings:
|
||||
categories_with_solved_button: "List of categories where solved button is allowed"
|
|
@ -0,0 +1,4 @@
|
|||
uncategorized:
|
||||
categories_with_solved_button:
|
||||
default: ''
|
||||
client: true
|
|
@ -0,0 +1,118 @@
|
|||
# name: discourse-solved-button
|
||||
# about: Add a solved button to answers on Discourse
|
||||
# version: 0.1
|
||||
# authors: Sam Saffron
|
||||
|
||||
PLUGIN_NAME = "discourse_solved_button".freeze
|
||||
|
||||
register_asset 'stylesheets/solutions.scss'
|
||||
|
||||
after_initialize do
|
||||
|
||||
module ::DiscourseSolvedButton
|
||||
class Engine < ::Rails::Engine
|
||||
engine_name PLUGIN_NAME
|
||||
isolate_namespace DiscourseSolvedButton
|
||||
end
|
||||
end
|
||||
|
||||
require_dependency "application_controller"
|
||||
class DiscourseSolvedButton::AnswerController < ::ApplicationController
|
||||
def accept
|
||||
|
||||
post = Post.find(params[:id].to_i)
|
||||
|
||||
accepted_id = post.topic.custom_fields["has_accepted_answer"].to_i
|
||||
if accepted_id
|
||||
if p2 = Post.find_by(id: accepted_id)
|
||||
p2.custom_fields["is_accepted_answer"] = nil
|
||||
p2.save!
|
||||
end
|
||||
end
|
||||
|
||||
post.custom_fields["is_accepted_answer"] = "true"
|
||||
post.topic.custom_fields["accepted_answer_post_id"] = post.id
|
||||
post.topic.save!
|
||||
post.save!
|
||||
|
||||
render json: success_json
|
||||
end
|
||||
|
||||
def unaccept
|
||||
post = Post.find(params[:id].to_i)
|
||||
post.custom_fields["is_accepted_answer"] = nil
|
||||
post.topic.custom_fields["accepted_answer_post_id"] = nil
|
||||
post.topic.save!
|
||||
post.save!
|
||||
|
||||
render json: success_json
|
||||
end
|
||||
end
|
||||
|
||||
DiscourseSolvedButton::Engine.routes.draw do
|
||||
post "/accept" => "answer#accept"
|
||||
post "/unaccept" => "answer#unaccept"
|
||||
end
|
||||
|
||||
Discourse::Application.routes.append do
|
||||
mount ::DiscourseSolvedButton::Engine, at: "solution"
|
||||
end
|
||||
|
||||
TopicView.add_post_custom_fields_whitelister do |user|
|
||||
["is_accepted_answer"]
|
||||
end
|
||||
|
||||
require_dependency 'topic_view_serializer'
|
||||
class ::TopicViewSerializer
|
||||
attributes :accepted_answer
|
||||
|
||||
def include_accepted_answer?
|
||||
accepted_answer_post_id
|
||||
end
|
||||
|
||||
def accepted_answer
|
||||
if info = accepted_answer_post_info
|
||||
{
|
||||
post_number: info[0],
|
||||
username: info[1],
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def accepted_answer_post_info
|
||||
# TODO: we may already have it in the stream ... so bypass query here
|
||||
|
||||
Post.where(id: accepted_answer_post_id, topic_id: object.topic.id)
|
||||
.joins(:user)
|
||||
.pluck('post_number, username')
|
||||
.first
|
||||
end
|
||||
|
||||
def accepted_answer_post_id
|
||||
id = object.topic.custom_fields["accepted_answer_post_id"]
|
||||
id && id.to_i
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
require_dependency 'post_serializer'
|
||||
class ::PostSerializer
|
||||
attributes :can_accept_answer, :can_unaccept_answer, :accepted_answer
|
||||
|
||||
def can_accept_answer
|
||||
topic = (topic_view && topic_view.topic) || object.topic
|
||||
if topic
|
||||
object.post_number > 1 && !accepted_answer
|
||||
end
|
||||
end
|
||||
|
||||
def can_unaccept_answer
|
||||
post_custom_fields["is_accepted_answer"]
|
||||
end
|
||||
|
||||
def accepted_answer
|
||||
post_custom_fields["is_accepted_answer"]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue