diff options
Diffstat (limited to 'web')
-rw-r--r-- | web/react/components/channel_header.jsx | 41 | ||||
-rw-r--r-- | web/react/components/navbar.jsx | 56 | ||||
-rw-r--r-- | web/react/components/post_body.jsx | 38 | ||||
-rw-r--r-- | web/react/components/rename_channel_modal.jsx | 51 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_forms.scss | 4 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_responsive.scss | 2 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_videos.scss | 2 | ||||
-rw-r--r-- | web/web.go | 2 |
8 files changed, 111 insertions, 85 deletions
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx index a8d4ec100..79c7f90a9 100644 --- a/web/react/components/channel_header.jsx +++ b/web/react/components/channel_header.jsx @@ -276,26 +276,27 @@ export default class ChannelHeader extends React.Component { </li> ); - if (!ChannelStore.isDefault(channel)) { - if (isAdmin) { - dropdownContents.push( - <li - key='rename_channel' - role='presentation' + if (isAdmin) { + dropdownContents.push( + <li + key='rename_channel' + role='presentation' + > + <a + role='menuitem' + href='#' + data-toggle='modal' + data-target='#rename_channel' + data-display={channel.display_name} + data-name={channel.name} + data-channelid={channel.id} > - <a - role='menuitem' - href='#' - data-toggle='modal' - data-target='#rename_channel' - data-display={channel.display_name} - data-name={channel.name} - data-channelid={channel.id} - > - {'Rename '}{channelTerm}{'...'} - </a> - </li> - ); + {'Rename '}{channelTerm}{'...'} + </a> + </li> + ); + + if (!ChannelStore.isDefault(channel)) { dropdownContents.push( <li key='delete_channel' @@ -314,7 +315,9 @@ export default class ChannelHeader extends React.Component { </li> ); } + } + if (!ChannelStore.isDefault(channel)) { dropdownContents.push( <li key='leave_channel' diff --git a/web/react/components/navbar.jsx b/web/react/components/navbar.jsx index af29f219e..7ad1f9305 100644 --- a/web/react/components/navbar.jsx +++ b/web/react/components/navbar.jsx @@ -178,18 +178,35 @@ export default class Navbar extends React.Component { var manageMembersOption; var renameChannelOption; var deleteChannelOption; - if (!isDirect && isAdmin && !ChannelStore.isDefault(channel)) { - manageMembersOption = ( - <li role='presentation'> - <a - role='menuitem' - href='#' - onClick={() => this.setState({showMembersModal: true})} - > - {'Manage Members'} - </a> - </li> - ); + if (!isDirect && isAdmin) { + if (!ChannelStore.isDefault(channel)) { + manageMembersOption = ( + <li role='presentation'> + <a + role='menuitem' + href='#' + onClick={() => this.setState({showMembersModal: true})} + > + {'Manage Members'} + </a> + </li> + ); + + deleteChannelOption = ( + <li role='presentation'> + <a + role='menuitem' + href='#' + data-toggle='modal' + data-target='#delete_channel' + data-title={channel.display_name} + data-channelid={channel.id} + > + {'Delete Channel...'} + </a> + </li> + ); + } renameChannelOption = ( <li role='presentation'> @@ -206,21 +223,6 @@ export default class Navbar extends React.Component { </a> </li> ); - - deleteChannelOption = ( - <li role='presentation'> - <a - role='menuitem' - href='#' - data-toggle='modal' - data-target='#delete_channel' - data-title={channel.display_name} - data-channelid={channel.id} - > - {'Delete Channel...'} - </a> - </li> - ); } var notificationPreferenceOption; diff --git a/web/react/components/post_body.jsx b/web/react/components/post_body.jsx index 617b4b36c..975ac64dc 100644 --- a/web/react/components/post_body.jsx +++ b/web/react/components/post_body.jsx @@ -16,13 +16,13 @@ export default class PostBody extends React.Component { super(props); this.receivedYoutubeData = false; - this.isGifLoading = false; + this.isImgLoading = false; this.handleUserChange = this.handleUserChange.bind(this); this.parseEmojis = this.parseEmojis.bind(this); this.createEmbed = this.createEmbed.bind(this); - this.createGifEmbed = this.createGifEmbed.bind(this); - this.loadGif = this.loadGif.bind(this); + this.createImageEmbed = this.createImageEmbed.bind(this); + this.loadImg = this.loadImg.bind(this); this.createYoutubeEmbed = this.createYoutubeEmbed.bind(this); const linkData = Utils.extractLinks(this.props.post.message); @@ -117,8 +117,12 @@ export default class PostBody extends React.Component { return embed; } - if (link.substring(link.length - 4) === '.gif') { - return this.createGifEmbed(link, this.state.gifLoaded); + for (let i = 0; i < Constants.IMAGE_TYPES.length; i++) { + const imageType = Constants.IMAGE_TYPES[i]; + const suffix = link.substring(link.length - (imageType.length + 1)); + if (suffix === '.' + imageType || suffix === '=' + imageType) { + return this.createImageEmbed(link, this.state.imgLoaded); + } } return null; @@ -135,29 +139,29 @@ export default class PostBody extends React.Component { return false; } - loadGif(src) { - if (this.isGifLoading) { + loadImg(src) { + if (this.isImgLoading) { return; } - this.isGifLoading = true; + this.isImgLoading = true; - const gif = new Image(); - gif.onload = ( + const img = new Image(); + img.onload = ( () => { - this.embed = this.createGifEmbed(src, true); - this.setState({gifLoaded: true}); + this.embed = this.createImageEmbed(src, true); + this.setState({imgLoaded: true}); } ); - gif.src = src; + img.src = src; } - createGifEmbed(link, isLoaded) { + createImageEmbed(link, isLoaded) { if (!isLoaded) { - this.loadGif(link); + this.loadImg(link); return ( <img - className='gif-div placeholder' + className='img-div placeholder' height='500px' /> ); @@ -165,7 +169,7 @@ export default class PostBody extends React.Component { return ( <img - className='gif-div' + className='img-div' src={link} /> ); diff --git a/web/react/components/rename_channel_modal.jsx b/web/react/components/rename_channel_modal.jsx index 9fb3af035..f47009cce 100644 --- a/web/react/components/rename_channel_modal.jsx +++ b/web/react/components/rename_channel_modal.jsx @@ -5,6 +5,7 @@ const Utils = require('../utils/utils.jsx'); const Client = require('../utils/client.jsx'); const AsyncClient = require('../utils/async_client.jsx'); const ChannelStore = require('../stores/channel_store.jsx'); +const Constants = require('../utils/constants.jsx'); export default class RenameChannelModal extends React.Component { constructor(props) { @@ -36,10 +37,10 @@ export default class RenameChannelModal extends React.Component { return; } - let channel = ChannelStore.get(this.state.channelId); + const channel = ChannelStore.get(this.state.channelId); const oldName = channel.name; const oldDisplayName = channel.displayName; - let state = {serverError: ''}; + const state = {serverError: ''}; channel.display_name = this.state.displayName.trim(); if (!channel.display_name) { @@ -60,7 +61,7 @@ export default class RenameChannelModal extends React.Component { state.nameError = 'This field must be less than 22 characters'; state.invalid = true; } else { - let cleanedName = Utils.cleanUpUrlable(channel.name); + const cleanedName = Utils.cleanUpUrlable(channel.name); if (cleanedName === channel.name) { state.nameError = ''; } else { @@ -76,7 +77,7 @@ export default class RenameChannelModal extends React.Component { } Client.updateChannel(channel, - function handleUpdateSuccess() { + () => { $(ReactDOM.findDOMNode(this.refs.modal)).modal('hide'); AsyncClient.getChannel(channel.id); @@ -84,12 +85,12 @@ export default class RenameChannelModal extends React.Component { ReactDOM.findDOMNode(this.refs.displayName).value = ''; ReactDOM.findDOMNode(this.refs.channelName).value = ''; - }.bind(this), - function handleUpdateError(err) { + }, + (err) => { state.serverError = err.message; state.invalid = true; this.setState(state); - }.bind(this) + } ); } onNameChange() { @@ -99,10 +100,12 @@ export default class RenameChannelModal extends React.Component { this.setState({displayName: ReactDOM.findDOMNode(this.refs.displayName).value}); } displayNameKeyUp() { - const displayName = ReactDOM.findDOMNode(this.refs.displayName).value.trim(); - const channelName = Utils.cleanUpUrlable(displayName); - ReactDOM.findDOMNode(this.refs.channelName).value = channelName; - this.setState({channelName: channelName}); + if (this.state.channelName !== Constants.DEFAULT_CHANNEL) { + const displayName = ReactDOM.findDOMNode(this.refs.displayName).value.trim(); + const channelName = Utils.cleanUpUrlable(displayName); + ReactDOM.findDOMNode(this.refs.channelName).value = channelName; + this.setState({channelName: channelName}); + } } handleClose() { this.setState({ @@ -150,6 +153,15 @@ export default class RenameChannelModal extends React.Component { serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>; } + let handleInputLabel = 'Handle'; + let handleInputClass = 'form-control'; + let readOnlyHandleInput = false; + if (this.state.channelName === Constants.DEFAULT_CHANNEL) { + handleInputLabel += ' - Cannot be changed for the default channel'; + handleInputClass += ' disabled-input'; + readOnlyHandleInput = true; + } + return ( <div className='modal fade' @@ -167,15 +179,15 @@ export default class RenameChannelModal extends React.Component { className='close' data-dismiss='modal' > - <span aria-hidden='true'>×</span> - <span className='sr-only'>Close</span> + <span aria-hidden='true'>{'×'}</span> + <span className='sr-only'>{'Close'}</span> </button> - <h4 className='modal-title'>Rename Channel</h4> + <h4 className='modal-title'>{'Rename Channel'}</h4> </div> <form role='form'> <div className='modal-body'> <div className={displayNameClass}> - <label className='control-label'>Display Name</label> + <label className='control-label'>{'Display Name'}</label> <input onKeyUp={this.displayNameKeyUp} onChange={this.onDisplayNameChange} @@ -190,15 +202,16 @@ export default class RenameChannelModal extends React.Component { {displayNameError} </div> <div className={nameClass}> - <label className='control-label'>Handle</label> + <label className='control-label'>{handleInputLabel}</label> <input onChange={this.onNameChange} type='text' - className='form-control' + className={handleInputClass} ref='channelName' placeholder='lowercase alphanumeric's only' value={this.state.channelName} maxLength='64' + readOnly={readOnlyHandleInput} /> {nameError} </div> @@ -210,14 +223,14 @@ export default class RenameChannelModal extends React.Component { className='btn btn-default' data-dismiss='modal' > - Cancel + {'Cancel'} </button> <button onClick={this.handleSubmit} type='submit' className='btn btn-primary' > - Save + {'Save'} </button> </div> </form> diff --git a/web/sass-files/sass/partials/_forms.scss b/web/sass-files/sass/partials/_forms.scss index 2d7b6cd26..685677ad0 100644 --- a/web/sass-files/sass/partials/_forms.scss +++ b/web/sass-files/sass/partials/_forms.scss @@ -43,3 +43,7 @@ margin: 10px 0 0; color: #999; } + +.disabled-input { + background-color: #dddddd !important; +} diff --git a/web/sass-files/sass/partials/_responsive.scss b/web/sass-files/sass/partials/_responsive.scss index 966ae5cd1..a4bdc3e92 100644 --- a/web/sass-files/sass/partials/_responsive.scss +++ b/web/sass-files/sass/partials/_responsive.scss @@ -285,7 +285,7 @@ min-height: 100px; } } - .gif-div { + .img-div { max-width: 100%; } .tip-div { diff --git a/web/sass-files/sass/partials/_videos.scss b/web/sass-files/sass/partials/_videos.scss index bb36b6223..3f15f8f1e 100644 --- a/web/sass-files/sass/partials/_videos.scss +++ b/web/sass-files/sass/partials/_videos.scss @@ -51,7 +51,7 @@ border-left:60px solid rgba(255,255,255,0.4); } -.gif-div { +.img-div { -moz-force-broken-image-icon: 1; position:relative; max-width: 450px; diff --git a/web/web.go b/web/web.go index ffc791cb7..02ceb69ba 100644 --- a/web/web.go +++ b/web/web.go @@ -989,7 +989,7 @@ func incomingWebhook(c *api.Context, w http.ResponseWriter, r *http.Request) { } text := parsedRequest.Text - if len(text) == 0 { + if len(text) == 0 && parsedRequest.Attachments == nil { c.Err = model.NewAppError("incomingWebhook", "No text specified", "") return } |