From 58c33f01d563d729e5fa5f8f037369210f8a1962 Mon Sep 17 00:00:00 2001 From: JoramWilander Date: Fri, 16 Oct 2015 08:16:34 -0400 Subject: Add default username and icon to incoming webhooks. --- model/webhook.go | 5 +++++ web/static/images/webhook_icon.jpg | Bin 0 -> 68190 bytes web/web.go | 16 ++++++++++++---- 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 web/static/images/webhook_icon.jpg diff --git a/model/webhook.go b/model/webhook.go index 3bf034908..9b9969b96 100644 --- a/model/webhook.go +++ b/model/webhook.go @@ -8,6 +8,11 @@ import ( "io" ) +const ( + DEFAULT_WEBHOOK_USERNAME = "webhook" + DEFAULT_WEBHOOK_ICON = "/static/images/webhook_icon.jpg" +) + type IncomingWebhook struct { Id string `json:"id"` CreateAt int64 `json:"create_at"` diff --git a/web/static/images/webhook_icon.jpg b/web/static/images/webhook_icon.jpg new file mode 100644 index 000000000..af5303421 Binary files /dev/null and b/web/static/images/webhook_icon.jpg differ diff --git a/web/web.go b/web/web.go index 7ab50a073..00e00b3b9 100644 --- a/web/web.go +++ b/web/web.go @@ -971,12 +971,20 @@ func incomingWebhook(c *api.Context, w http.ResponseWriter, r *http.Request) { post := &model.Post{UserId: hook.UserId, ChannelId: channel.Id, Message: text} post.AddProp("from_webhook", "true") - if len(overrideUsername) != 0 && utils.Cfg.ServiceSettings.EnablePostUsernameOverride { - post.AddProp("override_username", overrideUsername) + if utils.Cfg.ServiceSettings.EnablePostUsernameOverride { + if len(overrideUsername) != 0 { + post.AddProp("override_username", overrideUsername) + } else { + post.AddProp("override_username", model.DEFAULT_WEBHOOK_USERNAME) + } } - if len(overrideIconUrl) != 0 && utils.Cfg.ServiceSettings.EnablePostIconOverride { - post.AddProp("override_icon_url", overrideIconUrl) + if utils.Cfg.ServiceSettings.EnablePostIconOverride { + if len(overrideIconUrl) != 0 { + post.AddProp("override_icon_url", overrideIconUrl) + } else { + post.AddProp("override_icon_url", model.DEFAULT_WEBHOOK_ICON) + } } if !c.HasPermissionsToChannel(pchan, "createIncomingHook") && channel.Type != model.CHANNEL_OPEN { -- cgit v1.2.3-1-g7c22 From 5832f10bb98549aa4b9e8cd8b100d3972eadb78c Mon Sep 17 00:00:00 2001 From: hmhealey Date: Fri, 16 Oct 2015 09:55:50 -0400 Subject: Fixed preference test that was failing --- api/preference_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/preference_test.go b/api/preference_test.go index 9d3db9e2f..eaa92fe47 100644 --- a/api/preference_test.go +++ b/api/preference_test.go @@ -60,9 +60,10 @@ func TestGetAllPreferences(t *testing.T) { Client.LoginByEmail(team.Name, user2.Email, "pwd") + // note that user2 will automatically have a preference set for them to show user1 for direct messages if result, err := Client.GetAllPreferences(); err != nil { t.Fatal(err) - } else if data := result.Data.(model.Preferences); len(data) != 0 { + } else if data := result.Data.(model.Preferences); len(data) != 1 { t.Fatal("received the wrong number of preferences") } } -- cgit v1.2.3-1-g7c22 From 3c593af598b2bb986244099ed1b9a46ed3837911 Mon Sep 17 00:00:00 2001 From: it33 Date: Fri, 16 Oct 2015 07:19:18 -0700 Subject: Adding single-line Docker install --- doc/install/Docker-Single-Container.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/install/Docker-Single-Container.md b/doc/install/Docker-Single-Container.md index 4b952cd71..7c0784ad0 100644 --- a/doc/install/Docker-Single-Container.md +++ b/doc/install/Docker-Single-Container.md @@ -2,6 +2,13 @@ The following install instructions are for single-container installs of Mattermost using Docker for exploring product functionality and upgrading to newer versions. +### One-line Docker Install ### + +If you have Docker set up, Mattermost installs in one-line: +`docker run --name mattermost-dev -d --publish 8065:80 mattermost/platform` + +Otherwise, see step-by-step available: + ### Mac OSX ### 1. Install Docker Toolbox using instructions at: http://docs.docker.com/installation/mac/ -- cgit v1.2.3-1-g7c22 From 495673d80d75ddfc97dc8d9fe61021142418dcc2 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Fri, 16 Oct 2015 10:15:52 -0400 Subject: Fixing some client warnings --- .../components/admin_console/email_settings.jsx | 8 ++- .../components/admin_console/log_settings.jsx | 18 +++--- web/react/components/edit_post_modal.jsx | 4 +- web/react/components/popover_list_members.jsx | 24 ++++++-- web/react/components/post_info.jsx | 2 +- web/react/components/rhs_comment.jsx | 26 +++++---- web/react/components/sidebar.jsx | 20 ++++--- web/react/components/user_profile.jsx | 37 ++++++++---- .../user_settings/user_settings_appearance.jsx | 10 ++-- .../user_settings/user_settings_display.jsx | 21 +++---- .../user_settings/user_settings_notifications.jsx | 65 +++++++++------------- 11 files changed, 132 insertions(+), 103 deletions(-) diff --git a/web/react/components/admin_console/email_settings.jsx b/web/react/components/admin_console/email_settings.jsx index 01759b222..40e00ff04 100644 --- a/web/react/components/admin_console/email_settings.jsx +++ b/web/react/components/admin_console/email_settings.jsx @@ -440,9 +440,11 @@ export default class EmailSettings extends React.Component { className='table table-bordered' cellPadding='5' > - {'None'}{'Mattermost will send email over an unsecure connection.'} - {'TLS'}{'Encrypts the communication between Mattermost and your email server.'} - {'STARTTLS'}{'Takes an existing insecure connection and attempts to upgrade it to a secure connection using TLS.'} + + {'None'}{'Mattermost will send email over an unsecure connection.'} + {'TLS'}{'Encrypts the communication between Mattermost and your email server.'} + {'STARTTLS'}{'Takes an existing insecure connection and attempts to upgrade it to a secure connection using TLS.'} +
diff --git a/web/react/components/admin_console/log_settings.jsx b/web/react/components/admin_console/log_settings.jsx index 931818bb8..7e9eda89b 100644 --- a/web/react/components/admin_console/log_settings.jsx +++ b/web/react/components/admin_console/log_settings.jsx @@ -249,22 +249,24 @@ export default class LogSettings extends React.Component { onChange={this.handleChange} disabled={!this.state.fileEnable} /> -

+

{'Format of log message output. If blank will be set to "[%D %T] [%L] %M", where:'}
- - - - - - + + + + + + + +
{'%T'}{'Time (15:04:05 MST)'}
{'%D'}{'Date (2006/01/02)'}
{'%d'}{'Date (01/02/06)'}
{'%L'}{'Level (DEBG, INFO, EROR)'}
{'%S'}{'Source'}
{'%M'}{'Message'}
{'%T'}{'Time (15:04:05 MST)'}
{'%D'}{'Date (2006/01/02)'}
{'%d'}{'Date (01/02/06)'}
{'%L'}{'Level (DEBG, INFO, EROR)'}
{'%S'}{'Source'}
{'%M'}{'Message'}
-

+
diff --git a/web/react/components/edit_post_modal.jsx b/web/react/components/edit_post_modal.jsx index 90d9696e7..b259b3c18 100644 --- a/web/react/components/edit_post_modal.jsx +++ b/web/react/components/edit_post_modal.jsx @@ -70,7 +70,7 @@ export default class EditPostModal extends React.Component { refocusId: options.refocusId || '' }); - $(React.findDOMNode(this.refs.modal)).modal('show'); + $(ReactDOM.findDOMNode(this.refs.modal)).modal('show'); } componentDidMount() { var self = this; @@ -92,7 +92,7 @@ export default class EditPostModal extends React.Component { $('#edit_textbox').get(0).focus(); }); - $(React.findDOMNode(this.refs.modal)).on('hide.bs.modal', function onShown() { + $(ReactDOM.findDOMNode(this.refs.modal)).on('hide.bs.modal', function onShown() { if (self.state.refocusId !== '') { setTimeout(() => { $(self.state.refocusId).get(0).focus(); diff --git a/web/react/components/popover_list_members.jsx b/web/react/components/popover_list_members.jsx index 16ae693fa..155e88600 100644 --- a/web/react/components/popover_list_members.jsx +++ b/web/react/components/popover_list_members.jsx @@ -35,13 +35,20 @@ export default class PopoverListMembers extends React.Component { const teamMembers = UserStore.getProfilesUsernameMap(); if (members && teamMembers) { - members.sort(function compareByLocal(a, b) { + members.sort((a, b) => { return a.username.localeCompare(b.username); }); - members.forEach(function addMemberElement(m) { + members.forEach((m, i) => { if (teamMembers[m.username] && teamMembers[m.username].delete_at <= 0) { - popoverHtml.push(
{m.username}
); + popoverHtml.push( +
+ {m.username} +
+ ); count++; } }); @@ -57,8 +64,15 @@ export default class PopoverListMembers extends React.Component { {popoverHtml}} + rootClose={true} + overlay={ + + {popoverHtml} + + } >
diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx index a95095ff6..36260d77c 100644 --- a/web/react/components/post_info.jsx +++ b/web/react/components/post_info.jsx @@ -150,7 +150,7 @@ export default class PostInfo extends React.Component {
  • { AsyncClient.getPosts(post.channel_id); var channel = ChannelStore.get(post.channel_id); @@ -43,11 +43,11 @@ export default class RhsComment extends React.Component { post: data }); }, - function fail() { + () => { post.state = Constants.POST_FAILED; PostStore.updatePendingPost(post); this.forceUpdate(); - }.bind(this) + } ); post.state = Constants.POST_LOADING; @@ -84,7 +84,10 @@ export default class RhsComment extends React.Component { if (isOwner) { dropdownContents.push( -
  • +
  • - Edit + {'Edit'}
  • ); @@ -103,7 +106,10 @@ export default class RhsComment extends React.Component { if (isOwner || isAdmin) { dropdownContents.push( -
  • +
  • - Delete + {'Delete'}
  • ); @@ -162,7 +168,7 @@ export default class RhsComment extends React.Component { href='#' onClick={this.retryComment} > - Retry + {'Retry'} ); } else if (post.state === Constants.POST_LOADING) { @@ -213,14 +219,14 @@ export default class RhsComment extends React.Component {
-

+

{loading}
-

+
{fileAttachment}
diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx index 89506c028..889bc0fbd 100644 --- a/web/react/components/sidebar.jsx +++ b/web/react/components/sidebar.jsx @@ -46,7 +46,7 @@ export default class Sidebar extends React.Component { const state = this.getStateFromStores(); state.newChannelModalType = ''; - state.showMoreDirectChannelsModal = false; + state.showDirectChannelsModal = false; state.loadingDMChannel = -1; this.state = state; @@ -471,11 +471,13 @@ export default class Sidebar extends React.Component { } let closeButton = null; - const removeTooltip = {'Remove from list'}; + const removeTooltip = ( + {'Remove from list'} + ); if (handleClose && !badge) { closeButton = ( @@ -564,8 +566,12 @@ export default class Sidebar extends React.Component { showChannelModal = true; } - const createChannelTootlip = {'Create new channel'}; - const createGroupTootlip = {'Create new group'}; + const createChannelTootlip = ( + {'Create new channel'} + ); + const createGroupTootlip = ( + {'Create new group'} + ); return (
@@ -607,7 +613,7 @@ export default class Sidebar extends React.Component {

{'Channels'} @@ -640,7 +646,7 @@ export default class Sidebar extends React.Component {

{'Private Groups'} diff --git a/web/react/components/user_profile.jsx b/web/react/components/user_profile.jsx index 715161b4f..da0c1aaf9 100644 --- a/web/react/components/user_profile.jsx +++ b/web/react/components/user_profile.jsx @@ -65,19 +65,29 @@ export default class UserProfile extends React.Component { var dataContent = []; dataContent.push( - ); if (!global.window.config.ShowEmailAddress === 'true') { - dataContent.push(
{'Email not shared'}
); + dataContent.push( +
+ {'Email not shared'} +
+ ); } else { dataContent.push( @@ -164,9 +163,8 @@ export default class UserSettingsAppearance extends React.Component { - {'Custom Theme'} - + /> + {'Custom Theme'}

diff --git a/web/react/components/user_settings/user_settings_display.jsx b/web/react/components/user_settings/user_settings_display.jsx index ec209c218..22a62273c 100644 --- a/web/react/components/user_settings/user_settings_display.jsx +++ b/web/react/components/user_settings/user_settings_display.jsx @@ -1,7 +1,7 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import { savePreferences } from '../../utils/client.jsx'; +import {savePreferences} from '../../utils/client.jsx'; import SettingItemMin from '../setting_item_min.jsx'; import SettingItemMax from '../setting_item_max.jsx'; import Constants from '../../utils/constants.jsx'; @@ -38,7 +38,7 @@ export default class UserSettingsDisplay extends React.Component { ); } handleClockRadio(militaryTime) { - this.setState({militaryTime: militaryTime}); + this.setState({militaryTime}); } updateSection(section) { this.setState(getDisplayStateFromStores()); @@ -57,7 +57,7 @@ export default class UserSettingsDisplay extends React.Component { const serverError = this.state.serverError || null; let clockSection; if (this.props.activeSection === 'clock') { - let clockFormat = [false, false]; + const clockFormat = [false, false]; if (this.state.militaryTime === 'true') { clockFormat[1] = true; } else { @@ -77,9 +77,8 @@ export default class UserSettingsDisplay extends React.Component { type='radio' checked={clockFormat[0]} onChange={this.handleClockRadio.bind(this, 'false')} - > - 12-hour clock (example: 4:00 PM) - + /> + {'12-hour clock (example: 4:00 PM)'}
@@ -89,9 +88,8 @@ export default class UserSettingsDisplay extends React.Component { type='radio' checked={clockFormat[1]} onChange={this.handleClockRadio.bind(this, 'true')} - > - 24-hour clock (example: 16:00) - + /> + {'24-hour clock (example: 16:00)'}
@@ -99,7 +97,6 @@ export default class UserSettingsDisplay extends React.Component { ]; - clockSection = ( + >

+ > {'Display Settings'}

diff --git a/web/react/components/user_settings/user_settings_notifications.jsx b/web/react/components/user_settings/user_settings_notifications.jsx index 4dbb9b96f..8693af494 100644 --- a/web/react/components/user_settings/user_settings_notifications.jsx +++ b/web/react/components/user_settings/user_settings_notifications.jsx @@ -228,9 +228,8 @@ export default class NotificationsTab extends React.Component { - For all activity - + /> + {'For all activity'}
@@ -240,9 +239,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={notifyActive[1]} onChange={this.handleNotifyRadio.bind(this, 'mention')} - > - Only for mentions and direct messages - + /> + {'Only for mentions and direct messages'}
@@ -252,9 +250,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={notifyActive[2]} onChange={this.handleNotifyRadio.bind(this, 'none')} - > - Never - + /> + {'Never'} @@ -320,9 +317,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={soundActive[0]} onChange={this.handleSoundRadio.bind(this, 'true')} - > - On - + /> + {'On'}
@@ -332,9 +328,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={soundActive[1]} onChange={this.handleSoundRadio.bind(this, 'false')} - > - Off - + /> + {'Off'}
@@ -402,9 +397,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={emailActive[0]} onChange={this.handleEmailRadio.bind(this, 'true')} - > - On - + /> + {'On'}
@@ -414,9 +408,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={emailActive[1]} onChange={this.handleEmailRadio.bind(this, 'false')} - > - Off - + /> + {'Off'}
@@ -482,9 +475,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.firstNameKey} onChange={handleUpdateFirstNameKey} - > - {'Your case sensitive first name "' + user.first_name + '"'} - + /> + {'Your case sensitive first name "' + user.first_name + '"'} @@ -502,9 +494,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.usernameKey} onChange={handleUpdateUsernameKey} - > - {'Your non-case sensitive username "' + user.username + '"'} - + /> + {'Your non-case sensitive username "' + user.username + '"'} @@ -521,9 +512,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.mentionKey} onChange={handleUpdateMentionKey} - > - {'Your username mentioned "@' + user.username + '"'} - + /> + {'Your username mentioned "@' + user.username + '"'} @@ -540,9 +530,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.allKey} onChange={handleUpdateAllKey} - > - {'Team-wide mentions "@all"'} - + /> + {'Team-wide mentions "@all"'} @@ -559,9 +548,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.channelKey} onChange={handleUpdateChannelKey} - > - {'Channel-wide mentions "@channel"'} - + /> + {'Channel-wide mentions "@channel"'} @@ -576,9 +564,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.customKeysChecked} onChange={this.updateCustomMentionKeys} - > - {'Other non-case sensitive words, separated by commas:'} - + /> + {'Other non-case sensitive words, separated by commas:'}