[MM-13843] Edit channel autocomplete is same as the posting message one (#3038)
* [MM-13843] Edit channle autocomplete is same as the posting message * [MM-13843] Lint error fixes * [MM-13843] Address nestedscrollenable warning comment * [MM-13843] Added test case for edit_channel_info * [MM-13843] nestedScrollEnabled on at_mention * [MM-13843] Fix linting issue * [MM-13843] Fixed test case * [MM-13843] Address PR comments * [MM-13843] Made prop not required
This commit is contained in:
parent
4d22a28397
commit
ef8813f115
10 changed files with 97 additions and 4 deletions
|
|
@ -36,6 +36,7 @@ export default class AtMention extends PureComponent {
|
|||
theme: PropTypes.object.isRequired,
|
||||
value: PropTypes.string,
|
||||
isLandscape: PropTypes.bool.isRequired,
|
||||
nestedScrollEnabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
|
@ -207,7 +208,7 @@ export default class AtMention extends PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const {maxListHeight, theme} = this.props;
|
||||
const {maxListHeight, theme, nestedScrollEnabled} = this.props;
|
||||
const {mentionComplete, sections} = this.state;
|
||||
|
||||
if (sections.length === 0 || mentionComplete) {
|
||||
|
|
@ -228,6 +229,7 @@ export default class AtMention extends PureComponent {
|
|||
renderSectionHeader={this.renderSectionHeader}
|
||||
ItemSeparatorComponent={AutocompleteDivider}
|
||||
initialNumToRender={10}
|
||||
nestedScrollEnabled={nestedScrollEnabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,12 +33,14 @@ export default class Autocomplete extends PureComponent {
|
|||
enableDateSuggestion: PropTypes.bool.isRequired,
|
||||
valueEvent: PropTypes.string,
|
||||
cursorPositionEvent: PropTypes.string,
|
||||
nestedScrollEnabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
isSearch: false,
|
||||
cursorPosition: 0,
|
||||
enableDateSuggestion: false,
|
||||
nestedScrollEnabled: false,
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(props, state) {
|
||||
|
|
@ -191,6 +193,7 @@ export default class Autocomplete extends PureComponent {
|
|||
onChangeText={this.onChangeText}
|
||||
onResultCountChange={this.handleAtMentionCountChange}
|
||||
value={value || ''}
|
||||
nestedScrollEnabled={this.props.nestedScrollEnabled}
|
||||
/>
|
||||
<ChannelMention
|
||||
{...this.props}
|
||||
|
|
@ -199,6 +202,7 @@ export default class Autocomplete extends PureComponent {
|
|||
onChangeText={this.onChangeText}
|
||||
onResultCountChange={this.handleChannelMentionCountChange}
|
||||
value={value || ''}
|
||||
nestedScrollEnabled={this.props.nestedScrollEnabled}
|
||||
/>
|
||||
<EmojiSuggestion
|
||||
{...this.props}
|
||||
|
|
@ -207,6 +211,7 @@ export default class Autocomplete extends PureComponent {
|
|||
onChangeText={this.onChangeText}
|
||||
onResultCountChange={this.handleEmojiCountChange}
|
||||
value={value || ''}
|
||||
nestedScrollEnabled={this.props.nestedScrollEnabled}
|
||||
/>
|
||||
<SlashSuggestion
|
||||
{...this.props}
|
||||
|
|
@ -214,6 +219,7 @@ export default class Autocomplete extends PureComponent {
|
|||
onChangeText={this.onChangeText}
|
||||
onResultCountChange={this.handleCommandCountChange}
|
||||
value={value || ''}
|
||||
nestedScrollEnabled={this.props.nestedScrollEnabled}
|
||||
/>
|
||||
{(this.props.isSearch && this.props.enableDateSuggestion) &&
|
||||
<DateSuggestion
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ export default class ChannelMention extends PureComponent {
|
|||
value: PropTypes.string,
|
||||
serverVersion: PropTypes.string,
|
||||
isLandscape: PropTypes.bool.isRequired,
|
||||
nestedScrollEnabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
|
@ -211,7 +212,7 @@ export default class ChannelMention extends PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const {maxListHeight, theme} = this.props;
|
||||
const {maxListHeight, theme, nestedScrollEnabled} = this.props;
|
||||
const {mentionComplete, sections} = this.state;
|
||||
|
||||
if (sections.length === 0 || mentionComplete) {
|
||||
|
|
@ -232,6 +233,7 @@ export default class ChannelMention extends PureComponent {
|
|||
renderSectionHeader={this.renderSectionHeader}
|
||||
ItemSeparatorComponent={AutocompleteDivider}
|
||||
initialNumToRender={10}
|
||||
nestedScrollEnabled={nestedScrollEnabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ export default class EmojiSuggestion extends Component {
|
|||
rootId: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
serverVersion: PropTypes.string,
|
||||
nestedScrollEnabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
|
@ -188,7 +189,7 @@ export default class EmojiSuggestion extends Component {
|
|||
getItemLayout = ({index}) => ({length: 40, offset: 40 * index, index})
|
||||
|
||||
render() {
|
||||
const {maxListHeight, theme} = this.props;
|
||||
const {maxListHeight, theme, nestedScrollEnabled} = this.props;
|
||||
|
||||
if (!this.state.active) {
|
||||
// If we are not in an active state return null so nothing is rendered
|
||||
|
|
@ -209,6 +210,7 @@ export default class EmojiSuggestion extends Component {
|
|||
ItemSeparatorComponent={AutocompleteDivider}
|
||||
pageSize={10}
|
||||
initialListSize={10}
|
||||
nestedScrollEnabled={nestedScrollEnabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ export default class SlashSuggestion extends Component {
|
|||
onResultCountChange: PropTypes.func.isRequired,
|
||||
value: PropTypes.string,
|
||||
isLandscape: PropTypes.bool.isRequired,
|
||||
nestedScrollEnabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
|
@ -151,7 +152,7 @@ export default class SlashSuggestion extends Component {
|
|||
)
|
||||
|
||||
render() {
|
||||
const {maxListHeight, theme} = this.props;
|
||||
const {maxListHeight, theme, nestedScrollEnabled} = this.props;
|
||||
|
||||
if (!this.state.active) {
|
||||
// If we are not in an active state return null so nothing is rendered
|
||||
|
|
@ -172,6 +173,7 @@ export default class SlashSuggestion extends Component {
|
|||
ItemSeparatorComponent={AutocompleteDivider}
|
||||
pageSize={10}
|
||||
initialListSize={10}
|
||||
nestedScrollEnabled={nestedScrollEnabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
|
|||
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
|
||||
import Autocomplete from 'app/components/autocomplete';
|
||||
import ErrorText from 'app/components/error_text';
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
import Loading from 'app/components/loading';
|
||||
|
|
@ -220,6 +221,7 @@ export default class EditChannelInfo extends PureComponent {
|
|||
<KeyboardAwareScrollView
|
||||
ref={this.scroll}
|
||||
style={style.container}
|
||||
keyboardShouldPersistTaps={'always'}
|
||||
>
|
||||
{displayError}
|
||||
<TouchableWithoutFeedback onPress={this.blur}>
|
||||
|
|
@ -330,6 +332,13 @@ export default class EditChannelInfo extends PureComponent {
|
|||
defaultMessage='(optional)'
|
||||
/>
|
||||
</View>
|
||||
<Autocomplete
|
||||
cursorPosition={header.length}
|
||||
maxHeight={200}
|
||||
onChangeText={this.onHeaderChangeText}
|
||||
value={header}
|
||||
nestedScrollEnabled={true}
|
||||
/>
|
||||
<View style={[style.inputContainer, padding(isLandscape)]}>
|
||||
<TextInputWithLocalizedPlaceholder
|
||||
ref={this.headerInput}
|
||||
|
|
|
|||
63
app/components/edit_channel_info/edit_channel_info.test.js
Normal file
63
app/components/edit_channel_info/edit_channel_info.test.js
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
|
||||
import Preferences from 'mattermost-redux/constants/preferences';
|
||||
|
||||
import Autocomplete from 'app/components/autocomplete';
|
||||
import EditChannelInfo from './edit_channel_info';
|
||||
|
||||
describe('EditChannelInfo', () => {
|
||||
const baseProps = {
|
||||
actions: {
|
||||
dismissModal: jest.fn(),
|
||||
popTopScreen: jest.fn(),
|
||||
},
|
||||
theme: Preferences.THEMES.default,
|
||||
deviceWidth: 400,
|
||||
deviceHeight: 600,
|
||||
channelType: 'O',
|
||||
enableRightButton: jest.fn(),
|
||||
saving: false,
|
||||
editing: true,
|
||||
error: '',
|
||||
displayName: 'display_name',
|
||||
currentTeamUrl: '/team_a',
|
||||
channelURL: '/team_a/channels/channel_a',
|
||||
purpose: 'purpose',
|
||||
header: 'header',
|
||||
onDisplayNameChange: jest.fn(),
|
||||
onChannelURLChange: jest.fn(),
|
||||
onPurposeChange: jest.fn(),
|
||||
onHeaderChange: jest.fn(),
|
||||
oldDisplayName: 'old_display_name',
|
||||
oldChannelURL: '/team_a/channels/channel_old',
|
||||
oldHeader: 'old_header',
|
||||
oldPurpose: 'old_purpose',
|
||||
isLandscape: true,
|
||||
};
|
||||
|
||||
test('should have called onHeaderChangeText on text change from Autocomplete', () => {
|
||||
const wrapper = shallow(
|
||||
<EditChannelInfo {...baseProps}/>
|
||||
);
|
||||
|
||||
const instance = wrapper.instance();
|
||||
instance.enableRightButton = jest.fn();
|
||||
|
||||
const autocomplete = wrapper.find(Autocomplete);
|
||||
|
||||
expect(autocomplete.exists()).toEqual(true);
|
||||
expect(autocomplete.props().value).toEqual('header');
|
||||
expect(autocomplete.props().cursorPosition).toEqual(6);
|
||||
expect(autocomplete.props().nestedScrollEnabled).toEqual(true);
|
||||
|
||||
autocomplete.props().onChangeText('header');
|
||||
expect(baseProps.onHeaderChange).toHaveBeenCalledTimes(1);
|
||||
expect(baseProps.onHeaderChange).toHaveBeenCalledWith('header');
|
||||
expect(instance.enableRightButton).toHaveBeenCalledTimes(1);
|
||||
expect(instance.enableRightButton).toHaveBeenCalledWith(true);
|
||||
});
|
||||
});
|
||||
|
|
@ -493,6 +493,7 @@ export default class ChannelInfo extends PureComponent {
|
|||
theme,
|
||||
isBot,
|
||||
isLandscape,
|
||||
actions: {popToRoot},
|
||||
} = this.props;
|
||||
|
||||
const style = getStyleSheet(theme);
|
||||
|
|
@ -533,6 +534,7 @@ export default class ChannelInfo extends PureComponent {
|
|||
isBot={isBot}
|
||||
hasGuests={currentChannelGuestCount > 0}
|
||||
isGroupConstrained={currentChannel.group_constrained}
|
||||
popToRoot={popToRoot}
|
||||
/>
|
||||
}
|
||||
<View style={style.rowsContainer}>
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ export default class ChannelInfoHeader extends React.PureComponent {
|
|||
hasGuests: PropTypes.bool.isRequired,
|
||||
isGroupConstrained: PropTypes.bool,
|
||||
timeZone: PropTypes.string,
|
||||
popToRoot: PropTypes.func,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
|
|
@ -137,6 +138,7 @@ export default class ChannelInfoHeader extends React.PureComponent {
|
|||
isBot,
|
||||
isGroupConstrained,
|
||||
timeZone,
|
||||
popToRoot,
|
||||
} = this.props;
|
||||
|
||||
const style = getStyleSheet(theme);
|
||||
|
|
@ -210,6 +212,7 @@ export default class ChannelInfoHeader extends React.PureComponent {
|
|||
textStyles={textStyles}
|
||||
blockStyles={blockStyles}
|
||||
value={header}
|
||||
onChannelLinkPress={popToRoot}
|
||||
/>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
|
|||
import {
|
||||
popTopScreen,
|
||||
goToScreen,
|
||||
popToRoot,
|
||||
dismissModal,
|
||||
showModalOverCurrentContext,
|
||||
} from 'app/actions/navigation';
|
||||
|
|
@ -146,6 +147,7 @@ function mapDispatchToProps(dispatch) {
|
|||
handleSelectChannel,
|
||||
popTopScreen,
|
||||
goToScreen,
|
||||
popToRoot,
|
||||
dismissModal,
|
||||
showModalOverCurrentContext,
|
||||
}, dispatch),
|
||||
|
|
|
|||
Loading…
Reference in a new issue