Chore: Migrate RoomActionsView to Typescript (#3750)

This commit is contained in:
Diego Mello 2022-03-02 11:49:43 -03:00 committed by GitHub
parent 6b3730ce43
commit 6626510f50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 213 additions and 153 deletions

View File

@ -4,7 +4,7 @@ import { ERoomType } from '../definitions/ERoomType';
import { ROOM } from './actionsTypes';
// TYPE RETURN RELATED
type ISelected = Record<string, string>;
type ISelected = string[];
export interface ITransferData {
roomId: string;

View File

@ -1,26 +1,26 @@
import { Action } from 'redux';
import { ISettings, TSettings } from '../reducers/settings';
import { TSettingsState, TSupportedSettings, TSettingsValues } from '../reducers/settings';
import { SETTINGS } from './actionsTypes';
interface IAddSettings extends Action {
payload: ISettings;
payload: TSettingsState;
}
interface IUpdateSettings extends Action {
payload: { id: string; value: TSettings };
payload: { id: TSupportedSettings; value: TSettingsValues };
}
export type IActionSettings = IAddSettings & IUpdateSettings;
export function addSettings(settings: ISettings): IAddSettings {
export function addSettings(settings: TSettingsState): IAddSettings {
return {
type: SETTINGS.ADD,
payload: settings
};
}
export function updateSettings(id: string, value: TSettings): IUpdateSettings {
export function updateSettings(id: TSupportedSettings, value: TSettingsValues): IUpdateSettings {
return {
type: SETTINGS.UPDATE,
payload: { id, value }

View File

@ -206,4 +206,4 @@ export default {
Canned_Responses_Enable: {
type: 'valueAsBoolean'
}
};
} as const;

View File

@ -12,7 +12,7 @@ export enum SubscriptionType {
DIRECT = 'd',
CHANNEL = 'c',
OMNICHANNEL = 'l',
E2E = 'e2e',
E2E = 'e2e', // FIXME: this is not a type of subscription
THREAD = 'thread' // FIXME: this is not a type of subscription
}
@ -36,7 +36,7 @@ export interface ISubscription {
_updatedAt?: string; // from server
v?: IVisitor;
f: boolean;
t: SubscriptionType;
t: string; // TODO: we need to review this type later
ts: string | Date;
ls: Date;
name: string;
@ -81,6 +81,7 @@ export interface ISubscription {
usernames?: string[];
visitor?: IVisitor;
departmentId?: string;
status?: string;
servedBy?: IServedBy;
livechatData?: any;
tags?: string[];

View File

@ -30,6 +30,7 @@ export interface IBaseScreen<T extends Record<string, object | undefined>, S ext
route: RouteProp<T, S>;
dispatch: Dispatch;
theme: string;
isMasterDetail: boolean;
}
export * from './redux';

View File

@ -28,15 +28,15 @@ import { IRoles } from '../../reducers/roles';
import { IRoom } from '../../reducers/room';
import { ISelectedUsers } from '../../reducers/selectedUsers';
import { IServer } from '../../reducers/server';
import { ISettings } from '../../reducers/settings';
import { TSettingsState } from '../../reducers/settings';
import { IShare } from '../../reducers/share';
import { IPermissionsState } from '../../reducers/permissions';
import { IEnterpriseModules } from '../../reducers/enterpriseModules';
export interface IApplicationState {
settings: ISettings;
meteor: IConnect;
settings: TSettingsState;
login: ILogin;
meteor: IConnect;
server: IServer;
selectedUsers: ISelectedUsers;
app: IApp;

View File

@ -10,7 +10,7 @@ export const E2E_BANNER_TYPE = {
REQUEST_PASSWORD: 'REQUEST_PASSWORD',
SAVE_PASSWORD: 'SAVE_PASSWORD'
};
export const E2E_ROOM_TYPES = {
export const E2E_ROOM_TYPES: Record<string, string> = {
d: 'd',
p: 'p'
};

View File

@ -1,4 +1,4 @@
import { IRoom } from '../../definitions';
import { IRoom, SubscriptionType } from '../../definitions';
import { getSubscriptionByRoomId } from '../database/services/Subscription';
import RocketChat from '../rocketchat';
@ -10,7 +10,7 @@ const getRoomInfo = async (rid: string): Promise<Pick<IRoom, 'rid' | 'name' | 'f
rid,
name: result.name,
fname: result.fname,
t: result.t
t: result.t as SubscriptionType
};
}

View File

@ -1,6 +1,6 @@
import { addSettings, clearSettings, updateSettings } from '../actions/settings';
import { mockedStore } from './mockedStore';
import { initialState } from './settings';
import { initialState, TSettingsState } from './settings';
describe('test settings reducer', () => {
it('should return initial state', () => {
@ -8,7 +8,11 @@ describe('test settings reducer', () => {
expect(state).toEqual(initialState);
});
const settings = { API_Use_REST_For_DDP_Calls: true, FileUpload_MaxFileSize: 600857600, Jitsi_URL_Room_Prefix: 'RocketChat' };
const settings: TSettingsState = {
API_Use_REST_For_DDP_Calls: true,
FileUpload_MaxFileSize: 600857600,
Jitsi_URL_Room_Prefix: 'RocketChat'
};
it('should return modified store after call addSettings action', () => {
mockedStore.dispatch(addSettings(settings));

View File

@ -1,13 +1,17 @@
import { IActionSettings } from '../actions/settings';
import { SETTINGS } from '../actions/actionsTypes';
import settings from '../constants/settings';
export type TSettings = string | number | boolean | string[];
export type TSupportedSettings = keyof typeof settings;
export type TSettingsValues = string | number | boolean | string[];
export type ISettings = Record<string, TSettings>;
export type TSettingsState = {
[K in TSupportedSettings]?: TSettingsValues;
};
export const initialState: ISettings = {};
export const initialState: TSettingsState = {};
export default (state = initialState, action: IActionSettings): ISettings => {
export default (state = initialState, action: IActionSettings): TSettingsState => {
switch (action.type) {
case SETTINGS.ADD:
return {

View File

@ -19,35 +19,37 @@ export type ChatsStackParamList = {
NewMessageStackNavigator: any;
NewMessageStack: undefined;
RoomsListView: undefined;
RoomView?: {
rid: string;
t: SubscriptionType;
tmid?: string;
message?: object; // TODO: TMessageModel?
name?: string;
fname?: string;
prid?: string;
room?: TSubscriptionModel | { rid: string; t: string; name?: string; fname?: string; prid?: string };
jumpToMessageId?: string;
jumpToThreadId?: string;
roomUserId?: string | null;
usedCannedResponse?: string;
};
RoomView:
| {
rid: string;
t: SubscriptionType;
tmid?: string;
message?: object; // TODO: TMessageModel?
name?: string;
fname?: string;
prid?: string;
room?: TSubscriptionModel | { rid: string; t: string; name?: string; fname?: string; prid?: string };
jumpToMessageId?: string;
jumpToThreadId?: string;
roomUserId?: string | null;
usedCannedResponse?: string;
}
| undefined; // Navigates back to RoomView already on stack
RoomActionsView: {
room?: ISubscription;
room: TSubscriptionModel;
member: any;
rid: string;
t: SubscriptionType;
joined: boolean;
};
SelectListView: {
data: IRoom[];
data?: IRoom[];
title: string;
infoText: string;
infoText?: string;
nextAction: (selected: string[]) => void;
showAlert: () => void;
isSearch: boolean;
onSearch: (text: string) => Partial<IRoom[]>;
showAlert?: () => void;
isSearch?: boolean;
onSearch?: (text: string) => Promise<Partial<IRoom[]> | any>;
isRadio?: boolean;
};
RoomInfoView: {

View File

@ -1,9 +1,9 @@
import { ChatsStackParamList } from '../stacks/types';
import Navigation from '../lib/Navigation';
import RocketChat from '../lib/rocketchat';
import { IVisitor, SubscriptionType } from '../definitions/ISubscription';
import { ISubscription, IVisitor, SubscriptionType, TSubscriptionModel } from '../definitions/ISubscription';
export interface IGoRoomItem {
interface IGoRoomItem {
search?: boolean; // comes from spotlight
username?: string;
t?: SubscriptionType;
@ -13,12 +13,14 @@ export interface IGoRoomItem {
visitor?: IVisitor;
}
export type TGoRoomItem = IGoRoomItem | TSubscriptionModel | ISubscription;
const navigate = ({
item,
isMasterDetail,
...props
}: {
item: IGoRoomItem;
item: TGoRoomItem;
isMasterDetail: boolean;
navigationMethod?: () => ChatsStackParamList;
}) => {
@ -45,13 +47,13 @@ export const goRoom = async ({
isMasterDetail = false,
...props
}: {
item: IGoRoomItem;
item: TGoRoomItem;
isMasterDetail: boolean;
navigationMethod?: any;
jumpToMessageId?: string;
usedCannedResponse?: string;
}): Promise<void> => {
if (item.t === SubscriptionType.DIRECT && item?.search) {
if (!('id' in item) && item.t === SubscriptionType.DIRECT && item?.search) {
// if user is using the search we need first to join/create room
try {
const { username } = item;

View File

@ -115,7 +115,7 @@ const CannedResponseDetail = ({ navigation, route }: ICannedResponseDetailProps)
t: room.t,
fname: name
}),
t: room.t,
t: room.t as any,
roomUserId: RocketChat.getUidDirectMessage(room),
usedCannedResponse: item.text
};

View File

@ -118,7 +118,7 @@ const CannedResponsesListView = ({ navigation, route }: ICannedResponsesListView
t: room.t,
fname: name
}),
t: room.t,
t: room.t as any,
roomUserId: RocketChat.getUidDirectMessage(room),
usedCannedResponse: item.text
};

View File

@ -1,38 +1,94 @@
import { Q } from '@nozbe/watermelondb';
import { StackNavigationOptions } from '@react-navigation/stack';
import isEmpty from 'lodash/isEmpty';
import React from 'react';
import PropTypes from 'prop-types';
import { Share, Switch, Text, View } from 'react-native';
import { connect } from 'react-redux';
import isEmpty from 'lodash/isEmpty';
import { Q } from '@nozbe/watermelondb';
import { Observable, Subscription } from 'rxjs';
import { compareServerVersion } from '../../lib/utils';
import Touch from '../../utils/touch';
import { setLoading } from '../../actions/selectedUsers';
import { closeRoom, leaveRoom } from '../../actions/room';
import sharedStyles from '../Styles';
import Avatar from '../../containers/Avatar';
import Status from '../../containers/Status';
import * as List from '../../containers/List';
import RocketChat from '../../lib/rocketchat';
import log, { events, logEvent } from '../../utils/log';
import RoomTypeIcon from '../../containers/RoomTypeIcon';
import I18n from '../../i18n';
import StatusBar from '../../containers/StatusBar';
import { setLoading } from '../../actions/selectedUsers';
import { SWITCH_TRACK_COLOR, themes } from '../../constants/colors';
import { withTheme } from '../../theme';
import Avatar from '../../containers/Avatar';
import * as HeaderButton from '../../containers/HeaderButton';
import * as List from '../../containers/List';
import { MarkdownPreview } from '../../containers/markdown';
import { showConfirmationAlert, showErrorAlert } from '../../utils/info';
import RoomTypeIcon from '../../containers/RoomTypeIcon';
import SafeAreaView from '../../containers/SafeAreaView';
import Status from '../../containers/Status';
import StatusBar from '../../containers/StatusBar';
import { IApplicationState, IBaseScreen, IRoom, ISubscription, IUser, TSubscriptionModel } from '../../definitions';
import { withDimensions } from '../../dimensions';
import I18n from '../../i18n';
import database from '../../lib/database';
import { E2E_ROOM_TYPES } from '../../lib/encryption/constants';
import protectedFunction from '../../lib/methods/helpers/protectedFunction';
import database from '../../lib/database';
import { withDimensions } from '../../dimensions';
import RocketChat from '../../lib/rocketchat';
import { compareServerVersion } from '../../lib/utils';
import { getUserSelector } from '../../selectors/login';
import { ChatsStackParamList } from '../../stacks/types';
import { withTheme } from '../../theme';
import { showConfirmationAlert, showErrorAlert } from '../../utils/info';
import log, { events, logEvent } from '../../utils/log';
import Touch from '../../utils/touch';
import sharedStyles from '../Styles';
import styles from './styles';
import { ERoomType } from '../../definitions/ERoomType';
class RoomActionsView extends React.Component {
static navigationOptions = ({ navigation, isMasterDetail }) => {
const options = {
interface IRoomActionsViewProps extends IBaseScreen<ChatsStackParamList, 'RoomActionsView'> {
userId: string;
jitsiEnabled: boolean;
jitsiEnableTeams: boolean;
jitsiEnableChannels: boolean;
encryptionEnabled: boolean;
fontScale: number;
serverVersion: string | null;
addUserToJoinedRoomPermission?: string[];
addUserToAnyCRoomPermission?: string[];
addUserToAnyPRoomPermission?: string[];
createInviteLinksPermission?: string[];
editRoomPermission?: string[];
toggleRoomE2EEncryptionPermission?: string[];
viewBroadcastMemberListPermission?: string[];
transferLivechatGuestPermission?: string[];
createTeamPermission?: string[];
addTeamChannelPermission?: string[];
convertTeamPermission?: string[];
viewCannedResponsesPermission?: string[];
}
interface IRoomActionsViewState {
room: TSubscriptionModel;
membersCount: number;
member: Partial<IUser>;
joined: boolean;
canViewMembers: boolean;
canAutoTranslate: boolean;
canAddUser: boolean;
canInviteUser: boolean;
canForwardGuest: boolean;
canReturnQueue: boolean;
canEdit: boolean;
canToggleEncryption: boolean;
canCreateTeam: boolean;
canAddChannelToTeam: boolean;
canConvertTeam: boolean;
canViewCannedResponse: boolean;
}
class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomActionsViewState> {
private mounted: boolean;
private rid: string;
private t: string;
private joined: boolean;
private roomObservable?: Observable<TSubscriptionModel>;
private subscription?: Subscription;
static navigationOptions = ({
navigation,
isMasterDetail
}: Pick<IRoomActionsViewProps, 'navigation' | 'isMasterDetail'>): StackNavigationOptions => {
const options: StackNavigationOptions = {
title: I18n.t('Actions')
};
if (isMasterDetail) {
@ -41,34 +97,7 @@ class RoomActionsView extends React.Component {
return options;
};
static propTypes = {
navigation: PropTypes.object,
route: PropTypes.object,
leaveRoom: PropTypes.func,
jitsiEnabled: PropTypes.bool,
jitsiEnableTeams: PropTypes.bool,
jitsiEnableChannels: PropTypes.bool,
encryptionEnabled: PropTypes.bool,
setLoadingInvite: PropTypes.func,
closeRoom: PropTypes.func,
theme: PropTypes.string,
fontScale: PropTypes.number,
serverVersion: PropTypes.string,
addUserToJoinedRoomPermission: PropTypes.array,
addUserToAnyCRoomPermission: PropTypes.array,
addUserToAnyPRoomPermission: PropTypes.array,
createInviteLinksPermission: PropTypes.array,
editRoomPermission: PropTypes.array,
toggleRoomE2EEncryptionPermission: PropTypes.array,
viewBroadcastMemberListPermission: PropTypes.array,
transferLivechatGuestPermission: PropTypes.array,
createTeamPermission: PropTypes.array,
addTeamChannelPermission: PropTypes.array,
convertTeamPermission: PropTypes.array,
viewCannedResponsesPermission: PropTypes.array
};
constructor(props) {
constructor(props: IRoomActionsViewProps) {
super(props);
this.mounted = false;
const room = props.route.params?.room;
@ -77,7 +106,7 @@ class RoomActionsView extends React.Component {
this.t = props.route.params?.t;
this.joined = props.route.params?.joined;
this.state = {
room: room || { rid: this.rid, t: this.t },
room: room || ({ rid: this.rid, t: this.t } as any),
membersCount: 0,
member: member || {},
joined: !!room,
@ -100,6 +129,7 @@ class RoomActionsView extends React.Component {
if (this.mounted) {
this.setState({ room: changes });
} else {
// @ts-ignore
this.state.room = changes;
}
});
@ -123,7 +153,7 @@ class RoomActionsView extends React.Component {
if (room && room.t !== 'd' && this.canViewMembers()) {
try {
const counters = await RocketChat.getRoomCounters(room.rid, room.t);
const counters = await RocketChat.getRoomCounters(room.rid, room.t as any);
if (counters.success) {
this.setState({ membersCount: counters.members, joined: counters.joined });
}
@ -177,9 +207,15 @@ class RoomActionsView extends React.Component {
return room.t === 'l' && room.status === 'queued' && !this.joined;
}
onPressTouchable = item => {
// TODO: assert params required for navigation
onPressTouchable = (item: { route?: keyof ChatsStackParamList; params?: object; event?: Function }) => {
const { route, event, params } = item;
if (route) {
/**
* TODO: params can vary too much and ts is going to be happy
* Instead of playing with this, we should think on a better `logEvent` function
*/
// @ts-ignore
logEvent(events[`RA_GO_${route.replace('View', '').toUpperCase()}${params.name ? params.name.toUpperCase() : ''}`]);
const { navigation } = this.props;
navigation.navigate(route, params);
@ -349,7 +385,7 @@ class RoomActionsView extends React.Component {
onPress: async () => {
try {
await RocketChat.returnLivechat(rid);
} catch (e) {
} catch (e: any) {
showErrorAlert(e.reason, I18n.t('Oops'));
}
}
@ -364,7 +400,7 @@ class RoomActionsView extends React.Component {
const roomUserId = RocketChat.getUidDirectMessage(room);
const result = await RocketChat.getUserInfo(roomUserId);
if (result.success) {
this.setState({ member: result.user });
this.setState({ member: result.user as any });
}
}
} catch (e) {
@ -394,7 +430,7 @@ class RoomActionsView extends React.Component {
const { rid, blocker } = room;
const { member } = this.state;
try {
await RocketChat.toggleBlockUser(rid, member._id, !blocker);
await RocketChat.toggleBlockUser(rid, member._id as string, !blocker);
} catch (e) {
logEvent(events.RA_TOGGLE_BLOCK_USER_F);
log(e);
@ -411,9 +447,9 @@ class RoomActionsView extends React.Component {
const encrypted = !room.encrypted;
try {
// Instantly feedback to the user
await db.action(async () => {
await db.write(async () => {
await room.update(
protectedFunction(r => {
protectedFunction((r: TSubscriptionModel) => {
r.encrypted = encrypted;
})
);
@ -431,9 +467,9 @@ class RoomActionsView extends React.Component {
}
// If something goes wrong we go back to the previous value
await db.action(async () => {
await db.write(async () => {
await room.update(
protectedFunction(r => {
protectedFunction((r: TSubscriptionModel) => {
r.encrypted = room.encrypted;
})
);
@ -463,28 +499,31 @@ class RoomActionsView extends React.Component {
showConfirmationAlert({
message: I18n.t('Are_you_sure_you_want_to_leave_the_room', { room: RocketChat.getRoomTitle(room) }),
confirmationText: I18n.t('Yes_action_it', { action: I18n.t('leave') }),
onPress: () => dispatch(leaveRoom('channel', room))
onPress: () => dispatch(leaveRoom(ERoomType.c, room))
});
};
convertTeamToChannel = async () => {
const { room } = this.state;
const { navigation } = this.props;
const { navigation, userId } = this.props;
try {
const result = await RocketChat.teamListRoomsOfUser({ teamId: room.teamId, userId: room.u._id });
if (!room.teamId) {
return;
}
const result = await RocketChat.teamListRoomsOfUser({ teamId: room.teamId, userId });
if (result.rooms?.length) {
const teamChannels = result.rooms.map(r => ({
const teamChannels = result.rooms.map((r: any) => ({
rid: r._id,
name: r.name,
teamId: r.teamId
}));
navigation.navigate('SelectListView', {
title: 'Converting_Team_To_Channel',
data: teamChannels,
data: teamChannels as any,
infoText: 'Select_Team_Channels_To_Delete',
nextAction: data => this.convertTeamToChannelConfirmation(data)
nextAction: (data: string[]) => this.convertTeamToChannelConfirmation(data)
});
} else {
this.convertTeamToChannelConfirmation();
@ -494,12 +533,15 @@ class RoomActionsView extends React.Component {
}
};
handleConvertTeamToChannel = async selected => {
handleConvertTeamToChannel = async (selected: string[]) => {
logEvent(events.RA_CONVERT_TEAM_TO_CHANNEL);
try {
const { room } = this.state;
const { navigation } = this.props;
if (!room.teamId) {
return;
}
const result = await RocketChat.convertTeamToChannel({ teamId: room.teamId, selected });
if (result.success) {
@ -511,7 +553,7 @@ class RoomActionsView extends React.Component {
}
};
convertTeamToChannelConfirmation = (selected = []) => {
convertTeamToChannelConfirmation = (selected: string[] = []) => {
showConfirmationAlert({
title: I18n.t('Confirmation'),
message: I18n.t('You_are_converting_the_team'),
@ -522,13 +564,16 @@ class RoomActionsView extends React.Component {
leaveTeam = async () => {
const { room } = this.state;
const { navigation, dispatch } = this.props;
const { navigation, dispatch, userId } = this.props;
try {
const result = await RocketChat.teamListRoomsOfUser({ teamId: room.teamId, userId: room.u._id });
if (!room.teamId) {
return;
}
const result = await RocketChat.teamListRoomsOfUser({ teamId: room.teamId, userId });
if (result.rooms?.length) {
const teamChannels = result.rooms.map(r => ({
const teamChannels = result.rooms.map((r: any) => ({
rid: r._id,
name: r.name,
teamId: r.teamId,
@ -538,21 +583,21 @@ class RoomActionsView extends React.Component {
title: 'Leave_Team',
data: teamChannels,
infoText: 'Select_Team_Channels',
nextAction: data => dispatch(leaveRoom('team', room, data)),
nextAction: data => dispatch(leaveRoom(ERoomType.t, room, data)),
showAlert: () => showErrorAlert(I18n.t('Last_owner_team_room'), I18n.t('Cannot_leave'))
});
} else {
showConfirmationAlert({
message: I18n.t('You_are_leaving_the_team', { team: RocketChat.getRoomTitle(room) }),
confirmationText: I18n.t('Yes_action_it', { action: I18n.t('leave') }),
onPress: () => dispatch(leaveRoom('team', room))
onPress: () => dispatch(leaveRoom(ERoomType.t, room))
});
}
} catch (e) {
showConfirmationAlert({
message: I18n.t('You_are_leaving_the_team', { team: RocketChat.getRoomTitle(room) }),
confirmationText: I18n.t('Yes_action_it', { action: I18n.t('leave') }),
onPress: () => dispatch(leaveRoom('team', room))
onPress: () => dispatch(leaveRoom(ERoomType.t, room))
});
}
};
@ -562,7 +607,7 @@ class RoomActionsView extends React.Component {
try {
const { room } = this.state;
const { navigation } = this.props;
const result = await RocketChat.convertChannelToTeam({ rid: room.rid, name: room.name, type: room.t });
const result = await RocketChat.convertChannelToTeam({ rid: room.rid, name: room.name, type: room.t as any });
if (result.success) {
navigation.navigate('RoomView');
@ -582,7 +627,7 @@ class RoomActionsView extends React.Component {
});
};
handleMoveToTeam = async selected => {
handleMoveToTeam = async (selected: string[]) => {
logEvent(events.RA_MOVE_TO_TEAM);
try {
const { room } = this.state;
@ -603,14 +648,14 @@ class RoomActionsView extends React.Component {
const { navigation } = this.props;
const db = database.active;
const subCollection = db.get('subscriptions');
const teamRooms = await subCollection.query(Q.where('team_main', true));
const teamRooms = await subCollection.query(Q.where('team_main', true)).fetch();
if (teamRooms.length) {
const data = teamRooms.map(team => ({
rid: team.teamId,
t: team.t,
name: team.name
}));
})) as IRoom[]; // TODO: review this usage later
navigation.navigate('SelectListView', {
title: 'Move_to_Team',
infoText: 'Move_Channel_Paragraph',
@ -637,7 +682,7 @@ class RoomActionsView extends React.Component {
}
};
searchTeam = async onChangeText => {
searchTeam = async (onChangeText: string) => {
logEvent(events.RA_SEARCH_TEAM);
try {
const { addTeamChannelPermission, createTeamPermission } = this.props;
@ -650,9 +695,10 @@ class RoomActionsView extends React.Component {
Q.where('name', Q.like(`%${onChangeText}%`)),
Q.experimentalTake(QUERY_SIZE),
Q.experimentalSortBy('room_updated_at', Q.desc)
);
)
.fetch();
const asyncFilter = async teamArray => {
const asyncFilter = async (teamArray: TSubscriptionModel[]) => {
const results = await Promise.all(
teamArray.map(async team => {
const permissions = await RocketChat.hasPermission([addTeamChannelPermission, createTeamPermission], team.rid);
@ -698,7 +744,6 @@ class RoomActionsView extends React.Component {
}
style={{ backgroundColor: themes[theme].backgroundColor }}
accessibilityLabel={I18n.t('Room_Info')}
accessibilityTraits='button'
enabled={!isGroupChat}
testID='room-actions-info'
theme={theme}>
@ -708,7 +753,7 @@ class RoomActionsView extends React.Component {
<View style={[sharedStyles.status, { backgroundColor: themes[theme].backgroundColor }]}>
<Status size={16} id={member._id} />
</View>
) : null}
) : undefined}
</Avatar>
<View style={styles.roomTitleContainer}>
{room.t === 'd' ? (
@ -782,7 +827,7 @@ class RoomActionsView extends React.Component {
// If this room type can be encrypted
// If e2e is enabled
if (E2E_ROOM_TYPES[room?.t] && encryptionEnabled) {
if (E2E_ROOM_TYPES[room.t] && encryptionEnabled) {
return (
<List.Section>
<List.Separator />
@ -853,7 +898,7 @@ class RoomActionsView extends React.Component {
return null;
};
teamChannelActions = (t, room) => {
teamChannelActions = (t: string, room: ISubscription) => {
const { canEdit, canCreateTeam, canAddChannelToTeam } = this.state;
const canConvertToTeam = canEdit && canCreateTeam && !room.teamMain;
const canMoveToTeam = canEdit && canAddChannelToTeam && !room.teamId;
@ -897,7 +942,7 @@ class RoomActionsView extends React.Component {
);
};
teamToChannelActions = (t, room) => {
teamToChannelActions = (t: string, room: ISubscription) => {
const { canEdit, canConvertTeam } = this.state;
const canConvertTeamToChannel = canEdit && canConvertTeam && !!room?.teamMain;
@ -952,7 +997,7 @@ class RoomActionsView extends React.Component {
<>
<List.Item
title='Members'
subtitle={membersCount > 0 ? `${membersCount} ${I18n.t('members')}` : null}
subtitle={membersCount > 0 ? `${membersCount} ${I18n.t('members')}` : undefined}
onPress={() => this.onPressTouchable({ route: 'RoomMembersView', params: { rid, room } })}
testID='room-actions-members'
left={() => <List.Icon name='team' />}
@ -1221,10 +1266,11 @@ class RoomActionsView extends React.Component {
}
}
const mapStateToProps = state => ({
jitsiEnabled: state.settings.Jitsi_Enabled || false,
jitsiEnableTeams: state.settings.Jitsi_Enable_Teams || false,
jitsiEnableChannels: state.settings.Jitsi_Enable_Channels || false,
const mapStateToProps = (state: IApplicationState) => ({
userId: getUserSelector(state).id,
jitsiEnabled: (state.settings.Jitsi_Enabled || false) as boolean,
jitsiEnableTeams: (state.settings.Jitsi_Enable_Teams || false) as boolean,
jitsiEnableChannels: (state.settings.Jitsi_Enable_Channels || false) as boolean,
encryptionEnabled: state.encryption.enabled,
serverVersion: state.server.version,
isMasterDetail: state.app.isMasterDetail,

View File

@ -16,7 +16,7 @@ import StatusBar from '../../containers/StatusBar';
import RCTextInput from '../../containers/TextInput';
import { LISTENER } from '../../containers/Toast';
import { MultiSelect } from '../../containers/UIKit/MultiSelect';
import { IApplicationState, IBaseScreen, ISubscription, TSubscriptionModel } from '../../definitions';
import { IApplicationState, IBaseScreen, ISubscription, SubscriptionType, TSubscriptionModel } from '../../definitions';
import { ERoomType } from '../../definitions/ERoomType';
import I18n from '../../i18n';
import database from '../../lib/database';
@ -372,7 +372,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
title: 'Delete_Team',
data: teamChannelOwner,
infoText: 'Select_channels_to_delete',
nextAction: (selected: Record<string, string>) => {
nextAction: (selected: string[]) => {
showConfirmationAlert({
message: I18n.t('You_are_deleting_the_team', { team: RocketChat.getRoomTitle(room) }),
confirmationText: I18n.t('Yes_action_it', { action: I18n.t('delete') }),
@ -437,7 +437,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
onPress: async () => {
try {
logEvent(events.RI_EDIT_TOGGLE_ARCHIVE);
await RocketChat.toggleArchiveRoom(rid, t, !archived);
await RocketChat.toggleArchiveRoom(rid, t as SubscriptionType, !archived);
} catch (e) {
logEvent(events.RI_EDIT_TOGGLE_ARCHIVE_F);
log(e);

View File

@ -24,7 +24,7 @@ import { getUserSelector } from '../../selectors/login';
import { ModalStackParamList } from '../../stacks/MasterDetailStack/types';
import { withTheme } from '../../theme';
import EventEmitter from '../../utils/events';
import { goRoom, IGoRoomItem } from '../../utils/goRoom';
import { goRoom, TGoRoomItem } from '../../utils/goRoom';
import { showConfirmationAlert, showErrorAlert } from '../../utils/info';
import log from '../../utils/log';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
@ -469,7 +469,7 @@ class RoomMembersView extends React.Component<IRoomMembersViewProps, IRoomMember
}
};
goRoom = (item: IGoRoomItem) => {
goRoom = (item: TGoRoomItem) => {
const { navigation, isMasterDetail } = this.props;
if (isMasterDetail) {
// @ts-ignore

View File

@ -52,7 +52,7 @@ import { getHeaderTitlePosition } from '../../containers/Header';
import { E2E_MESSAGE_TYPE, E2E_STATUS } from '../../lib/encryption/constants';
import { takeInquiry } from '../../ee/omnichannel/lib';
import Loading from '../../containers/Loading';
import { goRoom } from '../../utils/goRoom';
import { goRoom, TGoRoomItem } from '../../utils/goRoom';
import getThreadName from '../../lib/methods/getThreadName';
import getRoomInfo from '../../lib/methods/getRoomInfo';
import RoomServices from './services';
@ -545,7 +545,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
navigation.push('RoomActionsView', {
rid: this.rid,
t: this.t as SubscriptionType,
room: room as ISubscription,
room: room as TSubscriptionModel,
member,
joined
});
@ -1040,7 +1040,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
const { navigation, isMasterDetail } = this.props;
const roomInfo = await getRoomInfo(message.rid);
return goRoom({
item: roomInfo as Partial<ISubscription>,
item: roomInfo as TGoRoomItem,
isMasterDetail,
navigationMethod: navigation.push,
jumpToMessageId: message.id

View File

@ -29,7 +29,7 @@ const styles = StyleSheet.create({
});
interface ISelectListViewState {
data: IRoom[];
data?: IRoom[];
dataFiltered?: IRoom[];
isSearching: boolean;
selected: string[];
@ -53,7 +53,7 @@ class SelectListView extends React.Component<ISelectListViewProps, ISelectListVi
private isSearch: boolean;
private onSearch: (text: string) => Partial<IRoom[]>;
private onSearch?: (text: string) => Promise<Partial<IRoom[]> | any>;
private isRadio?: boolean;
@ -61,10 +61,10 @@ class SelectListView extends React.Component<ISelectListViewProps, ISelectListVi
super(props);
const data = props.route?.params?.data;
this.title = props.route?.params?.title;
this.infoText = props.route?.params?.infoText;
this.infoText = props.route?.params?.infoText ?? '';
this.nextAction = props.route?.params?.nextAction;
this.showAlert = props.route?.params?.showAlert;
this.isSearch = props.route?.params?.isSearch;
this.showAlert = props.route?.params?.showAlert ?? (() => {});
this.isSearch = props.route?.params?.isSearch ?? false;
this.onSearch = props.route?.params?.onSearch;
this.isRadio = props.route?.params?.isRadio;
this.state = {
@ -122,7 +122,7 @@ class SelectListView extends React.Component<ISelectListViewProps, ISelectListVi
search = async (text: string) => {
try {
this.setState({ isSearching: true });
const result = (await this.onSearch(text)) as IRoom[];
const result = (await this.onSearch?.(text)) as IRoom[];
this.setState({ dataFiltered: result });
} catch (e) {
log(e);