mirror of
https://github.com/discourse/discourse.git
synced 2025-06-05 23:44:48 +08:00
This reverts commit 38ab3f23493e314b3658c4b1392688fdad2447ba.
This commit is contained in:
@ -1,149 +0,0 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { cached, tracked } from "@glimmer/tracking";
|
||||
import { service } from "@ember/service";
|
||||
import { modifier } from "ember-modifier";
|
||||
import { gt } from "truth-helpers";
|
||||
import UserLink from "discourse/components/user-link";
|
||||
import avatar from "discourse/helpers/avatar";
|
||||
import i18n from "discourse-common/helpers/i18n";
|
||||
|
||||
export default class ComposerPresenceDisplay extends Component {
|
||||
@service presence;
|
||||
@service composerPresenceManager;
|
||||
@service currentUser;
|
||||
@service siteSettings;
|
||||
|
||||
@tracked replyChannel;
|
||||
@tracked whisperChannel;
|
||||
@tracked editChannel;
|
||||
|
||||
setupReplyChannel = modifier(() => {
|
||||
const topic = this.args.model.topic;
|
||||
if (!topic || !this.isReply) {
|
||||
return;
|
||||
}
|
||||
|
||||
const replyChannel = this.presence.getChannel(
|
||||
`/discourse-presence/reply/${topic.id}`
|
||||
);
|
||||
replyChannel.subscribe();
|
||||
this.replyChannel = replyChannel;
|
||||
|
||||
return () => replyChannel.unsubscribe();
|
||||
});
|
||||
|
||||
setupWhisperChannel = modifier(() => {
|
||||
if (
|
||||
!this.args.model.topic ||
|
||||
!this.isReply ||
|
||||
!this.currentUser.staff ||
|
||||
!this.currentUser.whisperer
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const whisperChannel = this.presence.getChannel(
|
||||
`/discourse-presence/whisper/${this.args.model.topic.id}`
|
||||
);
|
||||
whisperChannel.subscribe();
|
||||
this.whisperChannel = whisperChannel;
|
||||
|
||||
return () => whisperChannel.unsubscribe();
|
||||
});
|
||||
|
||||
setupEditChannel = modifier(() => {
|
||||
if (!this.args.model.post || !this.isEdit) {
|
||||
return;
|
||||
}
|
||||
|
||||
const editChannel = this.presence.getChannel(
|
||||
`/discourse-presence/edit/${this.args.model.post.id}`
|
||||
);
|
||||
editChannel.subscribe();
|
||||
this.editChannel = editChannel;
|
||||
|
||||
return () => editChannel.unsubscribe();
|
||||
});
|
||||
|
||||
notifyState = modifier(() => {
|
||||
const { topic, post, reply } = 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);
|
||||
}
|
||||
|
||||
return () => this.composerPresenceManager.leave();
|
||||
});
|
||||
|
||||
get isReply() {
|
||||
return this.state === "reply" || this.state === "whisper";
|
||||
}
|
||||
|
||||
get isEdit() {
|
||||
return this.state === "edit";
|
||||
}
|
||||
|
||||
get state() {
|
||||
if (this.args.model.editingPost) {
|
||||
return "edit";
|
||||
} else if (this.args.model.whisper) {
|
||||
return "whisper";
|
||||
} else if (this.args.model.replyingToTopic) {
|
||||
return "reply";
|
||||
}
|
||||
}
|
||||
|
||||
@cached
|
||||
get users() {
|
||||
let users;
|
||||
if (this.isEdit) {
|
||||
users = this.editChannel?.users || [];
|
||||
} else {
|
||||
const replyUsers = this.replyChannel?.users || [];
|
||||
const whisperUsers = this.whisperChannel?.users || [];
|
||||
users = [...replyUsers, ...whisperUsers];
|
||||
}
|
||||
|
||||
return users
|
||||
.filter((u) => u.id !== this.currentUser.id)
|
||||
.slice(0, this.siteSettings.presence_max_users_shown);
|
||||
}
|
||||
|
||||
<template>
|
||||
<div
|
||||
{{this.setupReplyChannel}}
|
||||
{{this.setupWhisperChannel}}
|
||||
{{this.setupEditChannel}}
|
||||
{{this.notifyState}}
|
||||
>
|
||||
{{#if (gt this.users.length 0)}}
|
||||
<div class="presence-users">
|
||||
<div class="presence-avatars">
|
||||
{{#each this.users as |user|}}
|
||||
<UserLink @user={{user}}>
|
||||
{{avatar user imageSize="small"}}
|
||||
</UserLink>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<span class="presence-text">
|
||||
<span class="description">
|
||||
{{~#if this.isReply~}}
|
||||
{{i18n "presence.replying" count=this.users.length}}
|
||||
{{~else~}}
|
||||
{{i18n "presence.editing" count=this.users.length}}
|
||||
{{~/if~}}
|
||||
</span>
|
||||
<span class="wave">
|
||||
<span class="dot">.</span>
|
||||
<span class="dot">.</span>
|
||||
<span class="dot">.</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</template>
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
<div
|
||||
{{did-insert this.setupChannels}}
|
||||
{{did-update this.setupChannels @model.reply @model.whisper this.state}}
|
||||
>
|
||||
{{#if this.shouldDisplay}}
|
||||
<div class="presence-users">
|
||||
<div class="presence-avatars">
|
||||
{{#each this.users as |user|}}
|
||||
<UserLink @user={{user}}>
|
||||
{{avatar user imageSize="small"}}
|
||||
</UserLink>
|
||||
{{/each}}
|
||||
</div>
|
||||
<span class="presence-text">
|
||||
<span class="description">
|
||||
{{~#if this.isReply~}}
|
||||
{{i18n "presence.replying" count=this.users.length}}
|
||||
{{~else~}}
|
||||
{{i18n "presence.editing" count=this.users.length}}
|
||||
{{~/if~}}
|
||||
</span>
|
||||
<span class="wave">
|
||||
<span class="dot">.</span>
|
||||
<span class="dot">.</span>
|
||||
<span class="dot">.</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
@ -0,0 +1,137 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { action } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
|
||||
export default class ComposerPresenceDisplayComponent extends Component {
|
||||
@service presence;
|
||||
@service composerPresenceManager;
|
||||
@service currentUser;
|
||||
@service siteSettings;
|
||||
|
||||
@tracked replyChannel;
|
||||
@tracked whisperChannel;
|
||||
@tracked editChannel;
|
||||
|
||||
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";
|
||||
} else if (replyingToTopic) {
|
||||
return "reply";
|
||||
}
|
||||
}
|
||||
|
||||
get replyChannelName() {
|
||||
const topicId = this.args.model?.topic?.id;
|
||||
if (topicId && this.isReply) {
|
||||
return `/discourse-presence/reply/${topicId}`;
|
||||
}
|
||||
}
|
||||
|
||||
get whisperChannelName() {
|
||||
const topicId = this.args.model?.topic?.id;
|
||||
if (topicId && this.isReply && this.currentUser.whisperer) {
|
||||
return `/discourse-presence/whisper/${topicId}`;
|
||||
}
|
||||
}
|
||||
|
||||
get editChannelName() {
|
||||
const postId = this.args.model?.post?.id;
|
||||
if (postId && this.isEdit) {
|
||||
return `/discourse-presence/edit/${postId}`;
|
||||
}
|
||||
}
|
||||
|
||||
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[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);
|
||||
}
|
||||
}
|
||||
|
||||
willDestroy() {
|
||||
super.willDestroy(...arguments);
|
||||
this.unsubscribeFromChannels();
|
||||
this.composerPresenceManager.leave();
|
||||
}
|
||||
|
||||
unsubscribeFromChannels() {
|
||||
this.replyChannel?.unsubscribe();
|
||||
this.whisperChannel?.unsubscribe();
|
||||
this.editChannel?.unsubscribe();
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { cached, tracked } from "@glimmer/tracking";
|
||||
import { service } from "@ember/service";
|
||||
import { modifier } from "ember-modifier";
|
||||
import { gt } from "truth-helpers";
|
||||
import UserLink from "discourse/components/user-link";
|
||||
import avatar from "discourse/helpers/avatar";
|
||||
import i18n from "discourse-common/helpers/i18n";
|
||||
|
||||
export default class TopicPresenceDisplay extends Component {
|
||||
@service presence;
|
||||
@service currentUser;
|
||||
|
||||
@tracked replyChannel;
|
||||
@tracked whisperChannel;
|
||||
|
||||
setupReplyChannel = modifier(() => {
|
||||
const replyChannel = this.presence.getChannel(
|
||||
`/discourse-presence/reply/${this.args.topic.id}`
|
||||
);
|
||||
replyChannel.subscribe();
|
||||
this.replyChannel = replyChannel;
|
||||
|
||||
return () => replyChannel.unsubscribe();
|
||||
});
|
||||
|
||||
setupWhisperChannels = modifier(() => {
|
||||
if (!this.currentUser.staff) {
|
||||
return;
|
||||
}
|
||||
|
||||
const whisperChannel = this.presence.getChannel(
|
||||
`/discourse-presence/whisper/${this.args.topic.id}`
|
||||
);
|
||||
whisperChannel.subscribe();
|
||||
this.whisperChannel = whisperChannel;
|
||||
|
||||
return () => whisperChannel.unsubscribe();
|
||||
});
|
||||
|
||||
@cached
|
||||
get users() {
|
||||
const replyUsers = this.replyChannel?.users || [];
|
||||
const whisperUsers = this.whisperChannel?.users || [];
|
||||
|
||||
return [...replyUsers, ...whisperUsers].filter(
|
||||
(u) => u.id !== this.currentUser.id
|
||||
);
|
||||
}
|
||||
|
||||
<template>
|
||||
<div {{this.setupReplyChannel}} {{this.setupWhisperChannels}}>
|
||||
{{#if (gt this.users.length 0)}}
|
||||
<div class="presence-users">
|
||||
<div class="presence-avatars">
|
||||
{{#each this.users as |user|}}
|
||||
<UserLink @user={{user}}>
|
||||
{{avatar user imageSize="small"}}
|
||||
</UserLink>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<span class="presence-text">
|
||||
<span class="description">
|
||||
{{i18n "presence.replying_to_topic" count=this.users.length}}
|
||||
</span>
|
||||
<span class="wave">
|
||||
<span class="dot">.</span>
|
||||
<span class="dot">.</span>
|
||||
<span class="dot">.</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</template>
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<div
|
||||
{{did-insert this.setupChannels}}
|
||||
{{did-update this.setupChannels @topic.id}}
|
||||
>
|
||||
{{#if this.shouldDisplay}}
|
||||
<div class="presence-users">
|
||||
<div class="presence-avatars">
|
||||
{{#each this.users as |user|}}
|
||||
<UserLink @user={{user}}>
|
||||
{{avatar user imageSize="small"}}
|
||||
</UserLink>
|
||||
{{/each}}
|
||||
</div>
|
||||
<span class="presence-text">
|
||||
<span class="description">
|
||||
{{i18n "presence.replying_to_topic" count=this.users.length}}
|
||||
</span>
|
||||
<span class="wave">
|
||||
<span class="dot">.</span>
|
||||
<span class="dot">.</span>
|
||||
<span class="dot">.</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
@ -0,0 +1,72 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { action } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
|
||||
export default class TopicPresenceDisplayComponent extends Component {
|
||||
@service presence;
|
||||
@service currentUser;
|
||||
|
||||
@tracked replyChannel;
|
||||
@tracked whisperChannel;
|
||||
|
||||
get replyChannelName() {
|
||||
return `/discourse-presence/reply/${this.args.topic.id}`;
|
||||
}
|
||||
|
||||
get whisperChannelName() {
|
||||
return `/discourse-presence/whisper/${this.args.topic.id}`;
|
||||
}
|
||||
|
||||
get replyUsers() {
|
||||
return this.replyChannel?.users || [];
|
||||
}
|
||||
|
||||
get whisperUsers() {
|
||||
return this.whisperChannel?.users || [];
|
||||
}
|
||||
|
||||
get users() {
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
<ComposerPresenceDisplay @model={{@outletArgs.model}} />
|
||||
<ComposerPresenceDisplay @model={{this.model}} />
|
@ -1,2 +1,2 @@
|
||||
{{! Note: the topic-above-footer-buttons outlet is only rendered for logged-in users }}
|
||||
<TopicPresenceDisplay @topic={{@outletArgs.model}} />
|
||||
<TopicPresenceDisplay @topic={{this.model}} />
|
Reference in New Issue
Block a user