diff options
Diffstat (limited to 'web/react/components')
-rw-r--r-- | web/react/components/admin_console/email_settings.jsx | 67 | ||||
-rw-r--r-- | web/react/components/channel_notifications_modal.jsx | 12 | ||||
-rw-r--r-- | web/react/components/get_link_modal.jsx | 2 | ||||
-rw-r--r-- | web/react/components/member_list_item.jsx | 2 | ||||
-rw-r--r-- | web/react/components/member_list_team_item.jsx | 2 | ||||
-rw-r--r-- | web/react/components/popover_list_members.jsx | 46 | ||||
-rw-r--r-- | web/react/components/post.jsx | 7 | ||||
-rw-r--r-- | web/react/components/posts_view.jsx | 67 | ||||
-rw-r--r-- | web/react/components/posts_view_container.jsx | 4 | ||||
-rw-r--r-- | web/react/components/register_app_modal.jsx | 192 | ||||
-rw-r--r-- | web/react/components/sidebar.jsx | 6 | ||||
-rw-r--r-- | web/react/components/user_profile.jsx | 6 | ||||
-rw-r--r-- | web/react/components/user_settings/user_settings_developer.jsx | 12 | ||||
-rw-r--r-- | web/react/components/view_image.jsx | 37 |
14 files changed, 318 insertions, 144 deletions
diff --git a/web/react/components/admin_console/email_settings.jsx b/web/react/components/admin_console/email_settings.jsx index d0565a0e0..238ace3da 100644 --- a/web/react/components/admin_console/email_settings.jsx +++ b/web/react/components/admin_console/email_settings.jsx @@ -18,6 +18,7 @@ export default class EmailSettings extends React.Component { this.state = { sendEmailNotifications: this.props.config.EmailSettings.SendEmailNotifications, + sendPushNotifications: this.props.config.EmailSettings.SendPushNotifications, saveNeeded: false, serverError: null, emailSuccess: null, @@ -36,6 +37,14 @@ export default class EmailSettings extends React.Component { s.sendEmailNotifications = false; } + if (action === 'sendPushNotifications_true') { + s.sendPushNotifications = true; + } + + if (action === 'sendPushNotifications_false') { + s.sendPushNotifications = false; + } + this.setState(s); } @@ -43,11 +52,12 @@ export default class EmailSettings extends React.Component { var config = this.props.config; config.EmailSettings.EnableSignUpWithEmail = ReactDOM.findDOMNode(this.refs.allowSignUpWithEmail).checked; config.EmailSettings.SendEmailNotifications = ReactDOM.findDOMNode(this.refs.sendEmailNotifications).checked; + config.EmailSettings.SendPushlNotifications = ReactDOM.findDOMNode(this.refs.sendPushNotifications).checked; config.EmailSettings.RequireEmailVerification = ReactDOM.findDOMNode(this.refs.requireEmailVerification).checked; - config.EmailSettings.SendEmailNotifications = ReactDOM.findDOMNode(this.refs.sendEmailNotifications).checked; config.EmailSettings.FeedbackName = ReactDOM.findDOMNode(this.refs.feedbackName).value.trim(); config.EmailSettings.FeedbackEmail = ReactDOM.findDOMNode(this.refs.feedbackEmail).value.trim(); config.EmailSettings.SMTPServer = ReactDOM.findDOMNode(this.refs.SMTPServer).value.trim(); + config.EmailSettings.PushNotificationServer = ReactDOM.findDOMNode(this.refs.PushNotificationServer).value.trim(); config.EmailSettings.SMTPPort = ReactDOM.findDOMNode(this.refs.SMTPPort).value.trim(); config.EmailSettings.SMTPUsername = ReactDOM.findDOMNode(this.refs.SMTPUsername).value.trim(); config.EmailSettings.SMTPPassword = ReactDOM.findDOMNode(this.refs.SMTPPassword).value.trim(); @@ -526,6 +536,61 @@ export default class EmailSettings extends React.Component { </div> <div className='form-group'> + <label + className='control-label col-sm-4' + htmlFor='sendPushNotifications' + > + {'Send Push Notifications: '} + </label> + <div className='col-sm-8'> + <label className='radio-inline'> + <input + type='radio' + name='sendPushNotifications' + value='true' + ref='sendPushNotifications' + defaultChecked={this.props.config.EmailSettings.SendPushNotifications} + onChange={this.handleChange.bind(this, 'sendPushNotifications_true')} + /> + {'true'} + </label> + <label className='radio-inline'> + <input + type='radio' + name='sendPushNotifications' + value='false' + defaultChecked={!this.props.config.EmailSettings.SendPushNotifications} + onChange={this.handleChange.bind(this, 'sendPushNotifications_false')} + /> + {'false'} + </label> + <p className='help-text'>{'Typically set to true in production. When true, Mattermost attempts to send iOS and Android push notifications through the push notification server.'}</p> + </div> + </div> + + <div className='form-group'> + <label + className='control-label col-sm-4' + htmlFor='PushNotificationServer' + > + {'Push Notification Server:'} + </label> + <div className='col-sm-8'> + <input + type='text' + className='form-control' + id='PushNotificationServer' + ref='PushNotificationServer' + placeholder='E.g.: "https://push.mattermost.com"' + defaultValue={this.props.config.EmailSettings.PushNotificationServer} + onChange={this.handleChange} + disabled={!this.state.sendPushNotifications} + /> + <p className='help-text'>{'Location of the push notification server.'}</p> + </div> + </div> + + <div className='form-group'> <div className='col-sm-12'> {serverError} <button diff --git a/web/react/components/channel_notifications_modal.jsx b/web/react/components/channel_notifications_modal.jsx index 79b769c8a..887589468 100644 --- a/web/react/components/channel_notifications_modal.jsx +++ b/web/react/components/channel_notifications_modal.jsx @@ -32,11 +32,13 @@ export default class ChannelNotificationsModal extends React.Component { activeSection: '' }; } - componentDidMount() { - ChannelStore.addChangeListener(this.onListenerChange); - } - componentWillUnmount() { - ChannelStore.removeChangeListener(this.onListenerChange); + componentWillReceiveProps(nextProps) { + if (!this.props.show && nextProps.show) { + this.onListenerChange(); + ChannelStore.addChangeListener(this.onListenerChange); + } else { + ChannelStore.removeChangeListener(this.onListenerChange); + } } onListenerChange() { const curChannelId = ChannelStore.getCurrentId(); diff --git a/web/react/components/get_link_modal.jsx b/web/react/components/get_link_modal.jsx index df5d6b8e1..fd20834f4 100644 --- a/web/react/components/get_link_modal.jsx +++ b/web/react/components/get_link_modal.jsx @@ -75,7 +75,7 @@ export default class GetLinkModal extends React.Component { onHide={this.onHide} > <Modal.Header closeButton={true}> - {this.props.title} + <h4 className='modal-title'>{this.props.title}</h4> </Modal.Header> <Modal.Body> {helpText} diff --git a/web/react/components/member_list_item.jsx b/web/react/components/member_list_item.jsx index 390d25f2e..f5d5ab28b 100644 --- a/web/react/components/member_list_item.jsx +++ b/web/react/components/member_list_item.jsx @@ -110,7 +110,7 @@ export default class MemberListItem extends React.Component { height='36' width='36' /> - <div className='member-name'>{member.username}</div> + <div className='member-name'>{Utils.displayUsername(member.id)}</div> <div className='member-description'>{member.email}</div> </td> <td className='td--action lg'>{invite}</td> diff --git a/web/react/components/member_list_team_item.jsx b/web/react/components/member_list_team_item.jsx index 27fb6a4c1..316fad01a 100644 --- a/web/react/components/member_list_team_item.jsx +++ b/web/react/components/member_list_team_item.jsx @@ -174,7 +174,7 @@ export default class MemberListTeamItem extends React.Component { height='36' width='36' /> - <span className='member-name'>{Utils.getDisplayName(user)}</span> + <span className='member-name'>{Utils.displayUsername(user.id)}</span> <span className='member-email'>{email}</span> <div className='dropdown member-drop'> <a diff --git a/web/react/components/popover_list_members.jsx b/web/react/components/popover_list_members.jsx index b5000141a..f4cb542e4 100644 --- a/web/react/components/popover_list_members.jsx +++ b/web/react/components/popover_list_members.jsx @@ -5,6 +5,7 @@ import UserStore from '../stores/user_store.jsx'; var Popover = ReactBootstrap.Popover; var Overlay = ReactBootstrap.Overlay; import * as Utils from '../utils/utils.jsx'; +import Constants from '../utils/constants.jsx'; import ChannelStore from '../stores/channel_store.jsx'; @@ -68,7 +69,7 @@ export default class PopoverListMembers extends React.Component { } render() { - let popoverHtml = []; + const popoverHtml = []; const members = this.props.members; const teamMembers = UserStore.getProfilesUsernameMap(); const currentUserId = UserStore.getCurrentId(); @@ -76,35 +77,13 @@ export default class PopoverListMembers extends React.Component { if (members && teamMembers) { members.sort((a, b) => { - return a.username.localeCompare(b.username); + const aName = Utils.displayUsername(a.id); + const bName = Utils.displayUsername(b.id); + + return aName.localeCompare(bName); }); members.forEach((m, i) => { - const details = []; - - const fullName = Utils.getFullName(m); - if (fullName) { - details.push( - <span - key={`${m.id}__full-name`} - className='full-name' - > - {fullName} - </span> - ); - } - - if (m.nickname) { - const separator = fullName ? ' - ' : ''; - details.push( - <span - key={`${m.nickname}__nickname`} - > - {separator + m.nickname} - </span> - ); - } - let button = ''; if (currentUserId !== m.id && ch.type !== 'D') { button = ( @@ -118,7 +97,12 @@ export default class PopoverListMembers extends React.Component { ); } - if (teamMembers[m.username] && teamMembers[m.username].delete_at <= 0) { + let name = ''; + if (teamMembers[m.username]) { + name = Utils.displayUsername(teamMembers[m.username].id); + } + + if (name && teamMembers[m.username].delete_at <= 0) { popoverHtml.push( <div className='text-nowrap' @@ -135,7 +119,7 @@ export default class PopoverListMembers extends React.Component { <div className='more-name' > - {m.username} + {name} </div> </div> <div @@ -157,8 +141,8 @@ export default class PopoverListMembers extends React.Component { count = members.length; } - if (count > 20) { - countText = '20+'; + if (count > Constants.MAX_CHANNEL_POPOVER_COUNT) { + countText = Constants.MAX_CHANNEL_POPOVER_COUNT + '+'; } else if (count > 0) { countText = count.toString(); } diff --git a/web/react/components/post.jsx b/web/react/components/post.jsx index 278261e22..66d8c507a 100644 --- a/web/react/components/post.jsx +++ b/web/react/components/post.jsx @@ -87,6 +87,10 @@ export default class Post extends React.Component { return true; } + if (nextProps.displayNameType !== this.props.displayNameType) { + return true; + } + if (this.getCommentCount(nextProps) !== this.getCommentCount(this.props)) { return true; } @@ -224,5 +228,6 @@ Post.propTypes = { sameRoot: React.PropTypes.bool, hideProfilePic: React.PropTypes.bool, isLastComment: React.PropTypes.bool, - shouldHighlight: React.PropTypes.bool + shouldHighlight: React.PropTypes.bool, + displayNameType: React.PropTypes.string }; diff --git a/web/react/components/posts_view.jsx b/web/react/components/posts_view.jsx index 5e374b877..242b26b91 100644 --- a/web/react/components/posts_view.jsx +++ b/web/react/components/posts_view.jsx @@ -2,15 +2,18 @@ // See License.txt for license information. import UserStore from '../stores/user_store.jsx'; +import PreferenceStore from '../stores/preference_store.jsx'; import * as EventHelpers from '../dispatcher/event_helpers.jsx'; import * as Utils from '../utils/utils.jsx'; import Post from './post.jsx'; import Constants from '../utils/constants.jsx'; +const Preferences = Constants.Preferences; export default class PostsView extends React.Component { constructor(props) { super(props); + this.updateState = this.updateState.bind(this); this.handleScroll = this.handleScroll.bind(this); this.isAtBottom = this.isAtBottom.bind(this); this.loadMorePostsTop = this.loadMorePostsTop.bind(this); @@ -22,6 +25,8 @@ export default class PostsView extends React.Component { this.jumpToPostNode = null; this.wasAtBottom = true; this.scrollHeight = 0; + + this.state = {displayNameType: PreferenceStore.getPreference(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', {value: 'false'}).value}; } static get SCROLL_TYPE_FREE() { return 1; @@ -38,6 +43,9 @@ export default class PostsView extends React.Component { static get SCROLL_TYPE_POST() { return 5; } + updateState() { + this.setState({displayNameType: PreferenceStore.getPreference(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', {value: 'false'}).value}); + } isAtBottom() { return ((this.refs.postlist.scrollHeight - this.refs.postlist.scrollTop) === this.refs.postlist.clientHeight); } @@ -94,22 +102,53 @@ export default class PostsView extends React.Component { const prevPostIsComment = Utils.isComment(prevPost); const postFromWebhook = Boolean(post.props && post.props.from_webhook); const prevPostFromWebhook = Boolean(prevPost.props && prevPost.props.from_webhook); + let prevWebhookName = ''; + if (prevPost.props && prevPost.props.override_username) { + prevWebhookName = prevPost.props.override_username; + } + let curWebhookName = ''; + if (post.props && post.props.override_username) { + curWebhookName = post.props.override_username; + } + + // consider posts from the same user if: + // the previous post was made by the same user as the current post, + // the previous post was made within 5 minutes of the current post, + // the previous post and current post are both from webhooks or both not, + // the previous post and current post have the same webhook usernames + if (prevPost.user_id === post.user_id && + post.create_at - prevPost.create_at <= 1000 * 60 * 5 && + postFromWebhook === prevPostFromWebhook && + prevWebhookName === curWebhookName) { + sameUser = true; + } - sameUser = prevPost.user_id === post.user_id && postFromWebhook === prevPostFromWebhook && - post.create_at - prevPost.create_at <= 1000 * 60 * 5; - sameRoot = (postIsComment && (prevPost.id === post.root_id || prevPost.root_id === post.root_id)) || (!postIsComment && !prevPostIsComment && sameUser); + // consider posts from the same root if: + // the current post is a comment, + // the current post has the same root as the previous post + if (postIsComment && (prevPost.id === post.root_id || prevPost.root_id === post.root_id)) { + sameRoot = true; + } + + // consider posts from the same root if: + // the current post is not a comment, + // the previous post is not a comment, + // the previous post is from the same user + if (!postIsComment && !prevPostIsComment && sameUser) { + sameRoot = true; + } // hide the profile pic if: // the previous post was made by the same user as the current post, // the previous post is not a comment, // the current post is not a comment, - // the current post is not from a webhook - // and the previous post is not from a webhook - if ((prevPost.user_id === post.user_id) && + // the previous post and current post are both from webhooks or both not, + // the previous post and current post have the same webhook usernames + if (prevPost.user_id === post.user_id && !prevPostIsComment && !postIsComment && - !postFromWebhook && - !prevPostFromWebhook) { + postFromWebhook === prevPostFromWebhook && + prevWebhookName === curWebhookName) { hideProfilePic = true; } } @@ -135,6 +174,7 @@ export default class PostsView extends React.Component { isLastComment={isLastComment} shouldHighlight={shouldHighlight} onClick={() => EventHelpers.emitPostFocusEvent(post.id)} //eslint-disable-line no-loop-func + displayNameType={this.state.displayNameType} /> ); @@ -240,16 +280,20 @@ export default class PostsView extends React.Component { this.updateScrolling(); } window.addEventListener('resize', this.handleResize); + $(this.refs.postlist).perfectScrollbar(); + PreferenceStore.addChangeListener(this.updateState); } componentWillUnmount() { window.removeEventListener('resize', this.handleResize); + PreferenceStore.removeChangeListener(this.updateState); } componentDidUpdate() { if (this.props.postList != null) { this.updateScrolling(); } + $(this.refs.postlist).perfectScrollbar('update'); } - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps, nextState) { if (this.props.isActive !== nextProps.isActive) { return true; } @@ -268,6 +312,9 @@ export default class PostsView extends React.Component { if (!Utils.areObjectsEqual(this.props.postList, nextProps.postList)) { return true; } + if (nextState.displayNameType !== this.state.displayNameType) { + return true; + } return false; } @@ -326,7 +373,7 @@ export default class PostsView extends React.Component { return ( <div ref='postlist' - className={'post-list-holder-by-time ' + activeClass} + className={'ps-container post-list-holder-by-time ' + activeClass} onScroll={this.handleScroll} > <div className='post-list__table'> diff --git a/web/react/components/posts_view_container.jsx b/web/react/components/posts_view_container.jsx index 367d3687e..6d6694fec 100644 --- a/web/react/components/posts_view_container.jsx +++ b/web/react/components/posts_view_container.jsx @@ -99,10 +99,12 @@ export default class PostsViewContainer extends React.Component { if (newIndex === -1) { newIndex = channels.length; channels.push(channelId); - postLists[newIndex] = this.getChannelPosts(channelId); atTop[newIndex] = PostStore.getVisibilityAtTop(channelId); } + // make sure we have the latest posts from the store + postLists[newIndex] = this.getChannelPosts(channelId); + this.setState({ currentChannelIndex: newIndex, currentLastViewed: lastViewed, diff --git a/web/react/components/register_app_modal.jsx b/web/react/components/register_app_modal.jsx index 100600c4b..f49b33f73 100644 --- a/web/react/components/register_app_modal.jsx +++ b/web/react/components/register_app_modal.jsx @@ -2,21 +2,57 @@ // See License.txt for license information. import * as Client from '../utils/client.jsx'; +import ModalStore from '../stores/modal_store.jsx'; + +const Modal = ReactBootstrap.Modal; + +import Constants from '../utils/constants.jsx'; +const ActionTypes = Constants.ActionTypes; export default class RegisterAppModal extends React.Component { constructor() { super(); - this.register = this.register.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); this.onHide = this.onHide.bind(this); this.save = this.save.bind(this); + this.updateShow = this.updateShow.bind(this); - this.state = {clientId: '', clientSecret: '', saved: false}; + this.state = { + clientId: '', + clientSecret: '', + saved: false, + show: false + }; } componentDidMount() { - $(ReactDOM.findDOMNode(this)).on('hide.bs.modal', this.onHide); + ModalStore.addModalListener(ActionTypes.TOGGLE_REGISTER_APP_MODAL, this.updateShow); + } + componentWillUnmount() { + ModalStore.removeModalListener(ActionTypes.TOGGLE_REGISTER_APP_MODAL, this.updateShow); + } + updateShow(show) { + if (!show) { + if (this.state.clientId !== '' && !this.state.saved) { + return; + } + + this.setState({ + clientId: '', + clientSecret: '', + saved: false, + homepageError: null, + callbackError: null, + serverError: null, + nameError: null + }); + } + + this.setState({show}); } - register() { + handleSubmit(e) { + e.preventDefault(); + var state = this.state; state.serverError = null; @@ -94,6 +130,7 @@ export default class RegisterAppModal extends React.Component { } var body = ''; + var footer = ''; if (this.state.clientId === '') { body = ( <div className='settings-modal'> @@ -148,24 +185,29 @@ export default class RegisterAppModal extends React.Component { </div> </div> {serverError} - <hr /> - <a - className='btn btn-sm theme pull-right' - href='#' - data-dismiss='modal' - aria-label='Close' - > - {'Cancel'} - </a> - <a - className='btn btn-sm btn-primary pull-right' - onClick={this.register} - > - {'Register'} - </a> </div> </div> ); + + footer = ( + <div> + <button + type='button' + className='btn btn-default' + onClick={() => this.updateShow(false)} + > + {'Cancel'} + </button> + <button + onClick={this.handleSubmit} + type='submit' + className='btn btn-primary' + tabIndex='3' + > + {'Register'} + </button> + </div> + ); } else { var btnClass = ' disabled'; if (this.state.saved) { @@ -173,17 +215,35 @@ export default class RegisterAppModal extends React.Component { } body = ( - <div className='form-group user-settings'> - <h3>{'Your Application Credentials'}</h3> - <br/> - <br/> - <label className='col-sm-12 control-label'>{'Client ID: '}{this.state.clientId}</label> - <label className='col-sm-12 control-label'>{'Client Secret: '}{this.state.clientSecret}</label> + <div className='form-horizontal user-settings'> + <h4 className='padding-bottom x3'>{'Your Application Credentials'}</h4> <br/> + <div className='row'> + <label className='col-sm-4 control-label'>{'Client ID'}</label> + <div className='col-sm-7'> + <input + className='form-control' + type='text' + value={this.state.clientId} + readOnly='true' + /> + </div> + </div> <br/> + <div className='row padding-top x2'> + <label className='col-sm-4 control-label'>{'Client Secret'}</label> + <div className='col-sm-7'> + <input + className='form-control' + type='text' + value={this.state.clientSecret} + readOnly='true' + /> + </div> + </div> <br/> <br/> - <strong>{'Save these somewhere SAFE and SECURE. We can retrieve your Client Id if you lose it, but your Client Secret will be lost forever if you were to lose it.'}</strong> + <strong>{'Save these somewhere SAFE and SECURE. Treat your Client ID as your app\'s username and your Client Secret as the app\'s password.'}</strong> <br/> <br/> <div className='checkbox'> @@ -192,56 +252,50 @@ export default class RegisterAppModal extends React.Component { ref='save' type='checkbox' checked={this.state.saved} - onClick={this.save} - > - {'I have saved both my Client Id and Client Secret somewhere safe'} - </input> + onChange={this.save} + /> + {'I have saved both my Client Id and Client Secret somewhere safe'} </label> </div> - <a - className={'btn btn-sm btn-primary pull-right' + btnClass} - href='#' - data-dismiss='modal' - aria-label='Close' - > - {'Close'} - </a> </div> ); + + footer = ( + <a + className={'btn btn-sm btn-primary pull-right' + btnClass} + href='#' + onClick={(e) => { + e.preventDefault(); + this.updateShow(false); + }} + > + {'Close'} + </a> + ); } return ( - <div - className='modal fade' - ref='modal' - id='register_app' - 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' - > - <span aria-hidden='true'>{'×'}</span> - </button> - <h4 - className='modal-title' - ref='title' - > - {'Developer Applications'} - </h4> - </div> - <div className='modal-body'> - {body} - </div> - </div> - </div> - </div> + <span> + <Modal + show={this.state.show} + onHide={() => this.updateShow(false)} + > + <Modal.Header closeButton={true}> + <Modal.Title>{'Developer Applications'}</Modal.Title> + </Modal.Header> + <form + role='form' + className='form-horizontal' + > + <Modal.Body> + {body} + </Modal.Body> + <Modal.Footer> + {footer} + </Modal.Footer> + </form> + </Modal> + </span> ); } } diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx index 30422ff7d..5c8e73874 100644 --- a/web/react/components/sidebar.jsx +++ b/web/react/components/sidebar.jsx @@ -3,7 +3,6 @@ import NewChannelFlow from './new_channel_flow.jsx'; import MoreDirectChannels from './more_direct_channels.jsx'; -import SearchBox from './search_bar.jsx'; import SidebarHeader from './sidebar_header.jsx'; import UnreadChannelIndicator from './unread_channel_indicator.jsx'; import TutorialTip from './tutorial/tutorial_tip.jsx'; @@ -173,6 +172,10 @@ export default class Sidebar extends React.Component { this.updateScrollbar(); window.addEventListener('resize', this.handleResize); + + if ($(window).width() > 768) { + $('.nav-pills__container').perfectScrollbar(); + } } shouldComponentUpdate(nextProps, nextState) { if (!Utils.areObjectsEqual(nextState, this.state)) { @@ -582,7 +585,6 @@ export default class Sidebar extends React.Component { teamName={TeamStore.getCurrent().name} teamType={TeamStore.getCurrent().type} /> - <SearchBox /> <UnreadChannelIndicator show={this.state.showTopUnread} diff --git a/web/react/components/user_profile.jsx b/web/react/components/user_profile.jsx index 438c0bc82..ea104fedb 100644 --- a/web/react/components/user_profile.jsx +++ b/web/react/components/user_profile.jsx @@ -54,9 +54,11 @@ export default class UserProfile extends React.Component { } } render() { - var name = this.state.profile.username; + var name = Utils.displayUsername(this.state.profile.id); if (this.props.overwriteName) { name = this.props.overwriteName; + } else if (!name) { + name = '...'; } if (this.props.disablePopover) { @@ -107,7 +109,7 @@ export default class UserProfile extends React.Component { rootClose={true} overlay={ <Popover - title={this.state.profile.username} + title={name} id='user-profile-popover' > {dataContent} diff --git a/web/react/components/user_settings/user_settings_developer.jsx b/web/react/components/user_settings/user_settings_developer.jsx index 2d02c255a..01e13be57 100644 --- a/web/react/components/user_settings/user_settings_developer.jsx +++ b/web/react/components/user_settings/user_settings_developer.jsx @@ -3,16 +3,19 @@ import SettingItemMin from '../setting_item_min.jsx'; import SettingItemMax from '../setting_item_max.jsx'; +import * as EventHelpers from '../../dispatcher/event_helpers.jsx'; export default class DeveloperTab extends React.Component { constructor(props) { super(props); + this.register = this.register.bind(this); + this.state = {}; } register() { - $('#user_settings1').modal('hide'); - $('#register_app').modal('show'); + this.props.closeModal(); + EventHelpers.showRegisterAppModal(); } render() { var appSection; @@ -21,7 +24,10 @@ export default class DeveloperTab extends React.Component { var inputs = []; inputs.push( - <div className='form-group'> + <div + key='registerbtn' + className='form-group' + > <div className='col-sm-7'> <a className='btn btn-sm btn-primary' diff --git a/web/react/components/view_image.jsx b/web/react/components/view_image.jsx index 91f4b3bdc..820f8fd8e 100644 --- a/web/react/components/view_image.jsx +++ b/web/react/components/view_image.jsx @@ -423,24 +423,29 @@ export default class ViewImageModal extends React.Component { onClick={this.props.onModalDismissed} > <div - className={'image-wrapper ' + bgClass} - onMouseEnter={this.onMouseEnterImage} - onMouseLeave={this.onMouseLeaveImage} - onClick={(e) => e.stopPropagation()} + className={'image-wrapper'} + onClick={this.props.onModalDismissed} > <div - className={closeButtonClass} - onClick={this.props.onModalDismissed} - /> - {content} - <ViewImagePopoverBar - show={this.state.showFooter} - fileId={this.state.imgId} - totalFiles={this.props.filenames.length} - filename={name} - fileURL={fileUrl} - getPublicLink={this.getPublicLink} - /> + className={bgClass} + onMouseEnter={this.onMouseEnterImage} + onMouseLeave={this.onMouseLeaveImage} + onClick={(e) => e.stopPropagation()} + > + <div + className={closeButtonClass} + onClick={this.props.onModalDismissed} + /> + {content} + <ViewImagePopoverBar + show={this.state.showFooter} + fileId={this.state.imgId} + totalFiles={this.props.filenames.length} + filename={name} + fileURL={fileUrl} + getPublicLink={this.getPublicLink} + /> + </div> </div> {leftArrow} {rightArrow} |