summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/react/components/channel_header.jsx7
-rw-r--r--web/react/components/sidebar.jsx2
-rw-r--r--web/react/components/user_settings/manage_outgoing_hooks.jsx39
-rw-r--r--web/react/components/user_settings/user_settings_display.jsx100
-rw-r--r--web/react/components/user_settings/user_settings_integrations.jsx2
-rw-r--r--web/react/utils/utils.jsx19
6 files changed, 146 insertions, 23 deletions
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx
index 101fd85e5..20f106f30 100644
--- a/web/react/components/channel_header.jsx
+++ b/web/react/components/channel_header.jsx
@@ -4,6 +4,7 @@
const ChannelStore = require('../stores/channel_store.jsx');
const UserStore = require('../stores/user_store.jsx');
const SearchStore = require('../stores/search_store.jsx');
+const PreferenceStore = require('../stores/preference_store.jsx');
const NavbarSearchBox = require('./search_bar.jsx');
const AsyncClient = require('../utils/async_client.jsx');
const Client = require('../utils/client.jsx');
@@ -46,12 +47,14 @@ export default class ChannelHeader extends React.Component {
ChannelStore.addExtraInfoChangeListener(this.onListenerChange);
SearchStore.addSearchChangeListener(this.onListenerChange);
UserStore.addChangeListener(this.onListenerChange);
+ PreferenceStore.addChangeListener(this.onListenerChange);
}
componentWillUnmount() {
ChannelStore.removeChangeListener(this.onListenerChange);
ChannelStore.removeExtraInfoChangeListener(this.onListenerChange);
SearchStore.removeSearchChangeListener(this.onListenerChange);
- UserStore.addChangeListener(this.onListenerChange);
+ UserStore.removeChangeListener(this.onListenerChange);
+ PreferenceStore.removeChangeListener(this.onListenerChange);
}
onListenerChange() {
const newState = this.getStateFromStores();
@@ -134,7 +137,7 @@ export default class ChannelHeader extends React.Component {
} else {
contact = this.state.users[0];
}
- channelTitle = contact.nickname || contact.username;
+ channelTitle = Utils.displayUsername(contact.id);
}
}
diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 88753556c..023955e97 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -136,7 +136,7 @@ export default class Sidebar extends React.Component {
channel.type = 'D';
}
- channel.display_name = teammate.username;
+ channel.display_name = Utils.displayUsername(teammate.id);
channel.teammate_id = teammate.id;
channel.status = UserStore.getStatus(teammate.id);
diff --git a/web/react/components/user_settings/manage_outgoing_hooks.jsx b/web/react/components/user_settings/manage_outgoing_hooks.jsx
index 9b0701583..93be988d1 100644
--- a/web/react/components/user_settings/manage_outgoing_hooks.jsx
+++ b/web/react/components/user_settings/manage_outgoing_hooks.jsx
@@ -1,10 +1,12 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
-var Client = require('../../utils/client.jsx');
-var Constants = require('../../utils/constants.jsx');
-var ChannelStore = require('../../stores/channel_store.jsx');
-var LoadingScreen = require('../loading_screen.jsx');
+const LoadingScreen = require('../loading_screen.jsx');
+
+const ChannelStore = require('../../stores/channel_store.jsx');
+
+const Client = require('../../utils/client.jsx');
+const Constants = require('../../utils/constants.jsx');
export default class ManageOutgoingHooks extends React.Component {
constructor() {
@@ -44,10 +46,10 @@ export default class ManageOutgoingHooks extends React.Component {
hooks = [];
}
hooks.push(data);
- this.setState({hooks, serverError: null, channelId: '', triggerWords: '', callbackURLs: ''});
+ this.setState({hooks, addError: null, channelId: '', triggerWords: '', callbackURLs: ''});
},
(err) => {
- this.setState({serverError: err});
+ this.setState({addError: err.message});
}
);
}
@@ -74,7 +76,7 @@ export default class ManageOutgoingHooks extends React.Component {
this.setState({hooks});
},
(err) => {
- this.setState({serverError: err});
+ this.setState({editError: err.message});
}
);
}
@@ -93,10 +95,10 @@ export default class ManageOutgoingHooks extends React.Component {
}
}
- this.setState({hooks, serverError: null});
+ this.setState({hooks, editError: null});
},
(err) => {
- this.setState({serverError: err});
+ this.setState({editError: err.message});
}
);
}
@@ -104,11 +106,11 @@ export default class ManageOutgoingHooks extends React.Component {
Client.listOutgoingHooks(
(data) => {
if (data) {
- this.setState({hooks: data, getHooksComplete: true, serverError: null});
+ this.setState({hooks: data, getHooksComplete: true, editError: null});
}
},
(err) => {
- this.setState({serverError: err});
+ this.setState({editError: err.message});
}
);
}
@@ -122,9 +124,13 @@ export default class ManageOutgoingHooks extends React.Component {
this.setState({callbackURLs: e.target.value});
}
render() {
- let serverError;
- if (this.state.serverError) {
- serverError = <label className='has-error'>{this.state.serverError}</label>;
+ let addError;
+ if (this.state.addError) {
+ addError = <label className='has-error'>{this.state.addError}</label>;
+ }
+ let editError;
+ if (this.state.editError) {
+ addError = <label className='has-error'>{this.state.editError}</label>;
}
const channels = ChannelStore.getAll();
@@ -234,6 +240,7 @@ export default class ManageOutgoingHooks extends React.Component {
return (
<div key='addOutgoingHook'>
+ {'Create webhooks to send new message events to an external integration. Please see '}<a href='http://mattermost.org/webhooks'>{'http://mattermost.org/webhooks'}</a> {' to learn more.'}
<label className='control-label'>{'Add a new outgoing webhook'}</label>
<div className='padding-top divider-light'></div>
<div className='padding-top'>
@@ -274,10 +281,11 @@ export default class ManageOutgoingHooks extends React.Component {
resize={false}
rows={3}
onChange={this.updateCallbackURLs}
+ placeholder='Each URL must start with http:// or https://'
/>
</div>
<div className='padding-top'>{'New line separated URLs that will receive the HTTP POST event'}</div>
- {serverError}
+ {addError}
</div>
<div className='padding-top padding-bottom'>
<a
@@ -291,6 +299,7 @@ export default class ManageOutgoingHooks extends React.Component {
</div>
</div>
{existingHooks}
+ {editError}
</div>
);
}
diff --git a/web/react/components/user_settings/user_settings_display.jsx b/web/react/components/user_settings/user_settings_display.jsx
index 22a62273c..d086c78a9 100644
--- a/web/react/components/user_settings/user_settings_display.jsx
+++ b/web/react/components/user_settings/user_settings_display.jsx
@@ -9,8 +9,12 @@ import PreferenceStore from '../../stores/preference_store.jsx';
function getDisplayStateFromStores() {
const militaryTime = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', {value: 'false'});
+ const nameFormat = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', {value: 'username'});
- return {militaryTime: militaryTime.value};
+ return {
+ militaryTime: militaryTime.value,
+ nameFormat: nameFormat.value
+ };
}
export default class UserSettingsDisplay extends React.Component {
@@ -19,15 +23,17 @@ export default class UserSettingsDisplay extends React.Component {
this.handleSubmit = this.handleSubmit.bind(this);
this.handleClockRadio = this.handleClockRadio.bind(this);
+ this.handleNameRadio = this.handleNameRadio.bind(this);
this.updateSection = this.updateSection.bind(this);
this.handleClose = this.handleClose.bind(this);
this.state = getDisplayStateFromStores();
}
handleSubmit() {
- const preference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', this.state.militaryTime);
+ const timePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', this.state.militaryTime);
+ const namePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', this.state.nameFormat);
- savePreferences([preference],
+ savePreferences([timePreference, namePreference],
() => {
PreferenceStore.emitChange();
this.updateSection('');
@@ -40,6 +46,9 @@ export default class UserSettingsDisplay extends React.Component {
handleClockRadio(militaryTime) {
this.setState({militaryTime});
}
+ handleNameRadio(nameFormat) {
+ this.setState({nameFormat});
+ }
updateSection(section) {
this.setState(getDisplayStateFromStores());
this.props.updateSection(section);
@@ -56,6 +65,7 @@ export default class UserSettingsDisplay extends React.Component {
render() {
const serverError = this.state.serverError || null;
let clockSection;
+ let nameFormatSection;
if (this.props.activeSection === 'clock') {
const clockFormat = [false, false];
if (this.state.militaryTime === 'true') {
@@ -127,6 +137,88 @@ export default class UserSettingsDisplay extends React.Component {
);
}
+ if (this.props.activeSection === 'name_format') {
+ const nameFormat = [false, false, false];
+ if (this.state.nameFormat === 'nickname_full_name') {
+ nameFormat[0] = true;
+ } else if (this.state.nameFormat === 'full_name') {
+ nameFormat[2] = true;
+ } else {
+ nameFormat[1] = true;
+ }
+
+ const inputs = [
+ <div key='userDisplayNameOptions'>
+ <div className='radio'>
+ <label>
+ <input
+ type='radio'
+ checked={nameFormat[0]}
+ onChange={this.handleNameRadio.bind(this, 'nickname_full_name')}
+ />
+ {'Show nickname if one exists, otherwise show first and last name (team default)'}
+ </label>
+ <br/>
+ </div>
+ <div className='radio'>
+ <label>
+ <input
+ type='radio'
+ checked={nameFormat[1]}
+ onChange={this.handleNameRadio.bind(this, 'username')}
+ />
+ {'Show username'}
+ </label>
+ <br/>
+ </div>
+ <div className='radio'>
+ <label>
+ <input
+ type='radio'
+ checked={nameFormat[2]}
+ onChange={this.handleNameRadio.bind(this, 'full_name')}
+ />
+ {'Show first and last name'}
+ </label>
+ <br/>
+ </div>
+ <div><br/>{'How should other users be shown in Direct Messages list?'}</div>
+ </div>
+ ];
+
+ nameFormatSection = (
+ <SettingItemMax
+ title='Show real names, nick names or usernames?'
+ inputs={inputs}
+ submit={this.handleSubmit}
+ server_error={serverError}
+ updateSection={(e) => {
+ this.updateSection('');
+ e.preventDefault();
+ }}
+ />
+ );
+ } else {
+ let describe = '';
+ if (this.state.nameFormat === 'username') {
+ describe = 'Show username';
+ } else if (this.state.nameFormat === 'full_name') {
+ describe = 'Show first and last name';
+ } else {
+ describe = 'Show nickname if one exists, otherwise show first and last name (team default)';
+ }
+
+ nameFormatSection = (
+ <SettingItemMin
+ title='Show real names, nick names or usernames?'
+ describe={describe}
+ updateSection={() => {
+ this.props.updateSection('name_format');
+ }}
+ />
+ );
+ }
+
return (
<div>
<div className='modal-header'>
@@ -151,6 +243,8 @@ export default class UserSettingsDisplay extends React.Component {
<div className='divider-dark first'/>
{clockSection}
<div className='divider-dark'/>
+ {nameFormatSection}
+ <div className='divider-dark'/>
</div>
</div>
);
diff --git a/web/react/components/user_settings/user_settings_integrations.jsx b/web/react/components/user_settings/user_settings_integrations.jsx
index 9bee74343..4a9915a1f 100644
--- a/web/react/components/user_settings/user_settings_integrations.jsx
+++ b/web/react/components/user_settings/user_settings_integrations.jsx
@@ -56,7 +56,7 @@ export default class UserSettingsIntegrationsTab extends React.Component {
<SettingItemMin
title='Incoming Webhooks'
width='medium'
- describe='Manage your incoming webhooks (Developer feature)'
+ describe='Manage your incoming webhooks'
updateSection={() => {
this.updateSection('incoming-hooks');
}}
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index c7c8549b9..296307bc6 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -884,6 +884,23 @@ export function getDisplayName(user) {
return user.username;
}
+export function displayUsername(userId) {
+ const user = UserStore.getProfile(userId);
+ const nameFormat = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', {value: 'false'}).value;
+
+ let username = '';
+ if (nameFormat === 'nickname_full_name') {
+ username = user.nickname || getFullName(user);
+ } else if (nameFormat === 'full_name') {
+ username = getFullName(user);
+ }
+ if (!username.trim().length) {
+ username = user.username;
+ }
+
+ return username;
+}
+
//IE10 does not set window.location.origin automatically so this must be called instead when using it
export function getWindowLocationOrigin() {
var windowLocationOrigin = window.location.origin;
@@ -976,7 +993,7 @@ export function isBrowserIE() {
}
export function isBrowserEdge() {
- return window.naviagtor && navigator.userAgent && navigator.userAgent.toLowerCase().indexOf('edge') > -1;
+ return window.navigator && navigator.userAgent && navigator.userAgent.toLowerCase().indexOf('edge') > -1;
}
export function getDirectChannelName(id, otherId) {