mirror of
https://github.com/discourse/discourse.git
synced 2024-11-29 05:53:38 +08:00
DEV: glimmerify discourse-presence (#29235)
This commit is contained in:
parent
7b8ebebe93
commit
f05b984208
|
@ -1,16 +1,22 @@
|
||||||
|
<div
|
||||||
|
{{did-insert this.setupChannels}}
|
||||||
|
{{did-update this.setupChannels @model.reply @model.whisper this.state}}
|
||||||
|
>
|
||||||
{{#if this.shouldDisplay}}
|
{{#if this.shouldDisplay}}
|
||||||
<div class="presence-users">
|
<div class="presence-users">
|
||||||
<div class="presence-avatars">
|
<div class="presence-avatars">
|
||||||
{{#each this.presenceUsers as |user|}}
|
{{#each this.users as |user|}}
|
||||||
|
<UserLink @user={{user}}>
|
||||||
{{avatar user imageSize="small"}}
|
{{avatar user imageSize="small"}}
|
||||||
|
</UserLink>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
<span class="presence-text">
|
<span class="presence-text">
|
||||||
<span class="description">
|
<span class="description">
|
||||||
{{~#if this.isReply~}}
|
{{~#if this.isReply~}}
|
||||||
{{i18n "presence.replying" count=this.presenceUsers.length}}
|
{{i18n "presence.replying" count=this.users.length}}
|
||||||
{{~else~}}
|
{{~else~}}
|
||||||
{{i18n "presence.editing" count=this.presenceUsers.length}}
|
{{i18n "presence.editing" count=this.users.length}}
|
||||||
{{~/if~}}
|
{{~/if~}}
|
||||||
</span>
|
</span>
|
||||||
<span class="wave">
|
<span class="wave">
|
||||||
|
@ -21,3 +27,4 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
</div>
|
|
@ -1,32 +1,30 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@glimmer/component";
|
||||||
import { equal, gt, readOnly, union } from "@ember/object/computed";
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import { action } from "@ember/object";
|
||||||
import { service } from "@ember/service";
|
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 ComposerPresenceDisplayComponent extends Component {
|
||||||
export default class ComposerPresenceDisplay extends Component {
|
|
||||||
@service presence;
|
@service presence;
|
||||||
@service composerPresenceManager;
|
@service composerPresenceManager;
|
||||||
|
@service currentUser;
|
||||||
|
@service siteSettings;
|
||||||
|
|
||||||
@equal("state", "reply") isReply;
|
@tracked replyChannel;
|
||||||
@equal("state", "edit") isEdit;
|
@tracked whisperChannel;
|
||||||
@equal("state", "whisper") isWhisper;
|
@tracked editChannel;
|
||||||
@union("replyChannel.users", "whisperChannel.users") replyingUsers;
|
|
||||||
@readOnly("editChannel.users") editingUsers;
|
|
||||||
@gt("presenceUsers.length", 0) shouldDisplay;
|
|
||||||
|
|
||||||
@discourseComputed(
|
get isReply() {
|
||||||
"model.replyingToTopic",
|
return this.state === "reply" || this.state === "whisper";
|
||||||
"model.editingPost",
|
}
|
||||||
"model.whisper",
|
|
||||||
"model.composerOpened"
|
get isEdit() {
|
||||||
)
|
return this.state === "edit";
|
||||||
state(replyingToTopic, editingPost, whisper, composerOpen) {
|
}
|
||||||
if (!composerOpen) {
|
|
||||||
return;
|
get state() {
|
||||||
} else if (editingPost) {
|
const { editingPost, whisper, replyingToTopic } = this.args.model;
|
||||||
|
|
||||||
|
if (editingPost) {
|
||||||
return "edit";
|
return "edit";
|
||||||
} else if (whisper) {
|
} else if (whisper) {
|
||||||
return "whisper";
|
return "whisper";
|
||||||
|
@ -35,77 +33,105 @@ export default class ComposerPresenceDisplay extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed("model.topic.id", "isReply", "isWhisper")
|
get replyChannelName() {
|
||||||
replyChannelName(topicId, isReply, isWhisper) {
|
const topicId = this.args.model?.topic?.id;
|
||||||
if (topicId && (isReply || isWhisper)) {
|
if (topicId && this.isReply) {
|
||||||
return `/discourse-presence/reply/${topicId}`;
|
return `/discourse-presence/reply/${topicId}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed("model.topic.id", "isReply", "isWhisper")
|
get whisperChannelName() {
|
||||||
whisperChannelName(topicId, isReply, isWhisper) {
|
const topicId = this.args.model?.topic?.id;
|
||||||
if (topicId && this.currentUser.whisperer && (isReply || isWhisper)) {
|
if (topicId && this.isReply && this.currentUser.whisperer) {
|
||||||
return `/discourse-presence/whisper/${topicId}`;
|
return `/discourse-presence/whisper/${topicId}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed("isEdit", "model.post.id")
|
get editChannelName() {
|
||||||
editChannelName(isEdit, postId) {
|
const postId = this.args.model?.post?.id;
|
||||||
if (isEdit) {
|
if (postId && this.isEdit) {
|
||||||
return `/discourse-presence/edit/${postId}`;
|
return `/discourse-presence/edit/${postId}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_setupChannel(channelKey, name) {
|
get replyUsers() {
|
||||||
if (this[channelKey]?.name !== name) {
|
return this.replyChannel?.users || [];
|
||||||
this[channelKey]?.unsubscribe();
|
|
||||||
if (name) {
|
|
||||||
this.set(channelKey, this.presence.getChannel(name));
|
|
||||||
this[channelKey].subscribe();
|
|
||||||
} else if (this[channelKey]) {
|
|
||||||
this.set(channelKey, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@observes("replyChannelName", "whisperChannelName", "editChannelName")
|
get whisperUsers() {
|
||||||
_setupChannels() {
|
return this.whisperChannel?.users || [];
|
||||||
this._setupChannel("replyChannel", this.replyChannelName);
|
|
||||||
this._setupChannel("whisperChannel", this.whisperChannelName);
|
|
||||||
this._setupChannel("editChannel", this.editChannelName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_cleanupChannels() {
|
get replyingUsers() {
|
||||||
this._setupChannel("replyChannel", null);
|
return [...this.replyUsers, ...this.whisperUsers];
|
||||||
this._setupChannel("whisperChannel", null);
|
|
||||||
this._setupChannel("editChannel", null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed("isReply", "replyingUsers.[]", "editingUsers.[]")
|
get editingUsers() {
|
||||||
presenceUsers(isReply, replyingUsers, editingUsers) {
|
return this.editChannel?.users || [];
|
||||||
const users = isReply ? replyingUsers : editingUsers;
|
}
|
||||||
|
|
||||||
|
get users() {
|
||||||
|
const users = this.isEdit ? this.editingUsers : this.replyingUsers;
|
||||||
return users
|
return users
|
||||||
?.filter((u) => u.id !== this.currentUser.id)
|
.filter((u) => u.id !== this.currentUser.id)
|
||||||
?.slice(0, this.siteSettings.presence_max_users_shown);
|
.slice(0, this.siteSettings.presence_max_users_shown);
|
||||||
}
|
}
|
||||||
|
|
||||||
@on("didInsertElement")
|
get shouldDisplay() {
|
||||||
subscribe() {
|
return this.users.length > 0;
|
||||||
this._setupChannels();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@observes("model.reply", "state", "model.post.id", "model.topic.id")
|
@action
|
||||||
_contentChanged() {
|
setupChannels() {
|
||||||
if (this.model.reply === "") {
|
this.setupReplyChannel();
|
||||||
return;
|
this.setupWhisperChannel();
|
||||||
|
this.setupEditChannel();
|
||||||
|
this.notifyState();
|
||||||
}
|
}
|
||||||
const entity = this.state === "edit" ? this.model?.post : this.model?.topic;
|
|
||||||
|
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[key] = this.presence.getChannel(name);
|
||||||
|
this[key].subscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyState() {
|
||||||
|
const { reply, post, topic } = this.args.model;
|
||||||
|
const raw = this.isEdit ? post?.raw || "" : "";
|
||||||
|
const entity = this.isEdit ? post : topic;
|
||||||
|
|
||||||
|
if (reply !== raw) {
|
||||||
this.composerPresenceManager.notifyState(this.state, entity?.id);
|
this.composerPresenceManager.notifyState(this.state, entity?.id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@on("willDestroyElement")
|
willDestroy() {
|
||||||
closeComposer() {
|
super.willDestroy(...arguments);
|
||||||
this._cleanupChannels();
|
this.unsubscribeFromChannels();
|
||||||
this.composerPresenceManager.leave();
|
this.composerPresenceManager.leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsubscribeFromChannels() {
|
||||||
|
this.replyChannel?.unsubscribe();
|
||||||
|
this.whisperChannel?.unsubscribe();
|
||||||
|
this.editChannel?.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
<div
|
||||||
|
{{did-insert this.setupChannels}}
|
||||||
|
{{did-update this.setupChannels @topic.id}}
|
||||||
|
>
|
||||||
{{#if this.shouldDisplay}}
|
{{#if this.shouldDisplay}}
|
||||||
<div class="presence-users">
|
<div class="presence-users">
|
||||||
<div class="presence-avatars">
|
<div class="presence-avatars">
|
||||||
|
@ -19,3 +23,4 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
</div>
|
|
@ -1,64 +1,72 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@glimmer/component";
|
||||||
import { gt, union } from "@ember/object/computed";
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import { action } from "@ember/object";
|
||||||
import { service } from "@ember/service";
|
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 presence;
|
||||||
|
@service currentUser;
|
||||||
|
|
||||||
topic = null;
|
@tracked replyChannel;
|
||||||
replyChannel = null;
|
@tracked whisperChannel;
|
||||||
whisperChannel = null;
|
|
||||||
|
|
||||||
@union("replyUsers", "whisperUsers") users;
|
get replyChannelName() {
|
||||||
@gt("users.length", 0) shouldDisplay;
|
return `/discourse-presence/reply/${this.args.topic.id}`;
|
||||||
|
|
||||||
@discourseComputed("replyChannel.users.[]")
|
|
||||||
replyUsers(users) {
|
|
||||||
return users?.filter((u) => u.id !== this.currentUser.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed("whisperChannel.users.[]")
|
get whisperChannelName() {
|
||||||
whisperUsers(users) {
|
return `/discourse-presence/whisper/${this.args.topic.id}`;
|
||||||
return users?.filter((u) => u.id !== this.currentUser.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed("topic.id")
|
get replyUsers() {
|
||||||
replyChannelName(id) {
|
return this.replyChannel?.users || [];
|
||||||
return `/discourse-presence/reply/${id}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed("topic.id")
|
get whisperUsers() {
|
||||||
whisperChannelName(id) {
|
return this.whisperChannel?.users || [];
|
||||||
return `/discourse-presence/whisper/${id}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
didReceiveAttrs() {
|
get users() {
|
||||||
super.didReceiveAttrs(...arguments);
|
return [...this.replyUsers, ...this.whisperUsers].filter(
|
||||||
|
(u) => u.id !== this.currentUser.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
if (this.replyChannel?.name !== this.replyChannelName) {
|
||||||
this.replyChannel?.unsubscribe();
|
this.replyChannel?.unsubscribe();
|
||||||
this.set("replyChannel", this.presence.getChannel(this.replyChannelName));
|
this.replyChannel = this.presence.getChannel(this.replyChannelName);
|
||||||
this.replyChannel.subscribe();
|
this.replyChannel.subscribe();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
setupWhisperChannel() {
|
||||||
this.currentUser.staff &&
|
if (this.currentUser.staff) {
|
||||||
this.whisperChannel?.name !== this.whisperChannelName
|
if (this.whisperChannel?.name !== this.whisperChannelName) {
|
||||||
) {
|
|
||||||
this.whisperChannel?.unsubscribe();
|
this.whisperChannel?.unsubscribe();
|
||||||
this.set(
|
this.whisperChannel = this.presence.getChannel(this.whisperChannelName);
|
||||||
"whisperChannel",
|
|
||||||
this.presence.getChannel(this.whisperChannelName)
|
|
||||||
);
|
|
||||||
this.whisperChannel.subscribe();
|
this.whisperChannel.subscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@on("willDestroyElement")
|
|
||||||
_destroyed() {
|
|
||||||
this.replyChannel?.unsubscribe();
|
|
||||||
this.whisperChannel?.unsubscribe();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user