diff --git a/app/lib/methods/subscriptions/rooms.ts b/app/lib/methods/subscriptions/rooms.ts
index b18122566..c62dcbe76 100644
--- a/app/lib/methods/subscriptions/rooms.ts
+++ b/app/lib/methods/subscriptions/rooms.ts
@@ -410,7 +410,6 @@ export default function subscribeRooms() {
log(e);
}
}
-
if (/video-conference/.test(ev)) {
const [action, params] = ddpMessage.fields.args;
store.dispatch(handleVideoConfIncomingWebsocketMessages({ action, params }));
diff --git a/app/stacks/InsideStack.tsx b/app/stacks/InsideStack.tsx
index 54162d730..b4c1d677e 100644
--- a/app/stacks/InsideStack.tsx
+++ b/app/stacks/InsideStack.tsx
@@ -128,11 +128,7 @@ const ChatsStackNavigator = () => {
-
+
{/* @ts-ignore */}
{/* @ts-ignore */}
diff --git a/app/stacks/MasterDetailStack/index.tsx b/app/stacks/MasterDetailStack/index.tsx
index 5c9235120..285e145e2 100644
--- a/app/stacks/MasterDetailStack/index.tsx
+++ b/app/stacks/MasterDetailStack/index.tsx
@@ -130,12 +130,7 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
{/* @ts-ignore */}
-
+
diff --git a/app/stacks/types.ts b/app/stacks/types.ts
index 1002c75ec..0f73fabed 100644
--- a/app/stacks/types.ts
+++ b/app/stacks/types.ts
@@ -10,7 +10,6 @@ import { IMessage, TAnyMessageModel, TMessageModel } from '../definitions/IMessa
import { TServerModel } from '../definitions/IServer';
import { ISubscription, SubscriptionType, TSubscriptionModel } from '../definitions/ISubscription';
import { TChangeAvatarViewContext } from '../definitions/TChangeAvatarViewContext';
-import { IItem } from '../views/TeamChannelsView';
import { MasterDetailInsideStackParamList, ModalStackParamList } from './MasterDetailStack/types';
import { TNavigation } from './stackType';
@@ -154,12 +153,10 @@ export type ChatsStackParamList = {
teamId?: string;
};
AddChannelTeamView: {
- teamId?: string;
- teamChannels: IItem[];
+ teamId: string;
};
AddExistingChannelView: {
- teamId?: string;
- teamChannels: IItem[];
+ teamId: string;
};
MarkdownTableView: {
renderRows: (drawExtraBorders?: boolean) => JSX.Element;
diff --git a/app/views/AddChannelTeamView.tsx b/app/views/AddChannelTeamView.tsx
index 7b924b59e..e2da06e98 100644
--- a/app/views/AddChannelTeamView.tsx
+++ b/app/views/AddChannelTeamView.tsx
@@ -40,7 +40,9 @@ const setHeader = ({
const AddChannelTeamView = () => {
const navigation = useNavigation();
const isMasterDetail = useSelector((state: IApplicationState) => state.app.isMasterDetail);
- const { teamChannels, teamId } = useRoute().params;
+ const {
+ params: { teamId }
+ } = useRoute();
useEffect(() => {
setHeader({ navigation, isMasterDetail });
@@ -70,7 +72,7 @@ const AddChannelTeamView = () => {
navigation.navigate('AddExistingChannelView', { teamId, teamChannels })}
+ onPress={() => navigation.navigate('AddExistingChannelView', { teamId })}
testID='add-channel-team-view-add-existing'
left={() => }
right={() => }
diff --git a/app/views/AddExistingChannelView.tsx b/app/views/AddExistingChannelView.tsx
deleted file mode 100644
index cefa750ab..000000000
--- a/app/views/AddExistingChannelView.tsx
+++ /dev/null
@@ -1,217 +0,0 @@
-import React from 'react';
-import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
-import { RouteProp } from '@react-navigation/native';
-import { FlatList } from 'react-native';
-import { connect } from 'react-redux';
-import { Q } from '@nozbe/watermelondb';
-
-import * as List from '../containers/List';
-import database from '../lib/database';
-import I18n from '../i18n';
-import log, { events, logEvent } from '../lib/methods/helpers/log';
-import SearchBox from '../containers/SearchBox';
-import * as HeaderButton from '../containers/HeaderButton';
-import StatusBar from '../containers/StatusBar';
-import { themes } from '../lib/constants';
-import { TSupportedThemes, withTheme } from '../theme';
-import SafeAreaView from '../containers/SafeAreaView';
-import { sendLoadingEvent } from '../containers/Loading';
-import { animateNextTransition } from '../lib/methods/helpers/layoutAnimation';
-import { showErrorAlert } from '../lib/methods/helpers/info';
-import { ChatsStackParamList } from '../stacks/types';
-import { TSubscriptionModel, SubscriptionType, IApplicationState } from '../definitions';
-import { getRoomTitle, hasPermission, debounce } from '../lib/methods/helpers';
-import { Services } from '../lib/services';
-
-interface IAddExistingChannelViewState {
- search: TSubscriptionModel[];
- channels: TSubscriptionModel[];
- selected: string[];
-}
-
-interface IAddExistingChannelViewProps {
- navigation: StackNavigationProp;
- route: RouteProp;
- theme?: TSupportedThemes;
- isMasterDetail: boolean;
- addTeamChannelPermission?: string[];
-}
-
-const QUERY_SIZE = 50;
-
-class AddExistingChannelView extends React.Component {
- private teamId: string;
-
- constructor(props: IAddExistingChannelViewProps) {
- super(props);
- this.query();
- this.teamId = props.route?.params?.teamId ?? '';
- this.state = {
- search: [],
- channels: [],
- selected: []
- };
- this.setHeader();
- }
-
- setHeader = () => {
- const { navigation, isMasterDetail } = this.props;
- const { selected } = this.state;
-
- const options: StackNavigationOptions = {
- headerTitle: I18n.t('Add_Existing_Channel')
- };
-
- if (isMasterDetail) {
- options.headerLeft = () => ;
- }
-
- options.headerRight = () =>
- selected.length > 0 && (
-
-
-
- );
-
- navigation.setOptions(options);
- };
-
- query = async (stringToSearch = '') => {
- try {
- const { addTeamChannelPermission } = this.props;
- const db = database.active;
- const channels = await db
- .get('subscriptions')
- .query(
- Q.where('team_id', ''),
- Q.where('t', Q.oneOf(['c', 'p'])),
- Q.where('name', Q.like(`%${stringToSearch}%`)),
- Q.take(QUERY_SIZE),
- Q.sortBy('room_updated_at', Q.desc)
- )
- .fetch();
-
- const asyncFilter = async (channelsArray: TSubscriptionModel[]) => {
- const results = await Promise.all(
- channelsArray.map(async channel => {
- if (channel.prid) {
- return false;
- }
- const permissions = await hasPermission([addTeamChannelPermission], channel.rid);
- if (!permissions[0]) {
- return false;
- }
- return true;
- })
- );
-
- return channelsArray.filter((_v: any, index: number) => results[index]);
- };
- const channelFiltered = await asyncFilter(channels);
- this.setState({ channels: channelFiltered });
- } catch (e) {
- log(e);
- }
- };
-
- onSearchChangeText = debounce((text: string) => {
- this.query(text);
- }, 300);
-
- dismiss = () => {
- const { navigation } = this.props;
- return navigation.pop();
- };
-
- submit = async () => {
- const { selected } = this.state;
- const { navigation } = this.props;
-
- sendLoadingEvent({ visible: true });
- try {
- logEvent(events.CT_ADD_ROOM_TO_TEAM);
- const result = await Services.addRoomsToTeam({ rooms: selected, teamId: this.teamId });
- if (result.success) {
- sendLoadingEvent({ visible: false });
- // Expect that after you add an existing channel to a team, the user should move back to the team
- navigation.navigate('RoomView');
- }
- } catch (e: any) {
- logEvent(events.CT_ADD_ROOM_TO_TEAM_F);
- showErrorAlert(I18n.t(e.data.error), I18n.t('Add_Existing_Channel'), () => {});
- sendLoadingEvent({ visible: false });
- }
- };
-
- renderHeader = () => (
- this.onSearchChangeText(text)} testID='add-existing-channel-view-search' />
- );
-
- isChecked = (rid: string) => {
- const { selected } = this.state;
- return selected.includes(rid);
- };
-
- toggleChannel = (rid: string) => {
- const { selected } = this.state;
-
- animateNextTransition();
- if (!this.isChecked(rid)) {
- logEvent(events.AEC_ADD_CHANNEL);
- this.setState({ selected: [...selected, rid] }, () => this.setHeader());
- } else {
- logEvent(events.AEC_REMOVE_CHANNEL);
- const filterSelected = selected.filter(el => el !== rid);
- this.setState({ selected: filterSelected }, () => this.setHeader());
- }
- };
-
- renderItem = ({ item }: { item: TSubscriptionModel }) => {
- const isChecked = this.isChecked(item.rid);
- // TODO: reuse logic inside RoomTypeIcon
- const icon = item.t === SubscriptionType.DIRECT && !item?.teamId ? 'channel-private' : 'channel-public';
- return (
- this.toggleChannel(item.rid)}
- testID={`add-existing-channel-view-item-${item.name}`}
- left={() => }
- right={() => (isChecked ? : null)}
- />
- );
- };
-
- renderList = () => {
- const { search, channels } = this.state;
- const { theme } = this.props;
- return (
- 0 ? search : channels}
- extraData={this.state}
- keyExtractor={item => item.id}
- ListHeaderComponent={this.renderHeader}
- renderItem={this.renderItem}
- ItemSeparatorComponent={List.Separator}
- contentContainerStyle={{ backgroundColor: themes[theme!].backgroundColor }}
- keyboardShouldPersistTaps='always'
- />
- );
- };
-
- render() {
- return (
-
-
- {this.renderList()}
-
- );
- }
-}
-
-const mapStateToProps = (state: IApplicationState) => ({
- isMasterDetail: state.app.isMasterDetail,
- addTeamChannelPermission: state.permissions['add-team-channel']
-});
-
-export default connect(mapStateToProps)(withTheme(AddExistingChannelView));
diff --git a/app/views/AddExistingChannelView/index.tsx b/app/views/AddExistingChannelView/index.tsx
new file mode 100644
index 000000000..c42751f61
--- /dev/null
+++ b/app/views/AddExistingChannelView/index.tsx
@@ -0,0 +1,177 @@
+import React, { useEffect, useLayoutEffect, useState } from 'react';
+import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
+import { RouteProp, useNavigation, useRoute } from '@react-navigation/native';
+import { FlatList } from 'react-native';
+import { Q } from '@nozbe/watermelondb';
+
+import * as List from '../../containers/List';
+import database from '../../lib/database';
+import I18n from '../../i18n';
+import log, { events, logEvent } from '../../lib/methods/helpers/log';
+import SearchBox from '../../containers/SearchBox';
+import * as HeaderButton from '../../containers/HeaderButton';
+import StatusBar from '../../containers/StatusBar';
+import { useTheme } from '../../theme';
+import SafeAreaView from '../../containers/SafeAreaView';
+import { sendLoadingEvent } from '../../containers/Loading';
+import { animateNextTransition } from '../../lib/methods/helpers/layoutAnimation';
+import { showErrorAlert } from '../../lib/methods/helpers/info';
+import { ChatsStackParamList } from '../../stacks/types';
+import { TSubscriptionModel, SubscriptionType } from '../../definitions';
+import { getRoomTitle, hasPermission, useDebounce } from '../../lib/methods/helpers';
+import { Services } from '../../lib/services';
+import { useAppSelector } from '../../lib/hooks';
+
+type TNavigation = StackNavigationProp;
+type TRoute = RouteProp;
+
+const QUERY_SIZE = 50;
+
+const AddExistingChannelView = () => {
+ const [channels, setChannels] = useState([]);
+ const [selected, setSelected] = useState([]);
+
+ const { colors } = useTheme();
+
+ const navigation = useNavigation();
+ const {
+ params: { teamId }
+ } = useRoute();
+
+ const { addTeamChannelPermission, isMasterDetail } = useAppSelector(state => ({
+ isMasterDetail: state.app.isMasterDetail,
+ addTeamChannelPermission: state.permissions['add-team-channel']
+ }));
+
+ useLayoutEffect(() => {
+ setHeader();
+ }, [selected.length]);
+
+ useEffect(() => {
+ query();
+ }, []);
+
+ const setHeader = () => {
+ const options: StackNavigationOptions = {
+ headerTitle: I18n.t('Add_Existing_Channel')
+ };
+
+ if (isMasterDetail) {
+ options.headerLeft = () => ;
+ }
+
+ options.headerRight = () =>
+ selected.length > 0 && (
+
+
+
+ );
+
+ navigation.setOptions(options);
+ };
+
+ const query = async (stringToSearch = '') => {
+ try {
+ const db = database.active;
+ const channels = await db
+ .get('subscriptions')
+ .query(
+ Q.where('team_id', ''),
+ Q.where('t', Q.oneOf(['c', 'p'])),
+ Q.where('name', Q.like(`%${stringToSearch}%`)),
+ Q.take(QUERY_SIZE),
+ Q.sortBy('room_updated_at', Q.desc)
+ )
+ .fetch();
+
+ const asyncFilter = async (channelsArray: TSubscriptionModel[]) => {
+ const results = await Promise.all(
+ channelsArray.map(async channel => {
+ if (channel.prid) {
+ return false;
+ }
+ const permissions = await hasPermission([addTeamChannelPermission], channel.rid);
+ if (!permissions[0]) {
+ return false;
+ }
+ return true;
+ })
+ );
+
+ return channelsArray.filter((_v: any, index: number) => results[index]);
+ };
+ const channelFiltered = await asyncFilter(channels);
+ setChannels(channelFiltered);
+ } catch (e) {
+ log(e);
+ }
+ };
+
+ const onSearchChangeText = useDebounce((text: string) => {
+ query(text);
+ }, 300);
+
+ const isChecked = (rid: string) => selected.includes(rid);
+
+ const toggleChannel = (rid: string) => {
+ animateNextTransition();
+ if (!isChecked(rid)) {
+ logEvent(events.AEC_ADD_CHANNEL);
+ setSelected([...selected, rid]);
+ } else {
+ logEvent(events.AEC_REMOVE_CHANNEL);
+ const filterSelected = selected.filter(el => el !== rid);
+ setSelected(filterSelected);
+ }
+ };
+
+ const submit = async () => {
+ sendLoadingEvent({ visible: true });
+ try {
+ logEvent(events.CT_ADD_ROOM_TO_TEAM);
+ const result = await Services.addRoomsToTeam({ rooms: selected, teamId });
+ if (result.success) {
+ sendLoadingEvent({ visible: false });
+ // Expect that after you add an existing channel to a team, the user should move back to the team
+ navigation.navigate('RoomView');
+ }
+ } catch (e: any) {
+ logEvent(events.CT_ADD_ROOM_TO_TEAM_F);
+ showErrorAlert(I18n.t(e.data.error), I18n.t('Add_Existing_Channel'), () => {});
+ sendLoadingEvent({ visible: false });
+ }
+ };
+
+ return (
+
+
+ item.id}
+ ListHeaderComponent={
+ onSearchChangeText(text)} testID='add-existing-channel-view-search' />
+ }
+ renderItem={({ item }: { item: TSubscriptionModel }) => {
+ // TODO: reuse logic inside RoomTypeIcon
+ const icon = item.t === SubscriptionType.GROUP && !item?.teamId ? 'channel-private' : 'channel-public';
+ return (
+ toggleChannel(item.rid)}
+ testID={`add-existing-channel-view-item-${item.name}`}
+ left={() => }
+ right={() => (isChecked(item.rid) ? : null)}
+ />
+ );
+ }}
+ ItemSeparatorComponent={List.Separator}
+ contentContainerStyle={{ backgroundColor: colors.backgroundColor }}
+ keyboardShouldPersistTaps='always'
+ />
+
+ );
+};
+
+export default AddExistingChannelView;
diff --git a/app/views/TeamChannelsView.tsx b/app/views/TeamChannelsView.tsx
index bce566cb6..243978b90 100644
--- a/app/views/TeamChannelsView.tsx
+++ b/app/views/TeamChannelsView.tsx
@@ -186,7 +186,7 @@ class TeamChannelsView extends React.Component {
- const { isSearching, showCreate, data } = this.state;
+ const { isSearching, showCreate } = this.state;
const { navigation, isMasterDetail, theme } = this.props;
const { team } = this;
@@ -234,7 +234,7 @@ class TeamChannelsView extends React.Component navigation.navigate('AddChannelTeamView', { teamId: this.teamId, teamChannels: data })}
+ onPress={() => navigation.navigate('AddChannelTeamView', { teamId: this.teamId })}
/>
) : null}