import React from 'react';
import { Keyboard } from 'react-native';
import PropTypes from 'prop-types';
import { Q } from '@nozbe/watermelondb';
import { withSafeAreaInsets } from 'react-native-safe-area-context';
import { connect } from 'react-redux';
import { FlatList } from 'react-native-gesture-handler';
import { HeaderBackButton } from '@react-navigation/stack';
import StatusBar from '../containers/StatusBar';
import RoomHeader from '../containers/RoomHeader';
import { withTheme } from '../theme';
import SearchHeader from './ThreadMessagesView/SearchHeader';
import log, { events, logEvent } from '../utils/log';
import database from '../lib/database';
import { getUserSelector } from '../selectors/login';
import { getHeaderTitlePosition } from '../containers/Header';
import * as HeaderButton from '../containers/HeaderButton';
import BackgroundContainer from '../containers/BackgroundContainer';
import SafeAreaView from '../containers/SafeAreaView';
import ActivityIndicator from '../containers/ActivityIndicator';
import RoomItem, { ROW_HEIGHT } from '../presentation/RoomItem';
import RocketChat from '../lib/rocketchat';
import { withDimensions } from '../dimensions';
import { isIOS } from '../utils/deviceInfo';
import { themes } from '../constants/colors';
import debounce from '../utils/debounce';
import { showErrorAlert } from '../utils/info';
import { goRoom } from '../utils/goRoom';
import I18n from '../i18n';
const API_FETCH_COUNT = 25;
const getItemLayout = (data, index) => ({
length: data.length,
offset: ROW_HEIGHT * index,
index
});
const keyExtractor = item => item._id;
class TeamChannelsView extends React.Component {
static propTypes = {
route: PropTypes.object,
navigation: PropTypes.object,
isMasterDetail: PropTypes.bool,
insets: PropTypes.object,
theme: PropTypes.string,
useRealName: PropTypes.bool,
width: PropTypes.number,
StoreLastMessage: PropTypes.bool
}
constructor(props) {
super(props);
this.teamId = props.route.params?.teamId;
this.state = {
loading: true,
loadingMore: false,
data: [],
isSearching: false,
searchText: '',
search: [],
end: false
};
this.loadTeam();
}
componentDidMount() {
this.load();
}
loadTeam = async() => {
const db = database.active;
try {
const subCollection = db.get('subscriptions');
this.teamChannels = await subCollection.query(
Q.where('team_id', Q.eq(this.teamId))
);
this.team = this.teamChannels?.find(channel => channel.teamMain);
this.setHeader();
if (!this.team) {
throw new Error();
}
} catch {
const { navigation } = this.props;
navigation.pop();
showErrorAlert(I18n.t('Team_not_found'));
}
}
load = debounce(async() => {
const {
loadingMore, data, search, isSearching, searchText, end
} = this.state;
const length = isSearching ? search.length : data.length;
if (loadingMore || end) {
return;
}
this.setState({ loadingMore: true });
try {
const result = await RocketChat.getTeamListRoom({
teamId: this.teamId,
offset: length,
count: API_FETCH_COUNT,
type: 'all',
filter: searchText
});
if (result.success) {
const newState = {
loading: false,
loadingMore: false,
end: result.rooms.length < API_FETCH_COUNT
};
const rooms = result.rooms.map((room) => {
const record = this.teamChannels?.find(c => c.rid === room._id);
return record ?? room;
});
if (isSearching) {
newState.search = [...search, ...rooms];
} else {
newState.data = [...data, ...rooms];
}
this.setState(newState);
} else {
this.setState({ loading: false, loadingMore: false });
}
} catch (e) {
log(e);
this.setState({ loading: false, loadingMore: false });
}
}, 300)
getHeader = () => {
const { isSearching } = this.state;
const {
navigation, isMasterDetail, insets, theme
} = this.props;
const { team } = this;
if (!team) {
return;
}
const headerTitlePosition = getHeaderTitlePosition({ insets, numIconsRight: 1 });
if (isSearching) {
return {
headerTitleAlign: 'left',
headerLeft: () => (
),
headerTitle: () => ,
headerTitleContainerStyle: {
left: headerTitlePosition.left,
right: headerTitlePosition.right
},
headerRight: () => null
};
}
const options = {
headerShown: true,
headerTitleAlign: 'left',
headerTitleContainerStyle: {
left: headerTitlePosition.left,
right: headerTitlePosition.right
},
headerTitle: () => (
)
};
if (isMasterDetail) {
options.headerLeft = () => ;
} else {
options.headerLeft = () => (
navigation.pop()}
tintColor={themes[theme].headerTintColor}
/>
);
}
options.headerRight = () => (
);
return options;
}
setHeader = () => {
const { navigation } = this.props;
const options = this.getHeader();
navigation.setOptions(options);
}
onSearchPress = () => {
logEvent(events.TC_SEARCH);
this.setState({ isSearching: true }, () => this.setHeader());
}
onSearchChangeText = debounce((searchText) => {
this.setState({
searchText, search: [], loading: !!searchText, loadingMore: false, end: false
}, () => {
if (searchText) {
this.load();
}
});
}, 300)
onCancelSearchPress = () => {
logEvent(events.TC_CANCEL_SEARCH);
const { isSearching } = this.state;
if (!isSearching) {
return;
}
Keyboard.dismiss();
this.setState({
searchText: null, isSearching: false, search: [], loadingMore: false, end: false
}, () => {
this.setHeader();
});
};
goRoomActionsView = (screen) => {
logEvent(events.TC_GO_ACTIONS);
const { team } = this;
const {
navigation, isMasterDetail
} = this.props;
if (isMasterDetail) {
navigation.navigate('ModalStackNavigator', {
screen: screen ?? 'RoomActionsView',
params: {
rid: team.rid, t: team.t, room: team, showCloseModal: false
}
});
} else {
navigation.navigate('RoomActionsView', {
rid: team.rid, t: team.t, room: team
});
}
}
getRoomTitle = item => RocketChat.getRoomTitle(item)
getRoomAvatar = item => RocketChat.getRoomAvatar(item)
onPressItem = debounce(async(item) => {
logEvent(events.TC_GO_ROOM);
const { navigation, isMasterDetail } = this.props;
try {
let params = {};
if (item.rid) {
params = item;
} else {
const { room } = await RocketChat.getRoomInfo(item._id);
params = {
rid: item._id, name: RocketChat.getRoomTitle(room), joinCodeRequired: room.joinCodeRequired, t: room.t, teamId: room.teamId
};
}
if (isMasterDetail) {
navigation.pop();
}
goRoom({ item: params, isMasterDetail, navigationMethod: navigation.push });
} catch (e) {
// do nothing
}
}, 1000, true);
renderItem = ({ item }) => {
const {
StoreLastMessage,
useRealName,
theme,
width
} = this.props;
return (
);
};
renderFooter = () => {
const { loadingMore } = this.state;
const { theme } = this.props;
if (loadingMore) {
return ;
}
return null;
}
renderScroll = () => {
const {
loading, data, search, isSearching, searchText
} = this.state;
if (loading) {
return ;
}
if (isSearching && !search.length) {
return ;
}
if (!isSearching && !data.length) {
return ;
}
return (
this.load()}
onEndReachedThreshold={0.5}
ListFooterComponent={this.renderFooter}
/>
);
};
render() {
console.count(`${ this.constructor.name }.render calls`);
return (
{this.renderScroll()}
);
}
}
const mapStateToProps = state => ({
baseUrl: state.server.server,
user: getUserSelector(state),
useRealName: state.settings.UI_Use_Real_Name,
isMasterDetail: state.app.isMasterDetail,
StoreLastMessage: state.settings.Store_Last_Message
});
export default connect(mapStateToProps)(withDimensions(withSafeAreaInsets(withTheme(TeamChannelsView))));