Этот коммит содержится в:
Asaad Mahmood
2016-03-08 15:07:43 +05:00
родитель 81ccfca2bf
Коммит cc453a048d
41 изменённых файлов: 744 добавлений и 695 удалений

Просмотреть файл

@@ -120,8 +120,7 @@ class LicenseSettings extends React.Component {
expires: Utils.displayDate(parseInt(global.window.mm_license.ExpiresAt, 10)),
ldap: global.window.mm_license.LDAP
}}
defaultMessage='<div><p>This compiled release of Mattermost platform is provided under a <a href="http://mattermost.com" target="_blank">commercial license</a>
from Mattermost, Inc. based on your subscription level and is subject to the <a href="{terms}" target="_blank">Terms of Service.</a></p>
defaultMessage='<div><p>This compiled release of Mattermost platform is provided under a <a href="http://mattermost.com" target="_blank">commercial license</a> from Mattermost, Inc. based on your subscription level and is subject to the <a href="{terms}" target="_blank">Terms of Service.</a></p>
<p>Your subscription details are as follows:</p>
Name: {name}<br />
Company or organization name: {company}<br/>
@@ -152,9 +151,7 @@ class LicenseSettings extends React.Component {
<p className='help-text'>
<FormattedHTMLMessage
id='admin.licence.keyMigration'
defaultMessage='If youre migrating servers you may need to remove your license key from this server in order to install it on a new server. To start,
<a href="http://mattermost.com" target="_blank">disable all Enterprise Edition features on this server</a>.
This will enable the ability to remove the license key and downgrade this server from Enterprise Edition to Team Edition.'
defaultMessage='If youre migrating servers you may need to remove your license key from this server in order to install it on a new server. To start, <a href="http://mattermost.com" target="_blank">disable all Enterprise Edition features on this server</a>. This will enable the ability to remove the license key and downgrade this server from Enterprise Edition to Team Edition.'
/>
</p>
</div>

Просмотреть файл

@@ -44,6 +44,7 @@ export default class ChannelMembersModal extends React.Component {
}
getStateFromStores() {
const extraInfo = ChannelStore.getCurrentExtraInfo();
const profiles = UserStore.getActiveOnlyProfiles();
if (extraInfo.member_count !== extraInfo.members.length) {
AsyncClient.getChannelExtraInfo(this.props.channel.id, -1);
@@ -53,9 +54,8 @@ export default class ChannelMembersModal extends React.Component {
};
}
// clone the member list since we mutate it later on
const memberList = extraInfo.members.map((member) => {
return Object.assign({}, member);
return profiles[member.id];
});
function compareByUsername(a, b) {
@@ -130,8 +130,8 @@ export default class ChannelMembersModal extends React.Component {
onClick={this.handleRemove.bind(this, user)}
>
<FormattedMessage
id='channel_members_modal.removeMember'
defaultMessage='Remove Member'
id='channel_members_modal.remove'
defaultMessage='Remove'
/>
</button>
);
@@ -178,7 +178,6 @@ export default class ChannelMembersModal extends React.Component {
this.props.onModalDismissed();
}}
>
<i className='glyphicon glyphicon-envelope'/>
<FormattedMessage
id='channel_members_modal.addNew'
defaultMessage=' Add New Members'

Просмотреть файл

@@ -130,7 +130,7 @@ class CreatePost extends React.Component {
post.message,
false,
(data) => {
PostStore.storeDraft(data.channel_id, null);
PostStore.storeDraft(this.state.channelId, null);
this.setState({messageText: '', submitting: false, postError: null, previews: [], serverError: null});
if (data.goto_location && data.goto_location.length > 0) {
@@ -262,9 +262,7 @@ class CreatePost extends React.Component {
message = err.message;
}
if (clientId === -1) {
this.setState({serverError: message});
} else {
if (clientId !== -1) {
const draft = PostStore.getDraft(this.state.channelId);
const index = draft.uploadsInProgress.indexOf(clientId);
@@ -274,8 +272,10 @@ class CreatePost extends React.Component {
PostStore.storeDraft(this.state.channelId, draft);
this.setState({uploadsInProgress: draft.uploadsInProgress, serverError: message});
this.setState({uploadsInProgress: draft.uploadsInProgress});
}
this.setState({serverError: message});
}
removePreview(id) {
const previews = Object.assign([], this.state.previews);

Просмотреть файл

@@ -19,12 +19,10 @@ class FileAttachment extends React.Component {
super(props);
this.loadFiles = this.loadFiles.bind(this);
this.playGif = this.playGif.bind(this);
this.stopGif = this.stopGif.bind(this);
this.addBackgroundImage = this.addBackgroundImage.bind(this);
this.canSetState = false;
this.state = {fileSize: -1, mime: '', playing: false, loading: false, format: ''};
this.state = {fileSize: -1};
}
componentDidMount() {
this.loadFiles();
@@ -95,42 +93,6 @@ class FileAttachment extends React.Component {
return true;
}
playGif(e, filename) {
var img = new Image();
var fileUrl = utils.getFileUrl(filename);
this.setState({loading: true});
img.load(fileUrl);
img.onload = () => {
var state = {playing: true, loading: false};
switch (true) {
case img.width > img.height:
state.format = 'landscape';
break;
case img.height > img.width:
state.format = 'portrait';
break;
default:
state.format = 'quadrat';
break;
}
this.setState(state);
// keep displaying background image for a short moment while browser is
// loading gif, to prevent white background flashing through
setTimeout(() => this.removeBackgroundImage.bind(this)(filename), 100);
};
img.onError = () => this.setState({loading: false});
e.stopPropagation();
}
stopGif(e, filename) {
this.setState({playing: false});
this.addBackgroundImage(filename);
e.stopPropagation();
}
getFileInfoFromName(name) {
var fileInfo = utils.splitFileLocation(name);
@@ -164,74 +126,18 @@ class FileAttachment extends React.Component {
var filename = this.props.filename;
var fileInfo = utils.splitFileLocation(filename);
var fileUrl = utils.getFileUrl(filename);
var fileUrl = utils.getFileUrl(filename, true);
var type = utils.getFileType(fileInfo.ext);
var playbackControls = '';
var loadedFile = '';
var loadingIndicator = '';
if (this.state.mime === 'image/gif') {
playbackControls = (
<div
className='file-playback-controls play'
onClick={(e) => this.playGif(e, filename)}
>
{"►"}
</div>
);
}
if (this.state.playing) {
loadedFile = (
<img
className={'file__loaded ' + this.state.format}
src={fileUrl}
/>
);
playbackControls = (
<div
className='file-playback-controls stop'
onClick={(e) => this.stopGif(e, filename)}
>
{"■"}
</div>
);
}
if (this.state.loading) {
loadingIndicator = (
<img
className='spinner file__loading'
src='/static/images/load.gif'
/>
);
playbackControls = '';
}
var thumbnail;
if (type === 'image') {
if (this.state.playing) {
thumbnail = (
<div
ref={filename}
className='post__load'
style={{backgroundImage: 'url(/static/images/load.gif)'}}
>
{playbackControls}
{loadedFile}
</div>
);
} else {
thumbnail = (
<div
ref={filename}
className='post__load'
style={{backgroundImage: 'url(/static/images/load.gif)'}}
>
{loadingIndicator}
{playbackControls}
{loadedFile}
</div>
);
}
thumbnail = (
<div
ref={filename}
className='post__load'
style={{backgroundImage: 'url(/static/images/load.gif)'}}
/>
);
} else {
thumbnail = <div className={'file-icon ' + utils.getIconClassName(type)}/>;
}
@@ -242,7 +148,7 @@ class FileAttachment extends React.Component {
filename,
function success(data) {
if (this.canSetState) {
this.setState({fileSize: parseInt(data.size, 10), mime: data.mime});
this.setState({fileSize: parseInt(data.size, 10)});
}
}.bind(this),
function error() {

Просмотреть файл

@@ -108,12 +108,12 @@ class FileUpload extends React.Component {
}
}
handleChange() {
var element = $(ReactDOM.findDOMNode(this.refs.fileInput));
handleChange(e) {
if (e.target.files.length > 0) {
this.uploadFiles(e.target.files);
this.uploadFiles(element.prop('files'));
Utils.clearFileInput(element[0]);
Utils.clearFileInput(e.target);
}
}
handleDrop(e) {

Просмотреть файл

@@ -41,8 +41,6 @@ export default class GetLinkModal extends React.Component {
}
render() {
const userCreationEnabled = global.window.mm_config.EnableUserCreation === 'true';
let helpText = null;
if (this.props.helpText) {
helpText = (
@@ -55,7 +53,7 @@ export default class GetLinkModal extends React.Component {
}
let copyLink = null;
if (userCreationEnabled && document.queryCommandSupported('copy')) {
if (document.queryCommandSupported('copy')) {
copyLink = (
<button
data-copy-btn='true'
@@ -71,17 +69,14 @@ export default class GetLinkModal extends React.Component {
);
}
let linkText = null;
if (userCreationEnabled) {
linkText = (
<textarea
className='form-control no-resize min-height'
readOnly='true'
ref='textarea'
value={this.props.link}
/>
);
}
const linkText = (
<textarea
className='form-control no-resize min-height'
readOnly='true'
ref='textarea'
value={this.props.link}
/>
);
var copyLinkConfirm = null;
if (this.state.copiedLink) {

Просмотреть файл

@@ -495,7 +495,7 @@ class InviteMemberModal extends React.Component {
<ConfirmModal
title={formatMessage(holders.modalTitle)}
message={formatMessage(holders.modalMessage)}
confirm_button={formatMessage(holders.modalButton)}
confirmButton={formatMessage(holders.modalButton)}
show={this.state.showConfirmModal}
onConfirm={this.handleHide.bind(this, false)}
onCancel={() => this.setState({showConfirmModal: false})}
@@ -512,4 +512,4 @@ InviteMemberModal.propTypes = {
intl: intlShape.isRequired
};
export default injectIntl(InviteMemberModal);
export default injectIntl(InviteMemberModal);

Просмотреть файл

@@ -107,7 +107,7 @@ export default class NavbarDropdown extends React.Component {
</li>
);
if (this.props.teamType === Constants.OPEN_TEAM) {
if (this.props.teamType === Constants.OPEN_TEAM && global.window.mm_config.EnableUserCreation === 'true') {
teamLink = (
<li>
<a

Просмотреть файл

@@ -4,10 +4,6 @@
import * as Utils from '../utils/utils.jsx';
export default class SettingsSidebar extends React.Component {
componentDidUpdate() {
$('.settings-modal').find('.modal-body').scrollTop(0);
$('.settings-modal').find('.modal-body').perfectScrollbar('update');
}
constructor(props) {
super(props);

Просмотреть файл

@@ -30,7 +30,7 @@ export default class SearchSuggestionList extends SuggestionList {
text = (
<FormattedMessage
id='suggestion.search.private'
defaultMessage='Public Groups'
defaultMessage='Private Groups'
/>
);
}

Просмотреть файл

@@ -611,7 +611,9 @@ class GeneralTab extends React.Component {
className='modal-title'
ref='title'
>
<i className='modal-back'></i>
<div className='modal-back'>
<i className='fa fa-angle-left'></i>
</div>
<FormattedMessage
id='general_tab.title'
defaultMessage='General Settings'

Просмотреть файл

@@ -131,7 +131,10 @@ class TeamImportTab extends React.Component {
<h4
className='modal-title'
ref='title'
><i className='modal-back'></i>
>
<div className='modal-back'>
<i className='fa fa-angle-left'></i>
</div>
<FormattedMessage
id='team_import_tab.import'
defaultMessage='Import'

Просмотреть файл

@@ -308,8 +308,8 @@ export default class TeamMembersDropdown extends React.Component {
data-toggle='dropdown'
aria-expanded='true'
>
<span className='fa fa-pencil'></span>
<span>{currentRoles} </span>
<span className='fa fa-chevron-down'></span>
</a>
<ul
className='dropdown-menu member-menu'

Просмотреть файл

@@ -91,7 +91,7 @@ class TeamSettingsModal extends React.Component {
/>
</h4>
</div>
<div className='modal-body'>
<div className='modal-body settings-modal__body'>
<div className='settings-table'>
<div className='settings-links'>
<SettingsSidebar

Просмотреть файл

@@ -129,12 +129,12 @@ export default class Textbox extends React.Component {
}
render() {
const hasText = this.props.messageText.length > 0;
let previewLink = null;
if (Utils.isFeatureEnabled(PreReleaseFeatures.MARKDOWN_PREVIEW)) {
const previewLinkVisible = this.props.messageText.length > 0;
previewLink = (
<a
style={{visibility: previewLinkVisible ? 'visible' : 'hidden'}}
onClick={this.showPreview}
className='textbox-preview-link'
>
@@ -153,6 +153,51 @@ export default class Textbox extends React.Component {
);
}
let helpText = (
<div
style={{visibility: hasText ? 'visible' : 'hidden', opacity: hasText ? '0.5' : '0'}}
className='help_format_text'
>
<b>
<FormattedMessage
id='textbox.bold'
defaultMessage='**bold**'
/>
</b>
<i>
<FormattedMessage
id='textbox.italic'
defaultMessage='_italic_'
/>
</i>
<span>~~<strike>
<FormattedMessage
id='textbox.strike'
defaultMessage='strike'
/>
</strike>~~ </span>
<code>
<FormattedMessage
id='textbox.inlinecode'
defaultMessage='`inline code`'
/>
</code>
<code>
<FormattedMessage
id='textbox.preformatted'
defaultMessage='```preformatted```'
/>
</code>
<span>
<FormattedMessage
id='textbox.quote'
defaultMessage='>quote'
/>
</span>
{previewLink}
</div>
);
return (
<div
ref='wrapper'
@@ -184,7 +229,7 @@ export default class Textbox extends React.Component {
dangerouslySetInnerHTML={{__html: this.state.preview ? TextFormatting.formatText(this.props.messageText) : ''}}
>
</div>
{previewLink}
{helpText}
<a
target='_blank'
href='http://docs.mattermost.com/help/getting-started/messaging-basics.html'

Просмотреть файл

@@ -10,9 +10,9 @@ export default function UserListRow({user, actions}) {
let name = user.username;
if (user.nickname && nameFormat === Constants.Preferences.DISPLAY_PREFER_NICKNAME) {
name = `${user.nickname} (${user.username})`;
name = `${user.nickname} (@${user.username})`;
} else if ((user.first_name || user.last_name) && (nameFormat === Constants.Preferences.DISPLAY_PREFER_NICKNAME || nameFormat === Constants.Preferences.DISPLAY_PREFER_FULL_NAME)) {
name = `${Utils.getFullName(user)} (${user.username})`;
name = `${Utils.getFullName(user)} (@${user.username})`;
}
const buttons = actions.map((Action, index) => {

Просмотреть файл

@@ -300,10 +300,12 @@ class AdvancedSettingsDisplay extends React.Component {
className='modal-title'
ref='title'
>
<i
className='modal-back'
onClick={this.props.collapseModal}
/>
<div className='modal-back'>
<i
className='fa fa-angle-left'
onClick={this.props.collapseModal}
/>
</div>
<FormattedMessage
id='user.settings.advance.title'
defaultMessage='Advanced Settings'

Просмотреть файл

@@ -94,10 +94,12 @@ class DeveloperTab extends React.Component {
className='modal-title'
ref='title'
>
<i
className='modal-back'
onClick={this.props.collapseModal}
/>
<div className='modal-back'>
<i
className='fa fa-angle-left'
onClick={this.props.collapseModal}
/>
</div>
<FormattedMessage
id='user.settings.developer.title'
defaultMessage='Developer Settings'

Просмотреть файл

@@ -444,10 +444,12 @@ export default class UserSettingsDisplay extends React.Component {
className='modal-title'
ref='title'
>
<i
className='modal-back'
onClick={this.props.collapseModal}
/>
<div className='modal-back'>
<i
className='fa fa-angle-left'
onClick={this.props.collapseModal}
/>
</div>
<FormattedMessage
id='user.settings.display.title'
defaultMessage='Display Settings'

Просмотреть файл

@@ -759,10 +759,12 @@ class UserSettingsGeneralTab extends React.Component {
className='modal-title'
ref='title'
>
<i
className='modal-back'
onClick={this.props.collapseModal}
/>
<div className='modal-back'>
<i
className='fa fa-angle-left'
onClick={this.props.collapseModal}
/>
</div>
<FormattedMessage
id='user.settings.general.title'
defaultMessage='General Settings'

Просмотреть файл

@@ -163,10 +163,12 @@ class UserSettingsIntegrationsTab extends React.Component {
className='modal-title'
ref='title'
>
<i
className='modal-back'
onClick={this.props.collapseModal}
/>
<div className='modal-back'>
<i
className='fa fa-angle-left'
onClick={this.props.collapseModal}
/>
</div>
<FormattedMessage
id='user.settings.integrations.title'
defaultMessage='Integration Settings'

Просмотреть файл

@@ -277,7 +277,7 @@ class UserSettingsModal extends React.Component {
/>
</Modal.Title>
</Modal.Header>
<Modal.Body ref='modalBody'>
<Modal.Body bsClass='settings-modal__body modal' ref='modalBody'>
<div className='settings-table'>
<div className='settings-links'>
<SettingsSidebar
@@ -309,7 +309,7 @@ class UserSettingsModal extends React.Component {
<ConfirmModal
title={formatMessage(holders.confirmTitle)}
message={formatMessage(holders.confirmMsg)}
confirm_button={formatMessage(holders.confirmBtns)}
confirmButton={formatMessage(holders.confirmBtns)}
show={this.state.showConfirmModal}
onConfirm={this.handleConfirm}
onCancel={this.handleCancelConfirmation}

Просмотреть файл

@@ -774,10 +774,12 @@ class NotificationsTab extends React.Component {
className='modal-title'
ref='title'
>
<i
className='modal-back'
onClick={this.props.collapseModal}
/>
<div className='modal-back'>
<i
className='fa fa-angle-left'
onClick={this.props.collapseModal}
/>
</div>
<FormattedMessage
id='user.settings.notifications.title'
defaultMessage='Notification Settings'

Просмотреть файл

@@ -389,10 +389,12 @@ class SecurityTab extends React.Component {
className='modal-title'
ref='title'
>
<i
className='modal-back'
onClick={this.props.collapseModal}
/>
<div className='modal-back'>
<i
className='fa fa-angle-left'
onClick={this.props.collapseModal}
/>
</div>
<FormattedMessage
id='user.settings.security.title'
defaultMessage='Security Settings'