mirror of
https://github.com/discourse/discourse.git
synced 2025-06-06 00:47:15 +08:00
FIX: leaving a group channel should destroy membership (#24631)
In other kind of channels we will only unfollow but for group channels we don't want people to keep appearing in members list. This commit also creates appropriate services: - `Chat::LeaveChannel` - `Chat::UnfollowChannel` And dedicated endpoint for unfollow: `DELETE /chat/api/channels/:id/memberships/me/follows`
This commit is contained in:
@ -131,7 +131,7 @@ export default class ChatChannelRow extends Component {
|
||||
}
|
||||
|
||||
get leaveDirectMessageLabel() {
|
||||
return I18n.t("chat.direct_messages.leave");
|
||||
return I18n.t("chat.direct_messages.close");
|
||||
}
|
||||
|
||||
get leaveChannelLabel() {
|
||||
|
@ -29,12 +29,14 @@ const NOTIFICATION_LEVELS = [
|
||||
export default class ChatAboutScreen extends Component {
|
||||
@service chatApi;
|
||||
@service chatGuardian;
|
||||
@service chatChannelsManager;
|
||||
@service currentUser;
|
||||
@service siteSettings;
|
||||
@service dialog;
|
||||
@service modal;
|
||||
@service site;
|
||||
@service toasts;
|
||||
@service router;
|
||||
|
||||
notificationLevels = NOTIFICATION_LEVELS;
|
||||
|
||||
@ -309,6 +311,12 @@ export default class ChatAboutScreen extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
onLeaveChannel(channel) {
|
||||
this.chatChannelsManager.remove(channel);
|
||||
return this.router.transitionTo("chat");
|
||||
}
|
||||
|
||||
@action
|
||||
onEditChannelDescription() {
|
||||
return this.modal.show(ChatModalEditChannelDescription, {
|
||||
@ -573,6 +581,7 @@ export default class ChatAboutScreen extends Component {
|
||||
<:action>
|
||||
<ToggleChannelMembershipButton
|
||||
@channel={{@channel}}
|
||||
@onLeave={{this.onLeaveChannel}}
|
||||
@options={{hash
|
||||
joinClass="btn-primary"
|
||||
leaveClass="btn-danger"
|
||||
|
@ -6,10 +6,13 @@ import DButton from "discourse/components/d-button";
|
||||
import concatClass from "discourse/helpers/concat-class";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
export default class ToggleChannelMembershipButton extends Component {
|
||||
@service chat;
|
||||
@service chatApi;
|
||||
|
||||
@tracked isLoading = false;
|
||||
onToggle = null;
|
||||
|
||||
options = {};
|
||||
|
||||
constructor() {
|
||||
@ -54,7 +57,7 @@ export default class ToggleChannelMembershipButton extends Component {
|
||||
return this.chat
|
||||
.followChannel(this.args.channel)
|
||||
.then(() => {
|
||||
this.onToggle?.();
|
||||
this.args.onJoin?.(this.args.channel);
|
||||
})
|
||||
.catch(popupAjaxError)
|
||||
.finally(() => {
|
||||
@ -67,22 +70,22 @@ export default class ToggleChannelMembershipButton extends Component {
|
||||
}
|
||||
|
||||
@action
|
||||
onLeaveChannel() {
|
||||
async onLeaveChannel() {
|
||||
this.isLoading = true;
|
||||
|
||||
return this.chat
|
||||
.unfollowChannel(this.args.channel)
|
||||
.then(() => {
|
||||
this.onToggle?.();
|
||||
})
|
||||
.catch(popupAjaxError)
|
||||
.finally(() => {
|
||||
if (this.isDestroying || this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (this.args.channel.chatable.group) {
|
||||
await this.chatApi.leaveChannel(this.args.channel.id);
|
||||
} else {
|
||||
await this.chat.unfollowChannel(this.args.channel);
|
||||
}
|
||||
|
||||
this.isLoading = false;
|
||||
});
|
||||
this.args.onLeave?.(this.args.channel);
|
||||
} catch (error) {
|
||||
popupAjaxError(error);
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
<template>
|
||||
|
@ -211,7 +211,7 @@ export default {
|
||||
suffixCSSClass = "urgent";
|
||||
hoverType = "icon";
|
||||
hoverValue = "times";
|
||||
hoverTitle = I18n.t("chat.direct_messages.leave");
|
||||
hoverTitle = I18n.t("chat.direct_messages.close");
|
||||
|
||||
constructor({ channel, chatService, currentUser }) {
|
||||
super(...arguments);
|
||||
|
@ -34,6 +34,13 @@ export default function withChatChannel(extendedClass) {
|
||||
let { channelTitle } = this.paramsFor(this.routeName);
|
||||
|
||||
if (channelTitle && channelTitle !== model.slugifiedTitle) {
|
||||
if (this.routeName === "chat.channel.info") {
|
||||
return this.router.replaceWith(
|
||||
"chat.channel.info",
|
||||
...model.routeModels
|
||||
);
|
||||
}
|
||||
|
||||
const messageId = this.paramsFor("chat.channel.near-message").messageId;
|
||||
const threadId = this.paramsFor("chat.channel.thread").threadId;
|
||||
|
||||
|
@ -293,9 +293,19 @@ export default class ChatApi extends Service {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
unfollowChannel(channelId) {
|
||||
return this.#deleteRequest(`/channels/${channelId}/memberships/me`).then(
|
||||
(result) => UserChatChannelMembership.create(result.membership)
|
||||
);
|
||||
return this.#deleteRequest(
|
||||
`/channels/${channelId}/memberships/me/follows`
|
||||
).then((result) => UserChatChannelMembership.create(result.membership));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the membership of current user on a channel.
|
||||
*
|
||||
* @param {number} channelId - The ID of the channel.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
leaveChannel(channelId) {
|
||||
return this.#deleteRequest(`/channels/${channelId}/memberships/me`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,13 +77,15 @@ export default class ChatChannelsManager extends Service {
|
||||
}
|
||||
|
||||
async unfollow(model) {
|
||||
this.chatSubscriptionsManager.stopChannelSubscription(model);
|
||||
|
||||
return this.chatApi.unfollowChannel(model.id).then((membership) => {
|
||||
model.currentUserMembership = membership;
|
||||
|
||||
try {
|
||||
this.chatSubscriptionsManager.stopChannelSubscription(model);
|
||||
model.currentUserMembership = await this.chatApi.unfollowChannel(
|
||||
model.id
|
||||
);
|
||||
return model;
|
||||
});
|
||||
} catch (error) {
|
||||
popupAjaxError(error);
|
||||
}
|
||||
}
|
||||
|
||||
@debounce(300)
|
||||
|
Reference in New Issue
Block a user