summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/react/components/admin_console/service_settings.jsx50
-rw-r--r--web/react/components/channel_header.jsx2
-rw-r--r--web/react/components/create_comment.jsx4
-rw-r--r--web/react/components/create_post.jsx2
-rw-r--r--web/react/components/delete_post_modal.jsx8
-rw-r--r--web/react/components/edit_channel_header_modal.jsx2
-rw-r--r--web/react/components/navbar.jsx4
-rw-r--r--web/react/components/post.jsx6
-rw-r--r--web/react/components/post_deleted_modal.jsx6
-rw-r--r--web/react/components/rhs_comment.jsx4
-rw-r--r--web/react/components/rhs_header_post.jsx8
-rw-r--r--web/react/components/search_bar.jsx8
-rw-r--r--web/react/components/search_results_header.jsx8
-rw-r--r--web/react/components/setting_item_max.jsx7
-rw-r--r--web/react/components/user_settings/custom_theme_chooser.jsx8
-rw-r--r--web/react/components/user_settings/import_theme_modal.jsx4
-rw-r--r--web/react/components/user_settings/manage_command_hooks.jsx38
-rw-r--r--web/react/components/user_settings/premade_theme_chooser.jsx2
-rw-r--r--web/react/components/user_settings/user_settings.jsx18
-rw-r--r--web/react/components/user_settings/user_settings_display.jsx24
-rw-r--r--web/react/components/user_settings/user_settings_modal.jsx21
-rw-r--r--web/react/components/user_settings/user_settings_theme.jsx (renamed from web/react/components/user_settings/user_settings_appearance.jsx)222
-rw-r--r--web/react/dispatcher/event_helpers.jsx10
-rw-r--r--web/react/stores/admin_store.jsx8
-rw-r--r--web/react/stores/channel_store.jsx10
-rw-r--r--web/react/stores/error_store.jsx2
-rw-r--r--web/react/stores/file_store.jsx2
-rw-r--r--web/react/stores/post_store.jsx10
-rw-r--r--web/react/stores/preference_store.jsx4
-rw-r--r--web/react/stores/search_store.jsx4
-rw-r--r--web/react/stores/socket_store.jsx24
-rw-r--r--web/react/stores/team_store.jsx2
-rw-r--r--web/react/stores/user_store.jsx12
-rw-r--r--web/react/utils/async_client.jsx48
-rw-r--r--web/react/utils/channel_intro_messages.jsx2
-rw-r--r--web/react/utils/constants.jsx58
-rw-r--r--web/react/utils/utils.jsx2
-rw-r--r--web/sass-files/sass/partials/_base.scss4
-rw-r--r--web/sass-files/sass/partials/_post.scss14
-rw-r--r--web/sass-files/sass/partials/_responsive.scss5
-rw-r--r--web/sass-files/sass/partials/_settings.scss10
-rw-r--r--web/sass-files/sass/partials/_sidebar--right.scss16
-rw-r--r--web/static/i18n/en.json19
-rw-r--r--web/static/i18n/es.json15
-rw-r--r--web/templates/head.html6
45 files changed, 425 insertions, 318 deletions
diff --git a/web/react/components/admin_console/service_settings.jsx b/web/react/components/admin_console/service_settings.jsx
index 2cc68d1ed..f232d4633 100644
--- a/web/react/components/admin_console/service_settings.jsx
+++ b/web/react/components/admin_console/service_settings.jsx
@@ -75,6 +75,7 @@ class ServiceSettings extends React.Component {
config.ServiceSettings.EnableTesting = ReactDOM.findDOMNode(this.refs.EnableTesting).checked;
config.ServiceSettings.EnableDeveloper = ReactDOM.findDOMNode(this.refs.EnableDeveloper).checked;
config.ServiceSettings.EnableSecurityFixAlert = ReactDOM.findDOMNode(this.refs.EnableSecurityFixAlert).checked;
+ config.ServiceSettings.EnableInsecureOutgoingConnections = ReactDOM.findDOMNode(this.refs.EnableInsecureOutgoingConnections).checked;
config.ServiceSettings.EnableCommands = ReactDOM.findDOMNode(this.refs.EnableCommands).checked;
config.ServiceSettings.EnableOnlyAdminIntegrations = ReactDOM.findDOMNode(this.refs.EnableOnlyAdminIntegrations).checked;
@@ -720,6 +721,53 @@ class ServiceSettings extends React.Component {
<div className='form-group'>
<label
className='control-label col-sm-4'
+ htmlFor='EnableInsecureOutgoingConnections'
+ >
+ <FormattedMessage
+ id='admin.service.insecureTlsTitle'
+ defaultMessage='Enable Insecure Outgoing Connections: '
+ />
+ </label>
+ <div className='col-sm-8'>
+ <label className='radio-inline'>
+ <input
+ type='radio'
+ name='EnableInsecureOutgoingConnections'
+ value='true'
+ ref='EnableInsecureOutgoingConnections'
+ defaultChecked={this.props.config.ServiceSettings.EnableInsecureOutgoingConnections}
+ onChange={this.handleChange}
+ />
+ <FormattedMessage
+ id='admin.service.true'
+ defaultMessage='true'
+ />
+ </label>
+ <label className='radio-inline'>
+ <input
+ type='radio'
+ name='EnableInsecureOutgoingConnections'
+ value='false'
+ defaultChecked={!this.props.config.ServiceSettings.EnableInsecureOutgoingConnections}
+ onChange={this.handleChange}
+ />
+ <FormattedMessage
+ id='admin.service.false'
+ defaultMessage='false'
+ />
+ </label>
+ <p className='help-text'>
+ <FormattedMessage
+ id='admin.service.insecureTlsDesc'
+ defaultMessage='When true, any outgoing HTTPS requests will accept unverified, self-signed certificates. For example, outgoing webhooks to a server with a self-signed TLS certificate, using any domain, will be allowed. Note that this makes these connections susceptible to man-in-the-middle attacks.'
+ />
+ </p>
+ </div>
+ </div>
+
+ <div className='form-group'>
+ <label
+ className='control-label col-sm-4'
htmlFor='SessionLengthWebInDays'
>
<FormattedMessage
@@ -896,4 +944,4 @@ ServiceSettings.propTypes = {
config: React.PropTypes.object
};
-export default injectIntl(ServiceSettings); \ No newline at end of file
+export default injectIntl(ServiceSettings);
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx
index 8fc3cd63d..a827cbcc6 100644
--- a/web/react/components/channel_header.jsx
+++ b/web/react/components/channel_header.jsx
@@ -114,7 +114,7 @@ export default class ChannelHeader extends React.Component {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH_TERM,
+ type: ActionTypes.RECEIVED_SEARCH_TERM,
term: terms,
do_search: true,
is_mention_search: true
diff --git a/web/react/components/create_comment.jsx b/web/react/components/create_comment.jsx
index 709485991..55dd8276c 100644
--- a/web/react/components/create_comment.jsx
+++ b/web/react/components/create_comment.jsx
@@ -152,7 +152,7 @@ class CreateComment extends React.Component {
ChannelStore.setChannelMember(member);
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST,
+ type: ActionTypes.RECEIVED_POST,
post: data
});
}.bind(this),
@@ -216,7 +216,7 @@ class CreateComment extends React.Component {
}
AppDispatcher.handleViewAction({
- type: ActionTypes.RECIEVED_EDIT_POST,
+ type: ActionTypes.RECEIVED_EDIT_POST,
refocusId: '#reply_textbox',
title: this.props.intl.formatMessage(holders.commentTitle),
message: lastPost.message,
diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx
index ecabdaee6..b9fbf09b5 100644
--- a/web/react/components/create_post.jsx
+++ b/web/react/components/create_post.jsx
@@ -364,7 +364,7 @@ class CreatePost extends React.Component {
var type = (lastPost.root_id && lastPost.root_id.length > 0) ? formatMessage(holders.comment) : formatMessage(holders.post);
AppDispatcher.handleViewAction({
- type: ActionTypes.RECIEVED_EDIT_POST,
+ type: ActionTypes.RECEIVED_EDIT_POST,
refocusId: '#post_textbox',
title: type,
message: lastPost.message,
diff --git a/web/react/components/delete_post_modal.jsx b/web/react/components/delete_post_modal.jsx
index 9d7dcb3e5..65ffa96a1 100644
--- a/web/react/components/delete_post_modal.jsx
+++ b/web/react/components/delete_post_modal.jsx
@@ -62,12 +62,12 @@ export default class DeletePostModal extends React.Component {
var selectedPost = selectedList.posts[selectedList.order[0]];
if ((selectedPost.id === this.state.post.id && !this.state.root_id) || selectedPost.root_id === this.state.post.id) {
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
+ type: ActionTypes.RECEIVED_SEARCH,
results: null
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
+ type: ActionTypes.RECEIVED_POST_SELECTED,
results: null
});
} else if (selectedPost.id === this.state.post.id && this.state.root_id) {
@@ -76,12 +76,12 @@ export default class DeletePostModal extends React.Component {
delete selectedList.posts[selectedPost.id];
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
+ type: ActionTypes.RECEIVED_POST_SELECTED,
post_list: selectedList
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
+ type: ActionTypes.RECEIVED_SEARCH,
results: null
});
}
diff --git a/web/react/components/edit_channel_header_modal.jsx b/web/react/components/edit_channel_header_modal.jsx
index 1066d123e..f6865fadd 100644
--- a/web/react/components/edit_channel_header_modal.jsx
+++ b/web/react/components/edit_channel_header_modal.jsx
@@ -68,7 +68,7 @@ class EditChannelHeaderModal extends React.Component {
this.onHide();
AppDispatcher.handleServerAction({
- type: Constants.ActionTypes.RECIEVED_CHANNEL,
+ type: Constants.ActionTypes.RECEIVED_CHANNEL,
channel
});
},
diff --git a/web/react/components/navbar.jsx b/web/react/components/navbar.jsx
index 8005678a2..e6a9fbd25 100644
--- a/web/react/components/navbar.jsx
+++ b/web/react/components/navbar.jsx
@@ -82,12 +82,12 @@ export default class Navbar extends React.Component {
var windowWidth = $(window).outerWidth();
if (windowWidth <= 768) {
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
+ type: ActionTypes.RECEIVED_SEARCH,
results: null
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
+ type: ActionTypes.RECEIVED_POST_SELECTED,
results: null
});
diff --git a/web/react/components/post.jsx b/web/react/components/post.jsx
index 53fe7fb5d..3619a9f8f 100644
--- a/web/react/components/post.jsx
+++ b/web/react/components/post.jsx
@@ -31,12 +31,12 @@ export default class Post extends React.Component {
data.posts = this.props.posts;
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
+ type: ActionTypes.RECEIVED_POST_SELECTED,
post_list: data
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
+ type: ActionTypes.RECEIVED_SEARCH,
results: null
});
}
@@ -59,7 +59,7 @@ export default class Post extends React.Component {
ChannelStore.setChannelMember(member);
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST,
+ type: ActionTypes.RECEIVED_POST,
post: data
});
},
diff --git a/web/react/components/post_deleted_modal.jsx b/web/react/components/post_deleted_modal.jsx
index 218f57eb5..642befeab 100644
--- a/web/react/components/post_deleted_modal.jsx
+++ b/web/react/components/post_deleted_modal.jsx
@@ -24,19 +24,19 @@ export default class PostDeletedModal extends React.Component {
}
handleClose() {
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
+ type: ActionTypes.RECEIVED_SEARCH,
results: null
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH_TERM,
+ type: ActionTypes.RECEIVED_SEARCH_TERM,
term: null,
do_search: false,
is_mention_search: false
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
+ type: ActionTypes.RECEIVED_POST_SELECTED,
results: null
});
}
diff --git a/web/react/components/rhs_comment.jsx b/web/react/components/rhs_comment.jsx
index 1addebbe4..9c85e9940 100644
--- a/web/react/components/rhs_comment.jsx
+++ b/web/react/components/rhs_comment.jsx
@@ -49,7 +49,7 @@ class RhsComment extends React.Component {
ChannelStore.setChannelMember(member);
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST,
+ type: ActionTypes.RECEIVED_POST,
post: data
});
},
@@ -267,4 +267,4 @@ RhsComment.propTypes = {
post: React.PropTypes.object
};
-export default injectIntl(RhsComment); \ No newline at end of file
+export default injectIntl(RhsComment);
diff --git a/web/react/components/rhs_header_post.jsx b/web/react/components/rhs_header_post.jsx
index d56ba76f8..cd310df56 100644
--- a/web/react/components/rhs_header_post.jsx
+++ b/web/react/components/rhs_header_post.jsx
@@ -21,12 +21,12 @@ export default class RhsHeaderPost extends React.Component {
e.preventDefault();
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
+ type: ActionTypes.RECEIVED_SEARCH,
results: null
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
+ type: ActionTypes.RECEIVED_POST_SELECTED,
results: null
});
}
@@ -34,14 +34,14 @@ export default class RhsHeaderPost extends React.Component {
e.preventDefault();
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH_TERM,
+ type: ActionTypes.RECEIVED_SEARCH_TERM,
term: this.props.fromSearch,
do_search: true,
is_mention_search: this.props.isMentionSearch
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
+ type: ActionTypes.RECEIVED_POST_SELECTED,
results: null
});
}
diff --git a/web/react/components/search_bar.jsx b/web/react/components/search_bar.jsx
index 35d7e9514..f7cb1b8f2 100644
--- a/web/react/components/search_bar.jsx
+++ b/web/react/components/search_bar.jsx
@@ -74,19 +74,19 @@ class SearchBar extends React.Component {
e.preventDefault();
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
+ type: ActionTypes.RECEIVED_SEARCH,
results: null
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH_TERM,
+ type: ActionTypes.RECEIVED_SEARCH_TERM,
term: null,
do_search: false,
is_mention_search: false
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
+ type: ActionTypes.RECEIVED_POST_SELECTED,
results: null
});
}
@@ -117,7 +117,7 @@ class SearchBar extends React.Component {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
+ type: ActionTypes.RECEIVED_SEARCH,
results: data,
is_mention_search: isMentionSearch
});
diff --git a/web/react/components/search_results_header.jsx b/web/react/components/search_results_header.jsx
index 45f56f65a..7f88eb2c7 100644
--- a/web/react/components/search_results_header.jsx
+++ b/web/react/components/search_results_header.jsx
@@ -19,19 +19,19 @@ export default class SearchResultsHeader extends React.Component {
e.preventDefault();
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
+ type: ActionTypes.RECEIVED_SEARCH,
results: null
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH_TERM,
+ type: ActionTypes.RECEIVED_SEARCH_TERM,
term: null,
do_search: false,
is_mention_search: false
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
+ type: ActionTypes.RECEIVED_POST_SELECTED,
results: null
});
}
@@ -72,4 +72,4 @@ export default class SearchResultsHeader extends React.Component {
SearchResultsHeader.propTypes = {
isMentionSearch: React.PropTypes.bool
-}; \ No newline at end of file
+};
diff --git a/web/react/components/setting_item_max.jsx b/web/react/components/setting_item_max.jsx
index 537055641..ac750614b 100644
--- a/web/react/components/setting_item_max.jsx
+++ b/web/react/components/setting_item_max.jsx
@@ -46,9 +46,14 @@ export default class SettingItemMax extends React.Component {
widthClass = 'col-sm-9 col-sm-offset-3';
}
+ let title;
+ if (this.props.title) {
+ title = <li className='col-sm-12 section-title'>{this.props.title}</li>;
+ }
+
return (
<ul className='section-max form-horizontal'>
- <li className='col-sm-12 section-title'>{this.props.title}</li>
+ {title}
<li className={widthClass}>
<ul className='setting-list'>
<li className='setting-list-item'>
diff --git a/web/react/components/user_settings/custom_theme_chooser.jsx b/web/react/components/user_settings/custom_theme_chooser.jsx
index 9116dd938..2d88a3650 100644
--- a/web/react/components/user_settings/custom_theme_chooser.jsx
+++ b/web/react/components/user_settings/custom_theme_chooser.jsx
@@ -222,7 +222,7 @@ class CustomThemeChooser extends React.Component {
} else {
elements.push(
<div
- className='col-sm-4 form-group'
+ className='col-sm-4 form-group element'
key={'custom-theme-key' + index}
>
<label className='custom-label'>{formatMessage(messages[element.id])}</label>
@@ -265,8 +265,8 @@ class CustomThemeChooser extends React.Component {
);
return (
- <div>
- <div className='row form-group'>
+ <div className='appearance-section'>
+ <div className='theme-elements row form-group'>
{elements}
</div>
<div className='row'>
@@ -283,4 +283,4 @@ CustomThemeChooser.propTypes = {
updateTheme: React.PropTypes.func.isRequired
};
-export default injectIntl(CustomThemeChooser); \ No newline at end of file
+export default injectIntl(CustomThemeChooser);
diff --git a/web/react/components/user_settings/import_theme_modal.jsx b/web/react/components/user_settings/import_theme_modal.jsx
index 66bed0b0b..e9e90a936 100644
--- a/web/react/components/user_settings/import_theme_modal.jsx
+++ b/web/react/components/user_settings/import_theme_modal.jsx
@@ -84,7 +84,7 @@ class ImportThemeModal extends React.Component {
Client.updateUser(user,
(data) => {
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_ME,
+ type: ActionTypes.RECEIVED_ME,
me: data
});
@@ -212,4 +212,4 @@ ImportThemeModal.propTypes = {
intl: intlShape.isRequired
};
-export default injectIntl(ImportThemeModal); \ No newline at end of file
+export default injectIntl(ImportThemeModal);
diff --git a/web/react/components/user_settings/manage_command_hooks.jsx b/web/react/components/user_settings/manage_command_hooks.jsx
index b2fc0a4e1..d23d2957e 100644
--- a/web/react/components/user_settings/manage_command_hooks.jsx
+++ b/web/react/components/user_settings/manage_command_hooks.jsx
@@ -530,23 +530,19 @@ export default class ManageCommandCmds extends React.Component {
/>
</label>
<div className='padding-top'>
- <label>
- <input
- type='checkbox'
- checked={this.state.cmd.auto_complete}
- onChange={this.updateAutoComplete}
- />
- <FormattedMessage
- id='user.settings.cmds.auto_complete_desc_desc'
- defaultMessage='A short description of what this commands does'
- />
- </label>
- </div>
- <div className='padding-top'>
- <FormattedMessage
- id='user.settings.cmds.auto_complete_help'
- defaultMessage='Show this command in autocomplete list.'
- />
+ <div className='checkbox'>
+ <label>
+ <input
+ type='checkbox'
+ checked={this.state.cmd.auto_complete}
+ onChange={this.updateAutoComplete}
+ />
+ <FormattedMessage
+ id='user.settings.cmds.auto_complete_help'
+ defaultMessage=' Show this command in autocomplete list'
+ />
+ </label>
+ </div>
</div>
</div>
<div className='padding-top x2'>
@@ -565,12 +561,6 @@ export default class ManageCommandCmds extends React.Component {
placeholder={this.props.intl.formatMessage(holders.addAutoCompleteDescPlaceholder)}
/>
</div>
- <div className='padding-top'>
- <FormattedMessage
- id='user.settings.cmds.auto_complete_desc_desc'
- defaultMessage='A short description of what this commands does'
- />
- </div>
</div>
<div className='padding-top x2'>
<label className='control-label'>
@@ -649,7 +639,7 @@ export default class ManageCommandCmds extends React.Component {
</div>
{addError}
</div>
- <div className='padding-top padding-bottom'>
+ <div className='padding-top x2 padding-bottom'>
<a
className={'btn btn-sm btn-primary'}
href='#'
diff --git a/web/react/components/user_settings/premade_theme_chooser.jsx b/web/react/components/user_settings/premade_theme_chooser.jsx
index 9889bff5c..80ff8c4de 100644
--- a/web/react/components/user_settings/premade_theme_chooser.jsx
+++ b/web/react/components/user_settings/premade_theme_chooser.jsx
@@ -45,7 +45,7 @@ export default class PremadeThemeChooser extends React.Component {
}
return (
- <div className='row'>
+ <div className='row appearance-section'>
{premadeThemes}
</div>
);
diff --git a/web/react/components/user_settings/user_settings.jsx b/web/react/components/user_settings/user_settings.jsx
index 54d98bbde..4da51fa5f 100644
--- a/web/react/components/user_settings/user_settings.jsx
+++ b/web/react/components/user_settings/user_settings.jsx
@@ -6,7 +6,6 @@ import * as utils from '../../utils/utils.jsx';
import NotificationsTab from './user_settings_notifications.jsx';
import SecurityTab from './user_settings_security.jsx';
import GeneralTab from './user_settings_general.jsx';
-import AppearanceTab from './user_settings_appearance.jsx';
import DeveloperTab from './user_settings_developer.jsx';
import IntegrationsTab from './user_settings_integrations.jsx';
import DisplayTab from './user_settings_display.jsx';
@@ -85,21 +84,6 @@ export default class UserSettings extends React.Component {
/>
</div>
);
- } else if (this.props.activeTab === 'appearance') {
- return (
- <div>
- <AppearanceTab
- ref='activeTab'
- activeSection={this.props.activeSection}
- updateSection={this.props.updateSection}
- updateTab={this.props.updateTab}
- closeModal={this.props.closeModal}
- collapseModal={this.props.collapseModal}
- setEnforceFocus={this.props.setEnforceFocus}
- setRequireConfirm={this.props.setRequireConfirm}
- />
- </div>
- );
} else if (this.props.activeTab === 'developer') {
return (
<div>
@@ -137,6 +121,8 @@ export default class UserSettings extends React.Component {
updateTab={this.props.updateTab}
closeModal={this.props.closeModal}
collapseModal={this.props.collapseModal}
+ setEnforceFocus={this.props.setEnforceFocus}
+ setRequireConfirm={this.props.setRequireConfirm}
/>
</div>
);
diff --git a/web/react/components/user_settings/user_settings_display.jsx b/web/react/components/user_settings/user_settings_display.jsx
index 776bde442..4b11c06fb 100644
--- a/web/react/components/user_settings/user_settings_display.jsx
+++ b/web/react/components/user_settings/user_settings_display.jsx
@@ -1,15 +1,18 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-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';
-const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES;
-import PreferenceStore from '../../stores/preference_store.jsx';
import ManageLanguages from './manage_languages.jsx';
+import ThemeSetting from './user_settings_theme.jsx';
+
+import PreferenceStore from '../../stores/preference_store.jsx';
import * as Utils from '../../utils/utils.jsx';
+import Constants from '../../utils/constants.jsx';
+const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES;
+
+import {savePreferences} from '../../utils/client.jsx';
import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'mm-intl';
const holders = defineMessages({
@@ -452,6 +455,13 @@ class UserSettingsDisplay extends React.Component {
/>
</h3>
<div className='divider-dark first'/>
+ <ThemeSetting
+ selected={this.props.activeSection === 'theme'}
+ updateSection={this.updateSection}
+ setRequireConfirm={this.props.setRequireConfirm}
+ setEnforceFocus={this.props.setEnforceFocus}
+ />
+ <div className='divider-dark'/>
{fontSection}
<div className='divider-dark'/>
{clockSection}
@@ -472,7 +482,9 @@ UserSettingsDisplay.propTypes = {
updateTab: React.PropTypes.func,
activeSection: React.PropTypes.string,
closeModal: React.PropTypes.func.isRequired,
- collapseModal: React.PropTypes.func.isRequired
+ collapseModal: React.PropTypes.func.isRequired,
+ setRequireConfirm: React.PropTypes.func.isRequired,
+ setEnforceFocus: React.PropTypes.func.isRequired
};
-export default injectIntl(UserSettingsDisplay); \ No newline at end of file
+export default injectIntl(UserSettingsDisplay);
diff --git a/web/react/components/user_settings/user_settings_modal.jsx b/web/react/components/user_settings/user_settings_modal.jsx
index 2a0a90cf5..e0b72157b 100644
--- a/web/react/components/user_settings/user_settings_modal.jsx
+++ b/web/react/components/user_settings/user_settings_modal.jsx
@@ -2,9 +2,13 @@
// See License.txt for license information.
import ConfirmModal from '../confirm_modal.jsx';
-const Modal = ReactBootstrap.Modal;
-import SettingsSidebar from '../settings_sidebar.jsx';
import UserSettings from './user_settings.jsx';
+import SettingsSidebar from '../settings_sidebar.jsx';
+
+import UserStore from '../../stores/user_store.jsx';
+import * as Utils from '../../utils/utils.jsx';
+
+const Modal = ReactBootstrap.Modal;
import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'mm-intl';
@@ -21,10 +25,6 @@ const holders = defineMessages({
id: 'user.settings.modal.notifications',
defaultMessage: 'Notifications'
},
- appearance: {
- id: 'user.settings.modal.appearance',
- defaultMessage: 'Appearance'
- },
developer: {
id: 'user.settings.modal.developer',
defaultMessage: 'Developer'
@@ -214,6 +214,12 @@ class UserSettingsModal extends React.Component {
if (!skipConfirm && this.requireConfirm) {
this.showConfirmModal(() => this.updateSection(section, true));
} else {
+ if (this.state.active_section === 'theme' && section !== 'theme') {
+ const user = UserStore.getCurrentUser();
+ if (user.theme_props != null) {
+ Utils.applyTheme(user.theme_props);
+ }
+ }
this.setState({active_section: section});
}
}
@@ -224,7 +230,6 @@ class UserSettingsModal extends React.Component {
tabs.push({name: 'general', uiName: formatMessage(holders.general), icon: 'glyphicon glyphicon-cog'});
tabs.push({name: 'security', uiName: formatMessage(holders.security), icon: 'glyphicon glyphicon-lock'});
tabs.push({name: 'notifications', uiName: formatMessage(holders.notifications), icon: 'glyphicon glyphicon-exclamation-sign'});
- tabs.push({name: 'appearance', uiName: formatMessage(holders.appearance), icon: 'glyphicon glyphicon-wrench'});
if (global.window.mm_config.EnableOAuthServiceProvider === 'true') {
tabs.push({name: 'developer', uiName: formatMessage(holders.developer), icon: 'glyphicon glyphicon-th'});
}
@@ -294,4 +299,4 @@ UserSettingsModal.propTypes = {
onModalDismissed: React.PropTypes.func.isRequired
};
-export default injectIntl(UserSettingsModal); \ No newline at end of file
+export default injectIntl(UserSettingsModal);
diff --git a/web/react/components/user_settings/user_settings_appearance.jsx b/web/react/components/user_settings/user_settings_theme.jsx
index fb11dc81b..34c688db1 100644
--- a/web/react/components/user_settings/user_settings_appearance.jsx
+++ b/web/react/components/user_settings/user_settings_theme.jsx
@@ -1,8 +1,10 @@
-// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import CustomThemeChooser from './custom_theme_chooser.jsx';
import PremadeThemeChooser from './premade_theme_chooser.jsx';
+import SettingItemMin from '../setting_item_min.jsx';
+import SettingItemMax from '../setting_item_max.jsx';
import UserStore from '../../stores/user_store.jsx';
@@ -12,11 +14,22 @@ import * as Utils from '../../utils/utils.jsx';
import Constants from '../../utils/constants.jsx';
-import {FormattedMessage} from 'mm-intl';
+import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'mm-intl';
const ActionTypes = Constants.ActionTypes;
-export default class UserSettingsAppearance extends React.Component {
+const holders = defineMessages({
+ themeTitle: {
+ id: 'user.settings.display.theme.title',
+ defaultMessage: 'Theme'
+ },
+ themeDescribe: {
+ id: 'user.settings.display.theme.describe',
+ defaultMessage: 'Open to manage your theme'
+ }
+});
+
+export default class ThemeSetting extends React.Component {
constructor(props) {
super(props);
@@ -34,16 +47,21 @@ export default class UserSettingsAppearance extends React.Component {
componentDidMount() {
UserStore.addChangeListener(this.onChange);
- if (this.props.activeSection === 'theme') {
+ if (this.props.selected) {
$(ReactDOM.findDOMNode(this.refs[this.state.theme])).addClass('active-border');
}
}
componentDidUpdate() {
- if (this.props.activeSection === 'theme') {
+ if (this.props.selected) {
$('.color-btn').removeClass('active-border');
$(ReactDOM.findDOMNode(this.refs[this.state.theme])).addClass('active-border');
}
}
+ componentWillReceiveProps(nextProps) {
+ if (!this.props.selected && nextProps.selected) {
+ this.resetFields();
+ }
+ }
componentWillUnmount() {
UserStore.removeChangeListener(this.onChange);
}
@@ -89,13 +107,14 @@ export default class UserSettingsAppearance extends React.Component {
Client.updateUser(user,
(data) => {
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_ME,
+ type: ActionTypes.RECEIVED_ME,
me: data
});
this.props.setRequireConfirm(false);
this.originalTheme = Object.assign({}, this.state.theme);
this.scrollToTop();
+ this.props.updateSection('');
},
(err) => {
var state = this.getStateFromStores();
@@ -149,6 +168,8 @@ export default class UserSettingsAppearance extends React.Component {
this.props.setEnforceFocus(false);
}
render() {
+ const {formatMessage} = this.props.intl;
+
var serverError;
if (this.state.serverError) {
serverError = this.state.serverError;
@@ -160,136 +181,121 @@ export default class UserSettingsAppearance extends React.Component {
let premade;
if (displayCustom) {
custom = (
- <CustomThemeChooser
- theme={this.state.theme}
- updateTheme={this.updateTheme}
- />
+ <div key='customThemeChooser'>
+ <br/>
+ <CustomThemeChooser
+ theme={this.state.theme}
+ updateTheme={this.updateTheme}
+ />
+ </div>
);
} else {
premade = (
- <PremadeThemeChooser
- theme={this.state.theme}
- updateTheme={this.updateTheme}
- />
+ <div key='premadeThemeChooser'>
+ <br/>
+ <PremadeThemeChooser
+ theme={this.state.theme}
+ updateTheme={this.updateTheme}
+ />
+ </div>
);
}
- const themeUI = (
- <div className='section-max appearance-section'>
- <div className='col-sm-12'>
- <div className='radio'>
- <label>
- <input type='radio'
- checked={!displayCustom}
- onChange={this.updateType.bind(this, 'premade')}
- />
- <FormattedMessage
- id='user.settings.appearance.themeColors'
- defaultMessage='Theme Colors'
- />
- </label>
- <br/>
- </div>
- {premade}
- <div className='radio'>
- <label>
- <input type='radio'
- checked={displayCustom}
- onChange={this.updateType.bind(this, 'custom')}
- />
- <FormattedMessage
- id='user.settings.appearance.customTheme'
- defaultMessage='Custom Theme'
- />
- </label>
- <br/>
- </div>
- {custom}
- <hr />
- {serverError}
- <a
- className='btn btn-sm btn-primary'
- href='#'
- onClick={this.submitTheme}
- >
- <FormattedMessage
- id='user.settings.appearance.save'
- defaultMessage='Save'
+ let themeUI;
+ if (this.props.selected) {
+ let inputs = [];
+
+ inputs.push(
+ <div
+ className='radio'
+ key='premadeThemeColorLabel'
+ >
+ <label>
+ <input type='radio'
+ checked={!displayCustom}
+ onChange={this.updateType.bind(this, 'premade')}
/>
- </a>
- <a
- className='btn btn-sm theme'
- href='#'
- onClick={this.resetFields}
- >
<FormattedMessage
- id='user.settings.appearance.cancel'
- defaultMessage='Cancel'
+ id='user.settings.display.theme.themeColors'
+ defaultMessage='Theme Colors'
/>
- </a>
+ </label>
+ <br/>
</div>
- </div>
- );
+ );
- return (
- <div>
- <div className='modal-header'>
- <button
- type='button'
- className='close'
- aria-label='Close'
- onClick={this.props.closeModal}
- >
- <span aria-hidden='true'>{'×'}</span>
- </button>
- <h4
- className='modal-title'
- ref='title'
- >
- <i
- className='modal-back'
- onClick={this.props.collapseModal}
+ inputs.push(premade);
+
+ inputs.push(
+ <div
+ className='radio'
+ key='customThemeColorLabel'
+ >
+ <label>
+ <input type='radio'
+ checked={displayCustom}
+ onChange={this.updateType.bind(this, 'custom')}
/>
<FormattedMessage
- id='user.settings.appearance.title'
- defaultMessage='Appearance Settings'
+ id='user.settings.display.theme.customTheme'
+ defaultMessage='Custom Theme'
/>
- </h4>
+ </label>
+ <br/>
</div>
- <div className='user-settings'>
- <h3 className='tab-header'>
- <FormattedMessage
- id='user.settings.appearance.title'
- defaultMessage='Appearance Settings'
- />
- </h3>
- <div className='divider-dark first'/>
- {themeUI}
- <div className='divider-dark'/>
+ );
+
+ inputs.push(custom);
+
+ inputs.push(
+ <div key='importSlackThemeButton'>
<br/>
<a
className='theme'
onClick={this.handleImportModal}
>
<FormattedMessage
- id='user.settings.appearance.import'
+ id='user.settings.display.theme.import'
defaultMessage='Import theme colors from Slack'
/>
</a>
</div>
- </div>
- );
+ );
+
+ themeUI = (
+ <SettingItemMax
+ inputs={inputs}
+ submit={this.submitTheme}
+ server_error={serverError}
+ width='full'
+ updateSection={(e) => {
+ this.props.updateSection('');
+ e.preventDefault();
+ }}
+ />
+ );
+ } else {
+ themeUI = (
+ <SettingItemMin
+ title={formatMessage(holders.themeTitle)}
+ describe={formatMessage(holders.themeDescribe)}
+ updateSection={() => {
+ this.props.updateSection('theme');
+ }}
+ />
+ );
+ }
+
+ return themeUI;
}
}
-UserSettingsAppearance.defaultProps = {
- activeSection: ''
-};
-UserSettingsAppearance.propTypes = {
- activeSection: React.PropTypes.string,
- updateTab: React.PropTypes.func,
- closeModal: React.PropTypes.func.isRequired,
- collapseModal: React.PropTypes.func.isRequired,
+ThemeSetting.propTypes = {
+ intl: intlShape.isRequired,
+ selected: React.PropTypes.bool.isRequired,
+ updateSection: React.PropTypes.func.isRequired,
setRequireConfirm: React.PropTypes.func.isRequired,
setEnforceFocus: React.PropTypes.func.isRequired
};
+
+export default injectIntl(ThemeSetting);
diff --git a/web/react/dispatcher/event_helpers.jsx b/web/react/dispatcher/event_helpers.jsx
index c1041e438..5476d707f 100644
--- a/web/react/dispatcher/event_helpers.jsx
+++ b/web/react/dispatcher/event_helpers.jsx
@@ -30,7 +30,7 @@ export function emitPostFocusEvent(postId) {
postId,
(data) => {
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_FOCUSED_POST,
+ type: ActionTypes.RECEIVED_FOCUSED_POST,
postId,
post_list: data
});
@@ -47,13 +47,13 @@ export function emitPostFocusRightHandSideFromSearch(post, isMentionSearch) {
post.id,
(data) => {
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
+ type: ActionTypes.RECEIVED_POST_SELECTED,
post_list: data,
from_search: SearchStore.getSearchTerm()
});
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
+ type: ActionTypes.RECEIVED_SEARCH,
results: null,
is_mention_search: isMentionSearch
});
@@ -89,7 +89,7 @@ export function emitLoadMorePostsFocusedBottomEvent() {
export function emitPostRecievedEvent(post) {
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST,
+ type: ActionTypes.RECEIVED_POST,
post
});
}
@@ -177,7 +177,7 @@ export function emitClearSuggestions(suggestionId) {
export function emitPreferenceChangedEvent(preference) {
AppDispatcher.handleServerAction({
- type: Constants.ActionTypes.RECIEVED_PREFERENCE,
+ type: Constants.ActionTypes.RECEIVED_PREFERENCE,
preference
});
}
diff --git a/web/react/stores/admin_store.jsx b/web/react/stores/admin_store.jsx
index 8f43091a7..eb3254cfe 100644
--- a/web/react/stores/admin_store.jsx
+++ b/web/react/stores/admin_store.jsx
@@ -135,19 +135,19 @@ AdminStoreClass.dispatchToken = AppDispatcher.register((payload) => {
var action = payload.action;
switch (action.type) {
- case ActionTypes.RECIEVED_LOGS:
+ case ActionTypes.RECEIVED_LOGS:
AdminStore.saveLogs(action.logs);
AdminStore.emitLogChange();
break;
- case ActionTypes.RECIEVED_SERVER_AUDITS:
+ case ActionTypes.RECEIVED_SERVER_AUDITS:
AdminStore.saveAudits(action.audits);
AdminStore.emitAuditChange();
break;
- case ActionTypes.RECIEVED_CONFIG:
+ case ActionTypes.RECEIVED_CONFIG:
AdminStore.saveConfig(action.config);
AdminStore.emitConfigChange();
break;
- case ActionTypes.RECIEVED_ALL_TEAMS:
+ case ActionTypes.RECEIVED_ALL_TEAMS:
AdminStore.saveAllTeams(action.teams);
AdminStore.emitAllTeamsChange();
break;
diff --git a/web/react/stores/channel_store.jsx b/web/react/stores/channel_store.jsx
index 2337a573d..d650b23c2 100644
--- a/web/react/stores/channel_store.jsx
+++ b/web/react/stores/channel_store.jsx
@@ -296,7 +296,7 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => {
ChannelStore.emitChange();
break;
- case ActionTypes.RECIEVED_FOCUSED_POST: {
+ case ActionTypes.RECEIVED_FOCUSED_POST: {
const post = action.post_list.posts[action.postId];
ChannelStore.setCurrentId(post.channel_id);
ChannelStore.setPostMode(ChannelStore.POST_MODE_FOCUS);
@@ -304,7 +304,7 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => {
break;
}
- case ActionTypes.RECIEVED_CHANNELS:
+ case ActionTypes.RECEIVED_CHANNELS:
ChannelStore.storeChannels(action.channels);
ChannelStore.storeChannelMembers(action.members);
currentId = ChannelStore.getCurrentId();
@@ -315,7 +315,7 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => {
ChannelStore.emitChange();
break;
- case ActionTypes.RECIEVED_CHANNEL:
+ case ActionTypes.RECEIVED_CHANNEL:
ChannelStore.pStoreChannel(action.channel);
if (action.member) {
ChannelStore.pStoreChannelMember(action.member);
@@ -328,12 +328,12 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => {
ChannelStore.emitChange();
break;
- case ActionTypes.RECIEVED_MORE_CHANNELS:
+ case ActionTypes.RECEIVED_MORE_CHANNELS:
ChannelStore.storeMoreChannels(action.channels);
ChannelStore.emitMoreChange();
break;
- case ActionTypes.RECIEVED_CHANNEL_EXTRA_INFO:
+ case ActionTypes.RECEIVED_CHANNEL_EXTRA_INFO:
var extraInfos = ChannelStore.getExtraInfos();
extraInfos[action.extra_info.id] = action.extra_info;
ChannelStore.storeExtraInfos(extraInfos);
diff --git a/web/react/stores/error_store.jsx b/web/react/stores/error_store.jsx
index ed46d6b68..5afcefd12 100644
--- a/web/react/stores/error_store.jsx
+++ b/web/react/stores/error_store.jsx
@@ -57,7 +57,7 @@ var ErrorStore = new ErrorStoreClass();
ErrorStore.dispatchToken = AppDispatcher.register((payload) => {
var action = payload.action;
switch (action.type) {
- case ActionTypes.RECIEVED_ERROR:
+ case ActionTypes.RECEIVED_ERROR:
ErrorStore.storeLastError(action.err);
ErrorStore.emitChange();
break;
diff --git a/web/react/stores/file_store.jsx b/web/react/stores/file_store.jsx
index ca8c6a96b..6d7e0f354 100644
--- a/web/react/stores/file_store.jsx
+++ b/web/react/stores/file_store.jsx
@@ -49,7 +49,7 @@ class FileStore extends EventEmitter {
const action = payload.action;
switch (action.type) {
- case ActionTypes.RECIEVED_FILE_INFO:
+ case ActionTypes.RECEIVED_FILE_INFO:
this.setInfo(action.filename, action.info);
this.emitChange(action.filename);
break;
diff --git a/web/react/stores/post_store.jsx b/web/react/stores/post_store.jsx
index 8ff58f685..b0f421b60 100644
--- a/web/react/stores/post_store.jsx
+++ b/web/react/stores/post_store.jsx
@@ -540,23 +540,23 @@ PostStore.dispatchToken = AppDispatcher.register((payload) => {
var action = payload.action;
switch (action.type) {
- case ActionTypes.RECIEVED_POSTS: {
+ case ActionTypes.RECEIVED_POSTS: {
const id = PostStore.currentFocusedPostId == null ? action.id : PostStore.currentFocusedPostId;
PostStore.checkBounds(id, action.numRequested, makePostListNonNull(action.post_list), action.before);
PostStore.storePosts(id, makePostListNonNull(action.post_list));
PostStore.emitChange();
break;
}
- case ActionTypes.RECIEVED_FOCUSED_POST:
+ case ActionTypes.RECEIVED_FOCUSED_POST:
PostStore.clearChannelVisibility(action.postId, false);
PostStore.storeFocusedPost(action.postId, makePostListNonNull(action.post_list));
PostStore.emitChange();
break;
- case ActionTypes.RECIEVED_POST:
+ case ActionTypes.RECEIVED_POST:
PostStore.storePost(action.post);
PostStore.emitChange();
break;
- case ActionTypes.RECIEVED_EDIT_POST:
+ case ActionTypes.RECEIVED_EDIT_POST:
PostStore.emitEditPost(action);
PostStore.emitChange();
break;
@@ -577,7 +577,7 @@ PostStore.dispatchToken = AppDispatcher.register((payload) => {
PostStore.removePost(action.post);
PostStore.emitChange();
break;
- case ActionTypes.RECIEVED_POST_SELECTED:
+ case ActionTypes.RECEIVED_POST_SELECTED:
PostStore.storeSelectedPost(action.post_list);
PostStore.emitSelectedPostChange(action.from_search);
break;
diff --git a/web/react/stores/preference_store.jsx b/web/react/stores/preference_store.jsx
index 7ecaf0a95..30f5468c2 100644
--- a/web/react/stores/preference_store.jsx
+++ b/web/react/stores/preference_store.jsx
@@ -159,13 +159,13 @@ class PreferenceStoreClass extends EventEmitter {
const action = payload.action;
switch (action.type) {
- case ActionTypes.RECIEVED_PREFERENCE: {
+ case ActionTypes.RECEIVED_PREFERENCE: {
const preference = action.preference;
this.setPreference(preference.category, preference.name, preference.value);
this.emitChange();
break;
}
- case ActionTypes.RECIEVED_PREFERENCES:
+ case ActionTypes.RECEIVED_PREFERENCES:
this.setPreferences(action.preferences);
this.emitChange();
break;
diff --git a/web/react/stores/search_store.jsx b/web/react/stores/search_store.jsx
index f932c379a..549f355ef 100644
--- a/web/react/stores/search_store.jsx
+++ b/web/react/stores/search_store.jsx
@@ -119,11 +119,11 @@ SearchStore.dispatchToken = AppDispatcher.register((payload) => {
var action = payload.action;
switch (action.type) {
- case ActionTypes.RECIEVED_SEARCH:
+ case ActionTypes.RECEIVED_SEARCH:
SearchStore.storeSearchResults(action.results, action.is_mention_search);
SearchStore.emitSearchChange();
break;
- case ActionTypes.RECIEVED_SEARCH_TERM:
+ case ActionTypes.RECEIVED_SEARCH_TERM:
SearchStore.storeSearchTerm(action.term);
SearchStore.emitSearchTermChange(action.do_search, action.is_mention_search);
break;
diff --git a/web/react/stores/socket_store.jsx b/web/react/stores/socket_store.jsx
index 9c3270f68..bc2bdbe64 100644
--- a/web/react/stores/socket_store.jsx
+++ b/web/react/stores/socket_store.jsx
@@ -28,10 +28,13 @@ class SocketStoreClass extends EventEmitter {
this.addChangeListener = this.addChangeListener.bind(this);
this.removeChangeListener = this.removeChangeListener.bind(this);
this.sendMessage = this.sendMessage.bind(this);
+ this.close = this.close.bind(this);
+
this.failCount = 0;
this.initialize();
}
+
initialize() {
if (!UserStore.getCurrentId()) {
return;
@@ -106,15 +109,19 @@ class SocketStoreClass extends EventEmitter {
};
}
}
+
emitChange(msg) {
this.emit(CHANGE_EVENT, msg);
}
+
addChangeListener(callback) {
this.on(CHANGE_EVENT, callback);
}
+
removeChangeListener(callback) {
this.removeListener(CHANGE_EVENT, callback);
}
+
handleMessage(msg) {
switch (msg.action) {
case SocketEvents.POSTED:
@@ -153,6 +160,7 @@ class SocketStoreClass extends EventEmitter {
default:
}
}
+
sendMessage(msg) {
if (conn && conn.readyState === WebSocket.OPEN) {
conn.send(JSON.stringify(msg));
@@ -161,9 +169,16 @@ class SocketStoreClass extends EventEmitter {
this.initialize();
}
}
+
setTranslations(messages) {
this.translations = messages;
}
+
+ close() {
+ if (conn && conn.readyState === WebSocket.OPEN) {
+ conn.close();
+ }
+ }
}
function handleNewPostEvent(msg, translations) {
@@ -305,12 +320,5 @@ function handlePreferenceChangedEvent(msg) {
var SocketStore = new SocketStoreClass();
-/*SocketStore.dispatchToken = AppDispatcher.register((payload) => {
- var action = payload.action;
-
- switch (action.type) {
- default:
- }
- });*/
-
export default SocketStore;
+window.SocketStore = SocketStore;
diff --git a/web/react/stores/team_store.jsx b/web/react/stores/team_store.jsx
index 2d518d9e7..7a1a2ef42 100644
--- a/web/react/stores/team_store.jsx
+++ b/web/react/stores/team_store.jsx
@@ -116,7 +116,7 @@ TeamStore.dispatchToken = AppDispatcher.register((payload) => {
var action = payload.action;
switch (action.type) {
- case ActionTypes.RECIEVED_TEAM:
+ case ActionTypes.RECEIVED_TEAM:
TeamStore.saveTeam(action.team);
TeamStore.emitChange();
break;
diff --git a/web/react/stores/user_store.jsx b/web/react/stores/user_store.jsx
index b97a0d87b..dd60e166f 100644
--- a/web/react/stores/user_store.jsx
+++ b/web/react/stores/user_store.jsx
@@ -336,27 +336,27 @@ UserStore.dispatchToken = AppDispatcher.register((payload) => {
var action = payload.action;
switch (action.type) {
- case ActionTypes.RECIEVED_PROFILES:
+ case ActionTypes.RECEIVED_PROFILES:
UserStore.saveProfiles(action.profiles);
UserStore.emitChange();
break;
- case ActionTypes.RECIEVED_ME:
+ case ActionTypes.RECEIVED_ME:
UserStore.setCurrentUser(action.me);
UserStore.emitChange(action.me.id);
break;
- case ActionTypes.RECIEVED_SESSIONS:
+ case ActionTypes.RECEIVED_SESSIONS:
UserStore.setSessions(action.sessions);
UserStore.emitSessionsChange();
break;
- case ActionTypes.RECIEVED_AUDITS:
+ case ActionTypes.RECEIVED_AUDITS:
UserStore.setAudits(action.audits);
UserStore.emitAuditsChange();
break;
- case ActionTypes.RECIEVED_TEAMS:
+ case ActionTypes.RECEIVED_TEAMS:
UserStore.setTeams(action.teams);
UserStore.emitTeamsChange();
break;
- case ActionTypes.RECIEVED_STATUSES:
+ case ActionTypes.RECEIVED_STATUSES:
UserStore.pSetStatuses(action.statuses);
UserStore.emitStatusesChange();
break;
diff --git a/web/react/utils/async_client.jsx b/web/react/utils/async_client.jsx
index 7cada98b7..d5fc10b8f 100644
--- a/web/react/utils/async_client.jsx
+++ b/web/react/utils/async_client.jsx
@@ -18,7 +18,7 @@ var callTracker = {};
export function dispatchError(err, method) {
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_ERROR,
+ type: ActionTypes.RECEIVED_ERROR,
err: err,
method: method
});
@@ -71,7 +71,7 @@ export function getChannels(checkVersion) {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_CHANNELS,
+ type: ActionTypes.RECEIVED_CHANNELS,
channels: data.channels,
members: data.members
});
@@ -99,7 +99,7 @@ export function getChannel(id) {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_CHANNEL,
+ type: ActionTypes.RECEIVED_CHANNEL,
channel: data.channel,
member: data.member
});
@@ -156,7 +156,7 @@ export function getMoreChannels(force) {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_MORE_CHANNELS,
+ type: ActionTypes.RECEIVED_MORE_CHANNELS,
channels: data.channels,
members: data.members
});
@@ -195,7 +195,7 @@ export function getChannelExtraInfo(id, memberLimit) {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_CHANNEL_EXTRA_INFO,
+ type: ActionTypes.RECEIVED_CHANNEL_EXTRA_INFO,
extra_info: data
});
},
@@ -222,7 +222,7 @@ export function getProfiles() {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_PROFILES,
+ type: ActionTypes.RECEIVED_PROFILES,
profiles: data
});
},
@@ -249,7 +249,7 @@ export function getSessions() {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SESSIONS,
+ type: ActionTypes.RECEIVED_SESSIONS,
sessions: data
});
},
@@ -276,7 +276,7 @@ export function getAudits() {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_AUDITS,
+ type: ActionTypes.RECEIVED_AUDITS,
audits: data
});
},
@@ -302,7 +302,7 @@ export function getLogs() {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_LOGS,
+ type: ActionTypes.RECEIVED_LOGS,
logs: data
});
},
@@ -328,7 +328,7 @@ export function getServerAudits() {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SERVER_AUDITS,
+ type: ActionTypes.RECEIVED_SERVER_AUDITS,
audits: data
});
},
@@ -354,7 +354,7 @@ export function getConfig() {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_CONFIG,
+ type: ActionTypes.RECEIVED_CONFIG,
config: data
});
},
@@ -380,7 +380,7 @@ export function getAllTeams() {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_ALL_TEAMS,
+ type: ActionTypes.RECEIVED_ALL_TEAMS,
teams: data
});
},
@@ -409,7 +409,7 @@ export function findTeams(email) {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_TEAMS,
+ type: ActionTypes.RECEIVED_TEAMS,
teams: data
});
},
@@ -437,7 +437,7 @@ export function search(terms) {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
+ type: ActionTypes.RECEIVED_SEARCH,
results: data
});
},
@@ -489,7 +489,7 @@ export function getPostsPage(id, maxPosts) {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POSTS,
+ type: ActionTypes.RECEIVED_POSTS,
id: channelId,
before: true,
numRequested: numPosts,
@@ -539,7 +539,7 @@ export function getPosts(id) {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POSTS,
+ type: ActionTypes.RECEIVED_POSTS,
id: channelId,
before: true,
numRequested: Constants.POST_CHUNK_SIZE,
@@ -578,7 +578,7 @@ export function getPostsBefore(postId, offset, numPost) {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POSTS,
+ type: ActionTypes.RECEIVED_POSTS,
id: channelId,
before: true,
numRequested: numPost,
@@ -617,7 +617,7 @@ export function getPostsAfter(postId, offset, numPost) {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POSTS,
+ type: ActionTypes.RECEIVED_POSTS,
id: channelId,
before: false,
numRequested: numPost,
@@ -650,7 +650,7 @@ export function getMe() {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_ME,
+ type: ActionTypes.RECEIVED_ME,
me: data
});
},
@@ -685,7 +685,7 @@ export function getStatuses() {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_STATUSES,
+ type: ActionTypes.RECEIVED_STATUSES,
statuses: data
});
},
@@ -711,7 +711,7 @@ export function getMyTeam() {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_TEAM,
+ type: ActionTypes.RECEIVED_TEAM,
team: data
});
},
@@ -737,7 +737,7 @@ export function getAllPreferences() {
}
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_PREFERENCES,
+ type: ActionTypes.RECEIVED_PREFERENCES,
preferences: data
});
},
@@ -754,7 +754,7 @@ export function savePreferences(preferences, success, error) {
(data, textStatus, xhr) => {
if (xhr.status !== 304) {
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_PREFERENCES,
+ type: ActionTypes.RECEIVED_PREFERENCES,
preferences
});
}
@@ -821,7 +821,7 @@ export function getFileInfo(filename) {
callTracker[callName] = 0;
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_FILE_INFO,
+ type: ActionTypes.RECEIVED_FILE_INFO,
filename,
info: data
});
diff --git a/web/react/utils/channel_intro_messages.jsx b/web/react/utils/channel_intro_messages.jsx
index 69e08f143..1aca0467e 100644
--- a/web/react/utils/channel_intro_messages.jsx
+++ b/web/react/utils/channel_intro_messages.jsx
@@ -128,7 +128,7 @@ export function createDefaultIntroMessage(channel) {
<div className='channel-intro'>
<FormattedHTMLMessage
id='intro_messages.default'
- defaultMessage="<h4 class='channel-intro__title'>Beginning of {display_name}</h4><p class='channel-intro__content'><strong>Welcome to {display_name}!'</strong><br/><br/>This is the first channel teammates see when they sign up - use it for posting updates everyone needs to know.</p>"
+ defaultMessage="<h4 class='channel-intro__title'>Beginning of {display_name}</h4><p class='channel-intro__content'><strong>Welcome to {display_name}!</strong><br/><br/>This is the first channel teammates see when they sign up - use it for posting updates everyone needs to know.</p>"
values={{
display_name: channel.display_name
}}
diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx
index d78776aa3..d7d8a2ced 100644
--- a/web/react/utils/constants.jsx
+++ b/web/react/utils/constants.jsx
@@ -5,7 +5,7 @@ import keyMirror from 'keymirror';
export default {
ActionTypes: keyMirror({
- RECIEVED_ERROR: null,
+ RECEIVED_ERROR: null,
CLICK_CHANNEL: null,
CREATE_CHANNEL: null,
@@ -14,40 +14,40 @@ export default {
POST_DELETED: null,
REMOVE_POST: null,
- RECIEVED_CHANNELS: null,
- RECIEVED_CHANNEL: null,
- RECIEVED_MORE_CHANNELS: null,
- RECIEVED_CHANNEL_EXTRA_INFO: null,
+ RECEIVED_CHANNELS: null,
+ RECEIVED_CHANNEL: null,
+ RECEIVED_MORE_CHANNELS: null,
+ RECEIVED_CHANNEL_EXTRA_INFO: null,
FOCUS_POST: null,
- RECIEVED_POSTS: null,
- RECIEVED_FOCUSED_POST: null,
- RECIEVED_POST: null,
- RECIEVED_EDIT_POST: null,
- RECIEVED_SEARCH: null,
- RECIEVED_SEARCH_TERM: null,
- RECIEVED_POST_SELECTED: null,
- RECIEVED_MENTION_DATA: null,
- RECIEVED_ADD_MENTION: null,
+ RECEIVED_POSTS: null,
+ RECEIVED_FOCUSED_POST: null,
+ RECEIVED_POST: null,
+ RECEIVED_EDIT_POST: null,
+ RECEIVED_SEARCH: null,
+ RECEIVED_SEARCH_TERM: null,
+ RECEIVED_POST_SELECTED: null,
+ RECEIVED_MENTION_DATA: null,
+ RECEIVED_ADD_MENTION: null,
- RECIEVED_PROFILES: null,
- RECIEVED_ME: null,
- RECIEVED_SESSIONS: null,
- RECIEVED_AUDITS: null,
- RECIEVED_TEAMS: null,
- RECIEVED_STATUSES: null,
- RECIEVED_PREFERENCE: null,
- RECIEVED_PREFERENCES: null,
- RECIEVED_FILE_INFO: null,
+ RECEIVED_PROFILES: null,
+ RECEIVED_ME: null,
+ RECEIVED_SESSIONS: null,
+ RECEIVED_AUDITS: null,
+ RECEIVED_TEAMS: null,
+ RECEIVED_STATUSES: null,
+ RECEIVED_PREFERENCE: null,
+ RECEIVED_PREFERENCES: null,
+ RECEIVED_FILE_INFO: null,
- RECIEVED_MSG: null,
+ RECEIVED_MSG: null,
- RECIEVED_TEAM: null,
+ RECEIVED_TEAM: null,
- RECIEVED_CONFIG: null,
- RECIEVED_LOGS: null,
- RECIEVED_SERVER_AUDITS: null,
- RECIEVED_ALL_TEAMS: null,
+ RECEIVED_CONFIG: null,
+ RECEIVED_LOGS: null,
+ RECEIVED_SERVER_AUDITS: null,
+ RECEIVED_ALL_TEAMS: null,
SHOW_SEARCH: null,
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index 4beec8d64..238a209a4 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -490,7 +490,7 @@ export function insertHtmlEntities(text) {
export function searchForTerm(term) {
AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH_TERM,
+ type: ActionTypes.RECEIVED_SEARCH_TERM,
term: term,
do_search: true
});
diff --git a/web/sass-files/sass/partials/_base.scss b/web/sass-files/sass/partials/_base.scss
index a13689382..ee6a6b955 100644
--- a/web/sass-files/sass/partials/_base.scss
+++ b/web/sass-files/sass/partials/_base.scss
@@ -25,6 +25,10 @@ body {
}
}
+b, strong {
+ font-weight: 600;
+}
+
.inner__wrap {
height: 100%;
> .row.main {
diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss
index a018315e3..cc22cc913 100644
--- a/web/sass-files/sass/partials/_post.scss
+++ b/web/sass-files/sass/partials/_post.scss
@@ -485,8 +485,9 @@ body.ios {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
position: absolute;
- top: -3px;
- left: -1.0em;
+ top: -2px;
+ left: -7px;
+ font-size: 11px;
line-height: 37px;
@include opacity(0);
}
@@ -570,11 +571,20 @@ body.ios {
li {
display: inline-block;
+ vertical-align: top;
}
.col__name {
margin-right: 7px;
font-weight: 600;
+
+ .user-popover {
+ max-width: 200px;
+ @include clearfix;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
}
.col__reply {
diff --git a/web/sass-files/sass/partials/_responsive.scss b/web/sass-files/sass/partials/_responsive.scss
index 09d498a69..5d6cbee60 100644
--- a/web/sass-files/sass/partials/_responsive.scss
+++ b/web/sass-files/sass/partials/_responsive.scss
@@ -160,6 +160,11 @@
.col__name {
pointer-events: none;
+
+ .user-popover {
+ max-width: 130px;
+ }
+
}
}
diff --git a/web/sass-files/sass/partials/_settings.scss b/web/sass-files/sass/partials/_settings.scss
index bd47ca960..bf296e913 100644
--- a/web/sass-files/sass/partials/_settings.scss
+++ b/web/sass-files/sass/partials/_settings.scss
@@ -178,9 +178,17 @@
}
}
}
+
+ .theme-elements {
+ padding-left:15px;
+ .element {
+ margin-right:10px;
+ }
+ }
+
.custom-label {
font-weight: normal;
- font-size: 13px;
+ font-size: 12px;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
diff --git a/web/sass-files/sass/partials/_sidebar--right.scss b/web/sass-files/sass/partials/_sidebar--right.scss
index f40a50b03..aaa6f4c92 100644
--- a/web/sass-files/sass/partials/_sidebar--right.scss
+++ b/web/sass-files/sass/partials/_sidebar--right.scss
@@ -16,6 +16,22 @@
}
+ .post {
+
+ .post__header {
+
+ .col__name {
+
+ .user-popover {
+ max-width: 130px;
+ }
+
+ }
+
+ }
+
+ }
+
.sidebar--right__content {
height: 100%;
@include display-flex;
diff --git a/web/static/i18n/en.json b/web/static/i18n/en.json
index caa4afae3..64d06f46d 100644
--- a/web/static/i18n/en.json
+++ b/web/static/i18n/en.json
@@ -365,6 +365,8 @@
"admin.service.developerDesc": "(Developer Option) When true, extra information around errors will be displayed in the UI.",
"admin.service.securityTitle": "Enable Security Alerts: ",
"admin.service.securityDesc": "When true, System Administrators are notified by email if a relevant security fix alert has been announced in the last 12 hours. Requires email to be enabled.",
+ "admin.service.insecureTlsTitle": "Enable Insecure Outgoing Connections: ",
+ "admin.service.insecureTlsDesc": "When true, any outgoing HTTPS requests will accept unverified, self-signed certificates. For example, outgoing webhooks to a server with a self-signed TLS certificate, using any domain, will be allowed. Note that this makes these connections susceptible to man-in-the-middle attacks.",
"admin.service.webSessionDays": "Session Length for Web in Days:",
"admin.service.webSessionDaysDesc": "The web session will expire after the number of days specified and will require a user to login again.",
"admin.service.mobileSessionDays": "Session Length for Mobile Device in Days:",
@@ -1087,8 +1089,7 @@
"user.settings.cmds.username_desc": "The username to use when overriding the post.",
"user.settings.cmds.icon_url_desc": "URL to an icon",
"user.settings.cmds.trigger_desc": "Word to trigger on",
- "user.settings.cmds.auto_complete_desc_desc": "A short description of what this commands does",
- "user.settings.cmds.auto_complete_help": "Show this command in autocomplete list.",
+ "user.settings.cmds.auto_complete_help": "Show this command in autocomplete list",
"user.settings.cmds.auto_complete_hint_desc": "List parameters to be passed to the command.",
"user.settings.cmds.request_type_desc": "Command request type issued to the callback URL.",
"user.settings.cmds.url_desc": "URL that will receive the HTTP POST or GET event",
@@ -1129,12 +1130,6 @@
"user.settings.advance.sendDesc": "If enabled 'Enter' inserts a new line and 'Ctrl + Enter' submits the message.",
"user.settings.advance.preReleaseDesc": "Check any pre-released features you'd like to preview. You may also need to refresh the page before the setting will take effect.",
"user.settings.advance.title": "Advanced Settings",
- "user.settings.appearance.themeColors": "Theme Colors",
- "user.settings.appearance.customTheme": "Custom Theme",
- "user.settings.appearance.save": "Save",
- "user.settings.appearance.cancel": "Cancel",
- "user.settings.appearance.title": "Appearance Settings",
- "user.settings.appearance.import": "Import theme colors from Slack",
"user.settings.developer.applicationsPreview": "Applications (Preview)",
"user.settings.developer.thirdParty": "Open to register a new third-party application",
"user.settings.developer.register": "Register New Application",
@@ -1194,7 +1189,6 @@
"user.settings.modal.general": "General",
"user.settings.modal.security": "Security",
"user.settings.modal.notifications": "Notifications",
- "user.settings.modal.appearance": "Appearance",
"user.settings.modal.developer": "Developer",
"user.settings.modal.integrations": "Integrations",
"user.settings.modal.display": "Display",
@@ -1245,6 +1239,11 @@
"user.settings.security.title": "Security Settings",
"user.settings.security.viewHistory": "View Access History",
"user.settings.security.logoutActiveSessions": "View and Logout of Active Sessions",
+ "user.settings.display.theme.title": "Theme",
+ "user.settings.display.theme.describe": "Open to manage your theme",
+ "user.settings.display.theme.themeColors": "Theme Colors",
+ "user.settings.display.theme.customTheme": "Custom Theme",
+ "user.settings.display.theme.import": "Import theme colors from Slack",
"view_image_popover.publicLink": "Get Public Link",
"view_image_popover.file": "File {count} of {total}",
"view_image_popover.download": "Download",
@@ -1253,7 +1252,7 @@
"intro_messages.teammate": "This is the start of your direct message history with this teammate. Direct messages and files shared here are not shown to people outside this area.",
"intro_messages.offTopic": "<h4 class=\"channel-intro__title\">Beginning of {display_name}</h4><p class=\"channel-intro__content\">This is the start of {display_name}, a channel for non-work-related conversations.<br/></p>",
"intro_messages.inviteOthers": "Invite others to this team",
- "intro_messages.default": "<h4 class='channel-intro__title'>Beginning of {display_name}</h4><p class='channel-intro__content'><strong>Welcome to {display_name}!'</strong><br/><br/>This is the first channel teammates see when they sign up - use it for posting updates everyone needs to know.</p>",
+ "intro_messages.default": "<h4 class='channel-intro__title'>Beginning of {display_name}</h4><p class='channel-intro__content'><strong>Welcome to {display_name}!</strong><br/><br/>This is the first channel teammates see when they sign up - use it for posting updates everyone needs to know.</p>",
"intro_messages.group": "private group",
"intro_messages.onlyInvited": " Only invited members can see this private group.",
"intro_messages.channel": "channel",
diff --git a/web/static/i18n/es.json b/web/static/i18n/es.json
index b22a7cfd2..a65b20e4c 100644
--- a/web/static/i18n/es.json
+++ b/web/static/i18n/es.json
@@ -303,6 +303,8 @@
"admin.service.googleTitle": "Llave de desarrolador Google:",
"admin.service.iconDescription": "Cuando es verdadero, se le permitirá cambiar el icono del mensaje desde webhooks. Nota, en combinación con permitir el cambio de nombre de usuario, podría exponer a los usuarios a sufrir ataques de phishing.",
"admin.service.iconTitle": "Habilitar el cambio de icono desde los Webhooks: ",
+ "admin.service.insecureTlsDesc": "Cuando es verdadero, cualquier solicitud de salida por HTTPS será aceptada incluso si posee certificados no verificados o autofirmados. Por ejemplo, webhooks de salida a un servidor con un certificado TLS autofirmado, utilizando cualquier dominio, será permitido. Tenga en cuenta que esto hace que estas conexiones susceptibles a los ataques hombre-en-el-medio.",
+ "admin.service.insecureTlsTitle": "Habilitar Conexiones de Salida Inseguras: ",
"admin.service.integrationAdmin": "Habilitar Integraciones sólo para administradores: ",
"admin.service.integrationAdminDesc": "Cuando es verdadero, las integraciones creadas por usuarios solo pueden ser creadas por administradores.",
"admin.service.listenAddress": "Dirección de escucha:",
@@ -1057,12 +1059,6 @@
"user.settings.advance.sendDesc": "Si está habilitado 'Retorno' inserta una nueva linea y 'Ctrl + Retorno' envía el mensaje.",
"user.settings.advance.sendTitle": "Enviar mensajes con Ctrl + Retorno",
"user.settings.advance.title": "Configuración Avanzada",
- "user.settings.appearance.cancel": "Cancelar",
- "user.settings.appearance.customTheme": "Tema personalizado",
- "user.settings.appearance.import": "Importar los colores de tema de Slack",
- "user.settings.appearance.save": "Guardar",
- "user.settings.appearance.themeColors": "Selecciona un Tema",
- "user.settings.appearance.title": "Configuraciones de Apariencia",
"user.settings.cmds.add": "Agregar",
"user.settings.cmds.add_desc": "Crea comandos que permitan enviar eventos a integraciones externas. Por favor revisa <a href=\"http://mattermost.org/commands\">http://mattermost.org/commands</a> para aprender más.",
"user.settings.cmds.add_display_name.placeholder": "Nombre a mostrar",
@@ -1074,7 +1070,6 @@
"user.settings.cmds.auto_complete.yes": "sí",
"user.settings.cmds.auto_complete_desc": "Descripción del Auto Completado: ",
"user.settings.cmds.auto_complete_desc.placeholder": "Una pequeña descripción de que hace el comando.",
- "user.settings.cmds.auto_complete_desc_desc": "Una pequeña descripción de que hace el comando",
"user.settings.cmds.auto_complete_help": "Mostrar este comando en la lista de auto completado.",
"user.settings.cmds.auto_complete_hint": "Pista de auto completado: ",
"user.settings.cmds.auto_complete_hint.placeholder": "[código postal]",
@@ -1136,6 +1131,11 @@
"user.settings.display.showNickname": "Mostrar el sobrenombre si existe, de lo contrario mostrar el nombre y apellido",
"user.settings.display.showUsername": "Mostrar el nombre de usuario (predeterminado)",
"user.settings.display.teammateDisplay": "Visualización del nombre de los integrantes",
+ "user.settings.display.theme.customTheme": "Tema Personalizado",
+ "user.settings.display.theme.describe": "Abrir para administrar tu tema",
+ "user.settings.display.theme.import": "Importar colores del tema desde Slack",
+ "user.settings.display.theme.themeColors": "Colores del Tema",
+ "user.settings.display.theme.title": "Tema",
"user.settings.display.title": "Configuración de Visualización",
"user.settings.general.checkEmail": "Revisa tu correo electrónico {email} para verificar la dirección.",
"user.settings.general.checkEmailNoAddress": "Revisa tu correo electrónico para verificar la dirección",
@@ -1205,7 +1205,6 @@
"user.settings.languages": "Cambiar Idioma",
"user.settings.languages.change": "Cambia el idioma con el que se muestra la intefaz de usuario",
"user.settings.modal.advanced": "Avanzada",
- "user.settings.modal.appearance": "Apariencia",
"user.settings.modal.confirmBtns": "Sí, Descartar",
"user.settings.modal.confirmMsg": "Tienes cambios sin guardar, ¿Estás seguro que los quieres descartar?",
"user.settings.modal.confirmTitle": "¿Descartar Cambios?",
diff --git a/web/templates/head.html b/web/templates/head.html
index b1ec905b5..da65e1779 100644
--- a/web/templates/head.html
+++ b/web/templates/head.html
@@ -122,6 +122,12 @@
}
});
});
+
+ $(window).on('beforeunload', function(){
+ if (window.SocketStore) {
+ SocketStore.close();
+ }
+ });
</script>
<script>