PLT-1759 - Auto-complete for !channels when posting messages. (#3890)

* Auto-complete for !channels when posting messages.

This is part 1 of the fix for PLT-1759 to make channels linkable.

Still to do:
- Make the !channels clickable when they appear in messages. This is
  blocked until PR #3865 is resolved as it looks like that refactors
  some of the code that would be touched by making this change.

- Unit tests. Again, I think the above referenced PR should be merged
  before tackling this.

* Fix style problems.

* Highlighting of !channel-names in messages.

This only identifies the !channel-name (not the display name). The
implementation of the auto-complete on channel names now needs to be
modified to convert to the channel handle before sending the message.

* Display !channel-name as !Display Name.

When we encounter !channel-name in a message, display it as a link using
the channel's actual name rather than it's handle (name).

* Match on names and display name, and use name.

* Autocomplete channels matching on both the name and the the display
  name.
* Use the name as the text we fill in instead of the display name. It's
  potentially a bit ugly, but it minimises complexity for now as
  otherwise we'd have to do complicated things to the message box.

* Fix style issues.

* Load more channels everywhere.

Whenever we load the list of channels, we should also load the list of
more channels. This is to enable auto-completing and auto-linking of all
channels whether or not the user is in them currently.

* Include more channels in the map for linking.

* Listen for channel list updates for autolinking.

* Remove accidental console.log.

* Autocomplete on more channels too.

* i18n for channel autocomplete.

* Link directly to channels in !channel mentions.

This currently does not work if you aren't a member of that channel.
Need to decide what the correct behaviour is in that case.

* Fix style issues.

* Show channel name and handle in suggestion.

* Match channels only at start or after space.

* Better matching in text-formatting.

Only match channels after a space-type character or at the start in the
posts list too.

* Move the route construction to make tests work.

Moves route-construction out of text_formatting.jsx and into utils.jsx
so that the unit tests work once again.
Этот коммит содержится в:
George Goldberg
2016-09-19 13:21:22 +01:00
коммит произвёл Joram Wilander
родитель 781ff323db
Коммит 8443ca5828
11 изменённых файлов: 257 добавлений и 9 удалений

Просмотреть файл

@@ -3,6 +3,7 @@
import React from 'react';
import ChannelStore from 'stores/channel_store.jsx';
import EmojiStore from 'stores/emoji_store.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import {Preferences} from 'utils/constants.jsx';
@@ -26,6 +27,7 @@ export default class PostMessageContainer extends React.Component {
this.onEmojiChange = this.onEmojiChange.bind(this);
this.onPreferenceChange = this.onPreferenceChange.bind(this);
this.onUserChange = this.onUserChange.bind(this);
this.onChannelChange = this.onChannelChange.bind(this);
const mentionKeys = UserStore.getCurrentMentionKeys();
mentionKeys.push('@here');
@@ -34,7 +36,8 @@ export default class PostMessageContainer extends React.Component {
emojis: EmojiStore.getEmojis(),
enableFormatting: PreferenceStore.getBool(Preferences.CATEGORY_ADVANCED_SETTINGS, 'formatting', true),
mentionKeys,
usernameMap: UserStore.getProfilesUsernameMap()
usernameMap: UserStore.getProfilesUsernameMap(),
channelNamesMap: ChannelStore.getChannelNamesMap()
};
}
@@ -42,12 +45,16 @@ export default class PostMessageContainer extends React.Component {
EmojiStore.addChangeListener(this.onEmojiChange);
PreferenceStore.addChangeListener(this.onPreferenceChange);
UserStore.addChangeListener(this.onUserChange);
ChannelStore.addChangeListener(this.onChannelChange);
ChannelStore.addMoreChangeListener(this.onChannelChange);
}
componentWillUnmount() {
EmojiStore.removeChangeListener(this.onEmojiChange);
PreferenceStore.removeChangeListener(this.onPreferenceChange);
UserStore.removeChangeListener(this.onUserChange);
ChannelStore.removeChangeListener(this.onChannelChange);
ChannelStore.removeMoreChangeListener(this.onChannelChange);
}
onEmojiChange() {
@@ -72,6 +79,12 @@ export default class PostMessageContainer extends React.Component {
});
}
onChannelChange() {
this.setState({
channelNamesMap: ChannelStore.getChannelNamesMap()
});
}
render() {
return (
<PostMessageView
@@ -81,7 +94,8 @@ export default class PostMessageContainer extends React.Component {
enableFormatting={this.state.enableFormatting}
mentionKeys={this.state.mentionKeys}
usernameMap={this.state.usernameMap}
channelNamesMap={this.state.channelNamesMap}
/>
);
}
}
}

Просмотреть файл

@@ -13,7 +13,8 @@ export default class PostMessageView extends React.Component {
emojis: React.PropTypes.object.isRequired,
enableFormatting: React.PropTypes.bool.isRequired,
mentionKeys: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
usernameMap: React.PropTypes.object.isRequired
usernameMap: React.PropTypes.object.isRequired,
channelNamesMap: React.PropTypes.object.isRequired
};
shouldComponentUpdate(nextProps) {
@@ -40,6 +41,7 @@ export default class PostMessageView extends React.Component {
// Don't check if props.usernameMap changes since it is very large and inefficient to do so.
// This mimics previous behaviour, but could be changed if we decide it's worth it.
// The same choice (and reasoning) is also applied to the this.props.channelNamesMap.
return false;
}
@@ -53,7 +55,8 @@ export default class PostMessageView extends React.Component {
emojis: this.props.emojis,
siteURL: Utils.getSiteURL(),
mentionKeys: this.props.mentionKeys,
usernameMap: this.props.usernameMap
usernameMap: this.props.usernameMap,
channelNamesMap: this.props.channelNamesMap
});
return (
@@ -63,4 +66,4 @@ export default class PostMessageView extends React.Component {
/>
);
}
}
}