Add confirm dialog before leaving private channel (#6206)
Этот коммит содержится в:
коммит произвёл
Corey Hulen
родитель
6c4c706313
Коммит
f1668bad15
@@ -14,6 +14,7 @@ import ChannelMembersModal from './channel_members_modal.jsx';
|
|||||||
import ChannelNotificationsModal from './channel_notifications_modal.jsx';
|
import ChannelNotificationsModal from './channel_notifications_modal.jsx';
|
||||||
import DeleteChannelModal from './delete_channel_modal.jsx';
|
import DeleteChannelModal from './delete_channel_modal.jsx';
|
||||||
import RenameChannelModal from './rename_channel_modal.jsx';
|
import RenameChannelModal from './rename_channel_modal.jsx';
|
||||||
|
import ConfirmModal from './confirm_modal.jsx';
|
||||||
import ToggleModalButton from './toggle_modal_button.jsx';
|
import ToggleModalButton from './toggle_modal_button.jsx';
|
||||||
|
|
||||||
import ChannelStore from 'stores/channel_store.jsx';
|
import ChannelStore from 'stores/channel_store.jsx';
|
||||||
@@ -57,6 +58,8 @@ export default class ChannelHeader extends React.Component {
|
|||||||
this.initWebrtc = this.initWebrtc.bind(this);
|
this.initWebrtc = this.initWebrtc.bind(this);
|
||||||
this.onBusy = this.onBusy.bind(this);
|
this.onBusy = this.onBusy.bind(this);
|
||||||
this.openDirectMessageModal = this.openDirectMessageModal.bind(this);
|
this.openDirectMessageModal = this.openDirectMessageModal.bind(this);
|
||||||
|
this.createLeaveChannelModal = this.createLeaveChannelModal.bind(this);
|
||||||
|
this.hideLeaveChannelModal = this.hideLeaveChannelModal.bind(this);
|
||||||
|
|
||||||
const state = this.getStateFromStores();
|
const state = this.getStateFromStores();
|
||||||
state.showEditChannelPurposeModal = false;
|
state.showEditChannelPurposeModal = false;
|
||||||
@@ -84,7 +87,8 @@ export default class ChannelHeader extends React.Component {
|
|||||||
otherUserId,
|
otherUserId,
|
||||||
enableFormatting: PreferenceStore.getBool(Preferences.CATEGORY_ADVANCED_SETTINGS, 'formatting', true),
|
enableFormatting: PreferenceStore.getBool(Preferences.CATEGORY_ADVANCED_SETTINGS, 'formatting', true),
|
||||||
isBusy: WebrtcStore.isBusy(),
|
isBusy: WebrtcStore.isBusy(),
|
||||||
isFavorite: channel && ChannelUtils.isFavoriteChannel(channel)
|
isFavorite: channel && ChannelUtils.isFavoriteChannel(channel),
|
||||||
|
showLeaveChannelModal: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +139,13 @@ export default class ChannelHeader extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleLeave() {
|
handleLeave() {
|
||||||
ChannelActions.leaveChannel(this.state.channel.id);
|
if (this.state.channel.type === Constants.PRIVATE_CHANNEL) {
|
||||||
|
this.setState({
|
||||||
|
showLeaveChannelModal: true
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ChannelActions.leaveChannel(this.state.channel.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleFavorite = (e) => {
|
toggleFavorite = (e) => {
|
||||||
@@ -219,6 +229,54 @@ export default class ChannelHeader extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hideLeaveChannelModal() {
|
||||||
|
this.setState({
|
||||||
|
showLeaveChannelModal: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createLeaveChannelModal() {
|
||||||
|
const title = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='leave_private_channel_modal.title'
|
||||||
|
defaultMessage='Leave Private Channel {channel}'
|
||||||
|
values={{
|
||||||
|
channel: <b>{this.state.channel.display_name}</b>
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const message = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='leave_private_channel_modal.message'
|
||||||
|
defaultMessage='Are you sure you wish to leave the private channel {channel}? You must be re-invited in order to re-join this channel in the future.'
|
||||||
|
values={{
|
||||||
|
channel: <b>{this.state.channel.display_name}</b>
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const buttonClass = 'btn btn-danger';
|
||||||
|
const button = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='leave_private_channel_modal.leave'
|
||||||
|
defaultMessage='Yes, leave channel'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmModal
|
||||||
|
show={this.state.showLeaveChannelModal}
|
||||||
|
title={title}
|
||||||
|
message={message}
|
||||||
|
confirmButtonClass={buttonClass}
|
||||||
|
confirmButton={button}
|
||||||
|
onConfirm={() => ChannelActions.leaveChannel(this.state.channel.id)}
|
||||||
|
onCancel={this.hideLeaveChannelModal}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const flagIcon = Constants.FLAG_ICON_SVG;
|
const flagIcon = Constants.FLAG_ICON_SVG;
|
||||||
const pinIcon = Constants.PIN_ICON;
|
const pinIcon = Constants.PIN_ICON;
|
||||||
@@ -764,6 +822,8 @@ export default class ChannelHeader extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const leaveChannelModal = this.createLeaveChannelModal();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id='channel-header'
|
id='channel-header'
|
||||||
@@ -876,6 +936,7 @@ export default class ChannelHeader extends React.Component {
|
|||||||
</table>
|
</table>
|
||||||
{editPurposeModal}
|
{editPurposeModal}
|
||||||
{channelMembersModal}
|
{channelMembersModal}
|
||||||
|
{leaveChannelModal}
|
||||||
<RenameChannelModal
|
<RenameChannelModal
|
||||||
show={this.state.showRenameChannelModal}
|
show={this.state.showRenameChannelModal}
|
||||||
onHide={this.hideRenameChannelModal}
|
onHide={this.hideRenameChannelModal}
|
||||||
|
|||||||
@@ -10,11 +10,21 @@ export default class ConfirmModal extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.handleConfirm = this.handleConfirm.bind(this);
|
this.handleKeypress = this.handleKeypress.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConfirm() {
|
componentDidMount() {
|
||||||
this.props.onConfirm();
|
document.addEventListener('keypress', this.handleKeypress);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
document.removeEventListener('keypress', this.handleKeypress);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleKeypress(e) {
|
||||||
|
if (e.key === 'Enter' && this.props.show) {
|
||||||
|
this.props.onConfirm();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -43,7 +53,7 @@ export default class ConfirmModal extends React.Component {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type='button'
|
type='button'
|
||||||
className='btn btn-primary'
|
className={this.props.confirmButtonClass}
|
||||||
onClick={this.props.onConfirm}
|
onClick={this.props.onConfirm}
|
||||||
>
|
>
|
||||||
{this.props.confirmButton}
|
{this.props.confirmButton}
|
||||||
@@ -57,12 +67,14 @@ export default class ConfirmModal extends React.Component {
|
|||||||
ConfirmModal.defaultProps = {
|
ConfirmModal.defaultProps = {
|
||||||
title: '',
|
title: '',
|
||||||
message: '',
|
message: '',
|
||||||
|
confirmButtonClass: 'btn btn-primary',
|
||||||
confirmButton: ''
|
confirmButton: ''
|
||||||
};
|
};
|
||||||
ConfirmModal.propTypes = {
|
ConfirmModal.propTypes = {
|
||||||
show: React.PropTypes.bool.isRequired,
|
show: React.PropTypes.bool.isRequired,
|
||||||
title: React.PropTypes.node,
|
title: React.PropTypes.node,
|
||||||
message: React.PropTypes.node,
|
message: React.PropTypes.node,
|
||||||
|
confirmButtonClass: React.PropTypes.string,
|
||||||
confirmButton: React.PropTypes.node,
|
confirmButton: React.PropTypes.node,
|
||||||
onConfirm: React.PropTypes.func.isRequired,
|
onConfirm: React.PropTypes.func.isRequired,
|
||||||
onCancel: React.PropTypes.func.isRequired
|
onCancel: React.PropTypes.func.isRequired
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import ChannelMembersModal from './channel_members_modal.jsx';
|
|||||||
import ChannelNotificationsModal from './channel_notifications_modal.jsx';
|
import ChannelNotificationsModal from './channel_notifications_modal.jsx';
|
||||||
import DeleteChannelModal from './delete_channel_modal.jsx';
|
import DeleteChannelModal from './delete_channel_modal.jsx';
|
||||||
import RenameChannelModal from './rename_channel_modal.jsx';
|
import RenameChannelModal from './rename_channel_modal.jsx';
|
||||||
|
import ConfirmModal from './confirm_modal.jsx';
|
||||||
import ToggleModalButton from './toggle_modal_button.jsx';
|
import ToggleModalButton from './toggle_modal_button.jsx';
|
||||||
import StatusIcon from './status_icon.jsx';
|
import StatusIcon from './status_icon.jsx';
|
||||||
|
|
||||||
@@ -67,6 +68,9 @@ export default class Navbar extends React.Component {
|
|||||||
this.openDirectMessageModal = this.openDirectMessageModal.bind(this);
|
this.openDirectMessageModal = this.openDirectMessageModal.bind(this);
|
||||||
this.getPinnedPosts = this.getPinnedPosts.bind(this);
|
this.getPinnedPosts = this.getPinnedPosts.bind(this);
|
||||||
|
|
||||||
|
this.createLeaveChannelModal = this.createLeaveChannelModal.bind(this);
|
||||||
|
this.hideLeaveChannelModal = this.hideLeaveChannelModal.bind(this);
|
||||||
|
|
||||||
const state = this.getStateFromStores();
|
const state = this.getStateFromStores();
|
||||||
state.showEditChannelPurposeModal = false;
|
state.showEditChannelPurposeModal = false;
|
||||||
state.showEditChannelHeaderModal = false;
|
state.showEditChannelHeaderModal = false;
|
||||||
@@ -85,7 +89,8 @@ export default class Navbar extends React.Component {
|
|||||||
users: [],
|
users: [],
|
||||||
userCount: ChannelStore.getCurrentStats().member_count,
|
userCount: ChannelStore.getCurrentStats().member_count,
|
||||||
currentUser: UserStore.getCurrentUser(),
|
currentUser: UserStore.getCurrentUser(),
|
||||||
isFavorite: channel && ChannelUtils.isFavoriteChannel(channel)
|
isFavorite: channel && ChannelUtils.isFavoriteChannel(channel),
|
||||||
|
showLeaveChannelModal: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +122,13 @@ export default class Navbar extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleLeave() {
|
handleLeave() {
|
||||||
ChannelActions.leaveChannel(this.state.channel.id);
|
if (this.state.channel.type === Constants.PRIVATE_CHANNEL) {
|
||||||
|
this.setState({
|
||||||
|
showLeaveChannelModal: true
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ChannelActions.leaveChannel(this.state.channel.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hideSidebars(e) {
|
hideSidebars(e) {
|
||||||
@@ -676,6 +687,54 @@ export default class Navbar extends React.Component {
|
|||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hideLeaveChannelModal() {
|
||||||
|
this.setState({
|
||||||
|
showLeaveChannelModal: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createLeaveChannelModal() {
|
||||||
|
const title = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='leave_private_channel_modal.title'
|
||||||
|
defaultMessage='Leave Private Channel {channel}'
|
||||||
|
values={{
|
||||||
|
channel: <b>{this.state.channel.display_name}</b>
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const message = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='leave_private_channel_modal.message'
|
||||||
|
defaultMessage='Are you sure you wish to leave the private channel {channel}? You must be re-invited in order to re-join this channel in the future.'
|
||||||
|
values={{
|
||||||
|
channel: <b>{this.state.channel.display_name}</b>
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const buttonClass = 'btn btn-danger';
|
||||||
|
const button = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='leave_private_channel_modal.leave'
|
||||||
|
defaultMessage='Yes, leave channel'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmModal
|
||||||
|
show={this.state.showLeaveChannelModal}
|
||||||
|
title={title}
|
||||||
|
message={message}
|
||||||
|
confirmButtonClass={buttonClass}
|
||||||
|
confirmButton={button}
|
||||||
|
onConfirm={() => ChannelActions.leaveChannel(this.state.channel.id)}
|
||||||
|
onCancel={this.hideLeaveChannelModal}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
getTeammateStatus() {
|
getTeammateStatus() {
|
||||||
const channel = this.state.channel;
|
const channel = this.state.channel;
|
||||||
|
|
||||||
@@ -844,6 +903,8 @@ export default class Navbar extends React.Component {
|
|||||||
|
|
||||||
var channelMenuDropdown = this.createDropdown(channel, channelTitle, isSystemAdmin, isTeamAdmin, isChannelAdmin, isDirect, isGroup, popoverContent);
|
var channelMenuDropdown = this.createDropdown(channel, channelTitle, isSystemAdmin, isTeamAdmin, isChannelAdmin, isDirect, isGroup, popoverContent);
|
||||||
|
|
||||||
|
const leaveChannelModal = this.createLeaveChannelModal();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<nav
|
<nav
|
||||||
@@ -860,6 +921,7 @@ export default class Navbar extends React.Component {
|
|||||||
</nav>
|
</nav>
|
||||||
{editChannelHeaderModal}
|
{editChannelHeaderModal}
|
||||||
{editChannelPurposeModal}
|
{editChannelPurposeModal}
|
||||||
|
{leaveChannelModal}
|
||||||
{renameChannelModal}
|
{renameChannelModal}
|
||||||
{channelMembersModal}
|
{channelMembersModal}
|
||||||
{channelSwitchModal}
|
{channelSwitchModal}
|
||||||
|
|||||||
@@ -1583,6 +1583,9 @@
|
|||||||
"ldap_signup.length_error": "Name must be 3 or more characters up to a maximum of 15",
|
"ldap_signup.length_error": "Name must be 3 or more characters up to a maximum of 15",
|
||||||
"ldap_signup.teamName": "Enter name of new team",
|
"ldap_signup.teamName": "Enter name of new team",
|
||||||
"ldap_signup.team_error": "Please enter a team name",
|
"ldap_signup.team_error": "Please enter a team name",
|
||||||
|
"leave_private_channel_modal.title": "Leave Private Channel {channel}",
|
||||||
|
"leave_private_channel_modal.message": "Are you sure you wish to leave the private channel {channel}? You must be re-invited in order to re-join this channel in the future.",
|
||||||
|
"leave_private_channel_modal.leave": "Yes, leave channel",
|
||||||
"leave_team_modal.desc": "You will be removed from all public and private channels. If the team is private you will not be able to rejoin the team. Are you sure?",
|
"leave_team_modal.desc": "You will be removed from all public and private channels. If the team is private you will not be able to rejoin the team. Are you sure?",
|
||||||
"leave_team_modal.no": "No",
|
"leave_team_modal.no": "No",
|
||||||
"leave_team_modal.title": "Leave the team?",
|
"leave_team_modal.title": "Leave the team?",
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user