diff --git a/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.hbs b/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.hbs
index 8b547fd0bfd..848800ff3b8 100644
--- a/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.hbs
+++ b/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.hbs
@@ -1,23 +1,30 @@
-{{#if this.shouldDisplay}}
-
-
- {{#each this.presenceUsers as |user|}}
- {{avatar user imageSize="small"}}
- {{/each}}
+
+ {{#if this.shouldDisplay}}
+
+
+ {{#each this.users as |user|}}
+
+ {{avatar user imageSize="small"}}
+
+ {{/each}}
+
+
+
+ {{~#if this.isReply~}}
+ {{i18n "presence.replying" count=this.users.length}}
+ {{~else~}}
+ {{i18n "presence.editing" count=this.users.length}}
+ {{~/if~}}
+
+
+ .
+ .
+ .
+
+
-
-
- {{~#if this.isReply~}}
- {{i18n "presence.replying" count=this.presenceUsers.length}}
- {{~else~}}
- {{i18n "presence.editing" count=this.presenceUsers.length}}
- {{~/if~}}
-
-
- .
- .
- .
-
-
-
-{{/if}}
\ No newline at end of file
+ {{/if}}
+
\ No newline at end of file
diff --git a/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.js b/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.js
index 81ec9c191c7..80feba20f9d 100644
--- a/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.js
+++ b/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.js
@@ -1,32 +1,30 @@
-import Component from "@ember/component";
-import { equal, gt, readOnly, union } from "@ember/object/computed";
+import Component from "@glimmer/component";
+import { tracked } from "@glimmer/tracking";
+import { action } from "@ember/object";
import { service } from "@ember/service";
-import { tagName } from "@ember-decorators/component";
-import { observes, on } from "@ember-decorators/object";
-import discourseComputed from "discourse-common/utils/decorators";
-@tagName("")
-export default class ComposerPresenceDisplay extends Component {
+export default class ComposerPresenceDisplayComponent extends Component {
@service presence;
@service composerPresenceManager;
+ @service currentUser;
+ @service siteSettings;
- @equal("state", "reply") isReply;
- @equal("state", "edit") isEdit;
- @equal("state", "whisper") isWhisper;
- @union("replyChannel.users", "whisperChannel.users") replyingUsers;
- @readOnly("editChannel.users") editingUsers;
- @gt("presenceUsers.length", 0) shouldDisplay;
+ @tracked replyChannel;
+ @tracked whisperChannel;
+ @tracked editChannel;
- @discourseComputed(
- "model.replyingToTopic",
- "model.editingPost",
- "model.whisper",
- "model.composerOpened"
- )
- state(replyingToTopic, editingPost, whisper, composerOpen) {
- if (!composerOpen) {
- return;
- } else if (editingPost) {
+ get isReply() {
+ return this.state === "reply" || this.state === "whisper";
+ }
+
+ get isEdit() {
+ return this.state === "edit";
+ }
+
+ get state() {
+ const { editingPost, whisper, replyingToTopic } = this.args.model;
+
+ if (editingPost) {
return "edit";
} else if (whisper) {
return "whisper";
@@ -35,77 +33,105 @@ export default class ComposerPresenceDisplay extends Component {
}
}
- @discourseComputed("model.topic.id", "isReply", "isWhisper")
- replyChannelName(topicId, isReply, isWhisper) {
- if (topicId && (isReply || isWhisper)) {
+ get replyChannelName() {
+ const topicId = this.args.model?.topic?.id;
+ if (topicId && this.isReply) {
return `/discourse-presence/reply/${topicId}`;
}
}
- @discourseComputed("model.topic.id", "isReply", "isWhisper")
- whisperChannelName(topicId, isReply, isWhisper) {
- if (topicId && this.currentUser.whisperer && (isReply || isWhisper)) {
+ get whisperChannelName() {
+ const topicId = this.args.model?.topic?.id;
+ if (topicId && this.isReply && this.currentUser.whisperer) {
return `/discourse-presence/whisper/${topicId}`;
}
}
- @discourseComputed("isEdit", "model.post.id")
- editChannelName(isEdit, postId) {
- if (isEdit) {
+ get editChannelName() {
+ const postId = this.args.model?.post?.id;
+ if (postId && this.isEdit) {
return `/discourse-presence/edit/${postId}`;
}
}
- _setupChannel(channelKey, name) {
- if (this[channelKey]?.name !== name) {
- this[channelKey]?.unsubscribe();
+ get replyUsers() {
+ return this.replyChannel?.users || [];
+ }
+
+ get whisperUsers() {
+ return this.whisperChannel?.users || [];
+ }
+
+ get replyingUsers() {
+ return [...this.replyUsers, ...this.whisperUsers];
+ }
+
+ get editingUsers() {
+ return this.editChannel?.users || [];
+ }
+
+ get users() {
+ const users = this.isEdit ? this.editingUsers : this.replyingUsers;
+ return users
+ .filter((u) => u.id !== this.currentUser.id)
+ .slice(0, this.siteSettings.presence_max_users_shown);
+ }
+
+ get shouldDisplay() {
+ return this.users.length > 0;
+ }
+
+ @action
+ setupChannels() {
+ this.setupReplyChannel();
+ this.setupWhisperChannel();
+ this.setupEditChannel();
+ this.notifyState();
+ }
+
+ setupReplyChannel() {
+ this.setupChannel("replyChannel", this.replyChannelName);
+ }
+
+ setupWhisperChannel() {
+ if (this.currentUser.staff) {
+ this.setupChannel("whisperChannel", this.whisperChannelName);
+ }
+ }
+
+ setupEditChannel() {
+ this.setupChannel("editChannel", this.editChannelName);
+ }
+
+ setupChannel(key, name) {
+ if (this[key]?.name !== name) {
+ this[key]?.unsubscribe();
if (name) {
- this.set(channelKey, this.presence.getChannel(name));
- this[channelKey].subscribe();
- } else if (this[channelKey]) {
- this.set(channelKey, null);
+ this[key] = this.presence.getChannel(name);
+ this[key].subscribe();
}
}
}
- @observes("replyChannelName", "whisperChannelName", "editChannelName")
- _setupChannels() {
- this._setupChannel("replyChannel", this.replyChannelName);
- this._setupChannel("whisperChannel", this.whisperChannelName);
- this._setupChannel("editChannel", this.editChannelName);
- }
+ notifyState() {
+ const { reply, post, topic } = this.args.model;
+ const raw = this.isEdit ? post?.raw || "" : "";
+ const entity = this.isEdit ? post : topic;
- _cleanupChannels() {
- this._setupChannel("replyChannel", null);
- this._setupChannel("whisperChannel", null);
- this._setupChannel("editChannel", null);
- }
-
- @discourseComputed("isReply", "replyingUsers.[]", "editingUsers.[]")
- presenceUsers(isReply, replyingUsers, editingUsers) {
- const users = isReply ? replyingUsers : editingUsers;
- return users
- ?.filter((u) => u.id !== this.currentUser.id)
- ?.slice(0, this.siteSettings.presence_max_users_shown);
- }
-
- @on("didInsertElement")
- subscribe() {
- this._setupChannels();
- }
-
- @observes("model.reply", "state", "model.post.id", "model.topic.id")
- _contentChanged() {
- if (this.model.reply === "") {
- return;
+ if (reply !== raw) {
+ this.composerPresenceManager.notifyState(this.state, entity?.id);
}
- const entity = this.state === "edit" ? this.model?.post : this.model?.topic;
- this.composerPresenceManager.notifyState(this.state, entity?.id);
}
- @on("willDestroyElement")
- closeComposer() {
- this._cleanupChannels();
+ willDestroy() {
+ super.willDestroy(...arguments);
+ this.unsubscribeFromChannels();
this.composerPresenceManager.leave();
}
+
+ unsubscribeFromChannels() {
+ this.replyChannel?.unsubscribe();
+ this.whisperChannel?.unsubscribe();
+ this.editChannel?.unsubscribe();
+ }
}
diff --git a/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.hbs b/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.hbs
index 04fdfffd0f0..3da513e1bc4 100644
--- a/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.hbs
+++ b/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.hbs
@@ -1,21 +1,26 @@
-{{#if this.shouldDisplay}}
-
-
- {{#each this.users as |user|}}
-
- {{avatar user imageSize="small"}}
-
- {{/each}}
+
+ {{#if this.shouldDisplay}}
+
+
+ {{#each this.users as |user|}}
+
+ {{avatar user imageSize="small"}}
+
+ {{/each}}
+
+
+
+ {{i18n "presence.replying_to_topic" count=this.users.length}}
+
+
+ .
+ .
+ .
+
+
-
-
- {{i18n "presence.replying_to_topic" count=this.users.length}}
-
-
- .
- .
- .
-
-
-
-{{/if}}
\ No newline at end of file
+ {{/if}}
+
\ No newline at end of file
diff --git a/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.js b/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.js
index 4cd60b1674f..1018d4b403a 100644
--- a/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.js
+++ b/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.js
@@ -1,64 +1,72 @@
-import Component from "@ember/component";
-import { gt, union } from "@ember/object/computed";
+import Component from "@glimmer/component";
+import { tracked } from "@glimmer/tracking";
+import { action } from "@ember/object";
import { service } from "@ember/service";
-import { on } from "@ember-decorators/object";
-import discourseComputed from "discourse-common/utils/decorators";
-export default class TopicPresenceDisplay extends Component {
+export default class TopicPresenceDisplayComponent extends Component {
@service presence;
+ @service currentUser;
- topic = null;
- replyChannel = null;
- whisperChannel = null;
+ @tracked replyChannel;
+ @tracked whisperChannel;
- @union("replyUsers", "whisperUsers") users;
- @gt("users.length", 0) shouldDisplay;
-
- @discourseComputed("replyChannel.users.[]")
- replyUsers(users) {
- return users?.filter((u) => u.id !== this.currentUser.id);
+ get replyChannelName() {
+ return `/discourse-presence/reply/${this.args.topic.id}`;
}
- @discourseComputed("whisperChannel.users.[]")
- whisperUsers(users) {
- return users?.filter((u) => u.id !== this.currentUser.id);
+ get whisperChannelName() {
+ return `/discourse-presence/whisper/${this.args.topic.id}`;
}
- @discourseComputed("topic.id")
- replyChannelName(id) {
- return `/discourse-presence/reply/${id}`;
+ get replyUsers() {
+ return this.replyChannel?.users || [];
}
- @discourseComputed("topic.id")
- whisperChannelName(id) {
- return `/discourse-presence/whisper/${id}`;
+ get whisperUsers() {
+ return this.whisperChannel?.users || [];
}
- didReceiveAttrs() {
- super.didReceiveAttrs(...arguments);
-
- if (this.replyChannel?.name !== this.replyChannelName) {
- this.replyChannel?.unsubscribe();
- this.set("replyChannel", this.presence.getChannel(this.replyChannelName));
- this.replyChannel.subscribe();
- }
-
- if (
- this.currentUser.staff &&
- this.whisperChannel?.name !== this.whisperChannelName
- ) {
- this.whisperChannel?.unsubscribe();
- this.set(
- "whisperChannel",
- this.presence.getChannel(this.whisperChannelName)
- );
- this.whisperChannel.subscribe();
- }
+ get users() {
+ return [...this.replyUsers, ...this.whisperUsers].filter(
+ (u) => u.id !== this.currentUser.id
+ );
}
- @on("willDestroyElement")
- _destroyed() {
+ get shouldDisplay() {
+ return this.users.length > 0;
+ }
+
+ @action
+ setupChannels() {
+ this.setupReplyChannel();
+ this.setupWhisperChannel();
+ }
+
+ willDestroy() {
+ super.willDestroy(...arguments);
+ this.unsubscribeFromChannels();
+ }
+
+ unsubscribeFromChannels() {
this.replyChannel?.unsubscribe();
this.whisperChannel?.unsubscribe();
}
+
+ setupReplyChannel() {
+ if (this.replyChannel?.name !== this.replyChannelName) {
+ this.replyChannel?.unsubscribe();
+ this.replyChannel = this.presence.getChannel(this.replyChannelName);
+ this.replyChannel.subscribe();
+ }
+ }
+
+ setupWhisperChannel() {
+ if (this.currentUser.staff) {
+ if (this.whisperChannel?.name !== this.whisperChannelName) {
+ this.whisperChannel?.unsubscribe();
+ this.whisperChannel = this.presence.getChannel(this.whisperChannelName);
+ this.whisperChannel.subscribe();
+ }
+ }
+ }
}