diff options
author | =Corey Hulen <corey@hulen.com> | 2015-09-03 13:39:22 -0700 |
---|---|---|
committer | =Corey Hulen <corey@hulen.com> | 2015-09-03 13:39:22 -0700 |
commit | 05d95d80a896d14474c7f7384d67b9edd524b922 (patch) | |
tree | 2fcc619c38175014813ffc7df34abad82e5d5b77 /web | |
parent | 48ca3a4007c8b9c40a3bc3789563ed9992e9b64d (diff) | |
parent | 4f0c06114b61c92d982baac1c54ed80da93a9cc9 (diff) | |
download | chat-05d95d80a896d14474c7f7384d67b9edd524b922.tar.gz chat-05d95d80a896d14474c7f7384d67b9edd524b922.tar.bz2 chat-05d95d80a896d14474c7f7384d67b9edd524b922.zip |
Merge branch 'master' into PLT-12
Diffstat (limited to 'web')
45 files changed, 434 insertions, 257 deletions
diff --git a/web/react/.eslintrc b/web/react/.eslintrc index ab000e941..53cc75913 100644 --- a/web/react/.eslintrc +++ b/web/react/.eslintrc @@ -4,7 +4,9 @@ "jsx": true, "blockBindings": true, "modules": true, - "classes": true + "classes": true, + "arrowFunctions": true, + "defaultParams": true, }, "plugins": [ "react" @@ -21,36 +23,36 @@ "rules": { "comma-dangle": [2, "never"], "no-cond-assign": [2, "except-parens"], - "no-console": 1, - "no-constant-condition": 1, - "no-debugger": 1, + "no-console": 2, + "no-constant-condition": 2, + "no-debugger": 2, "no-dupe-args": 2, "no-dupe-keys": 2, "no-duplicate-case": 2, - "no-empty": 1, - "no-ex-assign": 1, + "no-empty": 2, + "no-ex-assign": 2, "no-extra-semi": 2, - "no-func-assign": 1, + "no-func-assign": 2, "no-inner-declarations": 0, "no-invalid-regexp": 2, "no-irregular-whitespace": 2, + "no-unexpected-multiline": 2, "no-unreachable": 2, "valid-typeof": 2, - "no-unexpected-multiline": 2, - "block-scoped-var": 1, - "complexity": [0, 8], + "block-scoped-var": 2, + "complexity": [1, 8], "consistent-return": 2, "curly": [2, "all"], - "dot-notation": 2, "dot-location": [2, "object"], + "dot-notation": 2, "eqeqeq": [2, "smart"], - "guard-for-in": 1, - "no-alert": 1, + "guard-for-in": 2, + "no-alert": 2, "no-array-constructor": 2, "no-caller": 2, - "no-div-regex": 1, - "no-else-return": 1, + "no-div-regex": 2, + "no-else-return": 2, "no-eval": 2, "no-extend-native": 2, "no-extra-bind": 2, @@ -58,7 +60,7 @@ "no-implied-eval": 2, "no-iterator": 2, "no-labels": 2, - "no-lone-blocks": 1, + "no-lone-blocks": 2, "no-loop-func": 2, "no-multi-spaces": [2, { "exceptions": { "Property": false } }], "no-multi-str": 0, @@ -78,10 +80,11 @@ "no-self-compare": 2, "no-sequences": 2, "no-throw-literal": 2, - "no-unused-expressions": 2, "no-undef-init": 2, + "no-unused-expressions": 2, + "no-useless-concat": 1, "no-void": 2, - "no-warning-comments": 0, + "no-warning-comments": 1, "no-with": 2, "radix": 2, "vars-on-top": 0, @@ -135,14 +138,33 @@ "space-unary-ops": [2, { "words": true, "nonwords": false }], "wrap-regex": 2, + // ES6 stuff + "arrow-parens": [2, "always"], + "arrow-spacing": [2, { "before": true, "after": true }], + "constructor-super": 2, + "generator-star-spacing": [2, {"before": false, "after": true}], + "no-class-assign": 2, + "no-const-assign": 2, + "no-dupe-class-members": 2, + "no-this-before-super": 2, + "no-var": 0, + "object-shorthand": [1, "always"], + "prefer-arrow-callback": 1, + "prefer-const": 1, + "prefer-spread": 2, + "prefer-reflect": 1, + "prefer-template": 0, + "require-yield": 2, + // React Specific "react/display-name": [2, { "acceptTranspilerName": true }], "react/jsx-boolean-value": [2, "always"], + "react/jsx-closing-bracket-location": [2, { "location": "tag-aligned" }], "react/jsx-curly-spacing": [2, "never"], + "react/jsx-indent-props": [2, 4], "react/jsx-max-props-per-line": [2, { "maximum": 1 }], - // SOON "react/jsx-indent-props": [2, 4], "react/jsx-no-duplicate-props": [2, { "ignoreCase": false }], - "react/jsx-no-literals": 0, + "react/jsx-no-literals": 1, "react/jsx-no-undef": 2, "react/jsx-quotes": [2, "single", "avoid-escape"], "react/jsx-uses-react": 2, @@ -151,10 +173,11 @@ "react/no-did-mount-set-state": 2, "react/no-did-update-set-state": 2, "react/no-multi-comp": 2, + "react/no-set-state": 0, "react/no-unknown-property": 2, "react/prop-types": 2, - "react/sort-comp": 0, "react/self-closing-comp": 2, + "react/sort-comp": 0, "react/wrap-multilines": 2 } } diff --git a/web/react/components/channel_info_modal.jsx b/web/react/components/channel_info_modal.jsx index fae86b4b9..fdd9a5c17 100644 --- a/web/react/components/channel_info_modal.jsx +++ b/web/react/components/channel_info_modal.jsx @@ -34,27 +34,27 @@ export default class CommandList extends React.Component { return ( <div - className='modal fade' - ref='modal' - id='channel_info' - tabIndex='-1' - role='dialog' - aria-hidden='true' + className='modal fade' + ref='modal' + id='channel_info' + tabIndex='-1' + role='dialog' + aria-hidden='true' > <div className='modal-dialog'> <div className='modal-content'> <div className='modal-header'> <button - type='button' - className='close' - data-dismiss='modal' - aria-label='Close' + type='button' + className='close' + data-dismiss='modal' + aria-label='Close' > <span aria-hidden='true'>×</span> </button> <h4 - className='modal-title' - id='myModalLabel' + className='modal-title' + id='myModalLabel' > <span className='name'>{channel.display_name}</span> </h4> @@ -75,9 +75,9 @@ export default class CommandList extends React.Component { </div> <div className='modal-footer'> <button - type='button' - className='btn btn-default' - data-dismiss='modal' + type='button' + className='btn btn-default' + data-dismiss='modal' >Close</button> </div> </div> diff --git a/web/react/components/channel_invite_modal.jsx b/web/react/components/channel_invite_modal.jsx index f76ede604..5feeb4e88 100644 --- a/web/react/components/channel_invite_modal.jsx +++ b/web/react/components/channel_invite_modal.jsx @@ -146,8 +146,8 @@ export default class ChannelInviteModal extends React.Component { aria-hidden='true' > <div - className='modal-dialog' - role='document' + className='modal-dialog' + role='document' > <div className='modal-content'> <div className='modal-header'> diff --git a/web/react/components/channel_notifications.jsx b/web/react/components/channel_notifications.jsx index 173646597..83067240d 100644 --- a/web/react/components/channel_notifications.jsx +++ b/web/react/components/channel_notifications.jsx @@ -162,6 +162,13 @@ export default class ChannelNotifications extends React.Component { e.preventDefault(); }.bind(this); + let curChannel = ChannelStore.get(this.state.channelId); + let extraInfo = (<span>These settings will override the global notification settings</span>); + + if (curChannel && curChannel.display_name) { + extraInfo = (<span>These settings will override the global notification settings for the <b>{curChannel.display_name}</b> channel</span>); + } + return ( <SettingItemMax title='Send desktop notifications' @@ -169,6 +176,7 @@ export default class ChannelNotifications extends React.Component { submit={this.handleUpdate} server_error={serverError} updateSection={handleUpdateSection} + extraInfo={extraInfo} /> ); } diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx index ce4ebac9e..871b72a43 100644 --- a/web/react/components/create_post.jsx +++ b/web/react/components/create_post.jsx @@ -117,7 +117,6 @@ export default class CreatePost extends React.Component { Client.createPost(post, channel, function handlePostSuccess(data) { - this.resizePostHolder(); AsyncClient.getPosts(); let member = ChannelStore.getMember(channel.id); @@ -129,7 +128,7 @@ export default class CreatePost extends React.Component { type: ActionTypes.RECIEVED_POST, post: data }); - }.bind(this), + }, function handlePostError(err) { let state = {}; @@ -149,9 +148,6 @@ export default class CreatePost extends React.Component { ); } } - componentDidUpdate() { - this.resizePostHolder(); - } postMsgKeyPress(e) { if (e.which === 13 && !e.shiftKey && !e.altKey) { e.preventDefault(); @@ -166,7 +162,6 @@ export default class CreatePost extends React.Component { } } handleUserInput(messageText) { - this.resizePostHolder(); this.setState({messageText: messageText}); let draft = PostStore.getCurrentDraft(); @@ -296,7 +291,8 @@ export default class CreatePost extends React.Component { <FilePreview files={this.state.previews} onRemove={this.removePreview} - uploadsInProgress={this.state.uploadsInProgress} /> + uploadsInProgress={this.state.uploadsInProgress} + /> ); } @@ -317,11 +313,13 @@ export default class CreatePost extends React.Component { <Textbox onUserInput={this.handleUserInput} onKeyPress={this.postMsgKeyPress} + onHeightChange={this.resizePostHolder} messageText={this.state.messageText} createMessage='Write a message...' channelId={this.state.channelId} id='post_textbox' - ref='textbox' /> + ref='textbox' + /> <FileUpload ref='fileUpload' getFileCount={this.getFileCount} @@ -329,7 +327,8 @@ export default class CreatePost extends React.Component { onFileUpload={this.handleFileUploadComplete} onUploadError={this.handleUploadError} postType='post' - channelId='' /> + channelId='' + /> </div> <div className={postFooterClassName}> {postError} diff --git a/web/react/components/edit_post_modal.jsx b/web/react/components/edit_post_modal.jsx index fef60c715..ad7bd30b5 100644 --- a/web/react/components/edit_post_modal.jsx +++ b/web/react/components/edit_post_modal.jsx @@ -88,7 +88,8 @@ export default class EditPostModal extends React.Component { id='edit_post' role='dialog' tabIndex='-1' - aria-hidden='true' > + aria-hidden='true' + > <div className='modal-dialog modal-push-down'> <div className='modal-content'> <div className='modal-header'> @@ -97,7 +98,8 @@ export default class EditPostModal extends React.Component { className='close' data-dismiss='modal' aria-label='Close' - onClick={this.handleEditClose}> + onClick={this.handleEditClose} + > <span aria-hidden='true'>×</span> </button> <h4 className='modal-title'>Edit {this.state.title}</h4> @@ -110,20 +112,22 @@ export default class EditPostModal extends React.Component { createMessage='Edit the post...' id='edit_textbox' ref='editbox' - /> + /> {error} </div> <div className='modal-footer'> <button type='button' className='btn btn-default' - data-dismiss='modal' > + data-dismiss='modal' + > Cancel </button> <button type='button' className='btn btn-primary' - onClick={this.handleEdit}> + onClick={this.handleEdit} + > Save </button> </div> diff --git a/web/react/components/email_verify.jsx b/web/react/components/email_verify.jsx index 396e201f8..95948c8dd 100644 --- a/web/react/components/email_verify.jsx +++ b/web/react/components/email_verify.jsx @@ -24,12 +24,14 @@ export default class EmailVerify extends React.Component { } else { title = config.SiteName + ' Email Not Verified'; body = <p>Please verify your email address. Check your inbox for an email.</p>; - resend = (<button - onClick={this.handleResend} - className='btn btn-primary' - > - Resend Email - </button>); + resend = ( + <button + onClick={this.handleResend} + className='btn btn-primary' + > + Resend Email + </button> + ); } return ( diff --git a/web/react/components/error_bar.jsx b/web/react/components/error_bar.jsx index 95f3e572c..87d94a41d 100644 --- a/web/react/components/error_bar.jsx +++ b/web/react/components/error_bar.jsx @@ -69,7 +69,8 @@ export default class ErrorBar extends React.Component { <a href='#' className='error-bar__close' - onClick={this.handleClose}> + onClick={this.handleClose} + > × </a> </div> diff --git a/web/react/components/file_attachment.jsx b/web/react/components/file_attachment.jsx index 5d7855037..78693df98 100644 --- a/web/react/components/file_attachment.jsx +++ b/web/react/components/file_attachment.jsx @@ -101,10 +101,13 @@ export default class FileAttachment extends React.Component { var thumbnail; if (type === 'image') { - thumbnail = (<div - ref={filename} - className='post__load' - style={{backgroundImage: 'url(/static/images/load.gif)'}} />); + thumbnail = ( + <div + ref={filename} + className='post__load' + style={{backgroundImage: 'url(/static/images/load.gif)'}} + /> + ); } else { thumbnail = <div className={'file-icon ' + utils.getIconClassName(type)}/>; } @@ -135,20 +138,23 @@ export default class FileAttachment extends React.Component { return ( <div className='post-image__column' - key={filename}> + key={filename} + > <a className='post-image__thumbnail' href='#' onClick={this.props.handleImageClick} data-img-id={this.props.index} data-toggle='modal' - data-target={'#' + this.props.modalId} > + data-target={'#' + this.props.modalId} + > {thumbnail} </a> <div className='post-image__details'> <div data-toggle='tooltip' title={filenameString} - className='post-image__name' > + className='post-image__name' + > {trimmedFilename} </div> <div> diff --git a/web/react/components/file_attachment_list.jsx b/web/react/components/file_attachment_list.jsx index d93f461e8..abe72089a 100644 --- a/web/react/components/file_attachment_list.jsx +++ b/web/react/components/file_attachment_list.jsx @@ -28,7 +28,8 @@ export default class FileAttachmentList extends React.Component { filename={filenames[i]} index={i} modalId={modalId} - handleImageClick={this.handleImageClick} /> + handleImageClick={this.handleImageClick} + /> ); } @@ -42,7 +43,8 @@ export default class FileAttachmentList extends React.Component { userId={this.props.userId} modalId={modalId} startId={this.state.startImgId} - filenames={filenames} /> + filenames={filenames} + /> </div> ); } diff --git a/web/react/components/find_team.jsx b/web/react/components/find_team.jsx index 4040a771d..52988886c 100644 --- a/web/react/components/find_team.jsx +++ b/web/react/components/find_team.jsx @@ -77,7 +77,10 @@ export default class FindTeam extends React.Component { </div> <button className='btn btn-md btn-primary' - type='submit'>Send</button> + type='submit' + > + Send + </button> </form> </div> ); diff --git a/web/react/components/member_list.jsx b/web/react/components/member_list.jsx index f8b07e05b..65495b569 100644 --- a/web/react/components/member_list.jsx +++ b/web/react/components/member_list.jsx @@ -23,14 +23,16 @@ export default class MemberList extends React.Component { return ( <div className='member-list-holder'> {members.map(function mymembers(member) { - return (<MemberListItem - key={member.id} - member={member} - isAdmin={this.props.isAdmin} - handleInvite={this.props.handleInvite} - handleRemove={this.props.handleRemove} - handleMakeAdmin={this.props.handleMakeAdmin} - />); + return ( + <MemberListItem + key={member.id} + member={member} + isAdmin={this.props.isAdmin} + handleInvite={this.props.handleInvite} + handleRemove={this.props.handleRemove} + handleMakeAdmin={this.props.handleMakeAdmin} + /> + ); }, this)} {message} </div> diff --git a/web/react/components/member_list_item.jsx b/web/react/components/member_list_item.jsx index bfce0f49f..9a31a2e30 100644 --- a/web/react/components/member_list_item.jsx +++ b/web/react/components/member_list_item.jsx @@ -36,8 +36,10 @@ export default class MemberListItem extends React.Component { invite = ( <a onClick={this.handleInvite} - className='btn btn-sm btn-primary member-invite'> - <i className='glyphicon glyphicon-envelope'/> Add + className='btn btn-sm btn-primary member-invite' + > + <i className='glyphicon glyphicon-envelope'/> + {' Add'} </a> ); } else if (isAdmin && !isMemberAdmin && (member.id !== UserStore.getCurrentId())) { @@ -50,7 +52,9 @@ export default class MemberListItem extends React.Component { <a href='' role='menuitem' - onClick={self.handleMakeAdmin}>Make Admin + onClick={self.handleMakeAdmin} + > + Make Admin </a> </li>); } @@ -62,7 +66,9 @@ export default class MemberListItem extends React.Component { <a href='' role='menuitem' - onClick={self.handleRemove}>Remove Member + onClick={self.handleRemove} + > + Remove Member </a> </li>); } @@ -75,14 +81,16 @@ export default class MemberListItem extends React.Component { type='button' id='channel_header_dropdown' data-toggle='dropdown' - aria-expanded='true' > + aria-expanded='true' + > <span className='text-capitalize'>{member.roles || 'Member'} </span> <span className='caret'></span> </a> <ul className='dropdown-menu member-menu' role='menu' - aria-labelledby='channel_header_dropdown'> + aria-labelledby='channel_header_dropdown' + > {makeAdminOption} {handleRemoveOption} </ul> @@ -98,7 +106,8 @@ export default class MemberListItem extends React.Component { className='post-profile-img pull-left' src={'/api/v1/users/' + member.id + '/image?time=' + timestamp} height='36' - width='36' /> + width='36' + /> <span className='member-name'>{member.username}</span> <span className='member-email'>{member.email}</span> {invite} diff --git a/web/react/components/mention.jsx b/web/react/components/mention.jsx index 72a2a6251..3a09e843d 100644 --- a/web/react/components/mention.jsx +++ b/web/react/components/mention.jsx @@ -19,11 +19,14 @@ export default class Mention extends React.Component { if (this.props.id === 'allmention' || this.props.id === 'channelmention') { icon = <span><i className='mention-img fa fa-users fa-2x'></i></span>; } else if (this.props.id != null) { - icon = (<span><img - className='mention-img' - src={'/api/v1/users/' + this.props.id + '/image?time=' + timestamp} - /> - </span>); + icon = ( + <span> + <img + className='mention-img' + src={'/api/v1/users/' + this.props.id + '/image?time=' + timestamp} + /> + </span> + ); } else { icon = <span><i className='mention-img fa fa-users fa-2x'></i></span>; } diff --git a/web/react/components/mention_list.jsx b/web/react/components/mention_list.jsx index afea30161..46a9d76ae 100644 --- a/web/react/components/mention_list.jsx +++ b/web/react/components/mention_list.jsx @@ -216,7 +216,8 @@ export default class MentionList extends React.Component { listId={index} isFocused={isFocused} handleMouseEnter={this.handleMouseEnter.bind(this, index)} - handleClick={this.handleClick} /> + handleClick={this.handleClick} + /> ); index++; } @@ -240,11 +241,13 @@ export default class MentionList extends React.Component { return ( <div className='mentions--top' - style={style}> + style={style} + > <div ref='mentionlist' className='mentions-box' - id='mentionsbox'> + id='mentionsbox' + > {mentions} </div> </div> diff --git a/web/react/components/more_channels.jsx b/web/react/components/more_channels.jsx index 08b2d7460..ba8be12b2 100644 --- a/web/react/components/more_channels.jsx +++ b/web/react/components/more_channels.jsx @@ -86,15 +86,21 @@ export default class MoreChannels extends React.Component { {channels.map(function cMap(channel, index) { var joinButton; if (self.state.joiningChannel === index) { - joinButton = (<img - className='join-channel-loading-gif' - src='/static/images/load.gif' - />); + joinButton = ( + <img + className='join-channel-loading-gif' + src='/static/images/load.gif' + /> + ); } else { - joinButton = (<button - onClick={self.handleJoin.bind(self, channel, index)} - className='btn btn-primary'>Join - </button>); + joinButton = ( + <button + onClick={self.handleJoin.bind(self, channel, index)} + className='btn btn-primary' + > + Join + </button> + ); } return ( @@ -152,7 +158,9 @@ export default class MoreChannels extends React.Component { data-channeltype={this.state.channelType} type='button' className='btn btn-primary channel-create-btn' - onClick={this.handleNewChannel}>Create New Channel + onClick={this.handleNewChannel} + > + Create New Channel </button> </div> <div className='modal-body'> diff --git a/web/react/components/navbar_dropdown.jsx b/web/react/components/navbar_dropdown.jsx index a949205da..99cdfa1ad 100644 --- a/web/react/components/navbar_dropdown.jsx +++ b/web/react/components/navbar_dropdown.jsx @@ -61,15 +61,17 @@ export default class NavbarDropdown extends React.Component { if (currentUser != null) { isAdmin = currentUser.roles.indexOf('admin') > -1; - inviteLink = (<li> - <a - href='#' - data-toggle='modal' - data-target='#invite_member' - > - Invite New Member - </a> - </li>); + inviteLink = ( + <li> + <a + href='#' + data-toggle='modal' + data-target='#invite_member' + > + Invite New Member + </a> + </li> + ); if (this.props.teamType === 'O') { teamLink = ( @@ -89,15 +91,17 @@ export default class NavbarDropdown extends React.Component { } if (isAdmin) { - manageLink = (<li> - <a - href='#' - data-toggle='modal' - data-target='#team_members' - > - Manage Team - </a> - </li>); + manageLink = ( + <li> + <a + href='#' + data-toggle='modal' + data-target='#team_members' + > + Manage Team + </a> + </li> + ); teamSettings = (<li> <a href='#' @@ -111,11 +115,13 @@ export default class NavbarDropdown extends React.Component { var teams = []; - teams.push(<li - className='divider' - key='div' - > - </li>); + teams.push( + <li + className='divider' + key='div' + > + </li> + ); if (this.state.teams.length > 1 && this.state.currentTeam) { var curTeamName = this.state.currentTeam.name; this.state.teams.forEach(function listTeams(teamName) { diff --git a/web/react/components/new_channel.jsx b/web/react/components/new_channel.jsx index a02a4c1c0..1a11fc652 100644 --- a/web/react/components/new_channel.jsx +++ b/web/react/components/new_channel.jsx @@ -134,14 +134,16 @@ export default class NewChannelModal extends React.Component { ref='modal' tabIndex='-1' role='dialog' - aria-hidden='true'> + aria-hidden='true' + > <div className='modal-dialog'> <div className='modal-content'> <div className='modal-header'> <button type='button' className='close' - data-dismiss='modal'> + data-dismiss='modal' + > <span aria-hidden='true'>×</span> <span className='sr-only'>Cancel</span> </button> @@ -157,7 +159,8 @@ export default class NewChannelModal extends React.Component { ref='display_name' className='form-control' placeholder='Enter display name' - maxLength='22' /> + maxLength='22' + /> {displayNameError} </div> <div className={nameClass}> @@ -167,7 +170,8 @@ export default class NewChannelModal extends React.Component { className='form-control' ref='channel_name' placeholder="lowercase alphanumeric's only" - maxLength='22' /> + maxLength='22' + /> {nameError} </div> <div className='form-group'> @@ -177,7 +181,8 @@ export default class NewChannelModal extends React.Component { ref='channel_desc' rows='3' placeholder='Description' - maxLength='1024' /> + maxLength='1024' + /> </div> {serverError} </div> @@ -185,13 +190,15 @@ export default class NewChannelModal extends React.Component { <button type='button' className='btn btn-default' - data-dismiss='modal' > + data-dismiss='modal' + > Cancel </button> <button onClick={this.handleSubmit} type='submit' - className='btn btn-primary' > + className='btn btn-primary' + > Create New {channelTerm} </button> </div> diff --git a/web/react/components/post.jsx b/web/react/components/post.jsx index 5f4aeb961..37de4ecc0 100644 --- a/web/react/components/post.jsx +++ b/web/react/components/post.jsx @@ -143,7 +143,8 @@ export default class Post extends React.Component { className='post-profile-img' src={'/api/v1/users/' + post.user_id + '/image?time=' + timestamp} height='36' - width='36' /> + width='36' + /> </div> ); } @@ -152,7 +153,8 @@ export default class Post extends React.Component { <div> <div id={post.id} - className={'post ' + sameUserClass + ' ' + rootUser + ' ' + postType + ' ' + currentUserCss} > + className={'post ' + sameUserClass + ' ' + rootUser + ' ' + postType + ' ' + currentUserCss} + > {profilePic} <div className='post__content'> <PostHeader @@ -161,21 +163,24 @@ export default class Post extends React.Component { sameRoot={this.props.sameRoot} commentCount={commentCount} handleCommentClick={this.handleCommentClick} - isLastComment={this.props.isLastComment} /> + isLastComment={this.props.isLastComment} + /> <PostBody post={post} sameRoot={this.props.sameRoot} parentPost={parentPost} posts={posts} handleCommentClick={this.handleCommentClick} - retryPost={this.retryPost} /> + retryPost={this.retryPost} + /> <PostInfo ref='info' post={post} sameRoot={this.props.sameRoot} commentCount={commentCount} handleCommentClick={this.handleCommentClick} - allowReply='true' /> + allowReply='true' + /> </div> </div> </div> diff --git a/web/react/components/post_body.jsx b/web/react/components/post_body.jsx index 88fb9aec8..d9b8f20ce 100644 --- a/web/react/components/post_body.jsx +++ b/web/react/components/post_body.jsx @@ -5,14 +5,26 @@ const FileAttachmentList = require('./file_attachment_list.jsx'); const UserStore = require('../stores/user_store.jsx'); const Utils = require('../utils/utils.jsx'); const Constants = require('../utils/constants.jsx'); +const twemoji = require('twemoji'); export default class PostBody extends React.Component { constructor(props) { super(props); + this.parseEmojis = this.parseEmojis.bind(this); + const linkData = Utils.extractLinks(this.props.post.message); this.state = {links: linkData.links, message: linkData.text}; } + parseEmojis() { + twemoji.parse(React.findDOMNode(this), {size: Constants.EMOJI_SIZE}); + } + componentDidMount() { + this.parseEmojis(); + } + componentDidUpdate() { + this.parseEmojis(); + } componentWillReceiveProps(nextProps) { const linkData = Utils.extractLinks(nextProps.post.message); this.setState({links: linkData.links, message: linkData.text}); diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index c5db3956d..6fa87ca4a 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -559,7 +559,7 @@ export default class PostList extends React.Component { > <hr className='separator__hr' - /> + /> <div className='separator__text'>New Messages</div> </div> ); diff --git a/web/react/components/rhs_comment.jsx b/web/react/components/rhs_comment.jsx index e74ab7f13..f1a90102c 100644 --- a/web/react/components/rhs_comment.jsx +++ b/web/react/components/rhs_comment.jsx @@ -12,12 +12,14 @@ var FileAttachmentList = require('./file_attachment_list.jsx'); var Client = require('../utils/client.jsx'); var AsyncClient = require('../utils/async_client.jsx'); var ActionTypes = Constants.ActionTypes; +var twemoji = require('twemoji'); export default class RhsComment extends React.Component { constructor(props) { super(props); this.retryComment = this.retryComment.bind(this); + this.parseEmojis = this.parseEmojis.bind(this); this.state = {}; } @@ -51,6 +53,12 @@ export default class RhsComment extends React.Component { PostStore.updatePendingPost(post); this.forceUpdate(); } + parseEmojis() { + twemoji.parse(React.findDOMNode(this), {size: Constants.EMOJI_SIZE}); + } + componentDidMount() { + this.parseEmojis(); + } shouldComponentUpdate(nextProps) { if (!Utils.areStatesEqual(nextProps.post, this.props.post)) { return true; @@ -58,6 +66,9 @@ export default class RhsComment extends React.Component { return false; } + componentDidUpdate() { + this.parseEmojis(); + } render() { var post = this.props.post; @@ -161,7 +172,8 @@ export default class RhsComment extends React.Component { filenames={post.filenames} modalId={'rhs_comment_view_image_modal_' + post.id} channelId={post.channel_id} - userId={post.user_id} /> + userId={post.user_id} + /> ); } diff --git a/web/react/components/rhs_root_post.jsx b/web/react/components/rhs_root_post.jsx index a407e6470..83b57b955 100644 --- a/web/react/components/rhs_root_post.jsx +++ b/web/react/components/rhs_root_post.jsx @@ -6,12 +6,23 @@ var UserProfile = require('./user_profile.jsx'); var UserStore = require('../stores/user_store.jsx'); var utils = require('../utils/utils.jsx'); var FileAttachmentList = require('./file_attachment_list.jsx'); +var twemoji = require('twemoji'); +var Constants = require('../utils/constants.jsx'); export default class RhsRootPost extends React.Component { constructor(props) { super(props); + + this.parseEmojis = this.parseEmojis.bind(this); + this.state = {}; } + parseEmojis() { + twemoji.parse(React.findDOMNode(this), {size: Constants.EMOJI_SIZE}); + } + componentDidMount() { + this.parseEmojis(); + } shouldComponentUpdate(nextProps) { if (!utils.areStatesEqual(nextProps.post, this.props.post)) { return true; @@ -19,6 +30,9 @@ export default class RhsRootPost extends React.Component { return false; } + componentDidUpdate() { + this.parseEmojis(); + } render() { var post = this.props.post; var message = utils.textToJsx(post.message); @@ -99,7 +113,8 @@ export default class RhsRootPost extends React.Component { filenames={post.filenames} modalId={'rhs_view_image_modal_' + post.id} channelId={post.channel_id} - userId={post.user_id} /> + userId={post.user_id} + /> ); } diff --git a/web/react/components/rhs_thread.jsx b/web/react/components/rhs_thread.jsx index d99177bda..2f23d80d9 100644 --- a/web/react/components/rhs_thread.jsx +++ b/web/react/components/rhs_thread.jsx @@ -18,7 +18,6 @@ export default class RhsThread extends React.Component { this.onChange = this.onChange.bind(this); this.onChangeAll = this.onChangeAll.bind(this); - this.onTimeChange = this.onTimeChange.bind(this); this.state = this.getStateFromStores(); } @@ -44,7 +43,6 @@ export default class RhsThread extends React.Component { componentDidMount() { PostStore.addSelectedPostChangeListener(this.onChange); PostStore.addChangeListener(this.onChangeAll); - UserStore.addStatusesChangeListener(this.onTimeChange); this.resize(); $(window).resize(function resize() { this.resize(); @@ -58,7 +56,6 @@ export default class RhsThread extends React.Component { componentWillUnmount() { PostStore.removeSelectedPostChangeListener(this.onChange); PostStore.removeChangeListener(this.onChangeAll); - UserStore.removeStatusesChangeListener(this.onTimeChange); } onChange() { var newState = this.getStateFromStores(); @@ -96,14 +93,6 @@ export default class RhsThread extends React.Component { this.setState(newState); } } - onTimeChange() { - for (var id in this.state.postList.posts) { - if (!this.refs[id]) { - continue; - } - this.refs[id].forceUpdate(); - } - } resize() { var height = $(window).height() - $('#error_bar').outerHeight() - 100; $('.post-right__scroll').css('height', height + 'px'); @@ -173,8 +162,7 @@ export default class RhsThread extends React.Component { return ( <div className='post-right__container'> - <FileUploadOverlay - overlayType='right' /> + <FileUploadOverlay overlayType='right' /> <div className='search-bar__container sidebar--right__search-header'>{searchForm}</div> <div className='sidebar-right__body'> <RhsHeaderPost diff --git a/web/react/components/search_bar.jsx b/web/react/components/search_bar.jsx index 8da8231a2..006d15459 100644 --- a/web/react/components/search_bar.jsx +++ b/web/react/components/search_bar.jsx @@ -116,19 +116,22 @@ export default class SearchBar extends React.Component { <div> <div className='sidebar__collapse' - onClick={this.handleClose} > + onClick={this.handleClose} + > <span className='fa fa-angle-left'></span> </div> <span className='search__clear' - onClick={this.clearFocus}> + onClick={this.clearFocus} + > Cancel </span> <form role='form' className='search__form relative-div' - onSubmit={this.handleSubmit}> - <span className='glyphicon glyphicon-search sidebar__search-icon'></span> + onSubmit={this.handleSubmit} + > + <span className='glyphicon glyphicon-search sidebar__search-icon' /> <input type='text' ref='search' @@ -136,7 +139,8 @@ export default class SearchBar extends React.Component { placeholder='Search' value={this.state.searchTerm} onFocus={this.handleUserFocus} - onChange={this.handleUserInput} /> + onChange={this.handleUserInput} + /> {isSearching} </form> </div> diff --git a/web/react/components/setting_item_max.jsx b/web/react/components/setting_item_max.jsx index e67e458af..b1bab1d48 100644 --- a/web/react/components/setting_item_max.jsx +++ b/web/react/components/setting_item_max.jsx @@ -15,16 +15,20 @@ export default class SettingItemMax extends React.Component { var extraInfo = null; if (this.props.extraInfo) { - extraInfo = this.props.extraInfo; + extraInfo = (<div className='setting-list__hint'>{this.props.extraInfo}</div>); } var submit = ''; if (this.props.submit) { - submit = (<a - className='btn btn-sm btn-primary' - href='#' - onClick={this.props.submit}> - Submit</a>); + submit = ( + <a + className='btn btn-sm btn-primary' + href='#' + onClick={this.props.submit} + > + Submit + </a> + ); } var inputs = this.props.inputs; @@ -46,7 +50,8 @@ export default class SettingItemMax extends React.Component { <a className='btn btn-sm theme' href='#' - onClick={this.props.updateSection} > + onClick={this.props.updateSection} + > Cancel </a> </li> diff --git a/web/react/components/setting_picture.jsx b/web/react/components/setting_picture.jsx index 6eaa4a96e..a53112651 100644 --- a/web/react/components/setting_picture.jsx +++ b/web/react/components/setting_picture.jsx @@ -98,12 +98,13 @@ export default class SettingPicture extends React.Component { <li className='setting-list-item'> {serverError} {clientError} - <span className='btn btn-sm btn-primary btn-file sel-btn' - >Select<input - ref='input' - accept='.jpg,.png,.bmp' - type='file' - onChange={this.props.pictureChange} + <span className='btn btn-sm btn-primary btn-file sel-btn'> + Select + <input + ref='input' + accept='.jpg,.png,.bmp' + type='file' + onChange={this.props.pictureChange} /> </span> {confirmButton} diff --git a/web/react/components/setting_upload.jsx b/web/react/components/setting_upload.jsx index 66afdfb41..5979091c4 100644 --- a/web/react/components/setting_upload.jsx +++ b/web/react/components/setting_upload.jsx @@ -2,7 +2,6 @@ // See License.txt for license information. export default class SettingsUpload extends React.Component { - constructor(props) { super(props); @@ -70,14 +69,19 @@ export default class SettingsUpload extends React.Component { <li className='col-xs-offset-3 col-xs-8'> <ul className='setting-list'> <li className='setting-list-item'> - <span className='btn btn-sm btn-primary btn-file sel-btn'>Select file<input - ref='uploadinput' - accept={this.props.fileTypesAccepted} - type='file' - onChange={this.onFileSelect}/></span> + <span className='btn btn-sm btn-primary btn-file sel-btn'> + Select file + <input + ref='uploadinput' + accept={this.props.fileTypesAccepted} + type='file' + onChange={this.onFileSelect} + /> + </span> <a className={'btn btn-sm btn-primary'} - onClick={this.doSubmit}> + onClick={this.doSubmit} + > Import </a> <div className='file-status file-name hide'></div> diff --git a/web/react/components/sidebar_header.jsx b/web/react/components/sidebar_header.jsx index fb79f8b1e..0056d7a2f 100644 --- a/web/react/components/sidebar_header.jsx +++ b/web/react/components/sidebar_header.jsx @@ -29,10 +29,12 @@ export default class SidebarHeader extends React.Component { } if (me.last_picture_update) { - profilePicture = (<img - className='user__picture' - src={'/api/v1/users/' + me.id + '/image?time=' + me.update_at} - />); + profilePicture = ( + <img + className='user__picture' + src={'/api/v1/users/' + me.id + '/image?time=' + me.update_at} + /> + ); } return ( diff --git a/web/react/components/sidebar_right.jsx b/web/react/components/sidebar_right.jsx index 9aeda6626..913715154 100644 --- a/web/react/components/sidebar_right.jsx +++ b/web/react/components/sidebar_right.jsx @@ -71,10 +71,12 @@ export default class SidebarRight extends React.Component { if (this.state.search_visible) { content = <SearchResults isMentionSearch={this.state.is_mention_search} />; } else if (this.state.post_right_visible) { - content = (<RhsThread - fromSearch={this.state.from_search} - isMentionSearch={this.state.is_mention_search} - />); + content = ( + <RhsThread + fromSearch={this.state.from_search} + isMentionSearch={this.state.is_mention_search} + /> + ); } return ( diff --git a/web/react/components/sidebar_right_menu.jsx b/web/react/components/sidebar_right_menu.jsx index 9c5733799..bd10a6ef1 100644 --- a/web/react/components/sidebar_right_menu.jsx +++ b/web/react/components/sidebar_right_menu.jsx @@ -68,7 +68,8 @@ export default class SidebarRightMenu extends React.Component { href='#' data-toggle='modal' data-target='#team_members' - ><i className='glyphicon glyphicon-wrench'></i>Manage Team</a> + > + <i className='glyphicon glyphicon-wrench'></i>Manage Team</a> </li> ); } diff --git a/web/react/components/signup_team_complete.jsx b/web/react/components/signup_team_complete.jsx index 1d45548da..dc0d1d376 100644 --- a/web/react/components/signup_team_complete.jsx +++ b/web/react/components/signup_team_complete.jsx @@ -44,52 +44,66 @@ export default class SignupTeamComplete extends React.Component { } render() { if (this.state.wizard === 'welcome') { - return (<WelcomePage - state={this.state} - updateParent={this.updateParent} - />); + return ( + <WelcomePage + state={this.state} + updateParent={this.updateParent} + /> + ); } if (this.state.wizard === 'team_display_name') { - return (<TeamDisplayNamePage - state={this.state} - updateParent={this.updateParent} - />); + return ( + <TeamDisplayNamePage + state={this.state} + updateParent={this.updateParent} + /> + ); } if (this.state.wizard === 'team_url') { - return (<TeamURLPage - state={this.state} - updateParent={this.updateParent} - />); + return ( + <TeamURLPage + state={this.state} + updateParent={this.updateParent} + /> + ); } if (this.state.wizard === 'allowed_domains') { - return (<AllowedDomainsPage - state={this.state} - updateParent={this.updateParent} - />); + return ( + <AllowedDomainsPage + state={this.state} + updateParent={this.updateParent} + /> + ); } if (this.state.wizard === 'send_invites') { - return (<SendInivtesPage - state={this.state} - updateParent={this.updateParent} - />); + return ( + <SendInivtesPage + state={this.state} + updateParent={this.updateParent} + /> + ); } if (this.state.wizard === 'username') { - return (<UsernamePage - state={this.state} - updateParent={this.updateParent} - />); + return ( + <UsernamePage + state={this.state} + updateParent={this.updateParent} + /> + ); } if (this.state.wizard === 'password') { - return (<PasswordPage - state={this.state} - updateParent={this.updateParent} - />); + return ( + <PasswordPage + state={this.state} + updateParent={this.updateParent} + /> + ); } return (<div>You've already completed the signup process for this invitation or this invitation has expired.</div>); diff --git a/web/react/components/team_import_tab.jsx b/web/react/components/team_import_tab.jsx index 627ff85f4..1ab348465 100644 --- a/web/react/components/team_import_tab.jsx +++ b/web/react/components/team_import_tab.jsx @@ -46,7 +46,8 @@ export default class TeamImportTab extends React.Component { title='Import from Slack' submit={this.doImportSlack} helpText={uploadHelpText} - fileTypesAccepted='.zip'/> + fileTypesAccepted='.zip' + /> ); var messageSection; @@ -62,14 +63,30 @@ export default class TeamImportTab extends React.Component { break; case 'done': messageSection = ( - <p className='confirm-import alert alert-success'><i className='fa fa-check'></i> Import successful: <a href={this.state.link} - download='MattermostImportSummary.txt'>View Summary</a></p> - ); + <p className='confirm-import alert alert-success'> + <i className='fa fa-check' /> + {' Import successful: '} + <a + href={this.state.link} + download='MattermostImportSummary.txt' + > + {'View Summary'} + </a> + </p> + ); break; case 'fail': messageSection = ( - <p className='confirm-import alert alert-warning'><i className='fa fa-warning'></i> Import failure: <a href={this.state.link} - download='MattermostImportSummary.txt'>View Summary</a></p> + <p className='confirm-import alert alert-warning'> + <i className='fa fa-warning' /> + {' Import failure: '} + <a + href={this.state.link} + download='MattermostImportSummary.txt' + > + {'View Summary'} + </a> + </p> ); break; } diff --git a/web/react/components/team_signup_choose_auth.jsx b/web/react/components/team_signup_choose_auth.jsx index 71780c677..acce6ab49 100644 --- a/web/react/components/team_signup_choose_auth.jsx +++ b/web/react/components/team_signup_choose_auth.jsx @@ -22,7 +22,7 @@ export default class ChooseAuthPage extends React.Component { this.props.updatePage('service', Constants.GITLAB_SERVICE); }.bind(this) } - > + > <span className='icon' /> <span>Create new {strings.Team} with GitLab Account</span> </a> @@ -40,7 +40,7 @@ export default class ChooseAuthPage extends React.Component { this.props.updatePage('email', ''); }.bind(this) } - > + > <span className='fa fa-envelope' /> <span>Create new {strings.Team} with email address</span> </a> diff --git a/web/react/components/team_signup_display_name_page.jsx b/web/react/components/team_signup_display_name_page.jsx index 5d0e4c7b3..1849f8222 100644 --- a/web/react/components/team_signup_display_name_page.jsx +++ b/web/react/components/team_signup_display_name_page.jsx @@ -52,8 +52,8 @@ export default class TeamSignupDisplayNamePage extends React.Component { <form> <img className='signup-team-logo' - src='/static/images/logo.png' /> - + src='/static/images/logo.png' + /> <h2>{utils.toTitleCase(strings.Team) + ' Name'}</h2> <div className={nameDivClass}> <div className='row'> @@ -66,22 +66,27 @@ export default class TeamSignupDisplayNamePage extends React.Component { maxLength='128' defaultValue={this.props.state.team.display_name} autoFocus={true} - onFocus={this.handleFocus} /> + onFocus={this.handleFocus} + /> </div> </div> {nameError} </div> - <div>{'Name your ' + strings.Team + ' in any language. Your ' + strings.Team + ' name shows in menus and headings.'}</div> + <div> + {'Name your ' + strings.Team + ' in any language. Your ' + strings.Team + ' name shows in menus and headings.'} + </div> <button type='submit' className='btn btn-primary margin--extra' - onClick={this.submitNext} > + onClick={this.submitNext} + > Next<i className='glyphicon glyphicon-chevron-right'></i> </button> <div className='margin--extra'> <a href='#' - onClick={this.submitBack}> + onClick={this.submitBack} + > Back to previous step </a> </div> diff --git a/web/react/components/textbox.jsx b/web/react/components/textbox.jsx index 0408a262d..b4518fe80 100644 --- a/web/react/components/textbox.jsx +++ b/web/react/components/textbox.jsx @@ -121,7 +121,6 @@ export default class Textbox extends React.Component { } this.addedMention = false; this.refs.commands.getSuggestedCommands(nextProps.messageText); - this.resize(); } updateMentionTab(mentionText) { // using setTimeout so dispatch isn't called during an in progress dispatch @@ -135,7 +134,6 @@ export default class Textbox extends React.Component { } handleChange() { this.props.onUserInput(React.findDOMNode(this.refs.message).value); - this.resize(); } handleKeyPress(e) { const text = React.findDOMNode(this.refs.message).value; @@ -244,6 +242,8 @@ export default class Textbox extends React.Component { const e = React.findDOMNode(this.refs.message); const w = React.findDOMNode(this.refs.wrapper); + let prevHeight = $(e).height(); + const lht = parseInt($(e).css('lineHeight'), 10); const lines = e.scrollHeight / lht; let mod = 15; @@ -259,6 +259,10 @@ export default class Textbox extends React.Component { $(e).css({height: 'auto', 'overflow-y': 'scroll'}).height(167); $(w).css({height: 'auto'}).height(167); } + + if (prevHeight !== $(e).height()) { + this.props.onHeightChange(); + } } handleFocus() { const elm = React.findDOMNode(this.refs.message); @@ -316,5 +320,6 @@ Textbox.propTypes = { messageText: React.PropTypes.string.isRequired, onUserInput: React.PropTypes.func.isRequired, onKeyPress: React.PropTypes.func.isRequired, + onHeightChange: React.PropTypes.func.isRequired, createMessage: React.PropTypes.string.isRequired }; diff --git a/web/react/components/user_settings_notifications.jsx b/web/react/components/user_settings_notifications.jsx index 5fe6bbb4e..33db1a332 100644 --- a/web/react/components/user_settings_notifications.jsx +++ b/web/react/components/user_settings_notifications.jsx @@ -1,7 +1,6 @@ // Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. // See License.txt for license information. -var ChannelStore = require('../stores/channel_store.jsx'); var UserStore = require('../stores/user_store.jsx'); var SettingItemMin = require('./setting_item_min.jsx'); var SettingItemMax = require('./setting_item_max.jsx'); @@ -69,11 +68,9 @@ function getNotificationsStateFromStores() { } } - var curChannel = ChannelStore.getCurrent().display_name; - return {notifyLevel: desktop, enableEmail: email, soundNeeded: soundNeeded, enableSound: sound, usernameKey: usernameKey, mentionKey: mentionKey, customKeys: customKeys, customKeysChecked: customKeys.length > 0, - firstNameKey: firstNameKey, allKey: allKey, channelKey: channelKey, curChannel: curChannel}; + firstNameKey: firstNameKey, allKey: allKey, channelKey: channelKey}; } export default class NotificationsTab extends React.Component { @@ -147,12 +144,10 @@ export default class NotificationsTab extends React.Component { } componentDidMount() { UserStore.addChangeListener(this.onListenerChange); - ChannelStore.addChangeListener(this.onListenerChange); $('#user_settings').on('hidden.bs.modal', this.handleClose); } componentWillUnmount() { UserStore.removeChangeListener(this.onListenerChange); - ChannelStore.removeChangeListener(this.onListenerChange); $('#user_settings').off('hidden.bs.modal', this.handleClose); this.props.updateSection(''); } @@ -271,12 +266,6 @@ export default class NotificationsTab extends React.Component { e.preventDefault(); }.bind(this); - let extraInfo = ( - <div className='setting-list__hint'> - These settings will override the global notification settings for the <b>{this.state.curChannel}</b> channel - </div> - ); - desktopSection = ( <SettingItemMax title='Send desktop notifications' @@ -284,7 +273,6 @@ export default class NotificationsTab extends React.Component { submit={this.handleSubmit} server_error={serverError} updateSection={handleUpdateDesktopSection} - extraInfo={extraInfo} /> ); } else { diff --git a/web/react/components/view_image.jsx b/web/react/components/view_image.jsx index ed88c3df4..b0eaba5d6 100644 --- a/web/react/components/view_image.jsx +++ b/web/react/components/view_image.jsx @@ -307,7 +307,8 @@ export default class ViewImageModal extends React.Component { ref='previewArrowLeft' className='modal-prev-bar' href='#' - onClick={this.handlePrev}> + onClick={this.handlePrev} + > <i className='image-control image-prev'/> </a> ); @@ -317,7 +318,8 @@ export default class ViewImageModal extends React.Component { ref='previewArrowRight' className='modal-next-bar' href='#' - onClick={this.handleNext}> + onClick={this.handleNext} + > <i className='image-control image-next'/> </a> ); @@ -351,7 +353,7 @@ export default class ViewImageModal extends React.Component { ref='imageFooter' className='modal-button-bar' > - <span className='pull-left text'>{'File ' + (this.state.imgId + 1) + ' of ' + this.props.filenames.length}</span> + <span className='pull-left text'>{'File ' + (this.state.imgId + 1) + ' of ' + this.props.filenames.length}</span> <div className='image-links'> {publicLink} <a diff --git a/web/react/package.json b/web/react/package.json index 5c33e2186..da55dc2b8 100644 --- a/web/react/package.json +++ b/web/react/package.json @@ -8,7 +8,8 @@ "keymirror": "^0.1.1", "object-assign": "^3.0.0", "react": "^0.13.3", - "react-zeroclipboard-mixin": "^0.1.0" + "react-zeroclipboard-mixin": "^0.1.0", + "twemoji": "^1.4.1" }, "devDependencies": { "browserify": "^11.0.1", @@ -16,12 +17,12 @@ "babelify": "^6.1.3", "uglify-js": "^2.4.24", "watchify": "^3.3.1", - "eslint": "^1.1.0", - "eslint-plugin-react": "^3.2.3" + "eslint": "^1.3.1", + "eslint-plugin-react": "^3.3.1" }, "scripts": { "start": "watchify --extension=jsx -o ../static/js/bundle.js -v -d ./**/*.jsx", - "build": "NODE_ENV=production browserify ./**/*.jsx | uglifyjs > ../static/js/bundle.min.js", + "build": "NODE_ENV=production browserify ./**/*.jsx | uglifyjs -c -m --screw-ie8 > ../static/js/bundle.min.js", "test": "jest" }, "browserify": { diff --git a/web/react/pages/channel.jsx b/web/react/pages/channel.jsx index d56b309fa..71a03cde0 100644 --- a/web/react/pages/channel.jsx +++ b/web/react/pages/channel.jsx @@ -73,7 +73,8 @@ function setupChannelPage(teamName, teamType, teamId, channelName, channelId) { React.render( <Sidebar teamDisplayName={teamName} - teamType={teamType} />, + teamType={teamType} + />, document.getElementById('sidebar-left') ); @@ -190,7 +191,8 @@ function setupChannelPage(teamName, teamType, teamId, channelName, channelId) { React.render( <SidebarRightMenu teamDisplayName={teamName} - teamType={teamType} />, + teamType={teamType} + />, document.getElementById('sidebar-menu') ); @@ -226,7 +228,8 @@ function setupChannelPage(teamName, teamType, teamId, channelName, channelId) { React.render( <FileUploadOverlay - overlayType='center' />, + overlayType='center' + />, document.getElementById('file_upload_overlay') ); } diff --git a/web/react/pages/login.jsx b/web/react/pages/login.jsx index e7305889d..424ae0e84 100644 --- a/web/react/pages/login.jsx +++ b/web/react/pages/login.jsx @@ -8,7 +8,8 @@ function setupLoginPage(teamDisplayName, teamName, authServices) { <Login teamDisplayName={teamDisplayName} teamName={teamName} - authServices={authServices} />, + authServices={authServices} + />, document.getElementById('login') ); } diff --git a/web/react/pages/signup_team_complete.jsx b/web/react/pages/signup_team_complete.jsx index 43e3aae65..72f9992a8 100644 --- a/web/react/pages/signup_team_complete.jsx +++ b/web/react/pages/signup_team_complete.jsx @@ -8,7 +8,8 @@ function setupSignupTeamCompletePage(email, data, hash) { <SignupTeamComplete email={email} hash={hash} - data={data}/>, + data={data} + />, document.getElementById('signup-team-complete') ); } diff --git a/web/react/pages/signup_user_complete.jsx b/web/react/pages/signup_user_complete.jsx index 71b526e5d..eaf93a61c 100644 --- a/web/react/pages/signup_user_complete.jsx +++ b/web/react/pages/signup_user_complete.jsx @@ -12,7 +12,8 @@ function setupSignupUserCompletePage(email, name, uiName, id, data, hash, authSe email={email} hash={hash} data={data} - authServices={authServices} />, + authServices={authServices} + />, document.getElementById('signup-user-complete') ); } diff --git a/web/react/pages/verify.jsx b/web/react/pages/verify.jsx index f42913315..7077b40b8 100644 --- a/web/react/pages/verify.jsx +++ b/web/react/pages/verify.jsx @@ -8,7 +8,8 @@ global.window.setupVerifyPage = function setupVerifyPage(isVerified, teamURL, us <EmailVerify isVerified={isVerified} teamURL={teamURL} - userEmail={userEmail} />, + userEmail={userEmail} + />, document.getElementById('verify') ); }; diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx index 3a6ca1b89..18b7ff59c 100644 --- a/web/react/utils/constants.jsx +++ b/web/react/utils/constants.jsx @@ -103,6 +103,7 @@ module.exports = { MONTHS: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], MAX_DMS: 20, MAX_POST_LEN: 4000, + EMOJI_SIZE: 16, ONLINE_ICON_SVG: "<svg version='1.1' id='Layer_1' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:cc='http://creativecommons.org/ns#' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:svg='http://www.w3.org/2000/svg' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' sodipodi:docname='TRASH_1_4.svg' inkscape:version='0.48.4 r9939' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='12px' height='12px' viewBox='0 0 12 12' enable-background='new 0 0 12 12' xml:space='preserve'><sodipodi:namedview inkscape:cy='139.7898' inkscape:cx='26.358185' inkscape:zoom='1.18' showguides='true' showgrid='false' id='namedview6' guidetolerance='10' gridtolerance='10' objecttolerance='10' borderopacity='1' bordercolor='#666666' pagecolor='#ffffff' inkscape:current-layer='Layer_1' inkscape:window-maximized='1' inkscape:window-y='-8' inkscape:window-x='-8' inkscape:window-height='705' inkscape:window-width='1366' inkscape:guide-bbox='true' inkscape:pageshadow='2' inkscape:pageopacity='0'><sodipodi:guide position='50.036793,85.991376' orientation='1,0' id='guide2986'></sodipodi:guide><sodipodi:guide position='58.426196,66.216355' orientation='0,1' id='guide3047'></sodipodi:guide></sodipodi:namedview><g><g><path class='online--icon' d='M6,5.487c1.371,0,2.482-1.116,2.482-2.493c0-1.378-1.111-2.495-2.482-2.495S3.518,1.616,3.518,2.994C3.518,4.371,4.629,5.487,6,5.487z M10.452,8.545c-0.101-0.829-0.36-1.968-0.726-2.541C9.475,5.606,8.5,5.5,8.5,5.5S8.43,7.521,6,7.521C3.507,7.521,3.5,5.5,3.5,5.5S2.527,5.606,2.273,6.004C1.908,6.577,1.648,7.716,1.547,8.545C1.521,8.688,1.49,9.082,1.498,9.142c0.161,1.295,2.238,2.322,4.375,2.358C5.916,11.501,5.958,11.501,6,11.501c0.043,0,0.084,0,0.127-0.001c2.076-0.026,4.214-1.063,4.375-2.358C10.509,9.082,10.471,8.696,10.452,8.545z'/></g></g></svg>", OFFLINE_ICON_SVG: "<svg version='1.1' id='Layer_1' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:cc='http://creativecommons.org/ns#' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:svg='http://www.w3.org/2000/svg' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' sodipodi:docname='TRASH_1_4.svg' inkscape:version='0.48.4 r9939' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='12px' height='12px' viewBox='0 0 12 12' enable-background='new 0 0 12 12' xml:space='preserve'><sodipodi:namedview inkscape:cy='139.7898' inkscape:cx='26.358185' inkscape:zoom='1.18' showguides='true' showgrid='false' id='namedview6' guidetolerance='10' gridtolerance='10' objecttolerance='10' borderopacity='1' bordercolor='#666666' pagecolor='#ffffff' inkscape:current-layer='Layer_1' inkscape:window-maximized='1' inkscape:window-y='-8' inkscape:window-x='-8' inkscape:window-height='705' inkscape:window-width='1366' inkscape:guide-bbox='true' inkscape:pageshadow='2' inkscape:pageopacity='0'><sodipodi:guide position='50.036793,85.991376' orientation='1,0' id='guide2986'></sodipodi:guide><sodipodi:guide position='58.426196,66.216355' orientation='0,1' id='guide3047'></sodipodi:guide></sodipodi:namedview><g><g><path fill='#cccccc' d='M6.002,7.143C5.645,7.363,5.167,7.52,4.502,7.52c-2.493,0-2.5-2.02-2.5-2.02S1.029,5.607,0.775,6.004C0.41,6.577,0.15,7.716,0.049,8.545c-0.025,0.145-0.057,0.537-0.05,0.598c0.162,1.295,2.237,2.321,4.375,2.357c0.043,0.001,0.085,0.001,0.127,0.001c0.043,0,0.084,0,0.127-0.001c1.879-0.023,3.793-0.879,4.263-2h-2.89L6.002,7.143L6.002,7.143z M4.501,5.488c1.372,0,2.483-1.117,2.483-2.494c0-1.378-1.111-2.495-2.483-2.495c-1.371,0-2.481,1.117-2.481,2.495C2.02,4.371,3.13,5.488,4.501,5.488z M7.002,6.5v2h5v-2H7.002z'/></g></g></svg>", MENU_ICON: "<svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'width='4px' height='16px' viewBox='0 0 8 32' enable-background='new 0 0 8 32' xml:space='preserve'> <g> <circle cx='4' cy='4.062' r='4'/> <circle cx='4' cy='16' r='4'/> <circle cx='4' cy='28' r='4'/> </g> </svg>", |