From 33b957ed1a8a44d4bed0f9c674d5602bad5028ea Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Mon, 5 Oct 2015 09:58:42 -0400 Subject: Disabling complexity warning. Allowing non-nested ternary. Upgrading ESList. Adding new ESLint rules. Fixing new ESLint errors. --- web/react/.eslintrc | 19 +++-- web/react/components/access_history_modal.jsx | 24 ++++-- web/react/components/activity_log_modal.jsx | 24 ++++-- web/react/components/channel_header.jsx | 40 ++++----- web/react/components/channel_members.jsx | 16 ++-- web/react/components/channel_notifications.jsx | 35 ++++---- web/react/components/command_list.jsx | 2 +- web/react/components/create_comment.jsx | 12 +-- web/react/components/create_post.jsx | 12 +-- web/react/components/delete_channel_modal.jsx | 16 ++-- web/react/components/delete_post_modal.jsx | 24 +++--- web/react/components/edit_channel_modal.jsx | 10 ++- web/react/components/file_upload.jsx | 2 +- web/react/components/get_link_modal.jsx | 18 ++-- web/react/components/login.jsx | 6 +- web/react/components/mention.jsx | 6 +- web/react/components/mention_list.jsx | 91 +++++++++++--------- web/react/components/more_channels.jsx | 98 +++++++++++----------- web/react/components/more_direct_channels.jsx | 32 +++---- web/react/components/post_list.jsx | 14 ++-- web/react/components/rename_channel_modal.jsx | 20 +++-- web/react/components/sidebar.jsx | 32 +++---- web/react/components/sidebar_right.jsx | 6 +- web/react/components/signup_user_complete.jsx | 27 +++--- web/react/components/team_signup_email_item.jsx | 9 +- .../components/team_signup_send_invites_page.jsx | 6 +- web/react/components/team_signup_url_page.jsx | 30 ++++--- web/react/components/team_signup_welcome_page.jsx | 3 +- web/react/package.json | 4 +- web/react/stores/browser_store.jsx | 2 +- web/react/stores/team_store.jsx | 8 +- web/react/utils/client.jsx | 2 +- web/react/utils/utils.jsx | 8 +- 33 files changed, 350 insertions(+), 308 deletions(-) (limited to 'web/react') diff --git a/web/react/.eslintrc b/web/react/.eslintrc index c0d0bb200..c4167829d 100644 --- a/web/react/.eslintrc +++ b/web/react/.eslintrc @@ -42,12 +42,13 @@ "valid-typeof": 2, "block-scoped-var": 2, - "complexity": [1, 8], + "complexity": [0, 8], "consistent-return": 2, "curly": [2, "all"], "dot-location": [2, "object"], "dot-notation": 2, "eqeqeq": [2, "smart"], + "global-require": 2, "guard-for-in": 2, "no-alert": 2, "no-array-constructor": 2, @@ -109,30 +110,34 @@ "func-names": 2, "func-style": [2, "declaration"], "indent": [2, 4, {"SwitchCase": 0}], + "jsx-quotes": [2, "prefer-single"], "key-spacing": [2, {"beforeColon": false, "afterColon": true}], - "lines-around-comment": [2, { "beforeBlockComment": true, "beforeLineComment": true, "allowBlockStart": true, "allowBlockEnd": true }], "linebreak-style": 2, + "lines-around-comment": [2, { "beforeBlockComment": true, "beforeLineComment": true, "allowBlockStart": true, "allowBlockEnd": true }], "new-cap": 2, "new-parens": 2, "no-lonely-if": 2, "no-mixed-spaces-and-tabs": 2, "no-multiple-empty-lines": [2, {"max": 1}], + "no-negated-condition": 2, + "no-nested-ternary": 2, "no-spaced-func": 2, - "no-ternary": 2, + "no-ternary": 0, "no-trailing-spaces": [2, { "skipBlankLines": false }], "no-underscore-dangle": 2, - "no-unneeded-ternary": 2, + "no-unneeded-ternary": [2, {"defaultAssignment": false}], "object-curly-spacing": [2, "never"], "one-var": [2, "never"], "operator-linebreak": [2, "after"], "padded-blocks": [2, "never"], "quote-props": [2, "as-needed"], "quotes": [2, "single", "avoid-escape"], - "semi-spacing": [2, {"before": false, "after": true}], "semi": [2, "always"], + "semi-spacing": [2, {"before": false, "after": true}], "space-after-keywords": [2, "always"], "space-before-blocks": [2, "always"], "space-before-function-paren": [2, "never"], + "space-before-keywords": [2, "always"], "space-in-parens": [2, "never"], "space-infix-ops": 2, "space-return-throw-case": 2, @@ -167,7 +172,6 @@ "react/jsx-no-duplicate-props": [2, { "ignoreCase": false }], "react/jsx-no-literals": 1, "react/jsx-no-undef": 2, - "react/jsx-quotes": [2, "single", "avoid-escape"], "react/jsx-uses-react": 2, "react/jsx-uses-vars": 2, "react/no-danger": 0, @@ -179,6 +183,7 @@ "react/prop-types": 2, "react/self-closing-comp": 2, "react/sort-comp": 0, - "react/wrap-multilines": 2 + "react/wrap-multilines": 2, + "react/no-direct-mutation-state": 2 } } diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx index a080150dd..0dfd36717 100644 --- a/web/react/components/access_history_modal.jsx +++ b/web/react/components/access_history_modal.jsx @@ -12,25 +12,31 @@ export default class AccessHistoryModal extends React.Component { this.onAuditChange = this.onAuditChange.bind(this); this.handleMoreInfo = this.handleMoreInfo.bind(this); + this.onHide = this.onHide.bind(this); + this.onShow = this.onShow.bind(this); - this.state = this.getStateFromStoresForAudits(); - this.state.moreInfo = []; + let state = this.getStateFromStoresForAudits(); + state.moreInfo = []; + + this.state = state; } getStateFromStoresForAudits() { return { audits: UserStore.getAudits() }; } + onShow() { + AsyncClient.getAudits(); + } + onHide() { + $('#user_settings').modal('show'); + this.setState({moreInfo: []}); + } componentDidMount() { UserStore.addAuditsChangeListener(this.onAuditChange); - $(React.findDOMNode(this.refs.modal)).on('shown.bs.modal', function show() { - AsyncClient.getAudits(); - }); + $(React.findDOMNode(this.refs.modal)).on('shown.bs.modal', this.onShow); - $(React.findDOMNode(this.refs.modal)).on('hidden.bs.modal', function hide() { - $('#user_settings').modal('show'); - this.setState({moreInfo: []}); - }.bind(this)); + $(React.findDOMNode(this.refs.modal)).on('hidden.bs.modal', this.onHide); } componentWillUnmount() { UserStore.removeAuditsChangeListener(this.onAuditChange); diff --git a/web/react/components/activity_log_modal.jsx b/web/react/components/activity_log_modal.jsx index fe40385a0..aee2541b5 100644 --- a/web/react/components/activity_log_modal.jsx +++ b/web/react/components/activity_log_modal.jsx @@ -14,9 +14,13 @@ export default class ActivityLogModal extends React.Component { this.submitRevoke = this.submitRevoke.bind(this); this.onListenerChange = this.onListenerChange.bind(this); this.handleMoreInfo = this.handleMoreInfo.bind(this); + this.onHide = this.onHide.bind(this); + this.onShow = this.onShow.bind(this); - this.state = this.getStateFromStores(); - this.state.moreInfo = []; + let state = this.getStateFromStores(); + state.moreInfo = []; + + this.state = state; } getStateFromStores() { return { @@ -38,16 +42,18 @@ export default class ActivityLogModal extends React.Component { }.bind(this) ); } + onShow() { + AsyncClient.getSessions(); + } + onHide() { + $('#user_settings').modal('show'); + this.setState({moreInfo: []}); + } componentDidMount() { UserStore.addSessionsChangeListener(this.onListenerChange); - $(React.findDOMNode(this.refs.modal)).on('shown.bs.modal', function handleShow() { - AsyncClient.getSessions(); - }); + $(React.findDOMNode(this.refs.modal)).on('shown.bs.modal', this.onShow); - $(React.findDOMNode(this.refs.modal)).on('hidden.bs.modal', function handleHide() { - $('#user_settings').modal('show'); - this.setState({moreInfo: []}); - }.bind(this)); + $(React.findDOMNode(this.refs.modal)).on('hidden.bs.modal', this.onHide); } componentWillUnmount() { UserStore.removeSessionsChangeListener(this.onListenerChange); diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx index b81936b57..f15974d35 100644 --- a/web/react/components/channel_header.jsx +++ b/web/react/components/channel_header.jsx @@ -132,7 +132,26 @@ export default class ChannelHeader extends React.Component { } let dropdownContents = []; - if (!isDirect) { + if (isDirect) { + dropdownContents.push( +
  • + + Set Channel Description... + +
  • + ); + } else { dropdownContents.push(
  • ); } - } else { - dropdownContents.push( -
  • - - Set Channel Description... - -
  • - ); } return ( diff --git a/web/react/components/channel_members.jsx b/web/react/components/channel_members.jsx index 1eda6a104..53c854eb7 100644 --- a/web/react/components/channel_members.jsx +++ b/web/react/components/channel_members.jsx @@ -15,6 +15,8 @@ export default class ChannelMembers extends React.Component { this.getStateFromStores = this.getStateFromStores.bind(this); this.onChange = this.onChange.bind(this); this.handleRemove = this.handleRemove.bind(this); + this.onHide = this.onHide.bind(this); + this.onShow = this.onShow.bind(this); this.state = this.getStateFromStores(); } @@ -63,16 +65,18 @@ export default class ChannelMembers extends React.Component { channelName: channelName }; } + onHide() { + this.setState({renderMembers: false}); + } + onShow() { + this.setState({renderMembers: true}); + } componentDidMount() { ChannelStore.addExtraInfoChangeListener(this.onChange); ChannelStore.addChangeListener(this.onChange); - $(React.findDOMNode(this.refs.modal)).on('hidden.bs.modal', function handleHide() { - this.setState({renderMembers: false}); - }.bind(this)); + $(React.findDOMNode(this.refs.modal)).on('hidden.bs.modal', this.onHide); - $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', function handleShow() { - this.setState({renderMembers: true}); - }.bind(this)); + $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', this.onShow); } componentWillUnmount() { ChannelStore.removeExtraInfoChangeListener(this.onChange); diff --git a/web/react/components/channel_notifications.jsx b/web/react/components/channel_notifications.jsx index 45981b295..fed8e789e 100644 --- a/web/react/components/channel_notifications.jsx +++ b/web/react/components/channel_notifications.jsx @@ -23,6 +23,7 @@ export default class ChannelNotifications extends React.Component { this.handleSubmitMarkUnreadLevel = this.handleSubmitMarkUnreadLevel.bind(this); this.handleUpdateMarkUnreadLevel = this.handleUpdateMarkUnreadLevel.bind(this); this.createMarkUnreadLevelSection = this.createMarkUnreadLevelSection.bind(this); + this.onShow = this.onShow.bind(this); this.state = { notifyLevel: '', @@ -32,30 +33,29 @@ export default class ChannelNotifications extends React.Component { activeSection: '' }; } + onShow(e) { + var button = e.relatedTarget; + var channelId = button.getAttribute('data-channelid'); + const member = ChannelStore.getMember(channelId); + var notifyLevel = member.notify_props.desktop; + var markUnreadLevel = member.notify_props.mark_unread; + + this.setState({ + notifyLevel, + markUnreadLevel, + title: button.getAttribute('data-title'), + channelId + }); + } componentDidMount() { ChannelStore.addChangeListener(this.onListenerChange); - $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', function showModal(e) { - var button = e.relatedTarget; - var channelId = button.getAttribute('data-channelid'); - - const member = ChannelStore.getMember(channelId); - var notifyLevel = member.notify_props.desktop; - var markUnreadLevel = member.notify_props.mark_unread; - - this.setState({ - notifyLevel, - markUnreadLevel, - title: button.getAttribute('data-title'), - channelId: channelId - }); - }.bind(this)); + $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', this.onShow); } componentWillUnmount() { ChannelStore.removeChangeListener(this.onListenerChange); } - onListenerChange() { if (!this.state.channelId) { return; @@ -76,7 +76,6 @@ export default class ChannelNotifications extends React.Component { updateSection(section) { this.setState({activeSection: section}); } - handleSubmitNotifyLevel() { var channelId = this.state.channelId; var notifyLevel = this.state.notifyLevel; @@ -103,12 +102,10 @@ export default class ChannelNotifications extends React.Component { } ); } - handleUpdateNotifyLevel(notifyLevel) { this.setState({notifyLevel}); React.findDOMNode(this.refs.modal).focus(); } - createNotifyLevelSection(serverError) { var handleUpdateSection; diff --git a/web/react/components/command_list.jsx b/web/react/components/command_list.jsx index fea7085b7..e027e87ae 100644 --- a/web/react/components/command_list.jsx +++ b/web/react/components/command_list.jsx @@ -51,7 +51,7 @@ export default class CommandList extends React.Component { this.setState({suggestions: data.suggestions, cmd: cmd}); }.bind(this), function fail() { - } + } ); } diff --git a/web/react/components/create_comment.jsx b/web/react/components/create_comment.jsx index 5097b3aa5..9c233ea26 100644 --- a/web/react/components/create_comment.jsx +++ b/web/react/components/create_comment.jsx @@ -170,7 +170,9 @@ export default class CreateComment extends React.Component { this.setState({uploadsInProgress: draft.uploadsInProgress, previews: draft.previews}); } handleUploadError(err, clientId) { - if (clientId !== -1) { + if (clientId === -1) { + this.setState({serverError: err}); + } else { let draft = PostStore.getCommentDraft(this.props.rootId); const index = draft.uploadsInProgress.indexOf(clientId); @@ -181,8 +183,6 @@ export default class CreateComment extends React.Component { PostStore.storeCommentDraft(this.props.rootId, draft); this.setState({uploadsInProgress: draft.uploadsInProgress, serverError: err}); - } else { - this.setState({serverError: err}); } } handleTextDrop(text) { @@ -196,15 +196,15 @@ export default class CreateComment extends React.Component { // id can either be the path of an uploaded file or the client id of an in progress upload let index = previews.indexOf(id); - if (index !== -1) { - previews.splice(index, 1); - } else { + if (index === -1) { index = uploadsInProgress.indexOf(id); if (index !== -1) { uploadsInProgress.splice(index, 1); this.refs.fileUpload.cancelUpload(id); } + } else { + previews.splice(index, 1); } let draft = PostStore.getCommentDraft(this.props.rootId); diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx index 0cd14747d..6e83f4faf 100644 --- a/web/react/components/create_post.jsx +++ b/web/react/components/create_post.jsx @@ -222,7 +222,9 @@ export default class CreatePost extends React.Component { this.setState({uploadsInProgress: draft.uploadsInProgress, previews: draft.previews}); } handleUploadError(err, clientId) { - if (clientId !== -1) { + if (clientId === -1) { + this.setState({serverError: err}); + } else { const draft = PostStore.getDraft(this.state.channelId); const index = draft.uploadsInProgress.indexOf(clientId); @@ -233,8 +235,6 @@ export default class CreatePost extends React.Component { PostStore.storeDraft(this.state.channelId, draft); this.setState({uploadsInProgress: draft.uploadsInProgress, serverError: err}); - } else { - this.setState({serverError: err}); } } handleTextDrop(text) { @@ -248,15 +248,15 @@ export default class CreatePost extends React.Component { // id can either be the path of an uploaded file or the client id of an in progress upload let index = previews.indexOf(id); - if (index !== -1) { - previews.splice(index, 1); - } else { + if (index === -1) { index = uploadsInProgress.indexOf(id); if (index !== -1) { uploadsInProgress.splice(index, 1); this.refs.fileUpload.cancelUpload(id); } + } else { + previews.splice(index, 1); } const draft = PostStore.getCurrentDraft(); diff --git a/web/react/components/delete_channel_modal.jsx b/web/react/components/delete_channel_modal.jsx index 44c54db72..71c636921 100644 --- a/web/react/components/delete_channel_modal.jsx +++ b/web/react/components/delete_channel_modal.jsx @@ -11,6 +11,7 @@ export default class DeleteChannelModal extends React.Component { super(props); this.handleDelete = this.handleDelete.bind(this); + this.onShow = this.onShow.bind(this); this.state = { title: '', @@ -32,14 +33,15 @@ export default class DeleteChannelModal extends React.Component { } ); } + onShow(e) { + var button = $(e.relatedTarget); + this.setState({ + title: button.attr('data-title'), + channelId: button.attr('data-channelid') + }); + } componentDidMount() { - $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', function handleShow(e) { - var button = $(e.relatedTarget); - this.setState({ - title: button.attr('data-title'), - channelId: button.attr('data-channelid') - }); - }.bind(this)); + $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', this.onShow); } render() { const channel = ChannelStore.getCurrent(); diff --git a/web/react/components/delete_post_modal.jsx b/web/react/components/delete_post_modal.jsx index 075f9c742..8e48a7a1c 100644 --- a/web/react/components/delete_post_modal.jsx +++ b/web/react/components/delete_post_modal.jsx @@ -16,6 +16,7 @@ export default class DeletePostModal extends React.Component { this.handleDelete = this.handleDelete.bind(this); this.onListenerChange = this.onListenerChange.bind(this); + this.onShow = this.onShow.bind(this); this.state = {title: '', postId: '', channelId: '', selectedList: PostStore.getSelectedPost(), comments: 0}; } @@ -60,18 +61,19 @@ export default class DeletePostModal extends React.Component { } ); } + onShow(e) { + var newState = {}; + if (BrowserStore.getItem('edit_state_transfer')) { + newState = BrowserStore.getItem('edit_state_transfer'); + BrowserStore.removeItem('edit_state_transfer'); + } else { + var button = e.relatedTarget; + newState = {title: $(button).attr('data-title'), channelId: $(button).attr('data-channelid'), postId: $(button).attr('data-postid'), comments: $(button).attr('data-comments')}; + } + this.setState(newState); + } componentDidMount() { - $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', function freshOpen(e) { - var newState = {}; - if (BrowserStore.getItem('edit_state_transfer')) { - newState = BrowserStore.getItem('edit_state_transfer'); - BrowserStore.removeItem('edit_state_transfer'); - } else { - var button = e.relatedTarget; - newState = {title: $(button).attr('data-title'), channelId: $(button).attr('data-channelid'), postId: $(button).attr('data-postid'), comments: $(button).attr('data-comments')}; - } - this.setState(newState); - }.bind(this)); + $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', this.onShow); PostStore.addSelectedPostChangeListener(this.onListenerChange); } componentWillUnmount() { diff --git a/web/react/components/edit_channel_modal.jsx b/web/react/components/edit_channel_modal.jsx index e93bab431..27219aba5 100644 --- a/web/react/components/edit_channel_modal.jsx +++ b/web/react/components/edit_channel_modal.jsx @@ -11,6 +11,7 @@ export default class EditChannelModal extends React.Component { this.handleEdit = this.handleEdit.bind(this); this.handleUserInput = this.handleUserInput.bind(this); this.handleClose = this.handleClose.bind(this); + this.onShow = this.onShow.bind(this); this.state = { description: '', @@ -50,11 +51,12 @@ export default class EditChannelModal extends React.Component { handleClose() { this.setState({description: '', serverError: ''}); } + onShow(e) { + const button = e.relatedTarget; + this.setState({description: $(button).attr('data-desc'), title: $(button).attr('data-title'), channelId: $(button).attr('data-channelid'), serverError: ''}); + } componentDidMount() { - $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', function handleShow(e) { - const button = e.relatedTarget; - this.setState({description: $(button).attr('data-desc'), title: $(button).attr('data-title'), channelId: $(button).attr('data-channelid'), serverError: ''}); - }.bind(this)); + $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', this.onShow); $(React.findDOMNode(this.refs.modal)).on('hidden.bs.modal', this.handleClose); } componentWillUnmount() { diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index 3dc4e5de2..0e9297b7b 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -97,7 +97,7 @@ export default class FileUpload extends React.Component { element[0].type = 'text'; element[0].type = 'file'; } - } catch(e) { + } catch (e) { // Do nothing } } diff --git a/web/react/components/get_link_modal.jsx b/web/react/components/get_link_modal.jsx index 5d8b13f00..1d4aac3e6 100644 --- a/web/react/components/get_link_modal.jsx +++ b/web/react/components/get_link_modal.jsx @@ -8,18 +8,22 @@ export default class GetLinkModal extends React.Component { super(props); this.handleClick = this.handleClick.bind(this); + this.onShow = this.onShow.bind(this); + this.onHide = this.onHide.bind(this); this.state = {copiedLink: false}; } + onShow(e) { + var button = e.relatedTarget; + this.setState({title: $(button).attr('data-title'), value: $(button).attr('data-value')}); + } + onHide() { + this.setState({copiedLink: false}); + } componentDidMount() { if (this.refs.modal) { - $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', function show(e) { - var button = e.relatedTarget; - this.setState({title: $(button).attr('data-title'), value: $(button).attr('data-value')}); - }.bind(this)); - $(React.findDOMNode(this.refs.modal)).on('hide.bs.modal', function hide() { - this.setState({copiedLink: false}); - }.bind(this)); + $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', this.onShow); + $(React.findDOMNode(this.refs.modal)).on('hide.bs.modal', this.onShow); } } handleClick() { diff --git a/web/react/components/login.jsx b/web/react/components/login.jsx index 8cc4f1483..70f7a5d6e 100644 --- a/web/react/components/login.jsx +++ b/web/react/components/login.jsx @@ -88,10 +88,10 @@ export default class Login extends React.Component { let focusEmail = false; let focusPassword = false; - if (priorEmail !== '') { - focusPassword = true; - } else { + if (priorEmail === '') { focusEmail = true; + } else { + focusPassword = true; } let loginMessage = []; diff --git a/web/react/components/mention.jsx b/web/react/components/mention.jsx index 3a09e843d..ef7cec408 100644 --- a/web/react/components/mention.jsx +++ b/web/react/components/mention.jsx @@ -18,7 +18,9 @@ export default class Mention extends React.Component { var timestamp = UserStore.getCurrentUser().update_at; if (this.props.id === 'allmention' || this.props.id === 'channelmention') { icon = ; - } else if (this.props.id != null) { + } else if (this.props.id == null) { + icon = ; + } else { icon = ( ); - } else { - icon = ; } return (
    - - {channels.map(function cMap(channel, index) { - var joinButton; - if (self.state.joiningChannel === index) { - joinButton = ( - - ); - } else { - joinButton = ( - - ); - } + if (channels.loading) { + moreChannels = ; + } else if (channels.length) { + moreChannels = ( + + + {channels.map(function cMap(channel, index) { + var joinButton; + if (self.state.joiningChannel === index) { + joinButton = ( + + ); + } else { + joinButton = ( + + ); + } - return ( - - - - - ); - })} - -
    -

    {channel.display_name}

    -

    {channel.description}

    -
    - {joinButton} -
    - ); - } else { - moreChannels = ( -
    -

    No more channels to join

    -

    Click 'Create New Channel' to make a new one

    -
    - ); - } + return ( + + +

    {channel.display_name}

    +

    {channel.description}

    + + + {joinButton} + + + ); + })} + + + ); } else { - moreChannels = ; + moreChannels = ( +
    +

    No more channels to join

    +

    Click 'Create New Channel' to make a new one

    +
    + ); } } diff --git a/web/react/components/more_direct_channels.jsx b/web/react/components/more_direct_channels.jsx index 54d77c358..c71abd43a 100644 --- a/web/react/components/more_direct_channels.jsx +++ b/web/react/components/more_direct_channels.jsx @@ -31,22 +31,7 @@ export default class MoreDirectChannels extends React.Component { var active = ''; var handleClick = null; - if (!channel.fake) { - if (channel.id === ChannelStore.getCurrentId()) { - active = 'active'; - } - - if (channel.unread) { - badge = {channel.unread}; - titleClass = 'unread-title'; - } - - handleClick = function clickHandler(e) { - e.preventDefault(); - utils.switchChannel(channel); - $(React.findDOMNode(self.refs.modal)).modal('hide'); - }; - } else { + if (channel.fake) { // It's a direct message channel that doesn't exist yet so let's create it now var otherUserId = utils.getUserIdFromChannelName(channel); @@ -78,6 +63,21 @@ export default class MoreDirectChannels extends React.Component { ); }; } + } else { + if (channel.id === ChannelStore.getCurrentId()) { + active = 'active'; + } + + if (channel.unread) { + badge = {channel.unread}; + titleClass = 'unread-title'; + } + + handleClick = function clickHandler(e) { + e.preventDefault(); + utils.switchChannel(channel); + $(React.findDOMNode(self.refs.modal)).modal('hide'); + }; } return ( diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index a31967257..a534e5789 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -37,9 +37,11 @@ export default class PostList extends React.Component { this.deactivate = this.deactivate.bind(this); this.resize = this.resize.bind(this); - this.state = this.getStateFromStores(props.channelId); - this.state.numToDisplay = Constants.POST_CHUNK_SIZE; - this.state.isFirstLoadComplete = false; + const state = this.getStateFromStores(props.channelId); + state.numToDisplay = Constants.POST_CHUNK_SIZE; + state.isFirstLoadComplete = false; + + this.state = state; } getStateFromStores(id) { var postList = PostStore.getPosts(id); @@ -449,10 +451,10 @@ export default class PostList extends React.Component { } var createMessage; - if (creatorName !== '') { - createMessage = (This is the start of the {uiName} {uiType}, created by {creatorName} on {utils.displayDate(channel.create_at)}); - } else { + if (creatorName === '') { createMessage = 'This is the start of the ' + uiName + ' ' + uiType + ', created on ' + utils.displayDate(channel.create_at) + '.'; + } else { + createMessage = (This is the start of the {uiName} {uiType}, created by {creatorName} on {utils.displayDate(channel.create_at)}); } return ( diff --git a/web/react/components/rename_channel_modal.jsx b/web/react/components/rename_channel_modal.jsx index 9d514c741..d60206ecf 100644 --- a/web/react/components/rename_channel_modal.jsx +++ b/web/react/components/rename_channel_modal.jsx @@ -15,6 +15,7 @@ export default class RenameChannelModal extends React.Component { this.onDisplayNameChange = this.onDisplayNameChange.bind(this); this.displayNameKeyUp = this.displayNameKeyUp.bind(this); this.handleClose = this.handleClose.bind(this); + this.handleShow = this.handleShow.bind(this); this.handleSubmit = this.handleSubmit.bind(this); this.state = { @@ -59,11 +60,11 @@ export default class RenameChannelModal extends React.Component { state.invalid = true; } else { let cleanedName = Utils.cleanUpUrlable(channel.name); - if (cleanedName !== channel.name) { + if (cleanedName === channel.name) { + state.nameError = ''; + } else { state.nameError = 'Must be lowercase alphanumeric characters'; state.invalid = true; - } else { - state.nameError = ''; } } @@ -103,7 +104,7 @@ export default class RenameChannelModal extends React.Component { this.setState({channelName: channelName}); } handleClose() { - this.state = { + this.setState({ displayName: '', channelName: '', channelId: '', @@ -111,13 +112,14 @@ export default class RenameChannelModal extends React.Component { nameError: '', displayNameError: '', invalid: false - }; + }); + } + handleShow(e) { + const button = $(e.relatedTarget); + this.setState({displayName: button.attr('data-display'), channelName: button.attr('data-name'), channelId: button.attr('data-channelid')}); } componentDidMount() { - $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', function handleShow(e) { - const button = $(e.relatedTarget); - this.setState({displayName: button.attr('data-display'), channelName: button.attr('data-name'), channelId: button.attr('data-channelid')}); - }.bind(this)); + $(React.findDOMNode(this.refs.modal)).on('show.bs.modal', this.handleShow); $(React.findDOMNode(this.refs.modal)).on('hidden.bs.modal', this.handleClose); } componentWillUnmount() { diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx index c0841a508..b696f4b53 100644 --- a/web/react/components/sidebar.jsx +++ b/web/react/components/sidebar.jsx @@ -29,9 +29,11 @@ export default class Sidebar extends React.Component { this.updateUnreadIndicators = this.updateUnreadIndicators.bind(this); this.createChannelElement = this.createChannelElement.bind(this); - this.state = this.getStateFromStores(); - this.state.modal = ''; - this.state.loadingDMChannel = -1; + const state = this.getStateFromStores(); + state.modal = ''; + state.loadingDMChannel = -1; + + this.state = state; } getStateFromStores() { var members = ChannelStore.getAllMembers(); @@ -65,7 +67,18 @@ export default class Sidebar extends React.Component { var channel = ChannelStore.getByName(channelName); - if (channel != null) { + if (channel == null) { + var tempChannel = {}; + tempChannel.fake = true; + tempChannel.name = channelName; + tempChannel.display_name = teammate.username; + tempChannel.teammate_username = teammate.username; + tempChannel.status = UserStore.getStatus(teammate.id); + tempChannel.last_post_at = 0; + tempChannel.total_msg_count = 0; + tempChannel.type = 'D'; + readDirectChannels.push(tempChannel); + } else { channel.display_name = teammate.username; channel.teammate_username = teammate.username; @@ -80,17 +93,6 @@ export default class Sidebar extends React.Component { } else { readDirectChannels.push(channel); } - } else { - var tempChannel = {}; - tempChannel.fake = true; - tempChannel.name = channelName; - tempChannel.display_name = teammate.username; - tempChannel.teammate_username = teammate.username; - tempChannel.status = UserStore.getStatus(teammate.id); - tempChannel.last_post_at = 0; - tempChannel.total_msg_count = 0; - tempChannel.type = 'D'; - readDirectChannels.push(tempChannel); } } diff --git a/web/react/components/sidebar_right.jsx b/web/react/components/sidebar_right.jsx index 708cd04cb..573515a46 100644 --- a/web/react/components/sidebar_right.jsx +++ b/web/react/components/sidebar_right.jsx @@ -30,11 +30,11 @@ export default class SidebarRight extends React.Component { PostStore.removeSelectedPostChangeListener(this.onSelectedChange); } componentDidUpdate() { - if (!this.plScrolledToBottom) { - $('.top-visible-post')[0].scrollIntoView(); - } else { + if (this.plScrolledToBottom) { var postHolder = $('.post-list-holder-by-time').not('.inactive'); postHolder.scrollTop(postHolder[0].scrollHeight); + } else { + $('.top-visible-post')[0].scrollIntoView(); } } onSelectedChange(fromSearch) { diff --git a/web/react/components/signup_user_complete.jsx b/web/react/components/signup_user_complete.jsx index 495159efc..ae3075495 100644 --- a/web/react/components/signup_user_complete.jsx +++ b/web/react/components/signup_user_complete.jsx @@ -41,15 +41,13 @@ export default class SignupUserComplete extends React.Component { return; } - this.state.user.email = providedEmail; - - this.state.user.username = React.findDOMNode(this.refs.name).value.trim().toLowerCase(); - if (!this.state.user.username) { + const providedUsername = React.findDOMNode(this.refs.name).value.trim().toLowerCase(); + if (!providedUsername) { this.setState({nameError: 'This field is required', emailError: '', passwordError: '', serverError: ''}); return; } - var usernameError = Utils.isValidUsername(this.state.user.username); + const usernameError = Utils.isValidUsername(this.state.user.username); if (usernameError === 'Cannot use a reserved word as a username.') { this.setState({nameError: 'This username is reserved, please choose a new one.', emailError: '', passwordError: '', serverError: ''}); return; @@ -63,15 +61,24 @@ export default class SignupUserComplete extends React.Component { return; } - this.state.user.password = React.findDOMNode(this.refs.password).value.trim(); - if (!this.state.user.password || this.state.user.password .length < 5) { + const providedPassword = React.findDOMNode(this.refs.password).value.trim(); + if (!providedPassword || providedPassword.length < 5) { this.setState({nameError: '', emailError: '', passwordError: 'Please enter at least 5 characters', serverError: ''}); return; } - this.setState({nameError: '', emailError: '', passwordError: '', serverError: ''}); - - this.state.user.allow_marketing = true; + this.setState({ + user: { + email: providedEmail, + username: providedUsername, + password: providedPassword, + allow_marketing: true + }, + nameError: '', + emailError: '', + passwordError: '', + serverError: '' + }); client.createUser(this.state.user, this.state.data, this.state.hash, function createUserSuccess() { diff --git a/web/react/components/team_signup_email_item.jsx b/web/react/components/team_signup_email_item.jsx index 10bb2d69e..01330a46c 100644 --- a/web/react/components/team_signup_email_item.jsx +++ b/web/react/components/team_signup_email_item.jsx @@ -23,17 +23,14 @@ export default class TeamSignupEmailItem extends React.Component { } if (!Utils.isEmail(email)) { - this.state.emailError = 'Please enter a valid email address'; - this.setState(this.state); + this.setState({emailError: 'Please enter a valid email address'}); return false; } else if (email === teamEmail) { - this.state.emailError = 'Please use a different email than the one used at signup'; - this.setState(this.state); + this.setState({emailError: 'Please use a different email than the one used at signup'}); return false; } - this.state.emailError = ''; - this.setState(this.state); + this.setState({emailError: ''}); return true; } render() { diff --git a/web/react/components/team_signup_send_invites_page.jsx b/web/react/components/team_signup_send_invites_page.jsx index 524bd5b50..8d8fb92ff 100644 --- a/web/react/components/team_signup_send_invites_page.jsx +++ b/web/react/components/team_signup_send_invites_page.jsx @@ -36,10 +36,10 @@ export default class TeamSignupSendInvitesPage extends React.Component { var emails = []; for (var i = 0; i < this.props.state.invites.length; i++) { - if (!this.refs['email_' + i].validate(this.props.state.team.email)) { - valid = false; - } else { + if (this.refs['email_' + i].validate(this.props.state.team.email)) { emails.push(this.refs['email_' + i].getValue()); + } else { + valid = false; } } diff --git a/web/react/components/team_signup_url_page.jsx b/web/react/components/team_signup_url_page.jsx index a3f89a217..a682bb49e 100644 --- a/web/react/components/team_signup_url_page.jsx +++ b/web/react/components/team_signup_url_page.jsx @@ -48,22 +48,20 @@ export default class TeamSignupUrlPage extends React.Component { } Client.findTeamByName(name, - function success(data) { - if (!data) { - this.props.state.wizard = 'send_invites'; - this.props.state.team.type = 'O'; - - this.props.state.team.name = name; - this.props.updateParent(this.props.state); - } else { - this.state.nameError = 'This URL is unavailable. Please try another.'; - this.setState(this.state); - } - }.bind(this), - function error(err) { - this.state.nameError = err.message; - this.setState(this.state); - }.bind(this) + (data) => { + if (data) { + this.setState({nameError: 'This URL is unavailable. Please try another.'}); + } else { + this.props.state.wizard = 'send_invites'; + this.props.state.team.type = 'O'; + + this.props.state.team.name = name; + this.props.updateParent(this.props.state); + } + }, + (err) => { + this.setState({nameError: err.message}); + } ); } handleFocus(e) { diff --git a/web/react/components/team_signup_welcome_page.jsx b/web/react/components/team_signup_welcome_page.jsx index 626c6a17b..019456c9f 100644 --- a/web/react/components/team_signup_welcome_page.jsx +++ b/web/react/components/team_signup_welcome_page.jsx @@ -59,8 +59,7 @@ export default class TeamSignupWelcomePage extends React.Component { } }.bind(this), function error(err) { - this.state.serverError = err.message; - this.setState(this.state); + this.setState({serverError: err.message}); }.bind(this) ); } diff --git a/web/react/package.json b/web/react/package.json index a9eba6c6c..31295873b 100644 --- a/web/react/package.json +++ b/web/react/package.json @@ -19,8 +19,8 @@ "babelify": "6.1.3", "uglify-js": "2.4.24", "watchify": "3.3.1", - "eslint": "1.3.1", - "eslint-plugin-react": "3.3.1" + "eslint": "1.6.0", + "eslint-plugin-react": "3.5.1" }, "scripts": { "start": "watchify --extension=jsx -o ../static/js/bundle.js -v -d ./**/*.jsx", diff --git a/web/react/stores/browser_store.jsx b/web/react/stores/browser_store.jsx index d2dedb271..e45d3d981 100644 --- a/web/react/stores/browser_store.jsx +++ b/web/react/stores/browser_store.jsx @@ -4,7 +4,7 @@ var UserStore; function getPrefix() { if (!UserStore) { - UserStore = require('./user_store.jsx'); + UserStore = require('./user_store.jsx'); //eslint-disable-line global-require } return UserStore.getCurrentId() + '_'; } diff --git a/web/react/stores/team_store.jsx b/web/react/stores/team_store.jsx index 1f33fe03b..fd9117747 100644 --- a/web/react/stores/team_store.jsx +++ b/web/react/stores/team_store.jsx @@ -10,12 +10,12 @@ var BrowserStore = require('../stores/browser_store.jsx'); var CHANGE_EVENT = 'change'; -var utils; +var Utils; function getWindowLocationOrigin() { - if (!utils) { - utils = require('../utils/utils.jsx'); + if (!Utils) { + Utils = require('../utils/utils.jsx'); //eslint-disable-line global-require } - return utils.getWindowLocationOrigin(); + return Utils.getWindowLocationOrigin(); } class TeamStoreClass extends EventEmitter { diff --git a/web/react/utils/client.jsx b/web/react/utils/client.jsx index 5cb165b4c..d9f486009 100644 --- a/web/react/utils/client.jsx +++ b/web/react/utils/client.jsx @@ -15,7 +15,7 @@ function handleError(methodName, xhr, status, err) { var e = null; try { e = JSON.parse(xhr.responseText); - } catch(parseError) { + } catch (parseError) { e = null; } diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 1bc082175..e2a95034f 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -231,10 +231,10 @@ function testUrlMatch(text) { var matchText = match.getMatchedText(); linkData.text = matchText; - if (matchText.trim().indexOf('http') !== 0) { - linkData.link = 'http://' + matchText; - } else { + if (matchText.trim().indexOf('http') === 0) { linkData.link = matchText; + } else { + linkData.link = 'http://' + matchText; } result.push(linkData); @@ -640,7 +640,7 @@ export function isValidUsername(name) { error = 'Must be between 3 and 15 characters'; } else if (!(/^[a-z0-9\.\-\_]+$/).test(name)) { error = "Must contain only letters, numbers, and the symbols '.', '-', and '_'."; - } else if (!(/[a-z]/).test(name.charAt(0))) { + } else if (!(/[a-z]/).test(name.charAt(0))) { //eslint-disable-line no-negated-condition error = 'First character must be a letter.'; } else { for (var i = 0; i < Constants.RESERVED_USERNAMES.length; i++) { -- cgit v1.2.3-1-g7c22