diff options
Diffstat (limited to 'web')
-rw-r--r-- | web/react/.eslintrc | 4 | ||||
-rw-r--r-- | web/react/components/command_list.jsx | 6 | ||||
-rw-r--r-- | web/react/components/post_info.jsx | 17 | ||||
-rw-r--r-- | web/react/components/post_list.jsx | 8 | ||||
-rw-r--r-- | web/react/components/setting_item_max.jsx | 2 | ||||
-rw-r--r-- | web/react/components/sidebar_header.jsx | 2 | ||||
-rw-r--r-- | web/react/components/user_settings_general.jsx | 237 | ||||
-rw-r--r-- | web/react/components/user_settings_notifications.jsx | 16 | ||||
-rw-r--r-- | web/react/stores/channel_store.jsx | 1 | ||||
-rw-r--r-- | web/react/utils/utils.jsx | 58 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_command-box.scss | 16 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_settings.scss | 5 | ||||
-rw-r--r-- | web/templates/head.html | 2 |
13 files changed, 278 insertions, 96 deletions
diff --git a/web/react/.eslintrc b/web/react/.eslintrc index cdf96905b..ab000e941 100644 --- a/web/react/.eslintrc +++ b/web/react/.eslintrc @@ -39,7 +39,7 @@ "no-unexpected-multiline": 2, "block-scoped-var": 1, - "complexity": [1, 8], + "complexity": [0, 8], "consistent-return": 2, "curly": [2, "all"], "dot-notation": 2, @@ -97,7 +97,7 @@ // Style "array-bracket-spacing": [2, "never"], "brace-style": [2, "1tbs", { "allowSingleLine": false }], - "camelcase": [2, {"properties": "always"}], + "camelcase": [2, {"properties": "never"}], "comma-spacing": [2, {"before": false, "after": true}], "comma-style": [2, "last"], "computed-property-spacing": [2, "never"], diff --git a/web/react/components/command_list.jsx b/web/react/components/command_list.jsx index 5efe98dc6..27264ff6e 100644 --- a/web/react/components/command_list.jsx +++ b/web/react/components/command_list.jsx @@ -48,15 +48,15 @@ module.exports = React.createClass({ if (this.state.suggestions[i].suggestion != this.state.cmd) { suggestions.push( <div key={i} className="command-name" onClick={this.handleClick.bind(this, i)}> - <div className="pull-left"><strong>{ this.state.suggestions[i].suggestion }</strong></div> - <div className="command-desc pull-right">{ this.state.suggestions[i].description }</div> + <div className="command__title"><strong>{ this.state.suggestions[i].suggestion }</strong></div> + <div className="command__desc">{ this.state.suggestions[i].description }</div> </div> ); } } return ( - <div ref="mentionlist" className="command-box" style={{height:(this.state.suggestions.length*37)+2}}> + <div ref="mentionlist" className="command-box" style={{height:(this.state.suggestions.length*56)+2}}> { suggestions } </div> ); diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx index 73e897f62..c80b287a3 100644 --- a/web/react/components/post_info.jsx +++ b/web/react/components/post_info.jsx @@ -43,13 +43,16 @@ export default class PostInfo extends React.Component { if (isOwner) { dropdownContents.push( - <li role='presentation'> + <li + key='editPost' + role='presentation' + > <a href='#' role='menuitem' data-toggle='modal' data-target='#edit_post' - data-refoucsid="#post_textbox" + data-refoucsid='#post_textbox' data-title={type} data-message={post.message} data-postid={post.id} @@ -64,7 +67,10 @@ export default class PostInfo extends React.Component { if (isOwner || isAdmin) { dropdownContents.push( - <li role='presentation'> + <li + key='deletePost' + role='presentation' + > <a href='#' role='menuitem' @@ -83,7 +89,10 @@ export default class PostInfo extends React.Component { if (this.props.allowReply === 'true') { dropdownContents.push( - <li role='presentation'> + <li + key='replyLink' + role='presentation' + > <a className='reply-link theme' href='#' diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index 5b0b1f79a..c1e6e490d 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -401,6 +401,14 @@ export default class PostList extends React.Component { > <i className='fa fa-pencil'></i>Set a description </a> + <a + className='intro-links' + href='#' + data-toggle='modal' + data-target='#channel_invite' + > + <i className='fa fa-user-plus'></i>Invite others to this channel + </a> </div> ); } diff --git a/web/react/components/setting_item_max.jsx b/web/react/components/setting_item_max.jsx index 1599041b0..b978cdb0c 100644 --- a/web/react/components/setting_item_max.jsx +++ b/web/react/components/setting_item_max.jsx @@ -5,6 +5,7 @@ module.exports = React.createClass({ render: function() { var clientError = this.props.client_error ? <div className='form-group'><label className='col-sm-12 has-error'>{ this.props.client_error }</label></div> : null; var server_error = this.props.server_error ? <div className='form-group'><label className='col-sm-12 has-error'>{ this.props.server_error }</label></div> : null; + var extraInfo = this.props.extraInfo ? this.props.extraInfo : null; var inputs = this.props.inputs; @@ -15,6 +16,7 @@ module.exports = React.createClass({ <ul className="setting-list"> <li className="setting-list-item"> {inputs} + {extraInfo} </li> <li className="setting-list-item"> <hr /> diff --git a/web/react/components/sidebar_header.jsx b/web/react/components/sidebar_header.jsx index d5d16816f..af65b7e1d 100644 --- a/web/react/components/sidebar_header.jsx +++ b/web/react/components/sidebar_header.jsx @@ -85,7 +85,7 @@ var NavbarDropdown = React.createClass({ } }); } - teams.push(<li key='newTeam_li'><a key='newTeam_a' href={utils.getWindowLocationOrigin() + '/signup_team' }>Create a New Team</a></li>); + teams.push(<li key='newTeam_li'><a key='newTeam_a' target="_blank" href={utils.getWindowLocationOrigin() + '/signup_team' }>Create a New Team</a></li>); return ( <ul className='nav navbar-nav navbar-right'> diff --git a/web/react/components/user_settings_general.jsx b/web/react/components/user_settings_general.jsx index fed11fbe9..ddd2fb607 100644 --- a/web/react/components/user_settings_general.jsx +++ b/web/react/components/user_settings_general.jsx @@ -11,10 +11,32 @@ var AsyncClient = require('../utils/async_client.jsx'); var utils = require('../utils/utils.jsx'); var assign = require('object-assign'); -module.exports = React.createClass({ - displayName: 'GeneralTab', - submitActive: false, - submitUsername: function(e) { +export default class UserSettingsGeneralTab extends React.Component { + constructor(props) { + super(props); + this.submitActive = false; + + this.submitUsername = this.submitUsername.bind(this); + this.submitNickname = this.submitNickname.bind(this); + this.submitName = this.submitName.bind(this); + this.submitEmail = this.submitEmail.bind(this); + this.submitUser = this.submitUser.bind(this); + this.submitPicture = this.submitPicture.bind(this); + + this.updateUsername = this.updateUsername.bind(this); + this.updateFirstName = this.updateFirstName.bind(this); + this.updateLastName = this.updateLastName.bind(this); + this.updateNickname = this.updateNickname.bind(this); + this.updateEmail = this.updateEmail.bind(this); + this.updatePicture = this.updatePicture.bind(this); + this.updateSection = this.updateSection.bind(this); + + this.handleClose = this.handleClose.bind(this); + this.setupInitialState = this.setupInitialState.bind(this); + + this.state = this.setupInitialState(props); + } + submitUsername(e) { e.preventDefault(); var user = this.props.user; @@ -37,8 +59,8 @@ module.exports = React.createClass({ user.username = username; this.submitUser(user); - }, - submitNickname: function(e) { + } + submitNickname(e) { e.preventDefault(); var user = UserStore.getCurrentUser(); @@ -52,8 +74,8 @@ module.exports = React.createClass({ user.nickname = nickname; this.submitUser(user); - }, - submitName: function(e) { + } + submitName(e) { e.preventDefault(); var user = UserStore.getCurrentUser(); @@ -69,8 +91,8 @@ module.exports = React.createClass({ user.last_name = lastName; this.submitUser(user); - }, - submitEmail: function(e) { + } + submitEmail(e) { e.preventDefault(); var user = UserStore.getCurrentUser(); @@ -88,15 +110,15 @@ module.exports = React.createClass({ user.email = email; this.submitUser(user); - }, - submitUser: function(user) { + } + submitUser(user) { client.updateUser(user, - function() { + function updateSuccess() { this.updateSection(''); AsyncClient.getMe(); }.bind(this), - function(err) { - var state = this.getInitialState(); + function updateFailure(err) { + var state = this.setupInitialState(this.props); if (err.message) { state.serverError = err.message; } else { @@ -105,8 +127,8 @@ module.exports = React.createClass({ this.setState(state); }.bind(this) ); - }, - submitPicture: function(e) { + } + submitPicture(e) { e.preventDefault(); if (!this.state.picture) { @@ -129,34 +151,34 @@ module.exports = React.createClass({ this.setState({loadingPicture: true}); client.uploadProfileImage(formData, - function() { + function imageUploadSuccess() { this.submitActive = false; AsyncClient.getMe(); window.location.reload(); }.bind(this), - function(err) { - var state = this.getInitialState(); + function imageUploadFailure(err) { + var state = this.setupInitialState(this.props); state.serverError = err; this.setState(state); }.bind(this) ); - }, - updateUsername: function(e) { + } + updateUsername(e) { this.setState({username: e.target.value}); - }, - updateFirstName: function(e) { + } + updateFirstName(e) { this.setState({firstName: e.target.value}); - }, - updateLastName: function(e) { + } + updateLastName(e) { this.setState({lastName: e.target.value}); - }, - updateNickname: function(e) { + } + updateNickname(e) { this.setState({nickname: e.target.value}); - }, - updateEmail: function(e) { + } + updateEmail(e) { this.setState({email: e.target.value}); - }, - updatePicture: function(e) { + } + updatePicture(e) { if (e.target.files && e.target.files[0]) { this.setState({picture: e.target.files[0]}); @@ -165,34 +187,33 @@ module.exports = React.createClass({ } else { this.setState({picture: null}); } - }, - updateSection: function(section) { - this.setState(assign({}, this.getInitialState(), {clientError: ''})); + } + updateSection(section) { + this.setState(assign({}, this.setupInitialState(this.props), {clientError: '', serverError: '', emailError: ''})); this.submitActive = false; this.props.updateSection(section); - }, - handleClose: function() { - $(this.getDOMNode()).find('.form-control').each(function() { + } + handleClose() { + $(this.getDOMNode()).find('.form-control').each(function clearForms() { this.value = ''; }); - this.setState(assign({}, this.getInitialState(), {clientError: null, serverError: null, emailError: null})); + this.setState(assign({}, this.setupInitialState(this.props), {clientError: null, serverError: null, emailError: null})); this.props.updateSection(''); - }, - componentDidMount: function() { + } + componentDidMount() { $('#user_settings').on('hidden.bs.modal', this.handleClose); - }, - componentWillUnmount: function() { + } + componentWillUnmount() { $('#user_settings').off('hidden.bs.modal', this.handleClose); - }, - getInitialState: function() { - var user = this.props.user; + } + setupInitialState(props) { + var user = props.user; var emailEnabled = !ConfigStore.getSettingAsBoolean('ByPassEmail', false); - return {username: user.username, firstName: user.first_name, lastName: user.last_name, nickname: user.nickname, - email: user.email, picture: null, loadingPicture: false, emailEnabled: emailEnabled}; - }, - render: function() { + email: user.email, picture: null, loadingPicture: false, emailEnabled: emailEnabled}; + } + render() { var user = this.props.user; var clientError = null; @@ -214,19 +235,35 @@ module.exports = React.createClass({ if (this.props.activeSection === 'name') { inputs.push( - <div className='form-group'> + <div + key='firstNameSetting' + className='form-group' + > <label className='col-sm-5 control-label'>First Name</label> <div className='col-sm-7'> - <input className='form-control' type='text' onChange={this.updateFirstName} value={this.state.firstName}/> + <input + className='form-control' + type='text' + onChange={this.updateFirstName} + value={this.state.firstName} + /> </div> </div> ); inputs.push( - <div className='form-group'> + <div + key='lastNameSetting' + className='form-group' + > <label className='col-sm-5 control-label'>Last Name</label> <div className='col-sm-7'> - <input className='form-control' type='text' onChange={this.updateLastName} value={this.state.lastName}/> + <input + className='form-control' + type='text' + onChange={this.updateLastName} + value={this.state.lastName} + /> </div> </div> ); @@ -238,7 +275,7 @@ module.exports = React.createClass({ submit={this.submitName} server_error={serverError} client_error={clientError} - updateSection={function(e) { + updateSection={function clearSection(e) { self.updateSection(''); e.preventDefault(); }} @@ -259,7 +296,7 @@ module.exports = React.createClass({ <SettingItemMin title='Full Name' describe={fullName} - updateSection={function() { + updateSection={function updateNameSection() { self.updateSection('name'); }} /> @@ -268,11 +305,24 @@ module.exports = React.createClass({ var nicknameSection; if (this.props.activeSection === 'nickname') { + let nicknameLabel = 'Nickname'; + if (utils.isMobile()) { + nicknameLabel = ''; + } + inputs.push( - <div className='form-group'> - <label className='col-sm-5 control-label'>{utils.isMobile() ? '' : 'Nickname'}</label> + <div + key='nicknameSetting' + className='form-group' + > + <label className='col-sm-5 control-label'>{nicknameLabel}</label> <div className='col-sm-7'> - <input className='form-control' type='text' onChange={this.updateNickname} value={this.state.nickname}/> + <input + className='form-control' + type='text' + onChange={this.updateNickname} + value={this.state.nickname} + /> </div> </div> ); @@ -284,7 +334,7 @@ module.exports = React.createClass({ submit={this.submitNickname} server_error={serverError} client_error={clientError} - updateSection={function(e) { + updateSection={function clearSection(e) { self.updateSection(''); e.preventDefault(); }} @@ -295,7 +345,7 @@ module.exports = React.createClass({ <SettingItemMin title='Nickname' describe={UserStore.getCurrentUser().nickname} - updateSection={function() { + updateSection={function updateNicknameSection() { self.updateSection('nickname'); }} /> @@ -304,11 +354,24 @@ module.exports = React.createClass({ var usernameSection; if (this.props.activeSection === 'username') { + let usernameLabel = 'Username'; + if (utils.isMobile()) { + usernameLabel = ''; + } + inputs.push( - <div className='form-group'> - <label className='col-sm-5 control-label'>{utils.isMobile() ? '' : 'Username'}</label> + <div + key='usernameSetting' + className='form-group' + > + <label className='col-sm-5 control-label'>{usernameLabel}</label> <div className='col-sm-7'> - <input className='form-control' type='text' onChange={this.updateUsername} value={this.state.username}/> + <input + className='form-control' + type='text' + onChange={this.updateUsername} + value={this.state.username} + /> </div> </div> ); @@ -320,7 +383,7 @@ module.exports = React.createClass({ submit={this.submitUsername} server_error={serverError} client_error={clientError} - updateSection={function(e) { + updateSection={function clearSection(e) { self.updateSection(''); e.preventDefault(); }} @@ -331,7 +394,7 @@ module.exports = React.createClass({ <SettingItemMin title='Username' describe={UserStore.getCurrentUser().username} - updateSection={function() { + updateSection={function updateUsernameSection() { self.updateSection('username'); }} /> @@ -346,11 +409,16 @@ module.exports = React.createClass({ } inputs.push( - <div> + <div key='emailSetting'> <div className='form-group'> <label className='col-sm-5 control-label'>Primary Email</label> <div className='col-sm-7'> - <input className='form-control' type='text' onChange={this.updateEmail} value={this.state.email}/> + <input + className='form-control' + type='text' + onChange={this.updateEmail} + value={this.state.email} + /> </div> </div> {helpText} @@ -364,7 +432,7 @@ module.exports = React.createClass({ submit={this.submitEmail} server_error={serverError} client_error={emailError} - updateSection={function(e) { + updateSection={function clearSection(e) { self.updateSection(''); e.preventDefault(); }} @@ -375,7 +443,7 @@ module.exports = React.createClass({ <SettingItemMin title='Email' describe={UserStore.getCurrentUser().email} - updateSection={function() { + updateSection={function updateEmailSection() { self.updateSection('email'); }} /> @@ -391,7 +459,7 @@ module.exports = React.createClass({ src={'/api/v1/users/' + user.id + '/image?time=' + user.last_picture_update} server_error={serverError} client_error={clientError} - updateSection={function(e) { + updateSection={function clearSection(e) { self.updateSection(''); e.preventDefault(); }} @@ -410,7 +478,7 @@ module.exports = React.createClass({ <SettingItemMin title='Profile Picture' describe={minMessage} - updateSection={function() { + updateSection={function updatePictureSection() { self.updateSection('picture'); }} /> @@ -419,8 +487,21 @@ module.exports = React.createClass({ return ( <div> <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'><i className='modal-back'></i>General Settings</h4> + <button + type='button' + className='close' + data-dismiss='modal' + aria-label='Close' + > + <span aria-hidden='true'>×</span> + </button> + <h4 + className='modal-title' + ref='title' + > + <i className='modal-back'></i> + General Settings + </h4> </div> <div className='user-settings'> <h3 className='tab-header'>General Settings</h3> @@ -439,4 +520,10 @@ module.exports = React.createClass({ </div> ); } -}); +} + +UserSettingsGeneralTab.propTypes = { + user: React.PropTypes.object, + updateSection: React.PropTypes.func, + activeSection: React.PropTypes.string +}; diff --git a/web/react/components/user_settings_notifications.jsx b/web/react/components/user_settings_notifications.jsx index b89f72987..ba0bda78e 100644 --- a/web/react/components/user_settings_notifications.jsx +++ b/web/react/components/user_settings_notifications.jsx @@ -1,6 +1,7 @@ // 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'); @@ -67,7 +68,11 @@ function getNotificationsStateFromStores() { } } - 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}; + 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}; } export default class NotificationsTab extends React.Component { @@ -141,10 +146,12 @@ 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(''); } @@ -265,6 +272,12 @@ export default class NotificationsTab extends React.Component { e.preventDefault(); }; + 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' @@ -272,6 +285,7 @@ export default class NotificationsTab extends React.Component { submit={this.handleSubmit} server_error={serverError} updateSection={handleUpdateDesktopSection} + extraInfo={extraInfo} /> ); } else { diff --git a/web/react/stores/channel_store.jsx b/web/react/stores/channel_store.jsx index f7c23841c..678d50bbd 100644 --- a/web/react/stores/channel_store.jsx +++ b/web/react/stores/channel_store.jsx @@ -270,4 +270,5 @@ ChannelStore.dispatchToken = AppDispatcher.register(function(payload) { } }); +ChannelStore.setMaxListeners(11); module.exports = ChannelStore; diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 5266b1381..a1dc72ae2 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -260,10 +260,40 @@ module.exports.escapeRegExp = function(string) { return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); }; +function handleYoutubeTime(link) { + var timeRegex = /[\\?&]t=([0-9hms]+)/; + + var time = link.trim().match(timeRegex); + if (!time || !time[1]) { + return ''; + } + + var hours = time[1].match(/([0-9]+)h/); + var minutes = time[1].match(/([0-9]+)m/); + var seconds = time[1].match(/([0-9]+)s/); + + var ticks = 0; + + if (hours && hours[1]) { + ticks += parseInt(hours[1], 10) * 3600; + } + + if (minutes && minutes[1]) { + ticks += parseInt(minutes[1], 10) * 60; + } + + if (seconds && seconds[1]) { + ticks += parseInt(seconds[1], 10); + } + + return '&start=' + ticks.toString(); +} + function getYoutubeEmbed(link) { var regex = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|watch\?(?:[a-zA-Z-_]+=[a-zA-Z0-9-_]+&)+v=)([^#\&\?]*).*/; var youtubeId = link.trim().match(regex)[1]; + var time = handleYoutubeTime(link); function onClick(e) { var div = $(e.target).closest('.video-thumbnail__container')[0]; @@ -271,7 +301,8 @@ function getYoutubeEmbed(link) { iframe.setAttribute('src', 'https://www.youtube.com/embed/' + div.id + - '?autoplay=1&autohide=1&border=0&wmode=opaque&fs=1&enablejsapi=1'); + '?autoplay=1&autohide=1&border=0&wmode=opaque&fs=1&enablejsapi=1' + + time); iframe.setAttribute('width', '480px'); iframe.setAttribute('height', '360px'); iframe.setAttribute('type', 'text/html'); @@ -286,6 +317,7 @@ function getYoutubeEmbed(link) { return; } var metadata = data.items[0].snippet; + $('.video-type.' + youtubeId).html("Youtube - ") $('.video-uploader.' + youtubeId).html(metadata.channelTitle); $('.video-title.' + youtubeId).find('a').html(metadata.title); $('.post-list-holder-by-time').scrollTop($('.post-list-holder-by-time')[0].scrollHeight); @@ -303,9 +335,11 @@ function getYoutubeEmbed(link) { return ( <div className='post-comment'> - <h4 className='video-type'>YouTube</h4> + <h4> + <span className={'video-type ' + youtubeId}>YouTube</span> + <span className={'video-title ' + youtubeId}><a href={link}></a></span> + </h4> <h4 className={'video-uploader ' + youtubeId}></h4> - <h4 className={'video-title ' + youtubeId}><a href={link}></a></h4> <div className='video-div embed-responsive-item' id={youtubeId} onClick={onClick}> <div className='embed-responsive embed-responsive-4by3 video-div__placeholder'> <div id={youtubeId} className='video-thumbnail__container'> @@ -456,9 +490,21 @@ module.exports.textToJsx = function(text, options) { var mentionRegex = /^(?:@)([a-z0-9_]+)$/gi; // looks loop invariant but a weird JS bug needs it to be redefined here var explicitMention = mentionRegex.exec(trimWord); - if ((trimWord.toLowerCase().indexOf(searchTerm) > -1 || word.toLowerCase().indexOf(searchTerm) > -1) && searchTerm != '') { - - highlightSearchClass = ' search-highlight'; + if (searchTerm !== '') { + let searchWords = searchTerm.split(' '); + for (let idx in searchWords) { + let searchWord = searchWords[idx]; + if (searchWord === word.toLowerCase() || searchWord === trimWord.toLowerCase()) { + highlightSearchClass = ' search-highlight'; + break; + } else if (searchWord.charAt(searchWord.length - 1) === '*') { + let searchWordPrefix = searchWord.slice(0,-1); + if (trimWord.toLowerCase().indexOf(searchWordPrefix) > -1 || word.toLowerCase().indexOf(searchWordPrefix) > -1) { + highlightSearchClass = ' search-highlight'; + break; + } + } + } } if (explicitMention && diff --git a/web/sass-files/sass/partials/_command-box.scss b/web/sass-files/sass/partials/_command-box.scss index 44eb9b8df..565296fae 100644 --- a/web/sass-files/sass/partials/_command-box.scss +++ b/web/sass-files/sass/partials/_command-box.scss @@ -4,20 +4,30 @@ width: 100%; border: $border-gray; bottom: 38px; + overflow: auto; @extend %popover-box-shadow; + .sidebar--right & { + bottom: 100px; + } } .command-name { position: relative; width: 100%; background-color: #fff; - height: 37px; - line-height: 37px; - padding: 2px 10px 2px 5px; + line-height: 24px; + padding: 5px 10px 8px; z-index: 101; + font-size: 0.95em; + border-bottom: 1px solid #ddd; &:hover { background-color: #e8eaed; } + .command__desc { + margin-left: 5px; + color: #999; + line-height: normal; + } } .command-desc { diff --git a/web/sass-files/sass/partials/_settings.scss b/web/sass-files/sass/partials/_settings.scss index 99a7eb7bc..8d743dfe2 100644 --- a/web/sass-files/sass/partials/_settings.scss +++ b/web/sass-files/sass/partials/_settings.scss @@ -94,6 +94,11 @@ list-style-type:none; } + .setting-list__hint { + color: #555; + margin-top: 20px; + } + .mentions-input { margin-top: 10px; } diff --git a/web/templates/head.html b/web/templates/head.html index c27597f82..6b6b7f09d 100644 --- a/web/templates/head.html +++ b/web/templates/head.html @@ -7,7 +7,7 @@ <!-- iOS add to homescreen --> <meta name="apple-mobile-web-app-capable" content="yes" /> - <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> + <meta name="apple-mobile-web-app-status-bar-style" content="default"> <meta name="mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-title" content="{{ .Title }}"> <meta name="application-name" content="{{ .Title }}"> |