Skip to content

Commit

Permalink
MM-9915 - Transition showPreview away from being mutable state on the… (
Browse files Browse the repository at this point in the history
mattermost#4651)

* MM-9915 - Transition showPreview away from being mutable state on the textbox component

* fix variable naming

* refactor: create textbox redux flow

* fix errors after merge

* fix bug on edit channel header page with updatePreview

* fix bugs when textbox doesn't reset on channel change and on rhs open/close

* move actions triggers to appropriate functions

* fix current issues

Co-authored-by: mattermod <[email protected]>
  • Loading branch information
0xVolodya and mattermod committed Mar 31, 2020
1 parent 9545390 commit 81d41a1
Show file tree
Hide file tree
Showing 19 changed files with 316 additions and 57 deletions.
31 changes: 31 additions & 0 deletions actions/views/textbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {ActionTypes} from '../../utils/constants';

export function setShowPreviewOnCreateComment(showPreview) {
return {
type: ActionTypes.SET_SHOW_PREVIEW_ON_CREATE_COMMENT,
showPreview,
};
}

export function setShowPreviewOnCreatePost(showPreview) {
return {
type: ActionTypes.SET_SHOW_PREVIEW_ON_CREATE_POST,
showPreview,
};
}

export function setShowPreviewOnEditChannelHeaderModal(showPreview) {
return {
type: ActionTypes.SET_SHOW_PREVIEW_ON_EDIT_CHANNEL_HEADER_MODAL,
showPreview,
};
}

export function setShowPreviewOnEditPostModal(showPreview) {
return {
type: ActionTypes.SET_SHOW_PREVIEW_ON_EDIT_POST_MODAL,
showPreview,
};
}
36 changes: 23 additions & 13 deletions components/create_comment/create_comment.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,16 @@ class CreateComment extends React.PureComponent {
* To determine if the current user can send special channel mentions
*/
useChannelMentions: PropTypes.bool.isRequired,

/**
* Set show preview for textbox
*/
setShowPreview: PropTypes.func.isRequired,

/**
* Should preview be showed
*/
shouldShowPreview: PropTypes.bool.isRequired,
}

static getDerivedStateFromProps(props, state) {
Expand Down Expand Up @@ -230,13 +240,11 @@ class CreateComment extends React.PureComponent {
showPostDeletedModal: false,
showConfirmModal: false,
showEmojiPicker: false,
showPreview: false,
channelTimezoneCount: 0,
uploadsProgressPercent: {},
renderScrollbar: false,
suggestionListStyle: 'top',
};

this.lastBlurAt = 0;
this.draftsForPost = {};
this.doInitialScrollToBottom = false;
Expand All @@ -245,6 +253,8 @@ class CreateComment extends React.PureComponent {
componentDidMount() {
this.props.clearCommentDraftUploads();
this.props.onResetHistoryIndex();
this.props.setShowPreview(false);

this.focusTextbox();
document.addEventListener('paste', this.pasteHandler);
document.addEventListener('keydown', this.focusTextboxIfNecessary);
Expand Down Expand Up @@ -274,7 +284,7 @@ class CreateComment extends React.PureComponent {
}

// Focus on textbox when returned from preview mode
if (prevState.showPreview && !this.state.showPreview) {
if (prevProps.shouldShowPreview && !this.props.shouldShowPreview) {
this.focusTextbox();
}

Expand All @@ -288,8 +298,8 @@ class CreateComment extends React.PureComponent {
}
}

updatePreview = (newState) => {
this.setState({showPreview: newState});
setShowPreview = (newPreviewValue) => {
this.props.setShowPreview(newPreviewValue);
}

focusTextboxIfNecessary = (e) => {
Expand Down Expand Up @@ -437,7 +447,7 @@ class CreateComment extends React.PureComponent {

handleSubmit = async (e) => {
e.preventDefault();
this.updatePreview(false);
this.setShowPreview(false);

const {channelMembersCount, enableConfirmNotificationsToChannel, useChannelMentions, isTimezoneEnabled} = this.props;
const {draft} = this.state;
Expand Down Expand Up @@ -556,7 +566,7 @@ class CreateComment extends React.PureComponent {
this.handleSubmit(e);
}

this.updatePreview(false);
this.setShowPreview(false);
setTimeout(() => {
this.focusTextbox();
});
Expand Down Expand Up @@ -620,7 +630,7 @@ class CreateComment extends React.PureComponent {
Utils.isKeyPressed(e, Constants.KeyCodes.ENTER) &&
(e.ctrlKey || e.metaKey)
) {
this.updatePreview(false);
this.setShowPreview(false);
this.commentMsgKeyPress(e);
return;
}
Expand Down Expand Up @@ -933,7 +943,7 @@ class CreateComment extends React.PureComponent {
}

let fileUpload;
if (!readOnlyChannel && !this.state.showPreview) {
if (!readOnlyChannel && !this.props.shouldShowPreview) {
fileUpload = (
<FileUpload
ref='fileUpload'
Expand All @@ -953,7 +963,7 @@ class CreateComment extends React.PureComponent {
let emojiPicker = null;
const emojiButtonAriaLabel = formatMessage({id: 'emoji_picker.emojiPicker', defaultMessage: 'Emoji Picker'}).toLowerCase();

if (this.props.enableEmojiPicker && !readOnlyChannel && !this.state.showPreview) {
if (this.props.enableEmojiPicker && !readOnlyChannel && !this.props.shouldShowPreview) {
emojiPicker = (
<div>
<EmojiPickerOverlay
Expand Down Expand Up @@ -1036,7 +1046,7 @@ class CreateComment extends React.PureComponent {
ref='textbox'
disabled={readOnlyChannel}
characterLimit={this.props.maxPostSize}
preview={this.state.showPreview}
preview={this.props.shouldShowPreview}
suggestionListStyle={this.state.suggestionListStyle}
badConnection={this.props.badConnection}
listenForMentionKeyClick={true}
Expand Down Expand Up @@ -1065,8 +1075,8 @@ class CreateComment extends React.PureComponent {
<div className='col col-auto'>
<TextboxLinks
characterLimit={this.props.maxPostSize}
showPreview={this.state.showPreview}
updatePreview={this.updatePreview}
showPreview={this.props.shouldShowPreview}
updatePreview={this.setShowPreview}
message={readOnlyChannel ? '' : this.state.message}
isMarkdownPreviewEnabled={this.props.isMarkdownPreviewEnabled}
/>
Expand Down
14 changes: 7 additions & 7 deletions components/create_comment/create_comment.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ describe('components/CreateComment', () => {
onMoveHistoryIndexForward: jest.fn(),
onEditLatestPost: jest.fn(),
resetCreatePostRequest: jest.fn(),
setShowPreview: jest.fn(),
shouldShowPreview: false,
readOnlyChannel: false,
enableEmojiPicker: true,
enableGifPicker: true,
Expand Down Expand Up @@ -1149,18 +1151,16 @@ describe('components/CreateComment', () => {
);
const instance = wrapper.instance();
instance.focusTextbox = jest.fn();

expect(wrapper.state('showPreview')).toBe(false);
expect(instance.focusTextbox).not.toBeCalled();

instance.updatePreview(true);
instance.setShowPreview(true);

expect(wrapper.state('showPreview')).toBe(true);
expect(baseProps.setShowPreview).toHaveBeenCalledWith(true);
expect(instance.focusTextbox).not.toBeCalled();

instance.updatePreview(false);

expect(wrapper.state('showPreview')).toBe(false);
wrapper.setProps({shouldShowPreview: true});
expect(instance.focusTextbox).not.toBeCalled();
wrapper.setProps({shouldShowPreview: false});
expect(instance.focusTextbox).toBeCalled();
});
});
6 changes: 5 additions & 1 deletion components/create_comment/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
} from 'actions/views/create_comment';
import {emitShortcutReactToLastPostFrom} from 'actions/post_actions';
import {getPostDraft, getIsRhsExpanded, getSelectedPostFocussedAt} from 'selectors/rhs';
import {showPreviewOnCreateComment} from 'selectors/views/textbox';
import {setShowPreviewOnCreateComment} from 'actions/views/textbox';

import CreateComment from './create_comment.jsx';

Expand Down Expand Up @@ -84,6 +86,7 @@ function makeMapStateToProps() {
selectedPostFocussedAt: getSelectedPostFocussedAt(state),
canPost,
useChannelMentions,
shouldShowPreview: showPreviewOnCreateComment(state),
};
};
}
Expand Down Expand Up @@ -137,7 +140,8 @@ function makeMapDispatchToProps() {
onEditLatestPost,
resetCreatePostRequest,
getChannelTimezones,
emitShortcutReactToLastPostFrom
emitShortcutReactToLastPostFrom,
setShowPreview: setShowPreviewOnCreateComment,
}, dispatch);
};
}
Expand Down
34 changes: 24 additions & 10 deletions components/create_post/create_post.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,19 @@ class CreatePost extends React.PureComponent {
useChannelMentions: PropTypes.bool.isRequired,

intl: intlShape.isRequired,

/**
* Should preview be showed
*/
shouldShowPreview: PropTypes.bool.isRequired,

actions: PropTypes.shape({

/**
* Set show preview for textbox
*/
setShowPreview: PropTypes.func.isRequired,

/**
* func called after message submit.
*/
Expand Down Expand Up @@ -279,7 +290,6 @@ class CreatePost extends React.PureComponent {
message: props.draft.message,
submitting: false,
serverError: null,
showPreview: false,
};
}
return updatedState;
Expand All @@ -295,7 +305,6 @@ class CreatePost extends React.PureComponent {
showEmojiPicker: false,
showConfirmModal: false,
channelTimezoneCount: 0,
showPreview: false,
uploadsProgressPercent: {},
renderScrollbar: false,
currentChannel: props.currentChannel,
Expand All @@ -309,6 +318,7 @@ class CreatePost extends React.PureComponent {

componentDidMount() {
this.onOrientationChange();
this.props.actions.setShowPreview(false);
this.props.actions.clearDraftUploads(StoragePrefixes.DRAFT, (key, value) => {
if (value) {
return {...value, uploadsInProgress: []};
Expand All @@ -328,6 +338,10 @@ class CreatePost extends React.PureComponent {
this.focusTextbox();
}

if (this.props.currentChannel.id !== prevProps.currentChannel.id) {
this.props.actions.setShowPreview(false);
}

// Focus on textbox when emoji picker is closed
if (prevState.showEmojiPicker && !this.state.showEmojiPicker) {
this.focusTextbox();
Expand All @@ -345,8 +359,8 @@ class CreatePost extends React.PureComponent {
}
}

updatePreview = (newState) => {
this.setState({showPreview: newState});
setShowPreview = (newPreviewValue) => {
this.props.actions.setShowPreview(newPreviewValue);
}

setOrientationListeners = () => {
Expand Down Expand Up @@ -701,7 +715,7 @@ class CreatePost extends React.PureComponent {
this.handleSubmit(e);
}

this.updatePreview(false);
this.setShowPreview(false);
}

this.emitTypingEvent();
Expand Down Expand Up @@ -1237,7 +1251,7 @@ class CreatePost extends React.PureComponent {
}

let fileUpload;
if (!readOnlyChannel && !this.state.showPreview) {
if (!readOnlyChannel && !this.props.shouldShowPreview) {
fileUpload = (
<FileUpload
ref='fileUpload'
Expand All @@ -1256,7 +1270,7 @@ class CreatePost extends React.PureComponent {
let emojiPicker = null;
const emojiButtonAriaLabel = formatMessage({id: 'emoji_picker.emojiPicker', defaultMessage: 'Emoji Picker'}).toLowerCase();

if (this.props.enableEmojiPicker && !readOnlyChannel && !this.state.showPreview) {
if (this.props.enableEmojiPicker && !readOnlyChannel && !this.props.shouldShowPreview) {
emojiPicker = (
<div>
<EmojiPickerOverlay
Expand Down Expand Up @@ -1334,7 +1348,7 @@ class CreatePost extends React.PureComponent {
ref='textbox'
disabled={readOnlyChannel}
characterLimit={this.props.maxPostSize}
preview={this.state.showPreview}
preview={this.props.shouldShowPreview}
badConnection={this.props.badConnection}
listenForMentionKeyClick={true}
useChannelMentions={this.props.useChannelMentions}
Expand Down Expand Up @@ -1379,8 +1393,8 @@ class CreatePost extends React.PureComponent {
/>
<TextboxLinks
characterLimit={this.props.maxPostSize}
showPreview={this.state.showPreview}
updatePreview={this.updatePreview}
showPreview={this.props.shouldShowPreview}
updatePreview={this.setShowPreview}
message={readOnlyChannel ? '' : this.state.message}
/>
</div>
Expand Down
6 changes: 2 additions & 4 deletions components/create_post/create_post.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ const actionsProp = {
setDraft: jest.fn(),
setEditingPost: jest.fn(),
openModal: jest.fn(),
setShowPreview: jest.fn(),
executeCommand: async () => {
return {data: true};
},
Expand Down Expand Up @@ -133,6 +134,7 @@ function createPost({
rhsExpanded={false}
emojiMap={emojiMap}
badConnection={false}
shouldShowPreview={false}
isTimezoneEnabled={false}
canPost={true}
useChannelMentions={true}
Expand Down Expand Up @@ -265,10 +267,6 @@ describe('components/create_post', () => {
const wrapper = shallowWithIntl(createPost());
wrapper.instance().refs = {textbox: {getWrappedInstance: () => ({blur: jest.fn()})}};

wrapper.setState({
showPreview: false,
});

const postTextbox = wrapper.find('#post_textbox');
postTextbox.simulate('KeyPress', {key: KeyCodes.ENTER[0], preventDefault: jest.fn(), persist: jest.fn()});
expect(GlobalActions.emitLocalUserTypingEvent).toHaveBeenCalledWith(currentChannelProp.id, '');
Expand Down
4 changes: 4 additions & 0 deletions components/create_post/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ import {connectionErrorCount} from 'selectors/views/system';
import {addReaction, createPost, setEditingPost, emitShortcutReactToLastPostFrom} from 'actions/post_actions.jsx';
import {scrollPostListToBottom} from 'actions/views/channel';
import {selectPostFromRightHandSideSearchByPostId} from 'actions/views/rhs';
import {setShowPreviewOnCreatePost} from 'actions/views/textbox';
import {executeCommand} from 'actions/command';
import {runMessageWillBePostedHooks, runSlashCommandWillBePostedHooks} from 'actions/hooks';
import {getPostDraft, getIsRhsExpanded} from 'selectors/rhs';
import {showPreviewOnCreatePost} from 'selectors/views/textbox';
import {getCurrentLocale} from 'selectors/i18n';
import {getEmojiMap, getShortcutReactToLastPostEmittedFrom} from 'selectors/emojis';
import {setGlobalItem, actionOnGlobalItemsWithPrefix} from 'actions/storage';
Expand Down Expand Up @@ -109,6 +111,7 @@ function makeMapStateToProps() {
shortcutReactToLastPostEmittedFrom,
canPost,
useChannelMentions,
shouldShowPreview: showPreviewOnCreatePost(state),
};
};
}
Expand Down Expand Up @@ -139,6 +142,7 @@ function mapDispatchToProps(dispatch) {
runMessageWillBePostedHooks,
runSlashCommandWillBePostedHooks,
scrollPostListToBottom,
setShowPreview: setShowPreviewOnCreatePost,
}, dispatch),
};
}
Expand Down
Loading

0 comments on commit 81d41a1

Please sign in to comment.