2020-09-04 07:22:22 -04:00
|
|
|
import I18n from "I18n";
|
2018-08-01 10:05:46 -04:00
|
|
|
import Topic from "discourse/models/topic";
|
|
|
|
import User from "discourse/models/user";
|
|
|
|
import TopicStatus from "discourse/raw-views/topic-status";
|
2019-03-13 13:10:54 -04:00
|
|
|
import TopicStatusIcons from "discourse/helpers/topic-status-icons";
|
2018-08-01 10:05:46 -04:00
|
|
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
|
|
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
|
|
|
import { ajax } from "discourse/lib/ajax";
|
|
|
|
import PostCooked from "discourse/widgets/post-cooked";
|
|
|
|
import { formatUsername } from "discourse/lib/utilities";
|
2018-11-12 13:26:28 -05:00
|
|
|
import { iconHTML } from "discourse-common/lib/icon-library";
|
2019-07-24 11:01:47 -04:00
|
|
|
import { iconNode } from "discourse-common/lib/icon-library";
|
2016-02-17 15:58:32 -05:00
|
|
|
|
|
|
|
function clearAccepted(topic) {
|
2018-08-01 10:05:46 -04:00
|
|
|
const posts = topic.get("postStream.posts");
|
2020-09-04 07:22:22 -04:00
|
|
|
posts.forEach((post) => {
|
2018-08-01 10:05:46 -04:00
|
|
|
if (post.get("post_number") > 1) {
|
2019-10-02 01:36:35 -04:00
|
|
|
post.setProperties({
|
|
|
|
accepted_answer: false,
|
|
|
|
can_accept_answer: true,
|
2020-09-04 07:22:22 -04:00
|
|
|
can_unaccept_answer: false,
|
2019-10-02 01:36:35 -04:00
|
|
|
});
|
2016-02-17 15:58:32 -05:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function unacceptPost(post) {
|
2019-10-02 01:36:35 -04:00
|
|
|
if (!post.can_unaccept_answer) {
|
2018-08-01 10:05:46 -04:00
|
|
|
return;
|
|
|
|
}
|
2016-02-17 15:58:32 -05:00
|
|
|
const topic = post.topic;
|
|
|
|
|
|
|
|
post.setProperties({
|
|
|
|
can_accept_answer: true,
|
|
|
|
can_unaccept_answer: false,
|
2020-09-04 07:22:22 -04:00
|
|
|
accepted_answer: false,
|
2016-02-17 15:58:32 -05:00
|
|
|
});
|
2018-08-01 10:05:46 -04:00
|
|
|
topic.set("accepted_answer", undefined);
|
2016-02-17 15:58:32 -05:00
|
|
|
|
2016-11-01 09:25:57 -04:00
|
|
|
ajax("/solution/unaccept", {
|
2018-08-01 10:05:46 -04:00
|
|
|
type: "POST",
|
2020-09-04 07:22:22 -04:00
|
|
|
data: { id: post.id },
|
2016-02-17 15:58:32 -05:00
|
|
|
}).catch(popupAjaxError);
|
|
|
|
}
|
|
|
|
|
|
|
|
function acceptPost(post) {
|
|
|
|
const topic = post.topic;
|
|
|
|
|
|
|
|
clearAccepted(topic);
|
|
|
|
|
|
|
|
post.setProperties({
|
|
|
|
can_unaccept_answer: true,
|
|
|
|
can_accept_answer: false,
|
2020-09-04 07:22:22 -04:00
|
|
|
accepted_answer: true,
|
2016-02-17 15:58:32 -05:00
|
|
|
});
|
|
|
|
|
2018-08-01 10:05:46 -04:00
|
|
|
topic.set("accepted_answer", {
|
2019-10-02 01:36:35 -04:00
|
|
|
username: post.username,
|
|
|
|
post_number: post.post_number,
|
2020-09-04 07:22:22 -04:00
|
|
|
excerpt: post.cooked,
|
2016-02-17 15:58:32 -05:00
|
|
|
});
|
|
|
|
|
2016-11-01 09:25:57 -04:00
|
|
|
ajax("/solution/accept", {
|
2018-08-01 10:05:46 -04:00
|
|
|
type: "POST",
|
2020-09-04 07:22:22 -04:00
|
|
|
data: { id: post.id },
|
2016-02-17 15:58:32 -05:00
|
|
|
}).catch(popupAjaxError);
|
|
|
|
}
|
|
|
|
|
2019-07-18 10:56:18 -04:00
|
|
|
function initializeWithApi(api) {
|
2019-06-28 18:12:41 -04:00
|
|
|
const currentUser = api.getCurrentUser();
|
2016-02-17 15:58:32 -05:00
|
|
|
|
2019-06-28 18:12:41 -04:00
|
|
|
TopicStatusIcons.addObject([
|
|
|
|
"has_accepted_answer",
|
|
|
|
"far-check-square",
|
2020-09-04 07:22:22 -04:00
|
|
|
"solved",
|
2019-06-28 18:12:41 -04:00
|
|
|
]);
|
2019-03-13 13:10:54 -04:00
|
|
|
|
2018-08-01 10:05:46 -04:00
|
|
|
api.includePostAttributes(
|
|
|
|
"can_accept_answer",
|
|
|
|
"can_unaccept_answer",
|
|
|
|
"accepted_answer"
|
|
|
|
);
|
2016-02-17 15:58:32 -05:00
|
|
|
|
2017-02-27 17:30:37 -05:00
|
|
|
if (api.addDiscoveryQueryParam) {
|
2018-08-01 10:05:46 -04:00
|
|
|
api.addDiscoveryQueryParam("solved", { replace: true, refreshModel: true });
|
2017-02-27 17:30:37 -05:00
|
|
|
}
|
2017-02-27 17:15:05 -05:00
|
|
|
|
2020-09-04 07:22:22 -04:00
|
|
|
api.addPostMenuButton("solved", (attrs) => {
|
2019-07-18 10:56:18 -04:00
|
|
|
const canAccept = attrs.can_accept_answer;
|
|
|
|
const canUnaccept = attrs.can_unaccept_answer;
|
|
|
|
const accepted = attrs.accepted_answer;
|
2019-06-28 18:12:41 -04:00
|
|
|
const isOp = currentUser && currentUser.id === attrs.topicCreatedById;
|
|
|
|
const position =
|
2019-07-18 10:56:18 -04:00
|
|
|
!accepted && canAccept && !isOp ? "second-last-hidden" : "first";
|
2019-06-28 18:12:41 -04:00
|
|
|
|
2019-07-18 10:56:18 -04:00
|
|
|
if (canAccept) {
|
2019-06-28 18:12:41 -04:00
|
|
|
return {
|
|
|
|
action: "acceptAnswer",
|
|
|
|
icon: "far-check-square",
|
2019-07-15 10:30:58 -04:00
|
|
|
className: "unaccepted",
|
2019-07-18 10:56:18 -04:00
|
|
|
title: "solved.accept_answer",
|
2019-07-24 11:01:47 -04:00
|
|
|
label: "solved.solution",
|
2020-09-04 07:22:22 -04:00
|
|
|
position,
|
2019-06-28 18:12:41 -04:00
|
|
|
};
|
2019-07-24 11:01:47 -04:00
|
|
|
} else if (canUnaccept && accepted) {
|
2019-07-18 10:56:18 -04:00
|
|
|
const title = canUnaccept
|
|
|
|
? "solved.unaccept_answer"
|
|
|
|
: "solved.accepted_answer";
|
2019-06-28 18:12:41 -04:00
|
|
|
return {
|
2019-07-18 10:56:18 -04:00
|
|
|
action: "unacceptAnswer",
|
2019-06-28 18:12:41 -04:00
|
|
|
icon: "check-square",
|
2019-07-18 10:56:18 -04:00
|
|
|
title,
|
|
|
|
className: "accepted fade-out",
|
|
|
|
position,
|
2020-09-04 07:22:22 -04:00
|
|
|
label: "solved.solution",
|
2019-07-24 11:01:47 -04:00
|
|
|
};
|
|
|
|
} else if (!canAccept && accepted) {
|
|
|
|
return {
|
|
|
|
className: "hidden",
|
|
|
|
disabled: "true",
|
|
|
|
position,
|
2019-07-18 10:56:18 -04:00
|
|
|
beforeButton(h) {
|
2019-07-24 11:01:47 -04:00
|
|
|
return h(
|
|
|
|
"span.accepted-text",
|
|
|
|
{
|
2020-09-04 07:22:22 -04:00
|
|
|
title: I18n.t("solved.accepted_description"),
|
2019-07-24 11:01:47 -04:00
|
|
|
},
|
|
|
|
[
|
|
|
|
h("span", iconNode("check")),
|
2020-09-04 07:22:22 -04:00
|
|
|
h("span.accepted-label", I18n.t("solved.solution")),
|
2019-07-24 11:01:47 -04:00
|
|
|
]
|
|
|
|
);
|
2020-09-04 07:22:22 -04:00
|
|
|
},
|
2019-06-28 18:12:41 -04:00
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
2016-02-17 15:58:32 -05:00
|
|
|
|
2020-09-04 07:22:22 -04:00
|
|
|
api.decorateWidget("post-contents:after-cooked", (dec) => {
|
2016-02-23 12:09:36 -05:00
|
|
|
if (dec.attrs.post_number === 1) {
|
2016-11-23 10:41:02 -05:00
|
|
|
const postModel = dec.getModel();
|
|
|
|
if (postModel) {
|
2019-10-02 01:36:35 -04:00
|
|
|
const topic = postModel.topic;
|
|
|
|
if (topic.accepted_answer) {
|
|
|
|
const hasExcerpt = !!topic.accepted_answer.excerpt;
|
2017-03-07 19:38:15 -05:00
|
|
|
|
2017-08-06 17:22:30 -04:00
|
|
|
const withExcerpt = `
|
2019-03-14 02:19:58 -04:00
|
|
|
<aside class='quote accepted-answer' data-post="${
|
2018-08-01 10:05:46 -04:00
|
|
|
topic.get("accepted_answer").post_number
|
2019-10-02 01:36:35 -04:00
|
|
|
}" data-topic="${topic.id}">
|
2017-03-07 19:38:15 -05:00
|
|
|
<div class='title'>
|
2019-10-02 01:36:35 -04:00
|
|
|
${topic.acceptedAnswerHtml} <div class="quote-controls"><\/div>
|
2017-03-07 18:33:10 -05:00
|
|
|
</div>
|
2017-03-08 10:21:41 -05:00
|
|
|
<blockquote>
|
2019-10-02 01:36:35 -04:00
|
|
|
${topic.accepted_answer.excerpt}
|
2017-03-08 10:21:41 -05:00
|
|
|
</blockquote>
|
2017-07-05 14:18:26 -04:00
|
|
|
</aside>`;
|
2017-03-07 18:33:10 -05:00
|
|
|
|
2017-08-06 17:22:30 -04:00
|
|
|
const withoutExcerpt = `
|
2019-03-14 02:19:58 -04:00
|
|
|
<aside class='quote accepted-answer'>
|
2017-08-06 17:22:30 -04:00
|
|
|
<div class='title title-only'>
|
2019-10-02 01:36:35 -04:00
|
|
|
${topic.acceptedAnswerHtml}
|
2017-08-06 17:22:30 -04:00
|
|
|
</div>
|
|
|
|
</aside>`;
|
|
|
|
|
2019-11-05 16:58:09 -05:00
|
|
|
const cooked = new PostCooked(
|
|
|
|
{ cooked: hasExcerpt ? withExcerpt : withoutExcerpt },
|
|
|
|
dec
|
|
|
|
);
|
2019-10-02 01:36:35 -04:00
|
|
|
return dec.rawHtml(cooked.init());
|
2016-11-23 10:41:02 -05:00
|
|
|
}
|
2016-02-23 12:09:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-09-04 07:22:22 -04:00
|
|
|
api.attachWidgetAction("post", "acceptAnswer", function () {
|
2016-02-17 15:58:32 -05:00
|
|
|
const post = this.model;
|
2020-09-04 07:22:22 -04:00
|
|
|
const current = post.get("topic.postStream.posts").filter((p) => {
|
2019-10-02 01:36:35 -04:00
|
|
|
return p.post_number === 1 || p.accepted_answer;
|
2016-02-23 12:09:36 -05:00
|
|
|
});
|
2016-02-17 15:58:32 -05:00
|
|
|
acceptPost(post);
|
|
|
|
|
2020-09-04 07:22:22 -04:00
|
|
|
current.forEach((p) =>
|
2018-08-01 10:05:46 -04:00
|
|
|
this.appEvents.trigger("post-stream:refresh", { id: p.id })
|
|
|
|
);
|
2016-02-17 15:58:32 -05:00
|
|
|
});
|
|
|
|
|
2020-09-04 07:22:22 -04:00
|
|
|
api.attachWidgetAction("post", "unacceptAnswer", function () {
|
2016-02-23 12:09:36 -05:00
|
|
|
const post = this.model;
|
2018-08-01 10:05:46 -04:00
|
|
|
const op = post
|
|
|
|
.get("topic.postStream.posts")
|
2020-09-04 07:22:22 -04:00
|
|
|
.find((p) => p.post_number === 1);
|
2016-02-23 12:09:36 -05:00
|
|
|
unacceptPost(post);
|
2019-10-02 01:36:35 -04:00
|
|
|
this.appEvents.trigger("post-stream:refresh", { id: op.id });
|
2016-02-17 15:58:32 -05:00
|
|
|
});
|
2016-12-19 22:04:23 -05:00
|
|
|
|
|
|
|
if (api.registerConnectorClass) {
|
2018-08-01 10:05:46 -04:00
|
|
|
api.registerConnectorClass("user-activity-bottom", "solved-list", {
|
2017-02-02 12:20:01 -05:00
|
|
|
shouldRender(args, component) {
|
|
|
|
return component.siteSettings.solved_enabled;
|
2020-09-04 07:22:22 -04:00
|
|
|
},
|
2017-02-02 12:20:01 -05:00
|
|
|
});
|
2018-08-01 10:05:46 -04:00
|
|
|
api.registerConnectorClass("user-summary-stat", "solved-count", {
|
2017-02-02 12:20:01 -05:00
|
|
|
shouldRender(args, component) {
|
2018-08-01 10:05:46 -04:00
|
|
|
return (
|
|
|
|
component.siteSettings.solved_enabled && args.model.solved_count > 0
|
|
|
|
);
|
2016-12-19 22:04:23 -05:00
|
|
|
},
|
|
|
|
setupComponent() {
|
2018-08-01 10:05:46 -04:00
|
|
|
this.set("classNames", ["linked-stat"]);
|
2020-09-04 07:22:22 -04:00
|
|
|
},
|
2016-12-19 22:04:23 -05:00
|
|
|
});
|
|
|
|
}
|
2016-02-17 15:58:32 -05:00
|
|
|
}
|
2015-05-19 01:45:19 -04:00
|
|
|
|
|
|
|
export default {
|
2018-08-01 10:05:46 -04:00
|
|
|
name: "extend-for-solved-button",
|
2019-07-18 10:56:18 -04:00
|
|
|
initialize() {
|
2015-05-19 01:45:19 -04:00
|
|
|
Topic.reopen({
|
|
|
|
// keeping this here cause there is complex localization
|
2020-09-04 07:22:22 -04:00
|
|
|
acceptedAnswerHtml: Ember.computed("accepted_answer", "id", function () {
|
2018-08-01 10:05:46 -04:00
|
|
|
const username = this.get("accepted_answer.username");
|
|
|
|
const postNumber = this.get("accepted_answer.post_number");
|
2015-05-19 02:26:22 -04:00
|
|
|
|
|
|
|
if (!username || !postNumber) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2015-06-15 00:24:49 -04:00
|
|
|
return I18n.t("solved.accepted_html", {
|
2019-06-28 18:12:41 -04:00
|
|
|
icon: iconHTML("check-square", { class: "accepted" }),
|
2015-05-19 02:26:22 -04:00
|
|
|
username_lower: username.toLowerCase(),
|
2018-08-01 10:05:46 -04:00
|
|
|
username: formatUsername(username),
|
2019-10-02 01:36:35 -04:00
|
|
|
post_path: `${this.url}/${postNumber}`,
|
2015-05-19 02:26:22 -04:00
|
|
|
post_number: postNumber,
|
2020-09-04 07:22:22 -04:00
|
|
|
user_path: User.create({ username }).path,
|
2015-05-19 02:26:22 -04:00
|
|
|
});
|
2020-09-04 07:22:22 -04:00
|
|
|
}),
|
2015-05-19 01:45:19 -04:00
|
|
|
});
|
|
|
|
|
2015-06-15 02:26:40 -04:00
|
|
|
TopicStatus.reopen({
|
2020-09-04 07:22:22 -04:00
|
|
|
statuses: Ember.computed(function () {
|
2019-10-02 01:36:35 -04:00
|
|
|
const results = this._super(...arguments);
|
|
|
|
|
2015-06-15 02:26:40 -04:00
|
|
|
if (this.topic.has_accepted_answer) {
|
|
|
|
results.push({
|
2018-08-01 10:05:46 -04:00
|
|
|
openTag: "span",
|
|
|
|
closeTag: "span",
|
2019-03-13 13:10:54 -04:00
|
|
|
title: I18n.t("topic_statuses.solved.help"),
|
2020-09-04 07:22:22 -04:00
|
|
|
icon: "far-check-square",
|
2015-06-15 02:26:40 -04:00
|
|
|
});
|
2018-08-01 10:05:46 -04:00
|
|
|
} else if (
|
|
|
|
this.topic.can_have_answer &&
|
|
|
|
this.siteSettings.solved_enabled &&
|
|
|
|
this.siteSettings.empty_box_on_unsolved
|
|
|
|
) {
|
2017-02-27 10:00:04 -05:00
|
|
|
results.push({
|
2018-08-01 10:05:46 -04:00
|
|
|
openTag: "span",
|
|
|
|
closeTag: "span",
|
|
|
|
title: I18n.t("solved.has_no_accepted_answer"),
|
2020-09-04 07:22:22 -04:00
|
|
|
icon: "far-square",
|
2017-02-27 10:00:04 -05:00
|
|
|
});
|
2015-06-15 02:26:40 -04:00
|
|
|
}
|
|
|
|
return results;
|
2020-09-04 07:22:22 -04:00
|
|
|
}),
|
2015-06-15 02:26:40 -04:00
|
|
|
});
|
|
|
|
|
2019-07-18 10:56:18 -04:00
|
|
|
withPluginApi("0.1", initializeWithApi);
|
2017-09-15 13:55:08 -04:00
|
|
|
|
2020-09-04 07:22:22 -04:00
|
|
|
withPluginApi("0.8.10", (api) => {
|
2018-08-01 10:05:46 -04:00
|
|
|
api.replaceIcon(
|
|
|
|
"notification.solved.accepted_notification",
|
2019-07-18 10:56:18 -04:00
|
|
|
"check-square"
|
2018-08-01 10:05:46 -04:00
|
|
|
);
|
2017-09-15 13:55:08 -04:00
|
|
|
});
|
2020-09-11 06:15:34 -04:00
|
|
|
|
|
|
|
withPluginApi("0.11.0", (api) => {
|
|
|
|
api.addAdvancedSearchOptions({
|
|
|
|
statusOptions: [
|
|
|
|
{
|
|
|
|
name: I18n.t("search.advanced.statuses.solved"),
|
|
|
|
value: "solved",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: I18n.t("search.advanced.statuses.unsolved"),
|
|
|
|
value: "unsolved",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
});
|
|
|
|
});
|
2020-09-04 07:22:22 -04:00
|
|
|
},
|
2015-05-19 01:45:19 -04:00
|
|
|
};
|