diff --git a/assets/javascripts/discourse/components/post-metadata-user-notes.gjs b/assets/javascripts/discourse/components/post-metadata-user-notes.gjs
new file mode 100644
index 0000000..da22b1a
--- /dev/null
+++ b/assets/javascripts/discourse/components/post-metadata-user-notes.gjs
@@ -0,0 +1,9 @@
+import Component from "@glimmer/component";
+import { service } from "@ember/service";
+import icon from "discourse/helpers/d-icon";
+
+export default class PostMetadataUserNotes extends Component {
+ @service siteSettings;
+
+ {{icon "pen-to-square"}}
+}
diff --git a/assets/javascripts/discourse/initializers/enable-user-notes.gjs b/assets/javascripts/discourse/initializers/enable-user-notes.gjs
new file mode 100644
index 0000000..3a5b7f6
--- /dev/null
+++ b/assets/javascripts/discourse/initializers/enable-user-notes.gjs
@@ -0,0 +1,166 @@
+import Component from "@glimmer/component";
+import { withSilencedDeprecations } from "discourse/lib/deprecated";
+import { iconNode } from "discourse/lib/icon-library";
+import { withPluginApi } from "discourse/lib/plugin-api";
+import { applyValueTransformer } from "discourse/lib/transformer";
+import PostMetadataUserNotes from "../components/post-metadata-user-notes";
+import { showUserNotes } from "../lib/user-notes";
+
+export default {
+ name: "enable-user-notes",
+ initialize(container) {
+ const siteSettings = container.lookup("service:site-settings");
+ const currentUser = container.lookup("service:current-user");
+
+ if (!siteSettings.user_notes_enabled || !currentUser?.staff) {
+ return;
+ }
+
+ withPluginApi((api) => {
+ customizePost(api, container);
+ customizePostMenu(api, container);
+ });
+ },
+};
+
+function customizePost(api, container) {
+ const siteSettings = container.lookup("service:site-settings");
+
+ const iconPlacement = applyValueTransformer(
+ "user-notes-icon-placement",
+ siteSettings.user_notes_icon_placement
+ );
+
+ if (iconPlacement === "name") {
+ api.renderBeforeWrapperOutlet(
+ "post-meta-data-poster-name",
+ class extends Component {
+ static shouldRender(args, context) {
+ return context.site.mobileView;
+ }
+
+
+ }
+ );
+
+ api.renderAfterWrapperOutlet(
+ "post-meta-data-poster-name",
+ class extends Component {
+ static shouldRender(args, context) {
+ return !context.site.mobileView;
+ }
+
+
+ }
+ );
+ } else if (iconPlacement === "avatar") {
+ api.renderAfterWrapperOutlet("poster-avatar", PostMetadataUserNotes);
+ }
+
+ withSilencedDeprecations("discourse.post-stream-widget-overrides", () =>
+ customizeWidgetPost(api)
+ );
+}
+
+function customizeWidgetPost(api) {
+ function widgetShowUserNotes() {
+ showUserNotes(
+ this.store,
+ this.attrs.user_id,
+ (count) => {
+ this.sendWidgetAction("refreshUserNotes", count);
+ },
+ {
+ postId: this.attrs.id,
+ }
+ );
+ }
+
+ api.attachWidgetAction("post", "refreshUserNotes", function (count) {
+ const cfs = this.model.user_custom_fields || {};
+ cfs.user_notes_count = count;
+ this.model.set("user_custom_fields", cfs);
+ });
+
+ const mobileView = api.container.lookup("service:site").mobileView;
+ const loc = mobileView ? "before" : "after";
+
+ api.decorateWidget(`poster-name:${loc}`, (dec) => {
+ if (dec.widget.settings.hideNotes) {
+ return;
+ }
+
+ const post = dec.getModel();
+ if (!post) {
+ return;
+ }
+
+ const ucf = post.user_custom_fields || {};
+ if (ucf.user_notes_count > 0) {
+ return dec.attach("user-notes-icon");
+ }
+ });
+
+ api.decorateWidget(`post-avatar:after`, (dec) => {
+ if (!dec.widget.settings.showNotes) {
+ return;
+ }
+
+ const post = dec.getModel();
+ if (!post) {
+ return;
+ }
+
+ const ucf = post.user_custom_fields || {};
+ if (ucf.user_notes_count > 0) {
+ return dec.attach("user-notes-icon");
+ }
+ });
+
+ api.attachWidgetAction("post", "showUserNotes", widgetShowUserNotes);
+
+ api.createWidget("user-notes-icon", {
+ services: ["site-settings"],
+
+ tagName: "span.user-notes-icon",
+ click: widgetShowUserNotes,
+
+ html() {
+ if (this.siteSettings.enable_emoji) {
+ return this.attach("emoji", { name: "memo" });
+ } else {
+ return iconNode("pen-to-square");
+ }
+ },
+ });
+}
+
+function customizePostMenu(api, container) {
+ const appEvents = container.lookup("service:app-events");
+ const store = container.lookup("service:store");
+
+ api.addPostAdminMenuButton((attrs) => {
+ return {
+ icon: "pen-to-square",
+ label: "user_notes.attach",
+ action: (post) => {
+ showUserNotes(
+ store,
+ attrs.user_id,
+ (count) => {
+ const ucf = post.user_custom_fields || {};
+ ucf.user_notes_count = count;
+ post.set("user_custom_fields", ucf);
+
+ appEvents.trigger("post-stream:refresh", {
+ id: post.id,
+ });
+ },
+ { postId: attrs.id }
+ );
+ },
+ secondaryAction: "closeAdminMenu",
+ className: "add-user-note",
+ };
+ });
+}
diff --git a/assets/javascripts/discourse/initializers/enable-user-notes.js b/assets/javascripts/discourse/initializers/enable-user-notes.js
deleted file mode 100644
index b23ad64..0000000
--- a/assets/javascripts/discourse/initializers/enable-user-notes.js
+++ /dev/null
@@ -1,114 +0,0 @@
-import { iconNode } from "discourse/lib/icon-library";
-import { withPluginApi } from "discourse/lib/plugin-api";
-import { showUserNotes } from "../lib/user-notes";
-
-export default {
- name: "enable-user-notes",
- initialize(container) {
- const siteSettings = container.lookup("service:site-settings");
- const currentUser = container.lookup("service:current-user");
- const appEvents = container.lookup("service:app-events");
-
- if (!siteSettings.user_notes_enabled || !currentUser?.staff) {
- return;
- }
-
- const store = container.lookup("service:store");
-
- withPluginApi("0.8.15", (api) => {
- function widgetShowUserNotes() {
- showUserNotes(
- this.store,
- this.attrs.user_id,
- (count) => {
- this.sendWidgetAction("refreshUserNotes", count);
- },
- {
- postId: this.attrs.id,
- }
- );
- }
-
- api.attachWidgetAction("post", "refreshUserNotes", function (count) {
- const cfs = this.model.user_custom_fields || {};
- cfs.user_notes_count = count;
- this.model.set("user_custom_fields", cfs);
- });
-
- const mobileView = api.container.lookup("service:site").mobileView;
- const loc = mobileView ? "before" : "after";
- api.decorateWidget(`poster-name:${loc}`, (dec) => {
- if (dec.widget.settings.hideNotes) {
- return;
- }
-
- const post = dec.getModel();
- if (!post) {
- return;
- }
-
- const ucf = post.user_custom_fields || {};
- if (ucf.user_notes_count > 0) {
- return dec.attach("user-notes-icon");
- }
- });
-
- api.decorateWidget(`post-avatar:after`, (dec) => {
- if (!dec.widget.settings.showNotes) {
- return;
- }
-
- const post = dec.getModel();
- if (!post) {
- return;
- }
-
- const ucf = post.user_custom_fields || {};
- if (ucf.user_notes_count > 0) {
- return dec.attach("user-notes-icon");
- }
- });
- api.addPostAdminMenuButton((attrs) => {
- return {
- icon: "pen-to-square",
- label: "user_notes.attach",
- action: (post) => {
- showUserNotes(
- store,
- attrs.user_id,
- (count) => {
- const ucf = post.user_custom_fields || {};
- ucf.user_notes_count = count;
- post.set("user_custom_fields", ucf);
-
- appEvents.trigger("post-stream:refresh", {
- id: post.id,
- });
- },
- { postId: attrs.id }
- );
- },
- secondaryAction: "closeAdminMenu",
- className: "add-user-note",
- };
- });
-
- api.attachWidgetAction("post", "showUserNotes", widgetShowUserNotes);
-
- api.createWidget("user-notes-icon", {
- services: ["site-settings"],
-
- tagName: "span.user-notes-icon",
- click: widgetShowUserNotes,
-
- html() {
- if (this.siteSettings.enable_emoji) {
- return this.attach("emoji", { name: "memo" });
- } else {
- return iconNode("pen-to-square");
- }
- },
- });
- });
- },
-};
diff --git a/assets/javascripts/discourse/pre-initializers/transformers.js b/assets/javascripts/discourse/pre-initializers/transformers.js
new file mode 100644
index 0000000..6117a6f
--- /dev/null
+++ b/assets/javascripts/discourse/pre-initializers/transformers.js
@@ -0,0 +1,11 @@
+import { withPluginApi } from "discourse/lib/plugin-api";
+
+export default {
+ before: "freeze-valid-transformers",
+
+ initialize() {
+ withPluginApi("1.33.0", (api) => {
+ api.addValueTransformerName("user-notes-icon-placement");
+ });
+ },
+};
diff --git a/config/settings.yml b/config/settings.yml
index 5f6a42a..d2beb64 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -2,6 +2,13 @@ plugins:
user_notes_enabled:
default: false
client: true
+ user_notes_icon_placement:
+ client: true
+ type: enum
+ default: "name"
+ choices:
+ - name
+ - avatar
user_notes_moderators_delete:
default: true
client: false