2018-02-19 21:19:39 +00:00
|
|
|
import React from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
2018-09-25 19:28:42 +00:00
|
|
|
import {
|
2020-10-30 13:59:44 +00:00
|
|
|
View, Text, Alert, Share, Switch
|
2018-09-25 19:28:42 +00:00
|
|
|
} from 'react-native';
|
2019-01-31 16:08:38 +00:00
|
|
|
import { connect } from 'react-redux';
|
2020-03-30 20:19:01 +00:00
|
|
|
import _ from 'lodash';
|
2021-01-25 17:14:45 +00:00
|
|
|
import semver from 'semver';
|
2018-02-19 21:19:39 +00:00
|
|
|
|
2019-12-04 16:39:53 +00:00
|
|
|
import Touch from '../../utils/touch';
|
2020-04-01 12:28:54 +00:00
|
|
|
import { setLoading as setLoadingAction } from '../../actions/selectedUsers';
|
2020-05-08 17:36:10 +00:00
|
|
|
import { leaveRoom as leaveRoomAction, closeRoom as closeRoomAction } from '../../actions/room';
|
2018-02-19 21:19:39 +00:00
|
|
|
import styles from './styles';
|
2018-03-29 17:55:37 +00:00
|
|
|
import sharedStyles from '../Styles';
|
2018-02-19 21:19:39 +00:00
|
|
|
import Avatar from '../../containers/Avatar';
|
2019-03-01 16:49:11 +00:00
|
|
|
import Status from '../../containers/Status';
|
2020-10-30 13:59:44 +00:00
|
|
|
import * as List from '../../containers/List';
|
2018-03-02 15:11:34 +00:00
|
|
|
import RocketChat from '../../lib/rocketchat';
|
2020-08-05 13:15:56 +00:00
|
|
|
import log, { logEvent, events } from '../../utils/log';
|
2018-05-18 16:41:47 +00:00
|
|
|
import RoomTypeIcon from '../../containers/RoomTypeIcon';
|
2018-06-01 17:38:13 +00:00
|
|
|
import I18n from '../../i18n';
|
2019-03-12 16:23:06 +00:00
|
|
|
import StatusBar from '../../containers/StatusBar';
|
2020-09-11 14:31:38 +00:00
|
|
|
import { themes, SWITCH_TRACK_COLOR } from '../../constants/colors';
|
2019-12-04 16:39:53 +00:00
|
|
|
import { withTheme } from '../../theme';
|
2020-10-30 16:15:58 +00:00
|
|
|
import * as HeaderButton from '../../containers/HeaderButton';
|
2020-03-30 20:19:01 +00:00
|
|
|
import Markdown from '../../containers/markdown';
|
2020-05-08 17:36:10 +00:00
|
|
|
import { showConfirmationAlert, showErrorAlert } from '../../utils/info';
|
2020-06-15 14:00:46 +00:00
|
|
|
import SafeAreaView from '../../containers/SafeAreaView';
|
2020-09-11 14:31:38 +00:00
|
|
|
import { E2E_ROOM_TYPES } from '../../lib/encryption/constants';
|
|
|
|
import protectedFunction from '../../lib/methods/helpers/protectedFunction';
|
|
|
|
import database from '../../lib/database';
|
2020-10-30 13:59:44 +00:00
|
|
|
import { withDimensions } from '../../dimensions';
|
2018-04-24 19:34:03 +00:00
|
|
|
|
2019-08-07 13:51:34 +00:00
|
|
|
class RoomActionsView extends React.Component {
|
2020-06-15 14:00:46 +00:00
|
|
|
static navigationOptions = ({ navigation, isMasterDetail }) => {
|
2019-11-25 20:01:17 +00:00
|
|
|
const options = {
|
|
|
|
title: I18n.t('Actions')
|
|
|
|
};
|
2020-06-15 14:00:46 +00:00
|
|
|
if (isMasterDetail) {
|
2020-10-30 16:15:58 +00:00
|
|
|
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} testID='room-actions-view-close' />;
|
2019-11-25 20:01:17 +00:00
|
|
|
}
|
|
|
|
return options;
|
2018-10-23 21:39:48 +00:00
|
|
|
}
|
|
|
|
|
2018-02-19 21:19:39 +00:00
|
|
|
static propTypes = {
|
2019-03-12 16:23:06 +00:00
|
|
|
navigation: PropTypes.object,
|
2020-06-15 14:00:46 +00:00
|
|
|
route: PropTypes.object,
|
2019-09-18 17:32:12 +00:00
|
|
|
leaveRoom: PropTypes.func,
|
2019-12-04 16:39:53 +00:00
|
|
|
jitsiEnabled: PropTypes.bool,
|
2021-01-25 17:14:45 +00:00
|
|
|
encryptionEnabled: PropTypes.bool,
|
2020-04-01 12:28:54 +00:00
|
|
|
setLoadingInvite: PropTypes.func,
|
2020-05-08 17:36:10 +00:00
|
|
|
closeRoom: PropTypes.func,
|
2020-10-30 13:59:44 +00:00
|
|
|
theme: PropTypes.string,
|
2021-01-25 17:14:45 +00:00
|
|
|
fontScale: PropTypes.number,
|
|
|
|
serverVersion: PropTypes.string
|
2018-02-19 21:19:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
constructor(props) {
|
2019-05-28 13:03:08 +00:00
|
|
|
super(props);
|
2019-09-16 20:26:32 +00:00
|
|
|
this.mounted = false;
|
2020-06-15 14:00:46 +00:00
|
|
|
const room = props.route.params?.room;
|
|
|
|
const member = props.route.params?.member;
|
|
|
|
this.rid = props.route.params?.rid;
|
|
|
|
this.t = props.route.params?.t;
|
2018-02-19 21:19:39 +00:00
|
|
|
this.state = {
|
2019-09-16 20:26:32 +00:00
|
|
|
room: room || { rid: this.rid, t: this.t },
|
2018-12-05 20:52:08 +00:00
|
|
|
membersCount: 0,
|
2020-03-30 20:19:01 +00:00
|
|
|
member: member || {},
|
2019-09-16 20:26:32 +00:00
|
|
|
joined: !!room,
|
2019-06-28 17:02:30 +00:00
|
|
|
canViewMembers: false,
|
2019-09-16 20:26:32 +00:00
|
|
|
canAutoTranslate: false,
|
2020-01-28 13:22:35 +00:00
|
|
|
canAddUser: false,
|
2020-05-08 17:36:10 +00:00
|
|
|
canInviteUser: false,
|
|
|
|
canForwardGuest: false,
|
2020-09-11 14:31:38 +00:00
|
|
|
canReturnQueue: false,
|
2021-01-25 17:14:45 +00:00
|
|
|
canEdit: false,
|
|
|
|
canToggleEncryption: false
|
2018-02-19 21:19:39 +00:00
|
|
|
};
|
2019-12-18 21:13:11 +00:00
|
|
|
if (room && room.observe && room.rid) {
|
2019-09-17 14:43:49 +00:00
|
|
|
this.roomObservable = room.observe();
|
|
|
|
this.subscription = this.roomObservable
|
|
|
|
.subscribe((changes) => {
|
|
|
|
if (this.mounted) {
|
|
|
|
this.setState({ room: changes });
|
|
|
|
} else {
|
|
|
|
this.state.room = changes;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2018-02-19 21:19:39 +00:00
|
|
|
}
|
|
|
|
|
2018-03-23 16:49:51 +00:00
|
|
|
async componentDidMount() {
|
2019-09-16 20:26:32 +00:00
|
|
|
this.mounted = true;
|
2020-03-30 20:19:01 +00:00
|
|
|
const { room, member } = this.state;
|
2020-04-30 18:11:34 +00:00
|
|
|
if (room.rid) {
|
2020-07-31 18:22:30 +00:00
|
|
|
if (!room.id && !this.isOmnichannelPreview) {
|
2020-04-30 18:11:34 +00:00
|
|
|
try {
|
|
|
|
const result = await RocketChat.getChannelInfo(room.rid);
|
|
|
|
if (result.success) {
|
|
|
|
this.setState({ room: { ...result.channel, rid: result.channel._id } });
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
log(e);
|
2019-04-08 12:35:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-30 18:11:34 +00:00
|
|
|
if (room && room.t !== 'd' && this.canViewMembers()) {
|
|
|
|
try {
|
|
|
|
const counters = await RocketChat.getRoomCounters(room.rid, room.t);
|
|
|
|
if (counters.success) {
|
|
|
|
this.setState({ membersCount: counters.members, joined: counters.joined });
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
log(e);
|
2018-12-05 20:52:08 +00:00
|
|
|
}
|
2020-04-30 18:11:34 +00:00
|
|
|
} else if (room.t === 'd' && _.isEmpty(member)) {
|
|
|
|
this.updateRoomMember();
|
2018-12-05 20:52:08 +00:00
|
|
|
}
|
2019-06-28 17:02:30 +00:00
|
|
|
|
2020-04-30 18:11:34 +00:00
|
|
|
const canAutoTranslate = await RocketChat.canAutoTranslate();
|
|
|
|
this.setState({ canAutoTranslate });
|
2019-06-28 17:02:30 +00:00
|
|
|
|
2020-04-30 18:11:34 +00:00
|
|
|
this.canAddUser();
|
|
|
|
this.canInviteUser();
|
2020-09-11 14:31:38 +00:00
|
|
|
this.canEdit();
|
2021-01-25 17:14:45 +00:00
|
|
|
this.canToggleEncryption();
|
2020-05-08 17:36:10 +00:00
|
|
|
|
|
|
|
// livechat permissions
|
|
|
|
if (room.t === 'l') {
|
|
|
|
this.canForwardGuest();
|
|
|
|
this.canReturnQueue();
|
|
|
|
}
|
2020-04-30 18:11:34 +00:00
|
|
|
}
|
2018-12-21 10:55:35 +00:00
|
|
|
}
|
|
|
|
|
2018-03-23 16:49:51 +00:00
|
|
|
componentWillUnmount() {
|
2019-09-16 20:26:32 +00:00
|
|
|
if (this.subscription && this.subscription.unsubscribe) {
|
|
|
|
this.subscription.unsubscribe();
|
|
|
|
}
|
2018-03-23 16:49:51 +00:00
|
|
|
}
|
|
|
|
|
2020-07-31 18:22:30 +00:00
|
|
|
get isOmnichannelPreview() {
|
|
|
|
const { room } = this.state;
|
|
|
|
return room.t === 'l' && room.status === 'queued';
|
|
|
|
}
|
|
|
|
|
2018-03-23 16:49:51 +00:00
|
|
|
onPressTouchable = (item) => {
|
2020-08-05 13:15:56 +00:00
|
|
|
const { route, event, params } = item;
|
|
|
|
if (route) {
|
|
|
|
logEvent(events[`RA_GO_${ route.replace('View', '').toUpperCase() }${ params.name ? params.name.toUpperCase() : '' }`]);
|
2019-03-12 16:23:06 +00:00
|
|
|
const { navigation } = this.props;
|
2020-08-05 13:15:56 +00:00
|
|
|
navigation.navigate(route, params);
|
2018-03-23 16:49:51 +00:00
|
|
|
}
|
2020-08-05 13:15:56 +00:00
|
|
|
if (event) {
|
|
|
|
return event();
|
2018-03-23 16:49:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-16 20:26:32 +00:00
|
|
|
canAddUser = async() => {
|
2018-12-05 20:52:08 +00:00
|
|
|
const { room, joined } = this.state;
|
2018-10-16 20:30:04 +00:00
|
|
|
const { rid, t } = room;
|
2019-09-16 20:26:32 +00:00
|
|
|
let canAdd = false;
|
2018-09-25 19:28:42 +00:00
|
|
|
|
2018-12-05 20:52:08 +00:00
|
|
|
const userInRoom = joined;
|
2019-09-16 20:26:32 +00:00
|
|
|
const permissions = await RocketChat.hasPermission(['add-user-to-joined-room', 'add-user-to-any-c-room', 'add-user-to-any-p-room'], rid);
|
2018-04-24 19:34:03 +00:00
|
|
|
|
2019-09-16 20:26:32 +00:00
|
|
|
if (permissions) {
|
|
|
|
if (userInRoom && permissions['add-user-to-joined-room']) {
|
|
|
|
canAdd = true;
|
|
|
|
}
|
|
|
|
if (t === 'c' && permissions['add-user-to-any-c-room']) {
|
|
|
|
canAdd = true;
|
|
|
|
}
|
|
|
|
if (t === 'p' && permissions['add-user-to-any-p-room']) {
|
|
|
|
canAdd = true;
|
|
|
|
}
|
2018-04-24 19:34:03 +00:00
|
|
|
}
|
2019-09-16 20:26:32 +00:00
|
|
|
this.setState({ canAddUser: canAdd });
|
2018-02-19 21:19:39 +00:00
|
|
|
}
|
2018-09-25 19:28:42 +00:00
|
|
|
|
2020-01-28 13:22:35 +00:00
|
|
|
canInviteUser = async() => {
|
|
|
|
const { room } = this.state;
|
|
|
|
const { rid } = room;
|
|
|
|
const permissions = await RocketChat.hasPermission(['create-invite-links'], rid);
|
|
|
|
|
|
|
|
const canInviteUser = permissions && permissions['create-invite-links'];
|
|
|
|
this.setState({ canInviteUser });
|
|
|
|
}
|
|
|
|
|
2020-09-11 14:31:38 +00:00
|
|
|
canEdit = async() => {
|
|
|
|
const { room } = this.state;
|
|
|
|
const { rid } = room;
|
|
|
|
const permissions = await RocketChat.hasPermission(['edit-room'], rid);
|
|
|
|
|
|
|
|
const canEdit = permissions && permissions['edit-room'];
|
|
|
|
this.setState({ canEdit });
|
|
|
|
}
|
|
|
|
|
2021-01-25 17:14:45 +00:00
|
|
|
canToggleEncryption = async() => {
|
|
|
|
const { room } = this.state;
|
|
|
|
const { rid } = room;
|
|
|
|
const permissions = await RocketChat.hasPermission(['toggle-room-e2e-encryption'], rid);
|
|
|
|
|
|
|
|
const canToggleEncryption = permissions && permissions['toggle-room-e2e-encryption'];
|
|
|
|
this.setState({ canToggleEncryption });
|
|
|
|
}
|
|
|
|
|
2019-09-16 20:26:32 +00:00
|
|
|
canViewMembers = async() => {
|
2018-09-25 19:28:42 +00:00
|
|
|
const { room } = this.state;
|
|
|
|
const { rid, t, broadcast } = room;
|
2018-05-24 20:17:45 +00:00
|
|
|
if (broadcast) {
|
|
|
|
const viewBroadcastMemberListPermission = 'view-broadcast-member-list';
|
2019-09-16 20:26:32 +00:00
|
|
|
const permissions = await RocketChat.hasPermission([viewBroadcastMemberListPermission], rid);
|
2018-05-24 20:17:45 +00:00
|
|
|
if (!permissions[viewBroadcastMemberListPermission]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2018-12-05 20:52:08 +00:00
|
|
|
|
|
|
|
// This method is executed only in componentDidMount and returns a value
|
|
|
|
// We save the state to read in render
|
|
|
|
const result = (t === 'c' || t === 'p');
|
|
|
|
this.setState({ canViewMembers: result });
|
|
|
|
return result;
|
2018-05-24 20:17:45 +00:00
|
|
|
}
|
2018-09-25 19:28:42 +00:00
|
|
|
|
2020-05-08 17:36:10 +00:00
|
|
|
canForwardGuest = async() => {
|
|
|
|
const { room } = this.state;
|
|
|
|
const { rid } = room;
|
|
|
|
let result = true;
|
|
|
|
|
|
|
|
const transferLivechatGuest = 'transfer-livechat-guest';
|
|
|
|
const permissions = await RocketChat.hasPermission([transferLivechatGuest], rid);
|
|
|
|
if (!permissions[transferLivechatGuest]) {
|
|
|
|
result = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setState({ canForwardGuest: result });
|
|
|
|
}
|
|
|
|
|
|
|
|
canReturnQueue = async() => {
|
|
|
|
try {
|
|
|
|
const { returnQueue } = await RocketChat.getRoutingConfig();
|
|
|
|
this.setState({ canReturnQueue: returnQueue });
|
|
|
|
} catch {
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-11 14:31:38 +00:00
|
|
|
renderEncryptedSwitch = () => {
|
2021-01-25 17:14:45 +00:00
|
|
|
const { room, canToggleEncryption, canEdit } = this.state;
|
2020-09-11 14:31:38 +00:00
|
|
|
const { encrypted } = room;
|
2021-01-25 17:14:45 +00:00
|
|
|
const { serverVersion } = this.props;
|
|
|
|
let hasPermission = false;
|
|
|
|
if (serverVersion && semver.lt(semver.coerce(serverVersion), '3.11.0')) {
|
|
|
|
hasPermission = canEdit;
|
|
|
|
} else {
|
|
|
|
hasPermission = canToggleEncryption;
|
|
|
|
}
|
2020-09-11 14:31:38 +00:00
|
|
|
return (
|
|
|
|
<Switch
|
|
|
|
value={encrypted}
|
|
|
|
trackColor={SWITCH_TRACK_COLOR}
|
|
|
|
onValueChange={this.toggleEncrypted}
|
2021-01-25 17:14:45 +00:00
|
|
|
disabled={!hasPermission}
|
2020-09-11 14:31:38 +00:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-05-08 17:36:10 +00:00
|
|
|
closeLivechat = () => {
|
|
|
|
const { room: { rid } } = this.state;
|
|
|
|
const { closeRoom } = this.props;
|
|
|
|
|
|
|
|
closeRoom(rid);
|
|
|
|
}
|
|
|
|
|
|
|
|
returnLivechat = () => {
|
|
|
|
const { room: { rid } } = this.state;
|
|
|
|
showConfirmationAlert({
|
|
|
|
message: I18n.t('Would_you_like_to_return_the_inquiry'),
|
2020-08-25 20:04:18 +00:00
|
|
|
confirmationText: I18n.t('Yes'),
|
2020-05-08 17:36:10 +00:00
|
|
|
onPress: async() => {
|
|
|
|
try {
|
|
|
|
await RocketChat.returnLivechat(rid);
|
|
|
|
} catch (e) {
|
|
|
|
showErrorAlert(e.reason, I18n.t('Oops'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-12-12 15:15:10 +00:00
|
|
|
updateRoomMember = async() => {
|
|
|
|
const { room } = this.state;
|
|
|
|
|
|
|
|
try {
|
2020-04-01 12:28:54 +00:00
|
|
|
if (!RocketChat.isGroupChat(room)) {
|
2020-04-09 05:20:57 +00:00
|
|
|
const roomUserId = RocketChat.getUidDirectMessage(room);
|
2020-04-01 12:28:54 +00:00
|
|
|
const result = await RocketChat.getUserInfo(roomUserId);
|
|
|
|
if (result.success) {
|
|
|
|
this.setState({ member: result.user });
|
|
|
|
}
|
2019-04-29 16:03:52 +00:00
|
|
|
}
|
2018-12-12 15:15:10 +00:00
|
|
|
} catch (e) {
|
2019-08-23 13:18:47 +00:00
|
|
|
log(e);
|
2018-12-21 10:55:35 +00:00
|
|
|
this.setState({ member: {} });
|
2018-12-12 15:15:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-01 12:28:54 +00:00
|
|
|
addUser = async() => {
|
|
|
|
const { room } = this.state;
|
|
|
|
const { setLoadingInvite, navigation } = this.props;
|
|
|
|
const { rid } = room;
|
|
|
|
try {
|
|
|
|
setLoadingInvite(true);
|
|
|
|
await RocketChat.addUsersToRoom(rid);
|
|
|
|
navigation.pop();
|
|
|
|
} catch (e) {
|
|
|
|
log(e);
|
|
|
|
} finally {
|
|
|
|
setLoadingInvite(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-11 14:31:38 +00:00
|
|
|
toggleBlockUser = async() => {
|
2020-08-05 13:15:56 +00:00
|
|
|
logEvent(events.RA_TOGGLE_BLOCK_USER);
|
2018-09-25 19:28:42 +00:00
|
|
|
const { room } = this.state;
|
|
|
|
const { rid, blocker } = room;
|
2018-03-29 17:55:37 +00:00
|
|
|
const { member } = this.state;
|
2018-05-18 17:55:08 +00:00
|
|
|
try {
|
2020-09-11 14:31:38 +00:00
|
|
|
await RocketChat.toggleBlockUser(rid, member._id, !blocker);
|
2018-05-18 17:55:08 +00:00
|
|
|
} catch (e) {
|
2020-08-05 13:15:56 +00:00
|
|
|
logEvent(events.RA_TOGGLE_BLOCK_USER_F);
|
2019-08-23 13:18:47 +00:00
|
|
|
log(e);
|
2018-05-18 17:55:08 +00:00
|
|
|
}
|
2018-03-23 16:49:51 +00:00
|
|
|
}
|
|
|
|
|
2020-09-11 14:31:38 +00:00
|
|
|
toggleEncrypted = async() => {
|
|
|
|
logEvent(events.RA_TOGGLE_ENCRYPTED);
|
|
|
|
const { room } = this.state;
|
|
|
|
const { rid } = room;
|
|
|
|
const db = database.active;
|
|
|
|
|
|
|
|
// Toggle encrypted value
|
|
|
|
const encrypted = !room.encrypted;
|
|
|
|
try {
|
|
|
|
// Instantly feedback to the user
|
|
|
|
await db.action(async() => {
|
|
|
|
await room.update(protectedFunction((r) => {
|
|
|
|
r.encrypted = encrypted;
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
try {
|
|
|
|
// Send new room setting value to server
|
|
|
|
const { result } = await RocketChat.saveRoomSettings(rid, { encrypted });
|
|
|
|
// If it was saved successfully
|
|
|
|
if (result) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} catch {
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
// If something goes wrong we go back to the previous value
|
|
|
|
await db.action(async() => {
|
|
|
|
await room.update(protectedFunction((r) => {
|
|
|
|
r.encrypted = room.encrypted;
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
} catch (e) {
|
|
|
|
logEvent(events.RA_TOGGLE_ENCRYPTED_F);
|
|
|
|
log(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-29 21:19:12 +00:00
|
|
|
handleShare = () => {
|
2020-08-05 13:15:56 +00:00
|
|
|
logEvent(events.RA_SHARE);
|
2019-05-29 21:19:12 +00:00
|
|
|
const { room } = this.state;
|
|
|
|
const permalink = RocketChat.getPermalinkChannel(room);
|
2020-02-05 16:40:44 +00:00
|
|
|
if (!permalink) {
|
|
|
|
return;
|
|
|
|
}
|
2019-05-29 21:19:12 +00:00
|
|
|
Share.share({
|
|
|
|
message: permalink
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2018-03-23 16:49:51 +00:00
|
|
|
leaveChannel = () => {
|
|
|
|
const { room } = this.state;
|
2018-09-25 19:28:42 +00:00
|
|
|
const { leaveRoom } = this.props;
|
|
|
|
|
2018-03-23 16:49:51 +00:00
|
|
|
Alert.alert(
|
2018-06-01 17:38:13 +00:00
|
|
|
I18n.t('Are_you_sure_question_mark'),
|
2020-04-30 16:24:49 +00:00
|
|
|
I18n.t('Are_you_sure_you_want_to_leave_the_room', { room: RocketChat.getRoomTitle(room) }),
|
2018-03-23 16:49:51 +00:00
|
|
|
[
|
|
|
|
{
|
2018-06-01 17:38:13 +00:00
|
|
|
text: I18n.t('Cancel'),
|
2018-03-23 16:49:51 +00:00
|
|
|
style: 'cancel'
|
|
|
|
},
|
|
|
|
{
|
2018-06-01 17:38:13 +00:00
|
|
|
text: I18n.t('Yes_action_it', { action: I18n.t('leave') }),
|
2018-03-23 16:49:51 +00:00
|
|
|
style: 'destructive',
|
2018-12-05 20:52:08 +00:00
|
|
|
onPress: () => leaveRoom(room.rid, room.t)
|
2018-03-23 16:49:51 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-10-30 13:59:44 +00:00
|
|
|
renderRoomInfo = () => {
|
2018-03-29 17:55:37 +00:00
|
|
|
const { room, member } = this.state;
|
2020-10-30 13:51:04 +00:00
|
|
|
const {
|
2020-10-30 13:59:44 +00:00
|
|
|
rid, name, t, topic
|
2020-10-30 13:51:04 +00:00
|
|
|
} = room;
|
2020-10-30 13:59:44 +00:00
|
|
|
const { theme, fontScale } = this.props;
|
2018-09-25 19:28:42 +00:00
|
|
|
|
2020-04-01 12:28:54 +00:00
|
|
|
const avatar = RocketChat.getRoomAvatar(room);
|
2020-10-30 13:59:44 +00:00
|
|
|
const isGroupChat = RocketChat.isGroupChat(room);
|
2020-04-01 12:28:54 +00:00
|
|
|
|
2018-03-02 15:11:34 +00:00
|
|
|
return (
|
2020-10-30 13:59:44 +00:00
|
|
|
<List.Section>
|
|
|
|
<List.Separator />
|
|
|
|
<Touch
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'RoomInfoView',
|
|
|
|
// forward room only if room isn't joined
|
|
|
|
params: {
|
|
|
|
rid, t, room, member
|
2020-04-01 12:28:54 +00:00
|
|
|
}
|
2020-10-30 13:59:44 +00:00
|
|
|
})}
|
|
|
|
style={{ backgroundColor: themes[theme].backgroundColor }}
|
|
|
|
accessibilityLabel={I18n.t('Room_Info')}
|
|
|
|
accessibilityTraits='button'
|
|
|
|
enabled={!isGroupChat}
|
|
|
|
testID='room-actions-info'
|
|
|
|
theme={theme}
|
|
|
|
>
|
|
|
|
<View style={[styles.roomInfoContainer, { height: 72 * fontScale }]}>
|
|
|
|
<Avatar
|
|
|
|
text={avatar}
|
|
|
|
style={styles.avatar}
|
2020-10-30 18:31:04 +00:00
|
|
|
size={50 * fontScale}
|
2020-10-30 13:59:44 +00:00
|
|
|
type={t}
|
|
|
|
rid={rid}
|
|
|
|
>
|
|
|
|
{t === 'd' && member._id ? <Status style={sharedStyles.status} id={member._id} /> : null }
|
|
|
|
</Avatar>
|
|
|
|
<View style={styles.roomTitleContainer}>
|
|
|
|
{room.t === 'd'
|
|
|
|
? <Text style={[styles.roomTitle, { color: themes[theme].titleText }]} numberOfLines={1}>{room.fname}</Text>
|
|
|
|
: (
|
|
|
|
<View style={styles.roomTitleRow}>
|
|
|
|
<RoomTypeIcon type={room.prid ? 'discussion' : room.t} status={room.visitor?.status} theme={theme} />
|
|
|
|
<Text style={[styles.roomTitle, { color: themes[theme].titleText }]} numberOfLines={1}>{RocketChat.getRoomTitle(room)}</Text>
|
|
|
|
</View>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
<Markdown
|
|
|
|
preview
|
|
|
|
msg={t === 'd' ? `@${ name }` : topic}
|
|
|
|
style={[styles.roomDescription, { color: themes[theme].auxiliaryText }]}
|
|
|
|
numberOfLines={1}
|
|
|
|
theme={theme}
|
|
|
|
/>
|
|
|
|
{room.t === 'd' && <Markdown msg={member.statusText} style={[styles.roomDescription, { color: themes[theme].auxiliaryText }]} preview theme={theme} numberOfLines={1} />}
|
|
|
|
</View>
|
2020-11-30 21:47:05 +00:00
|
|
|
{isGroupChat ? null : <List.Icon name='chevron-right' style={styles.actionIndicator} />}
|
2020-04-01 12:28:54 +00:00
|
|
|
</View>
|
2020-10-30 13:59:44 +00:00
|
|
|
</Touch>
|
|
|
|
<List.Separator />
|
|
|
|
</List.Section>
|
2018-03-02 15:11:34 +00:00
|
|
|
);
|
|
|
|
}
|
2018-02-19 21:19:39 +00:00
|
|
|
|
2020-10-30 13:59:44 +00:00
|
|
|
renderJitsi = () => {
|
|
|
|
const { room } = this.state;
|
|
|
|
const { jitsiEnabled } = this.props;
|
|
|
|
if (!jitsiEnabled) {
|
|
|
|
return null;
|
|
|
|
}
|
2019-12-04 16:39:53 +00:00
|
|
|
return (
|
2020-10-30 13:59:44 +00:00
|
|
|
<List.Section>
|
|
|
|
<List.Separator />
|
|
|
|
<List.Item
|
|
|
|
title='Voice_call'
|
|
|
|
onPress={() => RocketChat.callJitsi(room?.rid, true)}
|
|
|
|
testID='room-actions-voice'
|
|
|
|
left={() => <List.Icon name='phone' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
<List.Item
|
|
|
|
title='Video_call'
|
|
|
|
onPress={() => RocketChat.callJitsi(room?.rid)}
|
|
|
|
testID='room-actions-video'
|
|
|
|
left={() => <List.Icon name='camera' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</List.Section>
|
2019-12-04 16:39:53 +00:00
|
|
|
);
|
|
|
|
}
|
2018-02-19 21:19:39 +00:00
|
|
|
|
2020-10-30 13:59:44 +00:00
|
|
|
renderE2EEncryption = () => {
|
2021-01-25 17:14:45 +00:00
|
|
|
const { room } = this.state;
|
|
|
|
const { encryptionEnabled } = this.props;
|
2020-10-30 13:59:44 +00:00
|
|
|
|
2021-01-25 17:14:45 +00:00
|
|
|
// If this room type can be encrypted
|
|
|
|
// If e2e is enabled
|
|
|
|
if (E2E_ROOM_TYPES[room?.t] && encryptionEnabled) {
|
2020-10-30 13:59:44 +00:00
|
|
|
return (
|
|
|
|
<List.Section>
|
|
|
|
<List.Separator />
|
|
|
|
<List.Item
|
|
|
|
title='Encrypted'
|
|
|
|
testID='room-actions-encrypt'
|
|
|
|
left={() => <List.Icon name='encrypted' />}
|
|
|
|
right={this.renderEncryptedSwitch}
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</List.Section>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return null;
|
2018-02-19 21:19:39 +00:00
|
|
|
}
|
|
|
|
|
2020-10-30 13:59:44 +00:00
|
|
|
renderLastSection = () => {
|
|
|
|
const { room, joined } = this.state;
|
2019-12-04 16:39:53 +00:00
|
|
|
const { theme } = this.props;
|
2020-10-30 13:59:44 +00:00
|
|
|
const { t, blocker } = room;
|
|
|
|
|
|
|
|
if (!joined || t === 'l') {
|
|
|
|
return null;
|
2018-02-19 21:19:39 +00:00
|
|
|
}
|
2020-10-30 13:59:44 +00:00
|
|
|
|
|
|
|
if (t === 'd') {
|
|
|
|
return (
|
|
|
|
<List.Section>
|
|
|
|
<List.Separator />
|
|
|
|
<List.Item
|
|
|
|
title={`${ blocker ? 'Unblock' : 'Block' }_user`}
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
event: this.toggleBlockUser
|
|
|
|
})}
|
|
|
|
testID='room-actions-block-user'
|
2020-11-30 20:00:31 +00:00
|
|
|
left={() => <List.Icon name='ignore' color={themes[theme].dangerColor} />}
|
2020-10-30 13:59:44 +00:00
|
|
|
showActionIndicator
|
|
|
|
color={themes[theme].dangerColor}
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</List.Section>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (t === 'p' || t === 'c') {
|
|
|
|
return (
|
|
|
|
<List.Section>
|
|
|
|
<List.Separator />
|
|
|
|
<List.Item
|
|
|
|
title='Leave_channel'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
event: this.leaveChannel
|
|
|
|
})}
|
|
|
|
testID='room-actions-leave-channel'
|
|
|
|
left={() => <List.Icon name='logout' color={themes[theme].dangerColor} />}
|
|
|
|
showActionIndicator
|
|
|
|
color={themes[theme].dangerColor}
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</List.Section>
|
|
|
|
);
|
2018-04-24 19:34:03 +00:00
|
|
|
}
|
2018-02-19 21:19:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2020-10-30 13:59:44 +00:00
|
|
|
const {
|
|
|
|
room, membersCount, canViewMembers, canAddUser, canInviteUser, joined, canAutoTranslate, canForwardGuest, canReturnQueue
|
|
|
|
} = this.state;
|
|
|
|
const {
|
|
|
|
rid, t, encrypted
|
|
|
|
} = room;
|
|
|
|
const isGroupChat = RocketChat.isGroupChat(room);
|
2018-02-19 21:19:39 +00:00
|
|
|
return (
|
2020-10-30 13:59:44 +00:00
|
|
|
<SafeAreaView testID='room-actions-view'>
|
|
|
|
<StatusBar />
|
|
|
|
<List.Container>
|
|
|
|
{this.renderRoomInfo()}
|
|
|
|
{this.renderJitsi()}
|
|
|
|
{this.renderE2EEncryption()}
|
|
|
|
<List.Section>
|
|
|
|
<List.Separator />
|
|
|
|
|
|
|
|
{(['c', 'p'].includes(t) && canViewMembers) || isGroupChat
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Members'
|
|
|
|
subtitle={membersCount > 0 ? `${ membersCount } ${ I18n.t('members') }` : null}
|
|
|
|
onPress={() => this.onPressTouchable({ route: 'RoomMembersView', params: { rid, room } })}
|
|
|
|
testID='room-actions-members'
|
|
|
|
left={() => <List.Icon name='team' />}
|
|
|
|
showActionIndicator
|
|
|
|
translateSubtitle={false}
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['c', 'p'].includes(t) && canAddUser
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Add_users'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'SelectedUsersView',
|
|
|
|
params: {
|
|
|
|
rid,
|
|
|
|
title: I18n.t('Add_users'),
|
|
|
|
nextAction: this.addUser
|
|
|
|
}
|
|
|
|
})}
|
|
|
|
testID='room-actions-add-user'
|
|
|
|
left={() => <List.Icon name='add' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['c', 'p'].includes(t) && canInviteUser
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Invite_users'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'InviteUsersView',
|
|
|
|
params: { rid }
|
|
|
|
})}
|
|
|
|
testID='room-actions-invite-user'
|
|
|
|
left={() => <List.Icon name='user-add' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['c', 'p', 'd'].includes(t)
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Files'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'MessagesView',
|
|
|
|
params: { rid, t, name: 'Files' }
|
|
|
|
})}
|
|
|
|
testID='room-actions-files'
|
|
|
|
left={() => <List.Icon name='attach' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['c', 'p', 'd'].includes(t)
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Mentions'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'MessagesView',
|
|
|
|
params: { rid, t, name: 'Mentions' }
|
|
|
|
})}
|
|
|
|
testID='room-actions-mentioned'
|
|
|
|
left={() => <List.Icon name='mention' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['c', 'p', 'd'].includes(t)
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Starred'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'MessagesView',
|
|
|
|
params: { rid, t, name: 'Starred' }
|
|
|
|
})}
|
|
|
|
testID='room-actions-starred'
|
|
|
|
left={() => <List.Icon name='star' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['c', 'p', 'd'].includes(t)
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Search'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'SearchMessagesView',
|
|
|
|
params: { rid, encrypted }
|
|
|
|
})}
|
|
|
|
testID='room-actions-search'
|
|
|
|
left={() => <List.Icon name='search' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['c', 'p', 'd'].includes(t)
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Share'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
event: this.handleShare
|
|
|
|
})}
|
|
|
|
testID='room-actions-share'
|
|
|
|
left={() => <List.Icon name='share' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['c', 'p', 'd'].includes(t)
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Pinned'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'MessagesView',
|
|
|
|
params: { rid, t, name: 'Pinned' }
|
|
|
|
})}
|
|
|
|
testID='room-actions-pinned'
|
|
|
|
left={() => <List.Icon name='pin' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['c', 'p', 'd'].includes(t) && canAutoTranslate
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Auto_Translate'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'AutoTranslateView',
|
|
|
|
params: { rid, room }
|
|
|
|
})}
|
|
|
|
testID='room-actions-auto-translate'
|
|
|
|
left={() => <List.Icon name='language' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['c', 'p', 'd'].includes(t) && joined
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Notifications'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'NotificationPrefView',
|
|
|
|
params: { rid, room }
|
|
|
|
})}
|
|
|
|
testID='room-actions-notifications'
|
|
|
|
left={() => <List.Icon name='notification' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['l'].includes(t) && !this.isOmnichannelPreview
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Close'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
event: this.closeLivechat
|
|
|
|
})}
|
|
|
|
left={() => <List.Icon name='close' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['l'].includes(t) && !this.isOmnichannelPreview && canForwardGuest
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Forward'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'ForwardLivechatView',
|
|
|
|
params: { rid }
|
|
|
|
})}
|
|
|
|
left={() => <List.Icon name='user-forward' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['l'].includes(t) && !this.isOmnichannelPreview && canReturnQueue
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Return'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
event: this.returnLivechat
|
|
|
|
})}
|
|
|
|
left={() => <List.Icon name='undo' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
|
|
|
|
{['l'].includes(t) && !this.isOmnichannelPreview
|
|
|
|
? (
|
|
|
|
<>
|
|
|
|
<List.Item
|
|
|
|
title='Navigation_history'
|
|
|
|
onPress={() => this.onPressTouchable({
|
|
|
|
route: 'VisitorNavigationView',
|
|
|
|
params: { rid }
|
|
|
|
})}
|
|
|
|
left={() => <List.Icon name='history' />}
|
|
|
|
showActionIndicator
|
|
|
|
/>
|
|
|
|
<List.Separator />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
: null}
|
|
|
|
</List.Section>
|
|
|
|
|
|
|
|
{this.renderLastSection()}
|
|
|
|
</List.Container>
|
2018-08-01 19:35:06 +00:00
|
|
|
</SafeAreaView>
|
2018-02-19 21:19:39 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2019-08-07 13:51:34 +00:00
|
|
|
|
|
|
|
const mapStateToProps = state => ({
|
2020-09-11 14:31:38 +00:00
|
|
|
jitsiEnabled: state.settings.Jitsi_Enabled || false,
|
2021-01-25 17:14:45 +00:00
|
|
|
encryptionEnabled: state.encryption.enabled,
|
|
|
|
serverVersion: state.server.version
|
2019-08-07 13:51:34 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
const mapDispatchToProps = dispatch => ({
|
2020-04-01 12:28:54 +00:00
|
|
|
leaveRoom: (rid, t) => dispatch(leaveRoomAction(rid, t)),
|
2020-05-08 17:36:10 +00:00
|
|
|
closeRoom: rid => dispatch(closeRoomAction(rid)),
|
2020-04-01 12:28:54 +00:00
|
|
|
setLoadingInvite: loading => dispatch(setLoadingAction(loading))
|
2019-08-07 13:51:34 +00:00
|
|
|
});
|
|
|
|
|
2020-10-30 13:59:44 +00:00
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(withDimensions(RoomActionsView)));
|