This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/plugins/chat/assets/javascripts/discourse/services/chat-subscriptions-manager.js
Martin Brennan db5ad34508
FEATURE: Allow editing channel slug (#19948)
This commit introduces the ability to edit the channel
slug from the About tab for the chat channel when the user
is admin. Similar to the create channel modal functionality
introduced in 641e94f, if
the slug is left empty then we autogenerate a slug based
on the channel name, and if the user just changes the slug
manually we use that instead.

We do not do any link remapping or anything else of the
sort, when the category slug is changed that does not happen
either.
2023-01-30 13:18:34 +10:00

311 lines
8.6 KiB
JavaScript

import Service, { inject as service } from "@ember/service";
import { bind } from "discourse-common/utils/decorators";
import { CHANNEL_STATUSES } from "discourse/plugins/chat/discourse/models/chat-channel";
export default class ChatSubscriptionsManager extends Service {
@service store;
@service chatChannelsManager;
@service currentUser;
@service appEvents;
_channelSubscriptions = new Set();
startChannelSubscription(channel) {
if (
channel.currentUserMembership.muted ||
this._channelSubscriptions.has(channel.id)
) {
return;
}
this._channelSubscriptions.add(channel.id);
if (!channel.isDirectMessageChannel) {
this._startChannelMentionsSubscription(channel);
}
this._startChannelNewMessagesSubscription(channel);
}
stopChannelSubscription(channel) {
this.messageBus.unsubscribe(
`/chat/${channel.id}/new-messages`,
this._onNewMessages
);
if (!channel.isDirectMessageChannel) {
this.messageBus.unsubscribe(
`/chat/${channel.id}/new-mentions`,
this._onNewMentions
);
}
this._channelSubscriptions.delete(channel.id);
}
startChannelsSubscriptions(messageBusIds) {
this._startNewChannelSubscription(messageBusIds.new_channel);
this._startChannelArchiveStatusSubscription(messageBusIds.archive_status);
this._startUserTrackingStateSubscription(messageBusIds.user_tracking_state);
this._startChannelsEditsSubscription(messageBusIds.channel_edits);
this._startChannelsStatusChangesSubscription(messageBusIds.channel_status);
this._startChannelsMetadataChangesSubscription(
messageBusIds.channel_metadata
);
}
stopChannelsSubscriptions() {
this._stopNewChannelSubscription();
this._stopChannelArchiveStatusSubscription();
this._stopUserTrackingStateSubscription();
this._stopChannelsEditsSubscription();
this._stopChannelsStatusChangesSubscription();
this._stopChannelsMetadataChangesSubscription();
(this.chatChannelsManager.channels || []).forEach((channel) => {
this.stopChannelSubscription(channel);
});
}
_startChannelArchiveStatusSubscription(lastId) {
if (this.currentUser.admin) {
this.messageBus.subscribe(
"/chat/channel-archive-status",
this._onChannelArchiveStatusUpdate,
lastId
);
}
}
_stopChannelArchiveStatusSubscription() {
if (this.currentUser.admin) {
this.messageBus.unsubscribe(
"/chat/channel-archive-status",
this._onChannelArchiveStatusUpdate
);
}
}
_startChannelMentionsSubscription(channel) {
this.messageBus.subscribe(
`/chat/${channel.id}/new-mentions`,
this._onNewMentions,
channel.meta.message_bus_last_ids.new_mentions
);
}
@bind
_onChannelArchiveStatusUpdate(busData) {
// we don't want to fetch a channel we don't have locally because archive status changed
this.chatChannelsManager
.find(busData.chat_channel_id, { fetchIfNotFound: false })
.then((channel) => {
if (!channel) {
return;
}
channel.setProperties({
archive_failed: busData.archive_failed,
archive_completed: busData.archive_completed,
archived_messages: busData.archived_messages,
archive_topic_id: busData.archive_topic_id,
total_messages: busData.total_messages,
});
});
}
@bind
_onNewMentions(busData) {
this.chatChannelsManager.find(busData.channel_id).then((channel) => {
const membership = channel.currentUserMembership;
if (busData.message_id > membership?.last_read_message_id) {
membership.unread_mentions = (membership.unread_mentions || 0) + 1;
}
});
}
_startChannelNewMessagesSubscription(channel) {
this.messageBus.subscribe(
`/chat/${channel.id}/new-messages`,
this._onNewMessages,
channel.meta.message_bus_last_ids.new_messages
);
}
@bind
_onNewMessages(busData) {
this.chatChannelsManager.find(busData.channel_id).then((channel) => {
if (busData.user_id === this.currentUser.id) {
// User sent message, update tracking state to no unread
channel.currentUserMembership.last_read_message_id = busData.message_id;
} else {
// Ignored user sent message, update tracking state to no unread
if (this.currentUser.ignored_users.includes(busData.username)) {
channel.currentUserMembership.last_read_message_id =
busData.message_id;
} else {
// Message from other user. Increment trackings state
if (
busData.message_id >
(channel.currentUserMembership.last_read_message_id || 0)
) {
channel.currentUserMembership.unread_count =
channel.currentUserMembership.unread_count + 1;
}
}
}
channel.set("last_message_sent_at", new Date());
});
}
_startUserTrackingStateSubscription(lastId) {
if (!this.currentUser) {
return;
}
this.messageBus.subscribe(
`/chat/user-tracking-state/${this.currentUser.id}`,
this._onUserTrackingStateUpdate,
lastId
);
}
_stopUserTrackingStateSubscription() {
if (!this.currentUser) {
return;
}
this.messageBus.unsubscribe(
`/chat/user-tracking-state/${this.currentUser.id}`,
this._onUserTrackingStateUpdate
);
}
@bind
_onUserTrackingStateUpdate(busData) {
this.chatChannelsManager.find(busData.chat_channel_id).then((channel) => {
if (
channel?.currentUserMembership?.last_read_message_id <=
busData.chat_message_id
) {
channel.currentUserMembership.last_read_message_id =
busData.chat_message_id;
channel.currentUserMembership.unread_count = 0;
channel.currentUserMembership.unread_mentions = 0;
}
});
}
_startNewChannelSubscription(lastId) {
this.messageBus.subscribe(
"/chat/new-channel",
this._onNewChannelSubscription,
lastId
);
}
_stopNewChannelSubscription() {
this.messageBus.unsubscribe(
"/chat/new-channel",
this._onNewChannelSubscription
);
}
@bind
_onNewChannelSubscription(data) {
this.chatChannelsManager.find(data.channel.id).then((channel) => {
// we need to refrehs here to have correct last message ids
channel.meta = data.channel.meta;
if (
channel.isDirectMessageChannel &&
!channel.currentUserMembership.following
) {
channel.currentUserMembership.unread_count = 1;
}
this.chatChannelsManager.follow(channel);
});
}
_startChannelsMetadataChangesSubscription(lastId) {
this.messageBus.subscribe(
"/chat/channel-metadata",
this._onChannelMetadata,
lastId
);
}
_startChannelsEditsSubscription(lastId) {
this.messageBus.subscribe(
"/chat/channel-edits",
this._onChannelEdits,
lastId
);
}
_startChannelsStatusChangesSubscription(lastId) {
this.messageBus.subscribe(
"/chat/channel-status",
this._onChannelStatus,
lastId
);
}
_stopChannelsStatusChangesSubscription() {
this.messageBus.unsubscribe("/chat/channel-status", this._onChannelStatus);
}
_stopChannelsEditsSubscription() {
this.messageBus.unsubscribe("/chat/channel-edits", this._onChannelEdits);
}
_stopChannelsMetadataChangesSubscription() {
this.messageBus.unsubscribe(
"/chat/channel-metadata",
this._onChannelMetadata
);
}
@bind
_onChannelMetadata(busData) {
this.chatChannelsManager.find(busData.chat_channel_id).then((channel) => {
if (channel) {
channel.setProperties({
memberships_count: busData.memberships_count,
});
this.appEvents.trigger("chat:refresh-channel-members");
}
});
}
@bind
_onChannelEdits(busData) {
this.chatChannelsManager.find(busData.chat_channel_id).then((channel) => {
if (channel) {
channel.setProperties({
title: busData.name,
description: busData.description,
slug: busData.slug,
});
}
});
}
@bind
_onChannelStatus(busData) {
this.chatChannelsManager.find(busData.chat_channel_id).then((channel) => {
channel.set("status", busData.status);
// it is not possible for the user to set their last read message id
// if the channel has been archived, because all the messages have
// been deleted. we don't want them seeing the blue dot anymore so
// just completely reset the unreads
if (busData.status === CHANNEL_STATUSES.archived) {
channel.currentUserMembership.unread_count = 0;
channel.currentUserMembership.unread_mentions = 0;
}
});
}
}