forked from Ivasoft/mattermost-mobile
225 lines
6.9 KiB
JavaScript
225 lines
6.9 KiB
JavaScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
import React, {PureComponent} from 'react';
|
|
import PropTypes from 'prop-types';
|
|
|
|
import Post from 'app/components/post';
|
|
import {START_OF_NEW_MESSAGES} from 'app/selectors/post_list';
|
|
import mattermostManaged from 'app/mattermost_managed';
|
|
import {changeOpacity} from 'app/utils/theme';
|
|
import {matchPermalink} from 'app/utils/url';
|
|
|
|
import DateHeader from './date_header';
|
|
import {isDateLine} from './date_header/utils';
|
|
import NewMessagesDivider from './new_messages_divider';
|
|
|
|
export default class PostListBase extends PureComponent {
|
|
static propTypes = {
|
|
actions: PropTypes.shape({
|
|
loadChannelsByTeamName: PropTypes.func.isRequired,
|
|
refreshChannelWithRetry: PropTypes.func.isRequired,
|
|
selectFocusedPostId: PropTypes.func.isRequired,
|
|
setDeepLinkURL: PropTypes.func.isRequired,
|
|
}).isRequired,
|
|
channelId: PropTypes.string,
|
|
deepLinkURL: PropTypes.string,
|
|
extraData: PropTypes.any,
|
|
highlightPostId: PropTypes.string,
|
|
initialIndex: PropTypes.number,
|
|
isSearchResult: PropTypes.bool,
|
|
lastViewedAt: PropTypes.number, // Used by container // eslint-disable-line no-unused-prop-types
|
|
navigator: PropTypes.object,
|
|
onLoadMoreUp: PropTypes.func,
|
|
onPermalinkPress: PropTypes.func,
|
|
onPostPress: PropTypes.func,
|
|
onRefresh: PropTypes.func,
|
|
postIds: PropTypes.array.isRequired,
|
|
renderFooter: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
renderReplies: PropTypes.bool,
|
|
serverURL: PropTypes.string.isRequired,
|
|
shouldRenderReplyButton: PropTypes.bool,
|
|
siteURL: PropTypes.string.isRequired,
|
|
theme: PropTypes.object.isRequired,
|
|
};
|
|
|
|
static defaultProps = {
|
|
onLoadMoreUp: () => true,
|
|
renderFooter: () => null,
|
|
};
|
|
|
|
componentWillMount() {
|
|
this.listenerId = mattermostManaged.addEventListener('change', this.setManagedConfig);
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.mounted = true;
|
|
this.setManagedConfig();
|
|
}
|
|
|
|
componentDidUpdate() {
|
|
if (this.props.deepLinkURL) {
|
|
this.handleDeepLink(this.props.deepLinkURL);
|
|
this.props.actions.setDeepLinkURL('');
|
|
}
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.mounted = false;
|
|
mattermostManaged.removeEventListener(this.listenerId);
|
|
}
|
|
|
|
handleClosePermalink = () => {
|
|
const {actions} = this.props;
|
|
actions.selectFocusedPostId('');
|
|
this.showingPermalink = false;
|
|
};
|
|
|
|
handleDeepLink = (url) => {
|
|
const {serverURL, siteURL} = this.props;
|
|
|
|
const match = matchPermalink(url, serverURL) || matchPermalink(url, siteURL);
|
|
|
|
if (match) {
|
|
const teamName = match[1];
|
|
const postId = match[2];
|
|
this.handlePermalinkPress(postId, teamName);
|
|
}
|
|
};
|
|
|
|
handleRefresh = () => {
|
|
const {
|
|
actions,
|
|
channelId,
|
|
onRefresh,
|
|
} = this.props;
|
|
|
|
if (channelId) {
|
|
actions.refreshChannelWithRetry(channelId);
|
|
}
|
|
|
|
if (onRefresh) {
|
|
onRefresh();
|
|
}
|
|
};
|
|
|
|
handlePermalinkPress = (postId, teamName) => {
|
|
const {actions, onPermalinkPress} = this.props;
|
|
|
|
if (onPermalinkPress) {
|
|
onPermalinkPress(postId, true);
|
|
} else {
|
|
actions.loadChannelsByTeamName(teamName);
|
|
this.showPermalinkView(postId);
|
|
}
|
|
};
|
|
|
|
keyExtractor = (item) => {
|
|
// All keys are strings (either post IDs or special keys)
|
|
return item;
|
|
};
|
|
|
|
renderItem = ({item, index}) => {
|
|
if (item === START_OF_NEW_MESSAGES) {
|
|
// postIds includes a date item after the new message indicator so 2
|
|
// needs to be added to the index for the length check to be correct.
|
|
const moreNewMessages = this.props.postIds.length === index + 2;
|
|
|
|
return (
|
|
<NewMessagesDivider
|
|
index={index}
|
|
theme={this.props.theme}
|
|
moreMessages={moreNewMessages}
|
|
/>
|
|
);
|
|
} else if (isDateLine(item)) {
|
|
return (
|
|
<DateHeader
|
|
dateLineString={item}
|
|
index={index}
|
|
/>
|
|
);
|
|
}
|
|
|
|
const postId = item;
|
|
|
|
// Remember that the list is rendered with item 0 at the bottom so the "previous" post
|
|
// comes after this one in the list
|
|
const previousPostId = index < this.props.postIds.length - 1 ? this.props.postIds[index + 1] : null;
|
|
const nextPostId = index > 0 ? this.props.postIds[index - 1] : null;
|
|
|
|
return this.renderPost(postId, previousPostId, nextPostId);
|
|
};
|
|
|
|
renderPost = (postId, previousPostId, nextPostId) => {
|
|
const {
|
|
highlightPostId,
|
|
isSearchResult,
|
|
navigator,
|
|
onPostPress,
|
|
renderReplies,
|
|
shouldRenderReplyButton,
|
|
} = this.props;
|
|
const {managedConfig} = this.state;
|
|
|
|
const highlight = highlightPostId === postId;
|
|
return (
|
|
<Post
|
|
postId={postId}
|
|
previousPostId={previousPostId}
|
|
nextPostId={nextPostId}
|
|
onPermalinkPress={this.handlePermalinkPress}
|
|
highlight={highlight}
|
|
renderReplies={renderReplies}
|
|
isSearchResult={isSearchResult}
|
|
shouldRenderReplyButton={shouldRenderReplyButton}
|
|
onPress={onPostPress}
|
|
navigator={navigator}
|
|
managedConfig={managedConfig}
|
|
/>
|
|
);
|
|
};
|
|
|
|
setManagedConfig = async (config) => {
|
|
let nextConfig = config;
|
|
if (!nextConfig) {
|
|
nextConfig = await mattermostManaged.getLocalConfig();
|
|
}
|
|
|
|
if (this.mounted) {
|
|
this.setState({
|
|
managedConfig: nextConfig,
|
|
});
|
|
}
|
|
};
|
|
|
|
showPermalinkView = (postId) => {
|
|
const {actions, navigator} = this.props;
|
|
|
|
actions.selectFocusedPostId(postId);
|
|
|
|
if (!this.showingPermalink) {
|
|
const options = {
|
|
screen: 'Permalink',
|
|
animationType: 'none',
|
|
backButtonTitle: '',
|
|
overrideBackPress: true,
|
|
navigatorStyle: {
|
|
navBarHidden: true,
|
|
screenBackgroundColor: changeOpacity('#000', 0.2),
|
|
modalPresentationStyle: 'overCurrentContext',
|
|
},
|
|
passProps: {
|
|
isPermalink: true,
|
|
onClose: this.handleClosePermalink,
|
|
onPermalinkPress: this.handlePermalinkPress,
|
|
},
|
|
};
|
|
|
|
this.showingPermalink = true;
|
|
navigator.showModal(options);
|
|
}
|
|
};
|
|
}
|
|
|