From 4b6e691d8ac9df97f73ea1d0ef7a149bd6544989 Mon Sep 17 00:00:00 2001 From: Gerzon Z Date: Thu, 6 May 2021 05:22:34 -0400 Subject: [PATCH] Added SelectListView and logic for leaving team --- app/i18n/locales/en.json | 9 +- app/lib/rocketchat.js | 4 + app/stacks/InsideStack.js | 6 + app/views/RoomActionsView/index.js | 53 +++++- app/views/RoomView/index.js | 1 + app/views/RoomsListView/index.js | 1 - app/views/SelectListView.js | 278 +++++++++++++++++++++++++++++ 7 files changed, 348 insertions(+), 4 deletions(-) create mode 100644 app/views/SelectListView.js diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index 0ef3e03c4..46e15db18 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -290,6 +290,7 @@ "last_message": "last message", "Leave_channel": "Leave channel", "leaving_room": "leaving room", + "Leave": "Leave", "leave": "leave", "Legal": "Legal", "Light": "Light", @@ -726,5 +727,11 @@ "Auto-join": "Auto-join", "Delete_Team_Room_Warning": "Woud you like to remove this channel from the team? The channel will be moved back to the workspace", "Confirmation": "Confirmation", - "invalid-room": "Invalid room" + "invalid-room": "Invalid room", + "You_are_leaving_the_team": "You are leaving the team '{{team}}'", + "Leave_Team": "Leave Team", + "Select_Teams": "Select the Team's channels you would like to leave.", + "Cannot_leave": "Cannot leave", + "Last_owner_team_room": "You are the last owner of this channel. Once you leave the team, the channel will be kept inside the team but you will be managing it from outside.", + "last-owner-can-not-be-removed": "Last owner cannot be removed" } diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 0d68e9628..965b5be08 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -758,6 +758,10 @@ const RocketChat = { // RC 3.13.0 return this.post('teams.removeRoom', { roomId, teamId }); }, + leaveTeam({ teamName }) { + // RC 3.13.0 + return this.post('teams.leave', { teamName }); + }, joinRoom(roomId, joinCode, type) { // TODO: join code // RC 0.48.0 diff --git a/app/stacks/InsideStack.js b/app/stacks/InsideStack.js index 75758960b..18517368c 100644 --- a/app/stacks/InsideStack.js +++ b/app/stacks/InsideStack.js @@ -73,6 +73,7 @@ import CreateDiscussionView from '../views/CreateDiscussionView'; import QueueListView from '../ee/omnichannel/views/QueueListView'; import AddChannelTeamView from '../views/AddChannelTeamView'; import AddExistingChannelView from '../views/AddExistingChannelView'; +import SelectListView from '../views/SelectListView'; // ChatsStackNavigator const ChatsStack = createStackNavigator(); @@ -93,6 +94,11 @@ const ChatsStackNavigator = () => { component={RoomActionsView} options={RoomActionsView.navigationOptions} /> + { + try { + const { navigation } = this.props; + const result = await RocketChat.leaveTeam({ teamName }); + // Add isMasterDetail + if (result.success) { + navigation.navigate('RoomsListView'); + } + } catch (e) { + log(e); + } + } + + leaveTeam = async() => { + const { room } = this.state; + const { navigation } = this.props; + + try { + const db = database.active; + const subCollection = db.get('subscriptions'); + const teamChannels = await subCollection.query( + Q.where('team_id', Q.eq(room.teamId)) + ); + + if (teamChannels) { + navigation.navigate('SelectListView', { title: 'Leave_Team', teamChannels, teamName: room.name }); + } else { + Alert.alert( + I18n.t('Confirmation'), + I18n.t('You_are_leaving_the_team', { team: RocketChat.getRoomTitle(room) }), + [ + { + text: I18n.t('Cancel'), + style: 'cancel' + }, + { + text: I18n.t('Yes_action_it', { action: I18n.t('leave') }), + style: 'destructive', + onPress: () => this._leave(room.name) + } + ] + ); + } + } catch (e) { + log(e); + } + } + renderRoomInfo = () => { const { room, member } = this.state; const { @@ -568,9 +617,9 @@ class RoomActionsView extends React.Component { this.onPressTouchable({ - event: this.leaveChannel + event: room.teamId && room.teamMain ? this.leaveTeam : this.leaveChannel })} testID='room-actions-leave-channel' left={() => } diff --git a/app/views/RoomView/index.js b/app/views/RoomView/index.js index a41078216..d7bba1017 100644 --- a/app/views/RoomView/index.js +++ b/app/views/RoomView/index.js @@ -1033,6 +1033,7 @@ class RoomView extends React.Component { renderActions = () => { const { room, readOnly } = this.state; const { user } = this.props; + console.log({ room }); return ( <> ; } - return ( { + const { navigation, isMasterDetail, theme } = this.props; + + const options = { + headerShown: true, + headerTitleAlign: 'center', + headerTitle: I18n.t(this.title) + }; + + if (isMasterDetail) { + options.headerLeft = () => ; + } else { + options.headerLeft = () => navigation.pop()} tintColor={themes[theme].headerTintColor} />; + } + + options.headerRight = () => ( + + + + ); + + navigation.setOptions(options); + } + + submit = async() => { + const { selected } = this.state; + const { navigation, leaveRoom } = this.props; + + this.setState({ loading: true }); + try { + // logEvent(events.CT_ADD_ROOM_TO_TEAM); + const result = await RocketChat.leaveTeam({ teamName: this.teamName }); + if (selected) { + selected.map(room => leaveRoom(room.rid, room.t)); + } + if (result.success) { + this.setState({ loading: false }); + navigation.navigate('RoomsListView'); + } + } catch (e) { + // logEvent(events.CT_ADD_ROOM_TO_TEAM_F); + this.setState({ loading: false }); + Alert.alert( + I18n.t('Cannot_leave'), + I18n.t(e.data.error), + [ + { + text: 'OK', + style: 'cancel' + } + ] + ); + } + } + + renderHeader = () => { + const { theme } = this.props; + return ( + + {I18n.t('Select_Teams')} + + ); + } + + showAlert = () => { + Alert.alert( + I18n.t('Cannot_leave'), + I18n.t('Last_owner_team_room'), + [ + { + text: 'OK', + style: 'cancel' + } + ] + ); + } + + leaveChannel = () => { + const { room } = this.state; + const { leaveRoom } = this.props; + + Alert.alert( + I18n.t('Are_you_sure_question_mark'), + I18n.t('Are_you_sure_you_want_to_leave_the_room', { room: RocketChat.getRoomTitle(room) }), + [ + { + text: I18n.t('Cancel'), + style: 'cancel' + }, + { + text: I18n.t('Yes_action_it', { action: I18n.t('leave') }), + style: 'destructive', + onPress: () => leaveRoom(room.rid, room.t) + } + ] + ); + } + + renderChannel = ({ + onPress, testID, title, icon, checked, alert + }) => { + const { theme } = this.props; + + return ( + + + + + {title} + { alert + ? ( + this.showAlert()}> + + + ) : null} + + {checked ? : null} + + + ); + } + + isChecked = (rid) => { + const { selected } = this.state; + return selected.includes(rid); + } + + toggleChannel = (rid, roles) => { + const { selected } = this.state; + + if (roles) { + this.showAlert(); + return; + } + + animateNextTransition(); + if (!this.isChecked(rid)) { + this.setState({ selected: [...selected, rid] }, () => this.setHeader()); + } else { + const filterSelected = selected.filter(el => el !== rid); + this.setState({ selected: filterSelected }, () => this.setHeader()); + } + } + + renderItem = ({ item }) => ( + <> + {this.renderChannel({ + onPress: () => this.toggleChannel(item.rid, item.roles), + title: item.name, + icon: item.t === 'p' ? 'channel-private' : 'channel-public', + checked: this.isChecked(item.rid, item.roles) ? 'check' : null, + testID: 'select-list-view-item', + alert: item.roles ? 'info' : null + })} + + ) + + renderList = () => { + const { data } = this.state; + const { theme } = this.props; + + return ( + item._id} + renderItem={this.renderItem} + ListHeaderComponent={this.renderHeader} + ItemSeparatorComponent={List.Separator} + contentContainerStyle={{ backgroundColor: themes[theme].backgroundColor }} + keyboardShouldPersistTaps='always' + /> + ); + } + + render() { + const { loading } = this.state; + + return ( + + + {this.renderList()} + + + ); + } +} + +const mapStateToProps = state => ({ + isMasterDetail: state.app.isMasterDetail +}); + +const mapDispatchToProps = dispatch => ({ + leaveRoom: (rid, t) => dispatch(leaveRoomAction(rid, t)) +}); + +export default connect(mapStateToProps, mapDispatchToProps)(withTheme(SelectListView));