MM-16397 save draft when app state changes (#2899)
* MM-16397 save draft when app state changes * Unit tests
This commit is contained in:
parent
e5f98b5151
commit
e6fdef3451
3 changed files with 252 additions and 0 deletions
|
|
@ -0,0 +1,149 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PostTextBox should match, full snapshot 1`] = `
|
||||
<React.Fragment>
|
||||
<Connect(Typing) />
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"backgroundColor": "#ffffff",
|
||||
"borderTopColor": "rgba(61,60,64,0.2)",
|
||||
"borderTopWidth": 1,
|
||||
"flexDirection": "row",
|
||||
"paddingVertical": 4,
|
||||
}
|
||||
}
|
||||
>
|
||||
<AttachmentButton
|
||||
blurTextBox={[Function]}
|
||||
browseFileTypes="public.item"
|
||||
canBrowseFiles={true}
|
||||
canBrowsePhotoLibrary={true}
|
||||
canBrowseVideoLibrary={true}
|
||||
canTakePhoto={true}
|
||||
canTakeVideo={true}
|
||||
extraOptions={null}
|
||||
fileCount={0}
|
||||
maxFileCount={5}
|
||||
maxFileSize={1024}
|
||||
navigator={
|
||||
Object {
|
||||
"showModal": [MockFunction],
|
||||
}
|
||||
}
|
||||
onShowFileMaxWarning={[Function]}
|
||||
onShowFileSizeWarning={[Function]}
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
uploadFiles={[Function]}
|
||||
validMimeTypes={Array []}
|
||||
/>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "stretch",
|
||||
"backgroundColor": "#fff",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"marginRight": 10,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<TextInput
|
||||
allowFontScaling={true}
|
||||
blurOnSubmit={false}
|
||||
disableFullscreenUI={true}
|
||||
editable={true}
|
||||
keyboardType="default"
|
||||
multiline={true}
|
||||
onChangeText={[Function]}
|
||||
onEndEditing={[Function]}
|
||||
onSelectionChange={[Function]}
|
||||
placeholder="Write to Test Channel"
|
||||
placeholderTextColor="rgba(0,0,0,0.5)"
|
||||
rejectResponderTermination={true}
|
||||
style={
|
||||
Object {
|
||||
"color": "#000",
|
||||
"flex": 1,
|
||||
"fontSize": 14,
|
||||
"maxHeight": 100,
|
||||
"paddingBottom": 8,
|
||||
"paddingLeft": 12,
|
||||
"paddingRight": 12,
|
||||
"paddingTop": 8,
|
||||
}
|
||||
}
|
||||
underlineColorAndroid="transparent"
|
||||
value=""
|
||||
/>
|
||||
<Fade
|
||||
visible={false}
|
||||
>
|
||||
<SendButton
|
||||
disabled={false}
|
||||
handleSendMessage={[Function]}
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</Fade>
|
||||
</View>
|
||||
</View>
|
||||
</React.Fragment>
|
||||
`;
|
||||
90
app/components/post_textbox/post_textbox.test.js
Normal file
90
app/components/post_textbox/post_textbox.test.js
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {shallowWithIntl} from 'test/intl-test-helper';
|
||||
|
||||
import Preferences from 'mattermost-redux/constants/preferences';
|
||||
|
||||
import PostTextbox from './post_textbox.ios';
|
||||
|
||||
jest.mock('NativeEventEmitter');
|
||||
|
||||
describe('PostTextBox', () => {
|
||||
const baseProps = {
|
||||
actions: {
|
||||
addReactionToLatestPost: jest.fn(),
|
||||
createPost: jest.fn(),
|
||||
executeCommand: jest.fn(),
|
||||
handleCommentDraftChanged: jest.fn(),
|
||||
handlePostDraftChanged: jest.fn(),
|
||||
handleClearFiles: jest.fn(),
|
||||
handleClearFailedFiles: jest.fn(),
|
||||
handleRemoveLastFile: jest.fn(),
|
||||
initUploadFiles: jest.fn(),
|
||||
userTyping: jest.fn(),
|
||||
handleCommentDraftSelectionChanged: jest.fn(),
|
||||
setStatus: jest.fn(),
|
||||
selectPenultimateChannel: jest.fn(),
|
||||
},
|
||||
canUploadFiles: true,
|
||||
channelId: 'channel-id',
|
||||
channelDisplayName: 'Test Channel',
|
||||
channelTeamId: 'channel-team-id',
|
||||
channelIsLoading: false,
|
||||
channelIsReadOnly: false,
|
||||
currentUserId: 'current-user-id',
|
||||
deactivatedChannel: false,
|
||||
files: [],
|
||||
maxFileSize: 1024,
|
||||
maxMessageLength: 4000,
|
||||
navigator: {
|
||||
showModal: jest.fn(),
|
||||
},
|
||||
rootId: '',
|
||||
theme: Preferences.THEMES.default,
|
||||
uploadFileRequestStatus: 'NOT_STARTED',
|
||||
value: '',
|
||||
userIsOutOfOffice: false,
|
||||
channelIsArchived: false,
|
||||
onCloseChannel: jest.fn(),
|
||||
cursorPositionEvent: '',
|
||||
valueEvent: '',
|
||||
};
|
||||
|
||||
test('should match, full snapshot', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<PostTextbox {...baseProps}/>
|
||||
);
|
||||
|
||||
expect(wrapper.getElement()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should emit the event but no text is save to draft', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<PostTextbox {...baseProps}/>
|
||||
);
|
||||
|
||||
wrapper.setState({value: 'some text'});
|
||||
|
||||
const instance = wrapper.instance();
|
||||
|
||||
instance.changeDraft = jest.fn();
|
||||
instance.handleAppStateChange('active');
|
||||
expect(instance.changeDraft).not.toBeCalled();
|
||||
});
|
||||
|
||||
test('should emit the event and text is save to draft', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<PostTextbox {...baseProps}/>
|
||||
);
|
||||
|
||||
const instance = wrapper.instance();
|
||||
const value = 'some text';
|
||||
|
||||
wrapper.setState({value});
|
||||
instance.handleAppStateChange('background');
|
||||
expect(baseProps.actions.handlePostDraftChanged).toHaveBeenCalledWith(baseProps.channelId, value);
|
||||
expect(baseProps.actions.handlePostDraftChanged).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
|
@ -5,6 +5,7 @@ import React, {PureComponent} from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Alert,
|
||||
AppState,
|
||||
BackHandler,
|
||||
findNodeHandle,
|
||||
Keyboard,
|
||||
|
|
@ -99,7 +100,10 @@ export default class PostTextBoxBase extends PureComponent {
|
|||
|
||||
componentDidMount() {
|
||||
const event = this.props.rootId ? INSERT_TO_COMMENT : INSERT_TO_DRAFT;
|
||||
|
||||
EventEmitter.on(event, this.handleInsertTextToDraft);
|
||||
AppState.addEventListener('change', this.handleAppStateChange);
|
||||
|
||||
if (Platform.OS === 'android') {
|
||||
Keyboard.addListener('keyboardDidHide', this.handleAndroidKeyboard);
|
||||
BackHandler.addEventListener('hardwareBackPress', this.handleAndroidBack);
|
||||
|
|
@ -114,7 +118,10 @@ export default class PostTextBoxBase extends PureComponent {
|
|||
|
||||
componentWillUnmount() {
|
||||
const event = this.props.rootId ? INSERT_TO_COMMENT : INSERT_TO_DRAFT;
|
||||
|
||||
EventEmitter.off(event, this.handleInsertTextToDraft);
|
||||
AppState.removeEventListener('change', this.handleAppStateChange);
|
||||
|
||||
if (Platform.OS === 'android') {
|
||||
Keyboard.removeListener('keyboardDidHide', this.handleAndroidKeyboard);
|
||||
BackHandler.removeEventListener('hardwareBackPress', this.handleAndroidBack);
|
||||
|
|
@ -248,6 +255,12 @@ export default class PostTextBoxBase extends PureComponent {
|
|||
return false;
|
||||
};
|
||||
|
||||
handleAppStateChange = (nextAppState) => {
|
||||
if (nextAppState !== 'active') {
|
||||
this.changeDraft(this.state.value);
|
||||
}
|
||||
};
|
||||
|
||||
handleEndEditing = (e) => {
|
||||
if (e && e.nativeEvent) {
|
||||
this.changeDraft(e.nativeEvent.text || '');
|
||||
|
|
|
|||
Loading…
Reference in a new issue