Merge branch 'master' of https://github.com/mattermost/platform into ui-improvements
Conflicts: web/react/components/popover_list_members.jsx web/react/components/user_profile.jsx
Этот коммит содержится в:
@@ -60,9 +60,10 @@ func TestGetAllPreferences(t *testing.T) {
|
|||||||
|
|
||||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
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 {
|
if result, err := Client.GetAllPreferences(); err != nil {
|
||||||
t.Fatal(err)
|
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")
|
t.Fatal("received the wrong number of preferences")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
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 ###
|
### Mac OSX ###
|
||||||
|
|
||||||
1. Install Docker Toolbox using instructions at: http://docs.docker.com/installation/mac/
|
1. Install Docker Toolbox using instructions at: http://docs.docker.com/installation/mac/
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DEFAULT_WEBHOOK_USERNAME = "webhook"
|
||||||
|
DEFAULT_WEBHOOK_ICON = "/static/images/webhook_icon.jpg"
|
||||||
|
)
|
||||||
|
|
||||||
type IncomingWebhook struct {
|
type IncomingWebhook struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
CreateAt int64 `json:"create_at"`
|
CreateAt int64 `json:"create_at"`
|
||||||
|
|||||||
@@ -440,9 +440,11 @@ export default class EmailSettings extends React.Component {
|
|||||||
className='table table-bordered'
|
className='table table-bordered'
|
||||||
cellPadding='5'
|
cellPadding='5'
|
||||||
>
|
>
|
||||||
<tr><td className='help-text'>{'None'}</td><td className='help-text'>{'Mattermost will send email over an unsecure connection.'}</td></tr>
|
<tbody>
|
||||||
<tr><td className='help-text'>{'TLS'}</td><td className='help-text'>{'Encrypts the communication between Mattermost and your email server.'}</td></tr>
|
<tr><td className='help-text'>{'None'}</td><td className='help-text'>{'Mattermost will send email over an unsecure connection.'}</td></tr>
|
||||||
<tr><td className='help-text'>{'STARTTLS'}</td><td className='help-text'>{'Takes an existing insecure connection and attempts to upgrade it to a secure connection using TLS.'}</td></tr>
|
<tr><td className='help-text'>{'TLS'}</td><td className='help-text'>{'Encrypts the communication between Mattermost and your email server.'}</td></tr>
|
||||||
|
<tr><td className='help-text'>{'STARTTLS'}</td><td className='help-text'>{'Takes an existing insecure connection and attempts to upgrade it to a secure connection using TLS.'}</td></tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div className='help-text'>
|
<div className='help-text'>
|
||||||
|
|||||||
@@ -249,22 +249,24 @@ export default class LogSettings extends React.Component {
|
|||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
disabled={!this.state.fileEnable}
|
disabled={!this.state.fileEnable}
|
||||||
/>
|
/>
|
||||||
<p className='help-text'>
|
<div className='help-text'>
|
||||||
{'Format of log message output. If blank will be set to "[%D %T] [%L] %M", where:'}
|
{'Format of log message output. If blank will be set to "[%D %T] [%L] %M", where:'}
|
||||||
<div className='help-text'>
|
<div className='help-text'>
|
||||||
<table
|
<table
|
||||||
className='table table-bordered'
|
className='table table-bordered'
|
||||||
cellPadding='5'
|
cellPadding='5'
|
||||||
>
|
>
|
||||||
<tr><td className='help-text'>{'%T'}</td><td className='help-text'>{'Time (15:04:05 MST)'}</td></tr>
|
<tbody>
|
||||||
<tr><td className='help-text'>{'%D'}</td><td className='help-text'>{'Date (2006/01/02)'}</td></tr>
|
<tr><td className='help-text'>{'%T'}</td><td className='help-text'>{'Time (15:04:05 MST)'}</td></tr>
|
||||||
<tr><td className='help-text'>{'%d'}</td><td className='help-text'>{'Date (01/02/06)'}</td></tr>
|
<tr><td className='help-text'>{'%D'}</td><td className='help-text'>{'Date (2006/01/02)'}</td></tr>
|
||||||
<tr><td className='help-text'>{'%L'}</td><td className='help-text'>{'Level (DEBG, INFO, EROR)'}</td></tr>
|
<tr><td className='help-text'>{'%d'}</td><td className='help-text'>{'Date (01/02/06)'}</td></tr>
|
||||||
<tr><td className='help-text'>{'%S'}</td><td className='help-text'>{'Source'}</td></tr>
|
<tr><td className='help-text'>{'%L'}</td><td className='help-text'>{'Level (DEBG, INFO, EROR)'}</td></tr>
|
||||||
<tr><td className='help-text'>{'%M'}</td><td className='help-text'>{'Message'}</td></tr>
|
<tr><td className='help-text'>{'%S'}</td><td className='help-text'>{'Source'}</td></tr>
|
||||||
|
<tr><td className='help-text'>{'%M'}</td><td className='help-text'>{'Message'}</td></tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export default class EditPostModal extends React.Component {
|
|||||||
refocusId: options.refocusId || ''
|
refocusId: options.refocusId || ''
|
||||||
});
|
});
|
||||||
|
|
||||||
$(React.findDOMNode(this.refs.modal)).modal('show');
|
$(ReactDOM.findDOMNode(this.refs.modal)).modal('show');
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
var self = this;
|
var self = this;
|
||||||
@@ -92,7 +92,7 @@ export default class EditPostModal extends React.Component {
|
|||||||
$('#edit_textbox').get(0).focus();
|
$('#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 !== '') {
|
if (self.state.refocusId !== '') {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(self.state.refocusId).get(0).focus();
|
$(self.state.refocusId).get(0).focus();
|
||||||
|
|||||||
@@ -35,13 +35,20 @@ export default class PopoverListMembers extends React.Component {
|
|||||||
const teamMembers = UserStore.getProfilesUsernameMap();
|
const teamMembers = UserStore.getProfilesUsernameMap();
|
||||||
|
|
||||||
if (members && teamMembers) {
|
if (members && teamMembers) {
|
||||||
members.sort(function compareByLocal(a, b) {
|
members.sort((a, b) => {
|
||||||
return a.username.localeCompare(b.username);
|
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) {
|
if (teamMembers[m.username] && teamMembers[m.username].delete_at <= 0) {
|
||||||
popoverHtml.push(<div className='text--nowrap'>{m.username}</div>);
|
popoverHtml.push(
|
||||||
|
<div
|
||||||
|
className='text--nowrap'
|
||||||
|
key={'popover-member-' + i}
|
||||||
|
>
|
||||||
|
{m.username}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -58,7 +65,14 @@ export default class PopoverListMembers extends React.Component {
|
|||||||
trigger='click'
|
trigger='click'
|
||||||
placement='bottom'
|
placement='bottom'
|
||||||
rootClose={true}
|
rootClose={true}
|
||||||
overlay={<Popover title='Members'>{popoverHtml}</Popover>}
|
overlay={
|
||||||
|
<Popover
|
||||||
|
title='Members'
|
||||||
|
id='member-list-popover'
|
||||||
|
>
|
||||||
|
{popoverHtml}
|
||||||
|
</Popover>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div id='member_popover'>
|
<div id='member_popover'>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default class RhsComment extends React.Component {
|
|||||||
|
|
||||||
var post = this.props.post;
|
var post = this.props.post;
|
||||||
Client.createPost(post, post.channel_id,
|
Client.createPost(post, post.channel_id,
|
||||||
function success(data) {
|
(data) => {
|
||||||
AsyncClient.getPosts(post.channel_id);
|
AsyncClient.getPosts(post.channel_id);
|
||||||
|
|
||||||
var channel = ChannelStore.get(post.channel_id);
|
var channel = ChannelStore.get(post.channel_id);
|
||||||
@@ -43,11 +43,11 @@ export default class RhsComment extends React.Component {
|
|||||||
post: data
|
post: data
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function fail() {
|
() => {
|
||||||
post.state = Constants.POST_FAILED;
|
post.state = Constants.POST_FAILED;
|
||||||
PostStore.updatePendingPost(post);
|
PostStore.updatePendingPost(post);
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
}.bind(this)
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
post.state = Constants.POST_LOADING;
|
post.state = Constants.POST_LOADING;
|
||||||
@@ -84,7 +84,10 @@ export default class RhsComment extends React.Component {
|
|||||||
|
|
||||||
if (isOwner) {
|
if (isOwner) {
|
||||||
dropdownContents.push(
|
dropdownContents.push(
|
||||||
<li role='presentation'>
|
<li
|
||||||
|
role='presentation'
|
||||||
|
key='edit-button'
|
||||||
|
>
|
||||||
<a
|
<a
|
||||||
href='#'
|
href='#'
|
||||||
role='menuitem'
|
role='menuitem'
|
||||||
@@ -95,7 +98,7 @@ export default class RhsComment extends React.Component {
|
|||||||
data-postid={post.id}
|
data-postid={post.id}
|
||||||
data-channelid={post.channel_id}
|
data-channelid={post.channel_id}
|
||||||
>
|
>
|
||||||
Edit
|
{'Edit'}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
@@ -103,7 +106,10 @@ export default class RhsComment extends React.Component {
|
|||||||
|
|
||||||
if (isOwner || isAdmin) {
|
if (isOwner || isAdmin) {
|
||||||
dropdownContents.push(
|
dropdownContents.push(
|
||||||
<li role='presentation'>
|
<li
|
||||||
|
role='presentation'
|
||||||
|
key='delete-button'
|
||||||
|
>
|
||||||
<a
|
<a
|
||||||
href='#'
|
href='#'
|
||||||
role='menuitem'
|
role='menuitem'
|
||||||
@@ -114,7 +120,7 @@ export default class RhsComment extends React.Component {
|
|||||||
data-channelid={post.channel_id}
|
data-channelid={post.channel_id}
|
||||||
data-comments={0}
|
data-comments={0}
|
||||||
>
|
>
|
||||||
Delete
|
{'Delete'}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
@@ -162,7 +168,7 @@ export default class RhsComment extends React.Component {
|
|||||||
href='#'
|
href='#'
|
||||||
onClick={this.retryComment}
|
onClick={this.retryComment}
|
||||||
>
|
>
|
||||||
Retry
|
{'Retry'}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
} else if (post.state === Constants.POST_LOADING) {
|
} else if (post.state === Constants.POST_LOADING) {
|
||||||
@@ -213,14 +219,14 @@ export default class RhsComment extends React.Component {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div className='post-body'>
|
<div className='post-body'>
|
||||||
<p className={postClass}>
|
<div className={postClass}>
|
||||||
{loading}
|
{loading}
|
||||||
<div
|
<div
|
||||||
ref='message_holder'
|
ref='message_holder'
|
||||||
onClick={TextFormatting.handleClick}
|
onClick={TextFormatting.handleClick}
|
||||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(post.message)}}
|
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(post.message)}}
|
||||||
/>
|
/>
|
||||||
</p>
|
</div>
|
||||||
{fileAttachment}
|
{fileAttachment}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export default class Sidebar extends React.Component {
|
|||||||
|
|
||||||
const state = this.getStateFromStores();
|
const state = this.getStateFromStores();
|
||||||
state.newChannelModalType = '';
|
state.newChannelModalType = '';
|
||||||
state.showMoreDirectChannelsModal = false;
|
state.showDirectChannelsModal = false;
|
||||||
state.loadingDMChannel = -1;
|
state.loadingDMChannel = -1;
|
||||||
|
|
||||||
this.state = state;
|
this.state = state;
|
||||||
@@ -471,7 +471,9 @@ export default class Sidebar extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let closeButton = null;
|
let closeButton = null;
|
||||||
const removeTooltip = <Tooltip>{'Remove from list'}</Tooltip>;
|
const removeTooltip = (
|
||||||
|
<Tooltip id='remove-dm-tooltip'>{'Remove from list'}</Tooltip>
|
||||||
|
);
|
||||||
if (handleClose && !badge) {
|
if (handleClose && !badge) {
|
||||||
closeButton = (
|
closeButton = (
|
||||||
<OverlayTrigger
|
<OverlayTrigger
|
||||||
@@ -564,8 +566,12 @@ export default class Sidebar extends React.Component {
|
|||||||
showChannelModal = true;
|
showChannelModal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const createChannelTootlip = <Tooltip>{'Create new channel'}</Tooltip>;
|
const createChannelTootlip = (
|
||||||
const createGroupTootlip = <Tooltip>{'Create new group'}</Tooltip>;
|
<Tooltip id='new-channel-tooltip' >{'Create new channel'}</Tooltip>
|
||||||
|
);
|
||||||
|
const createGroupTootlip = (
|
||||||
|
<Tooltip id='new-group-tooltip'>{'Create new group'}</Tooltip>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -65,19 +65,29 @@ export default class UserProfile extends React.Component {
|
|||||||
|
|
||||||
var dataContent = [];
|
var dataContent = [];
|
||||||
dataContent.push(
|
dataContent.push(
|
||||||
<img className='user-popover__image'
|
<img
|
||||||
|
className='user-popover__image'
|
||||||
src={'/api/v1/users/' + this.state.profile.id + '/image?time=' + this.state.profile.update_at}
|
src={'/api/v1/users/' + this.state.profile.id + '/image?time=' + this.state.profile.update_at}
|
||||||
height='128'
|
height='128'
|
||||||
width='128'
|
width='128'
|
||||||
|
key='user-popover-image'
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
if (!global.window.config.ShowEmailAddress === 'true') {
|
if (!global.window.config.ShowEmailAddress === 'true') {
|
||||||
dataContent.push(<div className='text-nowrap'>{'Email not shared'}</div>);
|
dataContent.push(
|
||||||
|
<div
|
||||||
|
className='text-nowrap'
|
||||||
|
key='user-popover-no-email'
|
||||||
|
>
|
||||||
|
{'Email not shared'}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
dataContent.push(
|
dataContent.push(
|
||||||
<div
|
<div
|
||||||
data-toggle='tooltip'
|
data-toggle='tooltip'
|
||||||
title="' + this.state.profile.email + '"
|
title="' + this.state.profile.email + '"
|
||||||
|
key='user-popover-email'
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href="mailto:' + this.state.profile.email + '"
|
href="mailto:' + this.state.profile.email + '"
|
||||||
@@ -94,14 +104,21 @@ export default class UserProfile extends React.Component {
|
|||||||
trigger='click'
|
trigger='click'
|
||||||
placement='right'
|
placement='right'
|
||||||
rootClose={true}
|
rootClose={true}
|
||||||
overlay={<Popover title={this.state.profile.username}>{dataContent}</Popover>}
|
overlay={
|
||||||
|
<Popover
|
||||||
|
title={this.state.profile.username}
|
||||||
|
id='user-profile-popover'
|
||||||
|
>
|
||||||
|
{dataContent}
|
||||||
|
</Popover>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className='user-popover'
|
className='user-popover'
|
||||||
id={'profile_' + this.uniqueId}
|
id={'profile_' + this.uniqueId}
|
||||||
>
|
>
|
||||||
{name}
|
{name}
|
||||||
</div>
|
</div>
|
||||||
</OverlayTrigger>
|
</OverlayTrigger>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,9 +152,8 @@ export default class UserSettingsAppearance extends React.Component {
|
|||||||
<input type='radio'
|
<input type='radio'
|
||||||
checked={!displayCustom}
|
checked={!displayCustom}
|
||||||
onChange={this.updateType.bind(this, 'premade')}
|
onChange={this.updateType.bind(this, 'premade')}
|
||||||
>
|
/>
|
||||||
{'Theme Colors'}
|
{'Theme Colors'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
@@ -164,9 +163,8 @@ export default class UserSettingsAppearance extends React.Component {
|
|||||||
<input type='radio'
|
<input type='radio'
|
||||||
checked={displayCustom}
|
checked={displayCustom}
|
||||||
onChange={this.updateType.bind(this, 'custom')}
|
onChange={this.updateType.bind(this, 'custom')}
|
||||||
>
|
/>
|
||||||
{'Custom Theme'}
|
{'Custom Theme'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||||
// See License.txt for license information.
|
// 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 SettingItemMin from '../setting_item_min.jsx';
|
||||||
import SettingItemMax from '../setting_item_max.jsx';
|
import SettingItemMax from '../setting_item_max.jsx';
|
||||||
import Constants from '../../utils/constants.jsx';
|
import Constants from '../../utils/constants.jsx';
|
||||||
@@ -38,7 +38,7 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
handleClockRadio(militaryTime) {
|
handleClockRadio(militaryTime) {
|
||||||
this.setState({militaryTime: militaryTime});
|
this.setState({militaryTime});
|
||||||
}
|
}
|
||||||
updateSection(section) {
|
updateSection(section) {
|
||||||
this.setState(getDisplayStateFromStores());
|
this.setState(getDisplayStateFromStores());
|
||||||
@@ -57,7 +57,7 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
const serverError = this.state.serverError || null;
|
const serverError = this.state.serverError || null;
|
||||||
let clockSection;
|
let clockSection;
|
||||||
if (this.props.activeSection === 'clock') {
|
if (this.props.activeSection === 'clock') {
|
||||||
let clockFormat = [false, false];
|
const clockFormat = [false, false];
|
||||||
if (this.state.militaryTime === 'true') {
|
if (this.state.militaryTime === 'true') {
|
||||||
clockFormat[1] = true;
|
clockFormat[1] = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -77,9 +77,8 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
type='radio'
|
type='radio'
|
||||||
checked={clockFormat[0]}
|
checked={clockFormat[0]}
|
||||||
onChange={this.handleClockRadio.bind(this, 'false')}
|
onChange={this.handleClockRadio.bind(this, 'false')}
|
||||||
>
|
/>
|
||||||
12-hour clock (example: 4:00 PM)
|
{'12-hour clock (example: 4:00 PM)'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
@@ -89,9 +88,8 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
type='radio'
|
type='radio'
|
||||||
checked={clockFormat[1]}
|
checked={clockFormat[1]}
|
||||||
onChange={this.handleClockRadio.bind(this, 'true')}
|
onChange={this.handleClockRadio.bind(this, 'true')}
|
||||||
>
|
/>
|
||||||
24-hour clock (example: 16:00)
|
{'24-hour clock (example: 16:00)'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
@@ -99,7 +97,6 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
clockSection = (
|
clockSection = (
|
||||||
<SettingItemMax
|
<SettingItemMax
|
||||||
title='Clock Display'
|
title='Clock Display'
|
||||||
@@ -138,13 +135,13 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
className='close'
|
className='close'
|
||||||
data-dismiss='modal'
|
data-dismiss='modal'
|
||||||
aria-label='Close'
|
aria-label='Close'
|
||||||
>
|
>
|
||||||
<span aria-hidden='true'>{'×'}</span>
|
<span aria-hidden='true'>{'×'}</span>
|
||||||
</button>
|
</button>
|
||||||
<h4
|
<h4
|
||||||
className='modal-title'
|
className='modal-title'
|
||||||
ref='title'
|
ref='title'
|
||||||
>
|
>
|
||||||
<i className='modal-back'></i>
|
<i className='modal-back'></i>
|
||||||
{'Display Settings'}
|
{'Display Settings'}
|
||||||
</h4>
|
</h4>
|
||||||
|
|||||||
@@ -228,9 +228,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
<input type='radio'
|
<input type='radio'
|
||||||
checked={notifyActive[0]}
|
checked={notifyActive[0]}
|
||||||
onChange={this.handleNotifyRadio.bind(this, 'all')}
|
onChange={this.handleNotifyRadio.bind(this, 'all')}
|
||||||
>
|
/>
|
||||||
For all activity
|
{'For all activity'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
@@ -240,9 +239,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='radio'
|
type='radio'
|
||||||
checked={notifyActive[1]}
|
checked={notifyActive[1]}
|
||||||
onChange={this.handleNotifyRadio.bind(this, 'mention')}
|
onChange={this.handleNotifyRadio.bind(this, 'mention')}
|
||||||
>
|
/>
|
||||||
Only for mentions and direct messages
|
{'Only for mentions and direct messages'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
@@ -252,9 +250,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='radio'
|
type='radio'
|
||||||
checked={notifyActive[2]}
|
checked={notifyActive[2]}
|
||||||
onChange={this.handleNotifyRadio.bind(this, 'none')}
|
onChange={this.handleNotifyRadio.bind(this, 'none')}
|
||||||
>
|
/>
|
||||||
Never
|
{'Never'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -320,9 +317,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='radio'
|
type='radio'
|
||||||
checked={soundActive[0]}
|
checked={soundActive[0]}
|
||||||
onChange={this.handleSoundRadio.bind(this, 'true')}
|
onChange={this.handleSoundRadio.bind(this, 'true')}
|
||||||
>
|
/>
|
||||||
On
|
{'On'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
@@ -332,9 +328,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='radio'
|
type='radio'
|
||||||
checked={soundActive[1]}
|
checked={soundActive[1]}
|
||||||
onChange={this.handleSoundRadio.bind(this, 'false')}
|
onChange={this.handleSoundRadio.bind(this, 'false')}
|
||||||
>
|
/>
|
||||||
Off
|
{'Off'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
@@ -402,9 +397,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='radio'
|
type='radio'
|
||||||
checked={emailActive[0]}
|
checked={emailActive[0]}
|
||||||
onChange={this.handleEmailRadio.bind(this, 'true')}
|
onChange={this.handleEmailRadio.bind(this, 'true')}
|
||||||
>
|
/>
|
||||||
On
|
{'On'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
@@ -414,9 +408,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='radio'
|
type='radio'
|
||||||
checked={emailActive[1]}
|
checked={emailActive[1]}
|
||||||
onChange={this.handleEmailRadio.bind(this, 'false')}
|
onChange={this.handleEmailRadio.bind(this, 'false')}
|
||||||
>
|
/>
|
||||||
Off
|
{'Off'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
@@ -482,9 +475,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='checkbox'
|
type='checkbox'
|
||||||
checked={this.state.firstNameKey}
|
checked={this.state.firstNameKey}
|
||||||
onChange={handleUpdateFirstNameKey}
|
onChange={handleUpdateFirstNameKey}
|
||||||
>
|
/>
|
||||||
{'Your case sensitive first name "' + user.first_name + '"'}
|
{'Your case sensitive first name "' + user.first_name + '"'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -502,9 +494,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='checkbox'
|
type='checkbox'
|
||||||
checked={this.state.usernameKey}
|
checked={this.state.usernameKey}
|
||||||
onChange={handleUpdateUsernameKey}
|
onChange={handleUpdateUsernameKey}
|
||||||
>
|
/>
|
||||||
{'Your non-case sensitive username "' + user.username + '"'}
|
{'Your non-case sensitive username "' + user.username + '"'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -521,9 +512,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='checkbox'
|
type='checkbox'
|
||||||
checked={this.state.mentionKey}
|
checked={this.state.mentionKey}
|
||||||
onChange={handleUpdateMentionKey}
|
onChange={handleUpdateMentionKey}
|
||||||
>
|
/>
|
||||||
{'Your username mentioned "@' + user.username + '"'}
|
{'Your username mentioned "@' + user.username + '"'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -540,9 +530,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='checkbox'
|
type='checkbox'
|
||||||
checked={this.state.allKey}
|
checked={this.state.allKey}
|
||||||
onChange={handleUpdateAllKey}
|
onChange={handleUpdateAllKey}
|
||||||
>
|
/>
|
||||||
{'Team-wide mentions "@all"'}
|
{'Team-wide mentions "@all"'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -559,9 +548,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='checkbox'
|
type='checkbox'
|
||||||
checked={this.state.channelKey}
|
checked={this.state.channelKey}
|
||||||
onChange={handleUpdateChannelKey}
|
onChange={handleUpdateChannelKey}
|
||||||
>
|
/>
|
||||||
{'Channel-wide mentions "@channel"'}
|
{'Channel-wide mentions "@channel"'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -576,9 +564,8 @@ export default class NotificationsTab extends React.Component {
|
|||||||
type='checkbox'
|
type='checkbox'
|
||||||
checked={this.state.customKeysChecked}
|
checked={this.state.customKeysChecked}
|
||||||
onChange={this.updateCustomMentionKeys}
|
onChange={this.updateCustomMentionKeys}
|
||||||
>
|
/>
|
||||||
{'Other non-case sensitive words, separated by commas:'}
|
{'Other non-case sensitive words, separated by commas:'}
|
||||||
</input>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
|
|||||||
Двоичные данные
web/static/images/webhook_icon.jpg
Обычный файл
Двоичные данные
web/static/images/webhook_icon.jpg
Обычный файл
Двоичный файл не отображается.
|
После Ширина: | Высота: | Размер: 67 KiB |
16
web/web.go
16
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 := &model.Post{UserId: hook.UserId, ChannelId: channel.Id, Message: text}
|
||||||
post.AddProp("from_webhook", "true")
|
post.AddProp("from_webhook", "true")
|
||||||
|
|
||||||
if len(overrideUsername) != 0 && utils.Cfg.ServiceSettings.EnablePostUsernameOverride {
|
if utils.Cfg.ServiceSettings.EnablePostUsernameOverride {
|
||||||
post.AddProp("override_username", overrideUsername)
|
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 {
|
if utils.Cfg.ServiceSettings.EnablePostIconOverride {
|
||||||
post.AddProp("override_icon_url", overrideIconUrl)
|
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 {
|
if !c.HasPermissionsToChannel(pchan, "createIncomingHook") && channel.Type != model.CHANNEL_OPEN {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user