mirror of
https://github.com/discourse/discourse.git
synced 2024-12-19 10:54:01 +08:00
DEV: Deleted the "ChatComposerPresenceManager"... (#30098)
...since it was mostly duplicating the work the "ComposerPresenceManager" was doing. So now the #chat composer uses the same "presence manager" as the composer, benefiting from the "hide presence" checks, with the only difference that the "keep alive" timeout is 5s for chat and 10s for topics/posts.
This commit is contained in:
parent
838d7478c1
commit
1ce12ae718
|
@ -54,7 +54,6 @@ export default class ChatChannel extends Component {
|
|||
@service chat;
|
||||
@service chatApi;
|
||||
@service chatChannelsManager;
|
||||
@service chatComposerPresenceManager;
|
||||
@service chatDraftsManager;
|
||||
@service chatEmojiPickerManager;
|
||||
@service chatStateManager;
|
||||
|
|
|
@ -30,13 +30,15 @@ import { chatComposerButtons } from "discourse/plugins/chat/discourse/lib/chat-c
|
|||
import ChatMessageInteractor from "discourse/plugins/chat/discourse/lib/chat-message-interactor";
|
||||
import TextareaInteractor from "discourse/plugins/chat/discourse/lib/textarea-interactor";
|
||||
|
||||
const CHAT_PRESENCE_KEEP_ALIVE = 5 * 1000; // 5 seconds
|
||||
|
||||
export default class ChatComposer extends Component {
|
||||
@service capabilities;
|
||||
@service site;
|
||||
@service siteSettings;
|
||||
@service store;
|
||||
@service chat;
|
||||
@service chatComposerPresenceManager;
|
||||
@service composerPresenceManager;
|
||||
@service chatComposerWarningsTracker;
|
||||
@service appEvents;
|
||||
@service chatEmojiReactionStore;
|
||||
|
@ -256,9 +258,10 @@ export default class ChatComposer extends Component {
|
|||
return;
|
||||
}
|
||||
|
||||
this.chatComposerPresenceManager.notifyState(
|
||||
this.composerPresenceManager.notifyState(
|
||||
this.presenceChannelName,
|
||||
!this.draft.editing && this.hasContent
|
||||
!this.draft.editing && this.hasContent,
|
||||
CHAT_PRESENCE_KEEP_ALIVE
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ export default class ChatThread extends Component {
|
|||
@service capabilities;
|
||||
@service chat;
|
||||
@service chatApi;
|
||||
@service chatComposerPresenceManager;
|
||||
@service chatHistory;
|
||||
@service chatDraftsManager;
|
||||
@service chatThreadComposer;
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
import { cancel, debounce } from "@ember/runloop";
|
||||
import Service, { service } from "@ember/service";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
|
||||
const KEEP_ALIVE_DURATION_SECONDS = 10;
|
||||
|
||||
// This service is loosely based on discourse-presence's ComposerPresenceManager service
|
||||
// It is a singleton which receives notifications each time the value of the chat composer changes
|
||||
// This service ensures that a single browser can only be 'replying' to a single chatChannel at
|
||||
// one time, and automatically 'leaves' the channel if the composer value hasn't changed for 10 seconds
|
||||
export default class ChatComposerPresenceManager extends Service {
|
||||
@service presence;
|
||||
|
||||
willDestroy() {
|
||||
this.leave();
|
||||
}
|
||||
|
||||
notifyState(channelName, replying) {
|
||||
if (!replying) {
|
||||
this.leave();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._channelName !== channelName) {
|
||||
this._enter(channelName);
|
||||
this._channelName = channelName;
|
||||
}
|
||||
|
||||
if (!isTesting()) {
|
||||
this._autoLeaveTimer = debounce(
|
||||
this,
|
||||
this.leave,
|
||||
KEEP_ALIVE_DURATION_SECONDS * 1000
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
leave() {
|
||||
this._presentChannel?.leave();
|
||||
this._presentChannel = null;
|
||||
this._channelName = null;
|
||||
if (this._autoLeaveTimer) {
|
||||
cancel(this._autoLeaveTimer);
|
||||
this._autoLeaveTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
_enter(channelName) {
|
||||
this.leave();
|
||||
|
||||
this._presentChannel = this.presence.getChannel(channelName);
|
||||
this._presentChannel.enter();
|
||||
}
|
||||
}
|
|
@ -18,60 +18,58 @@ export default class ComposerPresenceDisplay extends Component {
|
|||
@tracked editChannel;
|
||||
|
||||
setupReplyChannel = helperFn((_, on) => {
|
||||
const topic = this.args.model.topic;
|
||||
const { topic } = this.args.model;
|
||||
|
||||
if (!topic || !this.isReply) {
|
||||
return;
|
||||
}
|
||||
|
||||
const replyChannel = this.presence.getChannel(
|
||||
`/discourse-presence/reply/${topic.id}`
|
||||
);
|
||||
replyChannel.subscribe();
|
||||
const name = `/discourse-presence/reply/${topic.id}`;
|
||||
const replyChannel = this.presence.getChannel(name);
|
||||
this.replyChannel = replyChannel;
|
||||
|
||||
replyChannel.subscribe();
|
||||
on.cleanup(() => replyChannel.unsubscribe());
|
||||
});
|
||||
|
||||
setupWhisperChannel = helperFn((_, on) => {
|
||||
if (
|
||||
!this.args.model.topic ||
|
||||
!this.isReply ||
|
||||
!this.currentUser.staff ||
|
||||
!this.currentUser.whisperer
|
||||
) {
|
||||
const { topic } = this.args.model;
|
||||
const { whisperer } = this.currentUser;
|
||||
|
||||
if (!topic || !this.isReply || !whisperer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const whisperChannel = this.presence.getChannel(
|
||||
`/discourse-presence/whisper/${this.args.model.topic.id}`
|
||||
);
|
||||
whisperChannel.subscribe();
|
||||
const name = `/discourse-presence/whisper/${topic.id}`;
|
||||
const whisperChannel = this.presence.getChannel(name);
|
||||
this.whisperChannel = whisperChannel;
|
||||
|
||||
whisperChannel.subscribe();
|
||||
on.cleanup(() => whisperChannel.unsubscribe());
|
||||
});
|
||||
|
||||
setupEditChannel = helperFn((_, on) => {
|
||||
if (!this.args.model.post || !this.isEdit) {
|
||||
const { post } = this.args.model;
|
||||
|
||||
if (!post || !this.isEdit) {
|
||||
return;
|
||||
}
|
||||
|
||||
const editChannel = this.presence.getChannel(
|
||||
`/discourse-presence/edit/${this.args.model.post.id}`
|
||||
);
|
||||
editChannel.subscribe();
|
||||
const name = `/discourse-presence/edit/${post.id}`;
|
||||
const editChannel = this.presence.getChannel(name);
|
||||
this.editChannel = editChannel;
|
||||
|
||||
editChannel.subscribe();
|
||||
on.cleanup(() => editChannel.unsubscribe());
|
||||
});
|
||||
|
||||
notifyState = helperFn((_, on) => {
|
||||
const { topic, post, reply } = this.args.model;
|
||||
const raw = this.isEdit ? post?.raw || "" : "";
|
||||
const { topic, post, replyDirty } = this.args.model;
|
||||
const entity = this.isEdit ? post : topic;
|
||||
|
||||
if (reply !== raw) {
|
||||
this.composerPresenceManager.notifyState(this.state, entity?.id);
|
||||
if (entity) {
|
||||
const name = `/discourse-presence/${this.state}/${entity.id}`;
|
||||
this.composerPresenceManager.notifyState(name, replyDirty);
|
||||
}
|
||||
|
||||
on.cleanup(() => this.composerPresenceManager.leave());
|
||||
|
@ -85,12 +83,15 @@ export default class ComposerPresenceDisplay extends Component {
|
|||
return this.state === "edit";
|
||||
}
|
||||
|
||||
@cached
|
||||
get state() {
|
||||
if (this.args.model.editingPost) {
|
||||
const { editingPost, whisper, replyingToTopic } = this.args.model;
|
||||
|
||||
if (editingPost) {
|
||||
return "edit";
|
||||
} else if (this.args.model.whisper) {
|
||||
} else if (whisper) {
|
||||
return "whisper";
|
||||
} else if (this.args.model.replyingToTopic) {
|
||||
} else if (replyingToTopic) {
|
||||
return "reply";
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +99,7 @@ export default class ComposerPresenceDisplay extends Component {
|
|||
@cached
|
||||
get users() {
|
||||
let users;
|
||||
|
||||
if (this.isEdit) {
|
||||
users = this.editChannel?.users || [];
|
||||
} else {
|
||||
|
|
|
@ -15,26 +15,33 @@ export default class TopicPresenceDisplay extends Component {
|
|||
@tracked whisperChannel;
|
||||
|
||||
setupReplyChannel = helperFn((_, on) => {
|
||||
const replyChannel = this.presence.getChannel(
|
||||
`/discourse-presence/reply/${this.args.topic.id}`
|
||||
);
|
||||
replyChannel.subscribe();
|
||||
this.replyChannel = replyChannel;
|
||||
const { topic } = this.args;
|
||||
|
||||
on.cleanup(() => replyChannel.unsubscribe());
|
||||
});
|
||||
|
||||
setupWhisperChannels = helperFn((_, on) => {
|
||||
if (!this.currentUser.staff) {
|
||||
if (!topic) {
|
||||
return;
|
||||
}
|
||||
|
||||
const whisperChannel = this.presence.getChannel(
|
||||
`/discourse-presence/whisper/${this.args.topic.id}`
|
||||
);
|
||||
whisperChannel.subscribe();
|
||||
const name = `/discourse-presence/reply/${topic.id}`;
|
||||
const replyChannel = this.presence.getChannel(name);
|
||||
this.replyChannel = replyChannel;
|
||||
|
||||
replyChannel.subscribe();
|
||||
on.cleanup(() => replyChannel.unsubscribe());
|
||||
});
|
||||
|
||||
setupWhisperChannel = helperFn((_, on) => {
|
||||
const { topic } = this.args;
|
||||
const { whisperer } = this.currentUser;
|
||||
|
||||
if (!topic || !whisperer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const name = `/discourse-presence/whisper/${topic.id}`;
|
||||
const whisperChannel = this.presence.getChannel(name);
|
||||
this.whisperChannel = whisperChannel;
|
||||
|
||||
whisperChannel.subscribe();
|
||||
on.cleanup(() => whisperChannel.unsubscribe());
|
||||
});
|
||||
|
||||
|
@ -50,7 +57,7 @@ export default class TopicPresenceDisplay extends Component {
|
|||
|
||||
<template>
|
||||
{{this.setupReplyChannel}}
|
||||
{{this.setupWhisperChannels}}
|
||||
{{this.setupWhisperChannel}}
|
||||
|
||||
{{#if (gt this.users.length 0)}}
|
||||
<div class="presence-users">
|
||||
|
|
|
@ -2,63 +2,47 @@ import { cancel, debounce } from "@ember/runloop";
|
|||
import Service, { service } from "@ember/service";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
|
||||
const PRESENCE_CHANNEL_PREFIX = "/discourse-presence";
|
||||
const KEEP_ALIVE_DURATION_SECONDS = 10;
|
||||
const KEEP_ALIVE = 10 * 1000; // 10 seconds
|
||||
|
||||
export default class ComposerPresenceManager extends Service {
|
||||
@service currentUser;
|
||||
@service presence;
|
||||
@service siteSettings;
|
||||
|
||||
willDestroy() {
|
||||
this.leave();
|
||||
}
|
||||
|
||||
notifyState(intent, id) {
|
||||
if (
|
||||
this.siteSettings.allow_users_to_hide_profile &&
|
||||
this.currentUser.user_option.hide_presence
|
||||
) {
|
||||
notifyState(name, replying = true, keepAlive = KEEP_ALIVE) {
|
||||
if (!replying) {
|
||||
this.leave();
|
||||
return;
|
||||
}
|
||||
|
||||
if (intent === undefined) {
|
||||
return this.leave();
|
||||
const canHideProfile = this.siteSettings.allow_users_to_hide_profile;
|
||||
const isHidingPresence = this.currentUser.user_option.hide_presence;
|
||||
|
||||
if (canHideProfile && isHidingPresence) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!["reply", "whisper", "edit"].includes(intent)) {
|
||||
throw `Unknown intent ${intent}`;
|
||||
}
|
||||
if (this._name !== name) {
|
||||
this.leave();
|
||||
|
||||
const state = `${intent}/${id}`;
|
||||
this._name = name;
|
||||
this._channel = this.presence.getChannel(name);
|
||||
this._channel.enter();
|
||||
|
||||
if (this._state !== state) {
|
||||
this._enter(intent, id);
|
||||
this._state = state;
|
||||
}
|
||||
|
||||
if (!isTesting()) {
|
||||
this._autoLeaveTimer = debounce(
|
||||
this,
|
||||
this.leave,
|
||||
KEEP_ALIVE_DURATION_SECONDS * 1000
|
||||
);
|
||||
if (!isTesting()) {
|
||||
this._autoLeaveTimer = debounce(this, this.leave, keepAlive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leave() {
|
||||
this._presentChannel?.leave();
|
||||
this._presentChannel = null;
|
||||
this._state = null;
|
||||
if (this._autoLeaveTimer) {
|
||||
cancel(this._autoLeaveTimer);
|
||||
this._autoLeaveTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
_enter(intent, id) {
|
||||
this.leave();
|
||||
|
||||
let channelName = `${PRESENCE_CHANNEL_PREFIX}/${intent}/${id}`;
|
||||
this._presentChannel = this.presence.getChannel(channelName);
|
||||
this._presentChannel.enter();
|
||||
this._channel?.leave();
|
||||
this._channel = null;
|
||||
this._name = null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user