From 12896bd23eeba79884245c1c29fdc568cf21a7fa Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Mon, 14 Mar 2016 08:50:46 -0400 Subject: Converting to Webpack. Stage 1. --- .../components/suggestion/at_mention_provider.jsx | 118 --------------- .../components/suggestion/command_provider.jsx | 43 ------ .../components/suggestion/emoticon_provider.jsx | 91 ------------ .../suggestion/search_channel_provider.jsx | 69 --------- .../suggestion/search_suggestion_list.jsx | 97 ------------ .../components/suggestion/search_user_provider.jsx | 62 -------- web/react/components/suggestion/suggestion_box.jsx | 163 --------------------- .../components/suggestion/suggestion_list.jsx | 125 ---------------- 8 files changed, 768 deletions(-) delete mode 100644 web/react/components/suggestion/at_mention_provider.jsx delete mode 100644 web/react/components/suggestion/command_provider.jsx delete mode 100644 web/react/components/suggestion/emoticon_provider.jsx delete mode 100644 web/react/components/suggestion/search_channel_provider.jsx delete mode 100644 web/react/components/suggestion/search_suggestion_list.jsx delete mode 100644 web/react/components/suggestion/search_user_provider.jsx delete mode 100644 web/react/components/suggestion/suggestion_box.jsx delete mode 100644 web/react/components/suggestion/suggestion_list.jsx (limited to 'web/react/components/suggestion') diff --git a/web/react/components/suggestion/at_mention_provider.jsx b/web/react/components/suggestion/at_mention_provider.jsx deleted file mode 100644 index b53b351d9..000000000 --- a/web/react/components/suggestion/at_mention_provider.jsx +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import SuggestionStore from '../../stores/suggestion_store.jsx'; -import UserStore from '../../stores/user_store.jsx'; -import * as Utils from '../../utils/utils.jsx'; - -import {FormattedMessage} from 'mm-intl'; - -const MaxUserSuggestions = 40; - -class AtMentionSuggestion extends React.Component { - render() { - const {item, isSelection, onClick} = this.props; - - let username; - let description; - let icon; - if (item.username === 'all') { - username = 'all'; - description = ( - - ); - icon = ; - } else if (item.username === 'channel') { - username = 'channel'; - description = ( - - ); - icon = ; - } else { - username = item.username; - description = Utils.getFullName(item); - icon = ( - -
- {icon} -
-
- - {'@' + username} - - - {description} - -
- - ); - } -} - -AtMentionSuggestion.propTypes = { - item: React.PropTypes.object.isRequired, - isSelection: React.PropTypes.bool, - onClick: React.PropTypes.func -}; - -export default class AtMentionProvider { - handlePretextChanged(suggestionId, pretext) { - const captured = (/@([a-z0-9\-\._]*)$/i).exec(pretext); - if (captured) { - const usernamePrefix = captured[1]; - - const users = UserStore.getActiveOnlyProfiles(true); - let filtered = []; - - for (const id of Object.keys(users)) { - const user = users[id]; - - if (user.username.startsWith(usernamePrefix) && user.delete_at <= 0) { - filtered.push(user); - } - - if (filtered.length >= MaxUserSuggestions) { - break; - } - } - - // add dummy users to represent the @all and @channel special mentions - if ('all'.startsWith(usernamePrefix)) { - filtered.push({username: 'all'}); - } - - if ('channel'.startsWith(usernamePrefix)) { - filtered.push({username: 'channel'}); - } - - filtered = filtered.sort((a, b) => a.username.localeCompare(b.username)); - - const mentions = filtered.map((user) => '@' + user.username); - - SuggestionStore.setMatchedPretext(suggestionId, captured[0]); - SuggestionStore.addSuggestions(suggestionId, mentions, filtered, AtMentionSuggestion); - } - } -} diff --git a/web/react/components/suggestion/command_provider.jsx b/web/react/components/suggestion/command_provider.jsx deleted file mode 100644 index fffb2df07..000000000 --- a/web/react/components/suggestion/command_provider.jsx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import * as AsyncClient from '../../utils/async_client.jsx'; - -class CommandSuggestion extends React.Component { - render() { - const {item, isSelection, onClick} = this.props; - - let className = 'command'; - if (isSelection) { - className += ' suggestion--selected'; - } - - return ( -
-
- {item.suggestion} {item.hint} -
-
- {item.description} -
-
- ); - } -} - -CommandSuggestion.propTypes = { - item: React.PropTypes.object.isRequired, - isSelection: React.PropTypes.bool, - onClick: React.PropTypes.func -}; - -export default class CommandProvider { - handlePretextChanged(suggestionId, pretext) { - if (pretext.startsWith('/')) { - AsyncClient.getSuggestedCommands(pretext, suggestionId, CommandSuggestion); - } - } -} diff --git a/web/react/components/suggestion/emoticon_provider.jsx b/web/react/components/suggestion/emoticon_provider.jsx deleted file mode 100644 index fd470cf21..000000000 --- a/web/react/components/suggestion/emoticon_provider.jsx +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import SuggestionStore from '../../stores/suggestion_store.jsx'; -import * as Emoticons from '../../utils/emoticons.jsx'; - -const MAX_EMOTICON_SUGGESTIONS = 40; - -class EmoticonSuggestion extends React.Component { - render() { - const text = this.props.term; - const name = this.props.item; - - let className = 'emoticon-suggestion'; - if (this.props.isSelection) { - className += ' suggestion--selected'; - } - - return ( -
-
- {text} -
-
- {text} -
-
- ); - } -} - -EmoticonSuggestion.propTypes = { - item: React.PropTypes.string.isRequired, - term: React.PropTypes.string.isRequired, - isSelection: React.PropTypes.bool, - onClick: React.PropTypes.func -}; - -export default class EmoticonProvider { - handlePretextChanged(suggestionId, pretext) { - const captured = (/(?:^|\s)(:([a-zA-Z0-9_+\-]*))$/g).exec(pretext); - if (captured) { - const text = captured[1]; - const partialName = captured[2]; - - const names = []; - - for (const emoticon of Emoticons.emoticonMap.keys()) { - if (emoticon.indexOf(partialName) !== -1) { - names.push(emoticon); - - if (names.length >= MAX_EMOTICON_SUGGESTIONS) { - break; - } - } - } - - // sort the emoticons so that emoticons starting with the entered text come first - names.sort((a, b) => { - const aPrefix = a.startsWith(partialName); - const bPrefix = b.startsWith(partialName); - - if (aPrefix === bPrefix) { - return a.localeCompare(b); - } else if (aPrefix) { - return -1; - } - - return 1; - }); - - const terms = names.map((name) => ':' + name + ':'); - - if (terms.length > 0) { - SuggestionStore.setMatchedPretext(suggestionId, text); - SuggestionStore.addSuggestions(suggestionId, terms, names, EmoticonSuggestion); - - // force the selection to be cleared since the order of elements may have changed - SuggestionStore.clearSelection(suggestionId); - } - } - } -} diff --git a/web/react/components/suggestion/search_channel_provider.jsx b/web/react/components/suggestion/search_channel_provider.jsx deleted file mode 100644 index 66a534907..000000000 --- a/web/react/components/suggestion/search_channel_provider.jsx +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import ChannelStore from '../../stores/channel_store.jsx'; -import Constants from '../../utils/constants.jsx'; -import SuggestionStore from '../../stores/suggestion_store.jsx'; - -class SearchChannelSuggestion extends React.Component { - render() { - const {item, isSelection, onClick} = this.props; - - let className = 'search-autocomplete__item'; - if (isSelection) { - className += ' selected'; - } - - return ( -
- {item.name} -
- ); - } -} - -SearchChannelSuggestion.propTypes = { - item: React.PropTypes.object.isRequired, - isSelection: React.PropTypes.bool, - onClick: React.PropTypes.func -}; - -export default class SearchChannelProvider { - handlePretextChanged(suggestionId, pretext) { - const captured = (/\b(?:in|channel):\s*(\S*)$/i).exec(pretext); - if (captured) { - const channelPrefix = captured[1]; - - const channels = ChannelStore.getAll(); - const publicChannels = []; - const privateChannels = []; - - for (const id of Object.keys(channels)) { - const channel = channels[id]; - - // don't show direct channels - if (channel.type !== Constants.DM_CHANNEL && channel.name.startsWith(channelPrefix)) { - if (channel.type === Constants.OPEN_CHANNEL) { - publicChannels.push(channel); - } else { - privateChannels.push(channel); - } - } - } - - publicChannels.sort((a, b) => a.name.localeCompare(b.name)); - const publicChannelNames = publicChannels.map((channel) => channel.name); - - privateChannels.sort((a, b) => a.name.localeCompare(b.name)); - const privateChannelNames = privateChannels.map((channel) => channel.name); - - SuggestionStore.setMatchedPretext(suggestionId, channelPrefix); - - SuggestionStore.addSuggestions(suggestionId, publicChannelNames, publicChannels, SearchChannelSuggestion); - SuggestionStore.addSuggestions(suggestionId, privateChannelNames, privateChannels, SearchChannelSuggestion); - } - } -} diff --git a/web/react/components/suggestion/search_suggestion_list.jsx b/web/react/components/suggestion/search_suggestion_list.jsx deleted file mode 100644 index 60a5562fa..000000000 --- a/web/react/components/suggestion/search_suggestion_list.jsx +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import Constants from '../../utils/constants.jsx'; -import SuggestionList from './suggestion_list.jsx'; - -import {FormattedMessage} from 'mm-intl'; - -export default class SearchSuggestionList extends SuggestionList { - componentDidUpdate(prevProps, prevState) { - if (this.state.items.length > 0 && prevState.items.length === 0) { - this.getContent().perfectScrollbar(); - } - } - - getContent() { - return $(ReactDOM.findDOMNode(this.refs.popover)).find('.popover-content'); - } - - renderChannelDivider(type) { - let text; - if (type === Constants.OPEN_CHANNEL) { - text = ( - - ); - } else { - text = ( - - ); - } - - return ( -
- {text} -
- ); - } - - render() { - if (this.state.items.length === 0) { - return null; - } - - const items = []; - for (let i = 0; i < this.state.items.length; i++) { - const item = this.state.items[i]; - const term = this.state.terms[i]; - const isSelection = term === this.state.selection; - - // ReactComponent names need to be upper case when used in JSX - const Component = this.state.components[i]; - - // temporary hack to add dividers between public and private channels in the search suggestion list - if (i === 0 || item.type !== this.state.items[i - 1].type) { - if (item.type === Constants.OPEN_CHANNEL) { - items.push(this.renderChannelDivider(Constants.OPEN_CHANNEL)); - } else if (item.type === Constants.PRIVATE_CHANNEL) { - items.push(this.renderChannelDivider(Constants.PRIVATE_CHANNEL)); - } - } - - items.push( - - ); - } - - return ( - - {items} - - ); - } -} - -SearchSuggestionList.propTypes = { - ...SuggestionList.propTypes -}; diff --git a/web/react/components/suggestion/search_user_provider.jsx b/web/react/components/suggestion/search_user_provider.jsx deleted file mode 100644 index 0d553bfc4..000000000 --- a/web/react/components/suggestion/search_user_provider.jsx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import SuggestionStore from '../../stores/suggestion_store.jsx'; -import UserStore from '../../stores/user_store.jsx'; - -class SearchUserSuggestion extends React.Component { - render() { - const {item, isSelection, onClick} = this.props; - - let className = 'search-autocomplete__item'; - if (isSelection) { - className += ' selected'; - } - - return ( -
- {item.username} -
- ); - } -} - -SearchUserSuggestion.propTypes = { - item: React.PropTypes.object.isRequired, - isSelection: React.PropTypes.bool, - onClick: React.PropTypes.func -}; - -export default class SearchUserProvider { - handlePretextChanged(suggestionId, pretext) { - const captured = (/\bfrom:\s*(\S*)$/i).exec(pretext); - if (captured) { - const usernamePrefix = captured[1]; - - const users = UserStore.getProfiles(); - let filtered = []; - - for (const id of Object.keys(users)) { - const user = users[id]; - - if (user.username.startsWith(usernamePrefix)) { - filtered.push(user); - } - } - - filtered = filtered.sort((a, b) => a.username.localeCompare(b.username)); - - const usernames = filtered.map((user) => user.username); - - SuggestionStore.setMatchedPretext(suggestionId, usernamePrefix); - SuggestionStore.addSuggestions(suggestionId, usernames, filtered, SearchUserSuggestion); - } - } -} diff --git a/web/react/components/suggestion/suggestion_box.jsx b/web/react/components/suggestion/suggestion_box.jsx deleted file mode 100644 index 12b098cbd..000000000 --- a/web/react/components/suggestion/suggestion_box.jsx +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import Constants from '../../utils/constants.jsx'; -import * as GlobalActions from '../../action_creators/global_actions.jsx'; -import SuggestionStore from '../../stores/suggestion_store.jsx'; -import * as Utils from '../../utils/utils.jsx'; - -const KeyCodes = Constants.KeyCodes; - -export default class SuggestionBox extends React.Component { - constructor(props) { - super(props); - - this.handleDocumentClick = this.handleDocumentClick.bind(this); - - this.handleChange = this.handleChange.bind(this); - this.handleCompleteWord = this.handleCompleteWord.bind(this); - this.handleKeyDown = this.handleKeyDown.bind(this); - this.handlePretextChanged = this.handlePretextChanged.bind(this); - - this.suggestionId = Utils.generateId(); - } - - componentDidMount() { - SuggestionStore.registerSuggestionBox(this.suggestionId); - $(document).on('click', this.handleDocumentClick); - - SuggestionStore.addCompleteWordListener(this.suggestionId, this.handleCompleteWord); - SuggestionStore.addPretextChangedListener(this.suggestionId, this.handlePretextChanged); - } - - componentWillUnmount() { - SuggestionStore.removeCompleteWordListener(this.suggestionId, this.handleCompleteWord); - SuggestionStore.removePretextChangedListener(this.suggestionId, this.handlePretextChanged); - - SuggestionStore.unregisterSuggestionBox(this.suggestionId); - $(document).off('click', this.handleDocumentClick); - } - - getTextbox() { - // this is to support old code that looks at the input/textarea DOM nodes - return ReactDOM.findDOMNode(this.refs.textbox); - } - - handleDocumentClick(e) { - const container = $(ReactDOM.findDOMNode(this)); - if (!(container.is(e.target) || container.has(e.target).length > 0)) { - // we can't just use blur for this because it fires and hides the children before - // their click handlers can be called - GlobalActions.emitClearSuggestions(this.suggestionId); - } - } - - handleChange(e) { - const textbox = ReactDOM.findDOMNode(this.refs.textbox); - const caret = Utils.getCaretPosition(textbox); - const pretext = textbox.value.substring(0, caret); - - GlobalActions.emitSuggestionPretextChanged(this.suggestionId, pretext); - - if (this.props.onUserInput) { - this.props.onUserInput(textbox.value); - } - - if (this.props.onChange) { - this.props.onChange(e); - } - } - - handleCompleteWord(term) { - const textbox = ReactDOM.findDOMNode(this.refs.textbox); - const caret = Utils.getCaretPosition(textbox); - - const text = this.props.value; - const prefix = text.substring(0, caret - SuggestionStore.getMatchedPretext(this.suggestionId).length); - const suffix = text.substring(caret); - - if (this.props.onUserInput) { - this.props.onUserInput(prefix + term + ' ' + suffix); - } - - // set the caret position after the next rendering - window.requestAnimationFrame(() => { - Utils.setCaretPosition(textbox, prefix.length + term.length + 1); - }); - } - - handleKeyDown(e) { - if (SuggestionStore.hasSuggestions(this.suggestionId)) { - if (e.which === KeyCodes.UP) { - GlobalActions.emitSelectPreviousSuggestion(this.suggestionId); - e.preventDefault(); - } else if (e.which === KeyCodes.DOWN) { - GlobalActions.emitSelectNextSuggestion(this.suggestionId); - e.preventDefault(); - } else if (e.which === KeyCodes.ENTER || e.which === KeyCodes.TAB) { - GlobalActions.emitCompleteWordSuggestion(this.suggestionId); - e.preventDefault(); - } else if (this.props.onKeyDown) { - this.props.onKeyDown(e); - } - } else if (this.props.onKeyDown) { - this.props.onKeyDown(e); - } - } - - handlePretextChanged(pretext) { - for (const provider of this.props.providers) { - provider.handlePretextChanged(this.suggestionId, pretext); - } - } - - render() { - const newProps = Object.assign({}, this.props, { - onChange: this.handleChange, - onKeyDown: this.handleKeyDown - }); - - let textbox = null; - if (this.props.type === 'input') { - textbox = ( - - ); - } else if (this.props.type === 'textarea') { - textbox = ( -