MM-9545: Disables threads with deleted root post, display system message. (#1526)

* MM-9545: Adds system message for deleted root posts in threads; disables input.

* MM-9545: Removes key.
This commit is contained in:
Martin Kraft 2018-03-21 09:17:54 -04:00 committed by Harrison Healey
parent 082b7022af
commit ebbbd9689b
6 changed files with 112 additions and 10 deletions

View file

@ -8,7 +8,7 @@ import Svg, {
Path,
} from 'react-native-svg';
export default class AwayStatus extends PureComponent {
export default class AppIcon extends PureComponent {
static propTypes = {
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,

View file

@ -0,0 +1,81 @@
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React, {PureComponent} from 'react';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import FormattedText from 'app/components/formatted_text';
import AppIcon from 'app/components/app_icon';
import {ViewTypes} from 'app/constants';
class DeletedPost extends PureComponent {
static propTypes = {
theme: PropTypes.object.isRequired,
};
render() {
const {theme} = this.props;
const style = getStyleSheet(theme);
return (
<View style={style.main}>
<View style={style.iconContainer}>
<AppIcon
color={theme.centerChannelColor}
height={ViewTypes.PROFILE_PICTURE_SIZE}
width={ViewTypes.PROFILE_PICTURE_SIZE}
/>
</View>
<View style={style.textContainer}>
<FormattedText
id='post_info.system'
defaultMessage='System'
style={style.displayName}
/>
<View style={style.messageContainer}>
<FormattedText
id='rhs_thread.rootPostDeletedMessage.body'
defaultMessage='Part of this thread has been deleted due to a data retention policy. You can no longer reply to this thread.'
style={style.message}
/>
</View>
</View>
</View>
);
}
}
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
const stdPadding = 12;
return {
main: {
flexDirection: 'row',
paddingTop: stdPadding,
},
iconContainer: {
paddingRight: stdPadding,
paddingLeft: stdPadding,
width: (stdPadding * 2) + ViewTypes.PROFILE_PICTURE_SIZE,
},
textContainer: {
paddingBottom: 10,
flex: 1,
marginRight: stdPadding,
},
messageContainer: {
marginTop: 3,
},
displayName: {
color: theme.centerChannelColor,
fontSize: 15,
fontWeight: '600',
},
message: {
color: changeOpacity(theme.centerChannelColor, 0.8),
fontSize: 15,
lineHeight: 22,
},
};
});
export default DeletedPost;

View file

@ -53,6 +53,7 @@ export default class PostList extends PureComponent {
showLoadMore: PropTypes.bool,
shouldRenderReplyButton: PropTypes.bool,
theme: PropTypes.object.isRequired,
renderFooter: PropTypes.func,
};
static defaultProps = {
@ -319,6 +320,10 @@ export default class PostList extends PureComponent {
};
renderFooter = () => {
if (this.props.renderFooter) {
return this.props.renderFooter();
}
if (!this.props.channelId) {
return null;
}

View file

@ -9,8 +9,7 @@ import AppIcon from 'app/components/app_icon';
import ProfilePicture from 'app/components/profile_picture';
import {emptyFunction} from 'app/utils/general';
import webhookIcon from 'assets/images/icons/webhook.jpg';
const PROFILE_PICTURE_SIZE = 32;
import {ViewTypes} from 'app/constants';
export default class PostProfilePicture extends PureComponent {
static propTypes = {
@ -43,8 +42,8 @@ export default class PostProfilePicture extends PureComponent {
<View>
<AppIcon
color={theme.centerChannelColor}
height={PROFILE_PICTURE_SIZE}
width={PROFILE_PICTURE_SIZE}
height={ViewTypes.PROFILE_PICTURE_SIZE}
width={ViewTypes.PROFILE_PICTURE_SIZE}
/>
</View>
);
@ -58,9 +57,9 @@ export default class PostProfilePicture extends PureComponent {
<Image
source={icon}
style={{
height: PROFILE_PICTURE_SIZE,
width: PROFILE_PICTURE_SIZE,
borderRadius: PROFILE_PICTURE_SIZE / 2,
height: ViewTypes.PROFILE_PICTURE_SIZE,
width: ViewTypes.PROFILE_PICTURE_SIZE,
borderRadius: ViewTypes.PROFILE_PICTURE_SIZE / 2,
}}
/>
</View>
@ -70,7 +69,7 @@ export default class PostProfilePicture extends PureComponent {
let component = (
<ProfilePicture
userId={userId}
size={PROFILE_PICTURE_SIZE}
size={ViewTypes.PROFILE_PICTURE_SIZE}
/>
);

View file

@ -81,4 +81,5 @@ export default {
IOS_TOP_PORTRAIT: 64,
IOSX_TOP_PORTRAIT: 88,
STATUS_BAR_HEIGHT: 20,
PROFILE_PICTURE_SIZE: 32,
};

View file

@ -14,6 +14,7 @@ import PostTextbox from 'app/components/post_textbox';
import SafeAreaView from 'app/components/safe_area_view';
import StatusBar from 'app/components/status_bar';
import {makeStyleSheetFromTheme, setNavigatorStyles} from 'app/utils/theme';
import DeletedPost from 'app/components/deleted_post';
class Thread extends PureComponent {
static propTypes = {
@ -81,6 +82,19 @@ class Thread extends PureComponent {
}
};
hasRootPost = () => {
return this.props.postIds.includes(this.props.rootId);
}
renderFooter = () => {
if (!this.hasRootPost()) {
return (
<DeletedPost theme={this.props.theme}/>
);
}
return null;
}
render() {
const {
channelId,
@ -104,17 +118,19 @@ class Thread extends PureComponent {
keyboardVerticalOffset={65}
>
<PostList
renderFooter={this.renderFooter}
indicateNewMessages={true}
postIds={postIds}
currentUserId={myMember.user_id}
lastViewedAt={this.state.lastViewedAt}
navigator={navigator}
/>
{this.hasRootPost() &&
<PostTextbox
rootId={rootId}
channelId={channelId}
navigator={navigator}
/>
/>}
</KeyboardLayout>
</SafeAreaView>
);