summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/diagnostics.go1
-rw-r--r--config/default.json1
-rw-r--r--model/config.go6
-rw-r--r--utils/config.go1
-rw-r--r--webapp/components/sidebar.jsx48
-rwxr-xr-xwebapp/i18n/en.json1
6 files changed, 55 insertions, 3 deletions
diff --git a/app/diagnostics.go b/app/diagnostics.go
index f05d90bec..62dcc0b64 100644
--- a/app/diagnostics.go
+++ b/app/diagnostics.go
@@ -243,6 +243,7 @@ func trackConfig() {
"isdefault_custom_description_text": isDefault(*utils.Cfg.TeamSettings.CustomDescriptionText, model.TEAM_SETTINGS_DEFAULT_CUSTOM_DESCRIPTION_TEXT),
"isdefault_user_status_away_timeout": isDefault(*utils.Cfg.TeamSettings.UserStatusAwayTimeout, model.TEAM_SETTINGS_DEFAULT_USER_STATUS_AWAY_TIMEOUT),
"restrict_private_channel_manage_members": *utils.Cfg.TeamSettings.RestrictPrivateChannelManageMembers,
+ "enable_X_to_leave_channels_from_LHS": *utils.Cfg.TeamSettings.EnableXToLeaveChannelsFromLHS,
"experimental_town_square_is_read_only": *utils.Cfg.TeamSettings.ExperimentalTownSquareIsReadOnly,
})
diff --git a/config/default.json b/config/default.json
index 1d08fd7cf..59bcf8bc6 100644
--- a/config/default.json
+++ b/config/default.json
@@ -71,6 +71,7 @@
"RestrictPublicChannelDeletion": "all",
"RestrictPrivateChannelDeletion": "all",
"RestrictPrivateChannelManageMembers": "all",
+ "EnableXToLeaveChannelsFromLHS": false,
"UserStatusAwayTimeout": 300,
"MaxChannelsPerTeam": 2000,
"MaxNotificationsPerChannel": 1000,
diff --git a/model/config.go b/model/config.go
index 58b3da4d1..a801f7f99 100644
--- a/model/config.go
+++ b/model/config.go
@@ -350,6 +350,7 @@ type TeamSettings struct {
RestrictPublicChannelDeletion *string
RestrictPrivateChannelDeletion *string
RestrictPrivateChannelManageMembers *string
+ EnableXToLeaveChannelsFromLHS *bool
UserStatusAwayTimeout *int64
MaxChannelsPerTeam *int64
MaxNotificationsPerChannel *int64
@@ -810,6 +811,11 @@ func (o *Config) SetDefaults() {
*o.TeamSettings.RestrictPrivateChannelManageMembers = PERMISSIONS_ALL
}
+ if o.TeamSettings.EnableXToLeaveChannelsFromLHS == nil {
+ o.TeamSettings.EnableXToLeaveChannelsFromLHS = new(bool)
+ *o.TeamSettings.EnableXToLeaveChannelsFromLHS = false
+ }
+
if o.TeamSettings.UserStatusAwayTimeout == nil {
o.TeamSettings.UserStatusAwayTimeout = new(int64)
*o.TeamSettings.UserStatusAwayTimeout = TEAM_SETTINGS_DEFAULT_USER_STATUS_AWAY_TIMEOUT
diff --git a/utils/config.go b/utils/config.go
index 642abfdf0..b99194c46 100644
--- a/utils/config.go
+++ b/utils/config.go
@@ -438,6 +438,7 @@ func getClientConfig(c *model.Config) map[string]string {
props["RestrictPublicChannelDeletion"] = *c.TeamSettings.RestrictPublicChannelDeletion
props["RestrictPrivateChannelDeletion"] = *c.TeamSettings.RestrictPrivateChannelDeletion
props["RestrictPrivateChannelManageMembers"] = *c.TeamSettings.RestrictPrivateChannelManageMembers
+ props["EnableXToLeaveChannelsFromLHS"] = strconv.FormatBool(*c.TeamSettings.EnableXToLeaveChannelsFromLHS)
props["TeammateNameDisplay"] = *c.TeamSettings.TeammateNameDisplay
props["AndroidLatestVersion"] = c.ClientRequirements.AndroidLatestVersion
diff --git a/webapp/components/sidebar.jsx b/webapp/components/sidebar.jsx
index ff889fd6b..3399734a6 100644
--- a/webapp/components/sidebar.jsx
+++ b/webapp/components/sidebar.jsx
@@ -21,6 +21,7 @@ import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import * as Utils from 'utils/utils.jsx';
import * as ChannelUtils from 'utils/channel_utils.jsx';
import * as ChannelActions from 'actions/channel_actions.jsx';
+import * as GlobalActions from 'actions/global_actions.jsx';
import {trackEvent} from 'actions/diagnostics_actions.jsx';
import {ActionTypes, Constants} from 'utils/constants.jsx';
@@ -326,6 +327,18 @@ export default class Sidebar extends React.Component {
return this.state.favoriteChannels.concat(this.state.publicChannels).concat(this.state.privateChannels).concat(this.state.directAndGroupChannels);
}
+ handleLeavePublicChannel = (e, channel) => {
+ e.preventDefault();
+ ChannelActions.leaveChannel(channel.id);
+ trackEvent('ui', 'ui_public_channel_x_button_clicked');
+ }
+
+ handleLeavePrivateChannel = (e, channel) => {
+ e.preventDefault();
+ GlobalActions.showLeavePrivateChannelModal(channel);
+ trackEvent('ui', 'ui_private_channel_x_button_clicked');
+ }
+
handleLeaveDirectChannel = (e, channel) => {
e.preventDefault();
@@ -354,6 +367,7 @@ export default class Sidebar extends React.Component {
}
this.setState(this.getStateFromStores());
+ trackEvent('ui', 'ui_direct_channel_x_button_clicked');
}
if (channel.id === this.state.activeId) {
@@ -545,7 +559,7 @@ export default class Sidebar extends React.Component {
}
let closeButton = null;
- const removeTooltip = (
+ let removeTooltip = (
<Tooltip id='remove-dm-tooltip'>
<FormattedMessage
id='sidebar.removeList'
@@ -553,6 +567,16 @@ export default class Sidebar extends React.Component {
/>
</Tooltip>
);
+ if (channel.type === Constants.OPEN_CHANNEL || channel.type === Constants.PRIVATE_CHANNEL) {
+ removeTooltip = (
+ <Tooltip id='remove-dm-tooltip'>
+ <FormattedMessage
+ id='sidebar.leave'
+ defaultMessage='Leave channel'
+ />
+ </Tooltip>
+ );
+ }
if (handleClose && !badge) {
closeButton = (
<OverlayTrigger
@@ -631,14 +655,32 @@ export default class Sidebar extends React.Component {
map((channel, index, arr) => {
if (channel.type === Constants.DM_CHANNEL || channel.type === Constants.GM_CHANNEL) {
return this.createChannelElement(channel, index, arr, this.handleLeaveDirectChannel);
+ } else if (global.window.mm_config.EnableXToLeaveChannelsFromLHS === 'true') {
+ if (channel.type === Constants.OPEN_CHANNEL && channel.name !== Constants.DEFAULT_CHANNEL) {
+ return this.createChannelElement(channel, index, arr, this.handleLeavePublicChannel);
+ } else if (channel.type === Constants.PRIVATE_CHANNEL) {
+ return this.createChannelElement(channel, index, arr, this.handleLeavePrivateChannel);
+ }
}
return this.createChannelElement(channel);
});
- const publicChannelItems = this.state.publicChannels.map(this.createChannelElement);
+ const publicChannelItems = this.state.publicChannels.map((channel, index, arr) => {
+ if (global.window.mm_config.EnableXToLeaveChannelsFromLHS !== 'true' ||
+ channel.name === Constants.DEFAULT_CHANNEL
+ ) {
+ return this.createChannelElement(channel);
+ }
+ return this.createChannelElement(channel, index, arr, this.handleLeavePublicChannel);
+ });
- const privateChannelItems = this.state.privateChannels.map(this.createChannelElement);
+ const privateChannelItems = this.state.privateChannels.map((channel, index, arr) => {
+ if (global.window.mm_config.EnableXToLeaveChannelsFromLHS !== 'true') {
+ return this.createChannelElement(channel);
+ }
+ return this.createChannelElement(channel, index, arr, this.handleLeavePrivateChannel);
+ });
const directMessageItems = this.state.directAndGroupChannels.map((channel, index, arr) => {
return this.createChannelElement(channel, index, arr, this.handleLeaveDirectChannel);
diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json
index 9f6a3a850..a23058f1d 100755
--- a/webapp/i18n/en.json
+++ b/webapp/i18n/en.json
@@ -2175,6 +2175,7 @@
"sidebar.createGroup": "Create new private channel",
"sidebar.direct": "DIRECT MESSAGES",
"sidebar.favorite": "FAVORITE CHANNELS",
+ "sidebar.leave": "Leave channel",
"sidebar.more": "More",
"sidebar.moreElips": "More...",
"sidebar.otherMembers": "Outside this team",