diff --git a/assets/javascripts/discourse/components/solved-accepted-answer.gjs b/assets/javascripts/discourse/components/solved-accepted-answer.gjs
new file mode 100644
index 0000000..fcafef5
--- /dev/null
+++ b/assets/javascripts/discourse/components/solved-accepted-answer.gjs
@@ -0,0 +1,166 @@
+import Component from "@glimmer/component";
+import { tracked } from "@glimmer/tracking";
+import { on } from "@ember/modifier";
+import { action } from "@ember/object";
+import { service } from "@ember/service";
+import { htmlSafe } from "@ember/template";
+import AsyncContent from "discourse/components/async-content";
+import PostCookedHtml from "discourse/components/post/cooked-html";
+import concatClass from "discourse/helpers/concat-class";
+import icon from "discourse/helpers/d-icon";
+import { ajax } from "discourse/lib/ajax";
+import { iconHTML } from "discourse/lib/icon-library";
+import { formatUsername } from "discourse/lib/utilities";
+import { i18n } from "discourse-i18n";
+
+export default class SolvedAcceptedAnswer extends Component {
+ @service siteSettings;
+ @service store;
+
+ @tracked expanded = false;
+
+ get acceptedAnswer() {
+ return this.topic.accepted_answer;
+ }
+
+ get quoteId() {
+ return `accepted-answer-${this.topic.id}-${this.acceptedAnswer.post_number}`;
+ }
+
+ get topic() {
+ return this.args.post.topic;
+ }
+
+ get hasExcerpt() {
+ return !!this.acceptedAnswer.excerpt;
+ }
+
+ get htmlAccepter() {
+ const username = this.acceptedAnswer.accepter_username;
+ const name = this.acceptedAnswer.accepter_name;
+
+ if (!this.siteSettings.show_who_marked_solved) {
+ return;
+ }
+
+ const formattedUsername =
+ this.siteSettings.display_name_on_posts && name
+ ? name
+ : formatUsername(username);
+
+ return htmlSafe(
+ i18n("solved.marked_solved_by", {
+ username: formattedUsername,
+ username_lower: username.toLowerCase(),
+ })
+ );
+ }
+
+ get htmlSolvedBy() {
+ const username = this.acceptedAnswer.username;
+ const name = this.acceptedAnswer.name;
+ const postNumber = this.acceptedAnswer.post_number;
+
+ if (!username || !postNumber) {
+ return;
+ }
+
+ const displayedUser =
+ this.siteSettings.display_name_on_posts && name
+ ? name
+ : formatUsername(username);
+
+ const data = {
+ icon: iconHTML("square-check", { class: "accepted" }),
+ username_lower: username.toLowerCase(),
+ username: displayedUser,
+ post_path: `${this.topic.url}/${postNumber}`,
+ post_number: postNumber,
+ user_path: this.store.createRecord("user", { username }).path,
+ };
+
+ return htmlSafe(i18n("solved.accepted_html", data));
+ }
+
+ @action
+ toggleExpandedPost() {
+ if (!this.hasExcerpt) {
+ return;
+ }
+
+ this.expanded = !this.expanded;
+ }
+
+ @action
+ async loadExpandedAcceptedAnswer(postNumber) {
+ const acceptedAnswer = await ajax(
+ `/posts/by_number/${this.topic.id}/${postNumber}`
+ );
+
+ return this.store.createRecord("post", acceptedAnswer);
+ }
+
+
+
+
+}
diff --git a/assets/javascripts/discourse/initializers/extend-for-solved-button.gjs b/assets/javascripts/discourse/initializers/extend-for-solved-button.gjs
new file mode 100644
index 0000000..207d73f
--- /dev/null
+++ b/assets/javascripts/discourse/initializers/extend-for-solved-button.gjs
@@ -0,0 +1,136 @@
+import Component from "@glimmer/component";
+import { computed } from "@ember/object";
+import { withSilencedDeprecations } from "discourse/lib/deprecated";
+import { iconHTML } from "discourse/lib/icon-library";
+import { withPluginApi } from "discourse/lib/plugin-api";
+import { formatUsername } from "discourse/lib/utilities";
+import Topic from "discourse/models/topic";
+import User from "discourse/models/user";
+import PostCooked from "discourse/widgets/post-cooked";
+import RenderGlimmer from "discourse/widgets/render-glimmer";
+import { i18n } from "discourse-i18n";
+import SolvedAcceptAnswerButton from "../components/solved-accept-answer-button";
+import SolvedAcceptedAnswer from "../components/solved-accepted-answer";
+import SolvedUnacceptAnswerButton from "../components/solved-unaccept-answer-button";
+
+function initializeWithApi(api) {
+ customizePost(api);
+ customizePostMenu(api);
+
+ if (api.addDiscoveryQueryParam) {
+ api.addDiscoveryQueryParam("solved", { replace: true, refreshModel: true });
+ }
+}
+
+function customizePost(api) {
+ api.addTrackedPostProperties(
+ "can_accept_answer",
+ "can_unaccept_answer",
+ "accepted_answer",
+ "topic_accepted_answer"
+ );
+
+ api.renderAfterWrapperOutlet(
+ "post-content-cooked-html",
+ class extends Component {
+ static shouldRender(args) {
+ return args.post.post_number === 1 && args.post.topic.accepted_answer;
+ }
+
+
${topic.accepted_answer.excerpt}` - : ""; - const solvedQuote = ` -