PLT-6262 Add config setting to disable file attachments (#6301)
* Add config setting to disable file attachments * Add unit tests * Updating UI for no attachments (#6312) * Update UI text on file upload System Console setting (#6313) * Update storage_settings.jsx * Update en.json
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
44a8f76d99
Коммит
49481caf6d
@@ -31,6 +31,11 @@ func InitFile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !*utils.Cfg.FileSettings.EnableFileAttachments {
|
||||||
|
c.Err = model.NewAppError("uploadFile", "api.file.attachments.disabled.app_error", nil, "", http.StatusNotImplemented)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if r.ContentLength > *utils.Cfg.FileSettings.MaxFileSize {
|
if r.ContentLength > *utils.Cfg.FileSettings.MaxFileSize {
|
||||||
c.Err = model.NewLocAppError("uploadFile", "api.file.upload_file.too_large.app_error", nil, "")
|
c.Err = model.NewLocAppError("uploadFile", "api.file.upload_file.too_large.app_error", nil, "")
|
||||||
c.Err.StatusCode = http.StatusRequestEntityTooLarge
|
c.Err.StatusCode = http.StatusRequestEntityTooLarge
|
||||||
@@ -181,9 +186,7 @@ func getPublicFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func getFileInfoForRequest(c *Context, r *http.Request, requireFileVisible bool) (*model.FileInfo, *model.AppError) {
|
func getFileInfoForRequest(c *Context, r *http.Request, requireFileVisible bool) (*model.FileInfo, *model.AppError) {
|
||||||
if len(utils.Cfg.FileSettings.DriverName) == 0 {
|
if len(utils.Cfg.FileSettings.DriverName) == 0 {
|
||||||
err := model.NewLocAppError("getFileInfoForRequest", "api.file.get_file_info_for_request.storage.app_error", nil, "")
|
return nil, model.NewAppError("getFileInfoForRequest", "api.file.get_info_for_request.storage.app_error", nil, "", http.StatusNotImplemented)
|
||||||
err.StatusCode = http.StatusNotImplemented
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
params := mux.Vars(r)
|
params := mux.Vars(r)
|
||||||
|
|||||||
@@ -99,6 +99,18 @@ func TestUploadFile(t *testing.T) {
|
|||||||
t.Fatalf("file preview should've been saved in %v", expectedPreviewPath)
|
t.Fatalf("file preview should've been saved in %v", expectedPreviewPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableFileAttachments := *utils.Cfg.FileSettings.EnableFileAttachments
|
||||||
|
defer func() {
|
||||||
|
*utils.Cfg.FileSettings.EnableFileAttachments = enableFileAttachments
|
||||||
|
}()
|
||||||
|
*utils.Cfg.FileSettings.EnableFileAttachments = false
|
||||||
|
|
||||||
|
if data, err := readTestFile("test.png"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if _, err = Client.UploadPostAttachment(data, channel.Id, "test.png"); err == nil {
|
||||||
|
t.Fatal("should have errored")
|
||||||
|
}
|
||||||
|
|
||||||
// Wait a bit for files to ready
|
// Wait a bit for files to ready
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,13 @@ func InitFile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !*utils.Cfg.FileSettings.EnableFileAttachments {
|
||||||
|
c.Err = model.NewAppError("uploadFile", "api.file.attachments.disabled.app_error", nil, "", http.StatusNotImplemented)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if r.ContentLength > *utils.Cfg.FileSettings.MaxFileSize {
|
if r.ContentLength > *utils.Cfg.FileSettings.MaxFileSize {
|
||||||
c.Err = model.NewLocAppError("uploadFile", "api.file.upload_file.too_large.app_error", nil, "")
|
c.Err = model.NewAppError("uploadFile", "api.file.upload_file.too_large.app_error", nil, "", http.StatusRequestEntityTooLarge)
|
||||||
c.Err.StatusCode = http.StatusRequestEntityTooLarge
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,15 @@ func TestUploadFile(t *testing.T) {
|
|||||||
|
|
||||||
_, resp = th.SystemAdminClient.UploadFile(data, channel.Id, "test.png")
|
_, resp = th.SystemAdminClient.UploadFile(data, channel.Id, "test.png")
|
||||||
CheckNoError(t, resp)
|
CheckNoError(t, resp)
|
||||||
|
|
||||||
|
enableFileAttachments := *utils.Cfg.FileSettings.EnableFileAttachments
|
||||||
|
defer func() {
|
||||||
|
*utils.Cfg.FileSettings.EnableFileAttachments = enableFileAttachments
|
||||||
|
}()
|
||||||
|
*utils.Cfg.FileSettings.EnableFileAttachments = false
|
||||||
|
|
||||||
|
_, resp = th.SystemAdminClient.UploadFile(data, channel.Id, "test.png")
|
||||||
|
CheckNotImplementedStatus(t, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetFile(t *testing.T) {
|
func TestGetFile(t *testing.T) {
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ func ReadFile(path string) ([]byte, *model.AppError) {
|
|||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, model.NewLocAppError("ReadFile", "api.file.read_file.configured.app_error", nil, "")
|
return nil, model.NewAppError("ReadFile", "api.file.read_file.configured.app_error", nil, "", http.StatusNotImplemented)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,7 @@
|
|||||||
"Symbol": false
|
"Symbol": false
|
||||||
},
|
},
|
||||||
"FileSettings": {
|
"FileSettings": {
|
||||||
|
"EnableFileAttachments": true,
|
||||||
"MaxFileSize": 52428800,
|
"MaxFileSize": 52428800,
|
||||||
"DriverName": "local",
|
"DriverName": "local",
|
||||||
"Directory": "./data/",
|
"Directory": "./data/",
|
||||||
|
|||||||
@@ -1051,7 +1051,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "api.file.get_info_for_request.storage.app_error",
|
"id": "api.file.get_info_for_request.storage.app_error",
|
||||||
"translation": "Unable to get info for file. Image storage is not configured."
|
"translation": "Unable to get info for file. File storage is not configured."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "api.file.attachments.disabled.app_error",
|
||||||
|
"translation": "File attachments have been disabled on this server."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "api.file.get_public_file_old.storage.app_error",
|
"id": "api.file.get_public_file_old.storage.app_error",
|
||||||
|
|||||||
@@ -214,6 +214,7 @@ type PasswordSettings struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type FileSettings struct {
|
type FileSettings struct {
|
||||||
|
EnableFileAttachments *bool
|
||||||
MaxFileSize *int64
|
MaxFileSize *int64
|
||||||
DriverName string
|
DriverName string
|
||||||
Directory string
|
Directory string
|
||||||
@@ -474,6 +475,11 @@ func (o *Config) SetDefaults() {
|
|||||||
*o.FileSettings.AmazonS3SSL = true // Secure by default.
|
*o.FileSettings.AmazonS3SSL = true // Secure by default.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if o.FileSettings.EnableFileAttachments == nil {
|
||||||
|
o.FileSettings.EnableFileAttachments = new(bool)
|
||||||
|
*o.FileSettings.EnableFileAttachments = true
|
||||||
|
}
|
||||||
|
|
||||||
if o.FileSettings.MaxFileSize == nil {
|
if o.FileSettings.MaxFileSize == nil {
|
||||||
o.FileSettings.MaxFileSize = new(int64)
|
o.FileSettings.MaxFileSize = new(int64)
|
||||||
*o.FileSettings.MaxFileSize = 52428800 // 50 MB
|
*o.FileSettings.MaxFileSize = 52428800 // 50 MB
|
||||||
|
|||||||
@@ -405,6 +405,7 @@ func getClientConfig(c *model.Config) map[string]string {
|
|||||||
props["ReportAProblemLink"] = *c.SupportSettings.ReportAProblemLink
|
props["ReportAProblemLink"] = *c.SupportSettings.ReportAProblemLink
|
||||||
props["SupportEmail"] = *c.SupportSettings.SupportEmail
|
props["SupportEmail"] = *c.SupportSettings.SupportEmail
|
||||||
|
|
||||||
|
props["EnableFileAttachments"] = strconv.FormatBool(*c.FileSettings.EnableFileAttachments)
|
||||||
props["EnablePublicLink"] = strconv.FormatBool(c.FileSettings.EnablePublicLink)
|
props["EnablePublicLink"] = strconv.FormatBool(c.FileSettings.EnablePublicLink)
|
||||||
props["ProfileHeight"] = fmt.Sprintf("%v", c.FileSettings.ProfileHeight)
|
props["ProfileHeight"] = fmt.Sprintf("%v", c.FileSettings.ProfileHeight)
|
||||||
props["ProfileWidth"] = fmt.Sprintf("%v", c.FileSettings.ProfileWidth)
|
props["ProfileWidth"] = fmt.Sprintf("%v", c.FileSettings.ProfileWidth)
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import store from 'stores/redux_store.jsx';
|
|||||||
const dispatch = store.dispatch;
|
const dispatch = store.dispatch;
|
||||||
const getState = store.getState;
|
const getState = store.getState;
|
||||||
import {viewChannel, getChannelAndMyMember, getChannelStats} from 'mattermost-redux/actions/channels';
|
import {viewChannel, getChannelAndMyMember, getChannelStats} from 'mattermost-redux/actions/channels';
|
||||||
|
import {setServerVersion} from 'mattermost-redux/actions/general';
|
||||||
import {ChannelTypes} from 'mattermost-redux/action_types';
|
import {ChannelTypes} from 'mattermost-redux/action_types';
|
||||||
|
|
||||||
const MAX_WEBSOCKET_FAILS = 7;
|
const MAX_WEBSOCKET_FAILS = 7;
|
||||||
@@ -390,7 +391,7 @@ function handleStatusChangedEvent(msg) {
|
|||||||
|
|
||||||
function handleHelloEvent(msg) {
|
function handleHelloEvent(msg) {
|
||||||
Client.serverVersion = msg.data.server_version;
|
Client.serverVersion = msg.data.server_version;
|
||||||
AsyncClient.checkVersion();
|
setServerVersion(msg.data.server_version)(dispatch, getState);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleWebrtc(msg) {
|
function handleWebrtc(msg) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default class StorageSettings extends AdminSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getConfigFromState(config) {
|
getConfigFromState(config) {
|
||||||
|
config.FileSettings.EnableFileAttachments = this.state.enableFileAttachments;
|
||||||
config.FileSettings.MaxFileSize = this.parseInt(this.state.maxFileSize) * 1024 * 1024;
|
config.FileSettings.MaxFileSize = this.parseInt(this.state.maxFileSize) * 1024 * 1024;
|
||||||
config.FileSettings.DriverName = this.state.driverName;
|
config.FileSettings.DriverName = this.state.driverName;
|
||||||
config.FileSettings.Directory = this.state.directory;
|
config.FileSettings.Directory = this.state.directory;
|
||||||
@@ -39,6 +40,7 @@ export default class StorageSettings extends AdminSettings {
|
|||||||
|
|
||||||
getStateFromConfig(config) {
|
getStateFromConfig(config) {
|
||||||
return {
|
return {
|
||||||
|
enableFileAttachments: config.FileSettings.EnableFileAttachments,
|
||||||
maxFileSize: config.FileSettings.MaxFileSize / 1024 / 1024,
|
maxFileSize: config.FileSettings.MaxFileSize / 1024 / 1024,
|
||||||
driverName: config.FileSettings.DriverName,
|
driverName: config.FileSettings.DriverName,
|
||||||
directory: config.FileSettings.Directory,
|
directory: config.FileSettings.Directory,
|
||||||
@@ -199,6 +201,23 @@ export default class StorageSettings extends AdminSettings {
|
|||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
disabled={this.state.driverName !== DRIVER_S3}
|
disabled={this.state.driverName !== DRIVER_S3}
|
||||||
/>
|
/>
|
||||||
|
<BooleanSetting
|
||||||
|
id='enableFileAttachments'
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='admin.file.enableFileAttachments'
|
||||||
|
defaultMessage='Enable File Attachments:'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
helpText={
|
||||||
|
<FormattedMessage
|
||||||
|
id='admin.file.enableFileAttachmentsDesc'
|
||||||
|
defaultMessage='When false, disable file and image uploads on messages.'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
value={this.state.enableFileAttachments}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
/>
|
||||||
<TextSetting
|
<TextSetting
|
||||||
id='maxFileSize'
|
id='maxFileSize'
|
||||||
label={
|
label={
|
||||||
@@ -216,6 +235,7 @@ export default class StorageSettings extends AdminSettings {
|
|||||||
}
|
}
|
||||||
value={this.state.maxFileSize}
|
value={this.state.maxFileSize}
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
|
disabled={!this.state.enableFileAttachments}
|
||||||
/>
|
/>
|
||||||
</SettingsGroup>
|
</SettingsGroup>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -630,6 +630,11 @@ export default class CreatePost extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let attachmentsDisabled = '';
|
||||||
|
if (global.window.mm_config.EnableFileAttachments === 'false') {
|
||||||
|
attachmentsDisabled = ' post-create--attachment-disabled';
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
id='create_post'
|
id='create_post'
|
||||||
@@ -638,7 +643,7 @@ export default class CreatePost extends React.Component {
|
|||||||
className={centerClass}
|
className={centerClass}
|
||||||
onSubmit={this.handleSubmit}
|
onSubmit={this.handleSubmit}
|
||||||
>
|
>
|
||||||
<div className='post-create'>
|
<div className={'post-create' + attachmentsDisabled}>
|
||||||
<div className='post-create-body'>
|
<div className='post-create-body'>
|
||||||
<div className='post-body__cell'>
|
<div className='post-body__cell'>
|
||||||
<Textbox
|
<Textbox
|
||||||
|
|||||||
@@ -132,6 +132,11 @@ class FileUpload extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleDrop(e) {
|
handleDrop(e) {
|
||||||
|
if (global.window.mm_config.EnableFileAttachments === 'false') {
|
||||||
|
this.props.onUploadError(Utils.localizeMessage('file_upload.disabled', 'File attachments are disabled.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.props.onUploadError(null);
|
this.props.onUploadError(null);
|
||||||
|
|
||||||
var files = e.originalEvent.dataTransfer.files;
|
var files = e.originalEvent.dataTransfer.files;
|
||||||
@@ -163,7 +168,9 @@ class FileUpload extends React.Component {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(containerSelector).dragster({
|
let dragsterActions = {};
|
||||||
|
if (global.window.mm_config.EnableFileAttachments === 'true') {
|
||||||
|
dragsterActions = {
|
||||||
enter(dragsterEvent, e) {
|
enter(dragsterEvent, e) {
|
||||||
var files = e.originalEvent.dataTransfer;
|
var files = e.originalEvent.dataTransfer;
|
||||||
|
|
||||||
@@ -192,7 +199,16 @@ class FileUpload extends React.Component {
|
|||||||
|
|
||||||
self.handleDrop(e);
|
self.handleDrop(e);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
} else {
|
||||||
|
dragsterActions = {
|
||||||
|
drop(dragsterEvent, e) {
|
||||||
|
self.handleDrop(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$(containerSelector).dragster(dragsterActions);
|
||||||
|
|
||||||
this.props.onFileUploadChange();
|
this.props.onFileUploadChange();
|
||||||
}
|
}
|
||||||
@@ -247,7 +263,12 @@ class FileUpload extends React.Component {
|
|||||||
|
|
||||||
// This looks redundant, but must be done this way due to
|
// This looks redundant, but must be done this way due to
|
||||||
// setState being an asynchronous call
|
// setState being an asynchronous call
|
||||||
if (items) {
|
if (items && items.length > 0) {
|
||||||
|
if (global.window.mm_config.EnableFileAttachments === 'false') {
|
||||||
|
this.props.onUploadError(Utils.localizeMessage('file_upload.disabled', 'File attachments are disabled.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var numToUpload = Math.min(Constants.MAX_UPLOAD_FILES - this.props.getFileCount(ChannelStore.getCurrentId()), items.length);
|
var numToUpload = Math.min(Constants.MAX_UPLOAD_FILES - this.props.getFileCount(ChannelStore.getCurrentId()), items.length);
|
||||||
|
|
||||||
if (items.length > numToUpload) {
|
if (items.length > numToUpload) {
|
||||||
@@ -305,6 +326,12 @@ class FileUpload extends React.Component {
|
|||||||
keyUpload(e) {
|
keyUpload(e) {
|
||||||
if (Utils.cmdOrCtrlPressed(e) && e.keyCode === Constants.KeyCodes.U) {
|
if (Utils.cmdOrCtrlPressed(e) && e.keyCode === Constants.KeyCodes.U) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (global.window.mm_config.EnableFileAttachments === 'false') {
|
||||||
|
this.props.onUploadError(Utils.localizeMessage('file_upload.disabled', 'File attachments are disabled.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((this.props.postType === 'post' && document.activeElement.id === 'post_textbox') ||
|
if ((this.props.postType === 'post' && document.activeElement.id === 'post_textbox') ||
|
||||||
(this.props.postType === 'comment' && document.activeElement.id === 'reply_textbox')) {
|
(this.props.postType === 'comment' && document.activeElement.id === 'reply_textbox')) {
|
||||||
$(this.refs.fileInput).focus().trigger('click');
|
$(this.refs.fileInput).focus().trigger('click');
|
||||||
@@ -361,11 +388,9 @@ class FileUpload extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
let fileDiv;
|
||||||
<span
|
if (global.window.mm_config.EnableFileAttachments === 'true') {
|
||||||
ref='input'
|
fileDiv = (
|
||||||
className={'btn btn-file' + (uploadsRemaining <= 0 ? ' btn-file__disabled' : '')}
|
|
||||||
>
|
|
||||||
<div className='icon--attachment'>
|
<div className='icon--attachment'>
|
||||||
<span
|
<span
|
||||||
className='icon'
|
className='icon'
|
||||||
@@ -380,6 +405,15 @@ class FileUpload extends React.Component {
|
|||||||
accept={accept}
|
accept={accept}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
ref='input'
|
||||||
|
className={'btn btn-file' + (uploadsRemaining <= 0 ? ' btn-file__disabled' : '')}
|
||||||
|
>
|
||||||
|
{fileDiv}
|
||||||
{emojiSpan}
|
{emojiSpan}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -300,6 +300,8 @@
|
|||||||
"admin.email.smtpUsernameTitle": "SMTP Server Username:",
|
"admin.email.smtpUsernameTitle": "SMTP Server Username:",
|
||||||
"admin.email.testing": "Testing...",
|
"admin.email.testing": "Testing...",
|
||||||
"admin.false": "false",
|
"admin.false": "false",
|
||||||
|
"admin.file.enableFileAttachments": "Enable File Attachments:",
|
||||||
|
"admin.file.enableFileAttachmentsDesc": "When false, disable file and image uploads on messages.",
|
||||||
"admin.file_upload.chooseFile": "Choose File",
|
"admin.file_upload.chooseFile": "Choose File",
|
||||||
"admin.file_upload.noFile": "No file uploaded",
|
"admin.file_upload.noFile": "No file uploaded",
|
||||||
"admin.file_upload.uploadFile": "Upload",
|
"admin.file_upload.uploadFile": "Upload",
|
||||||
@@ -1324,6 +1326,7 @@
|
|||||||
"file_info_preview.type": "File type ",
|
"file_info_preview.type": "File type ",
|
||||||
"file_upload.fileAbove": "File above {max}MB cannot be uploaded: {filename}",
|
"file_upload.fileAbove": "File above {max}MB cannot be uploaded: {filename}",
|
||||||
"file_upload.filesAbove": "Files above {max}MB cannot be uploaded: {filenames}",
|
"file_upload.filesAbove": "Files above {max}MB cannot be uploaded: {filenames}",
|
||||||
|
"file_upload.disabled": "File attachments are disabled.",
|
||||||
"file_upload.limited": "Uploads limited to {count} files maximum. Please use additional posts for more files.",
|
"file_upload.limited": "Uploads limited to {count} files maximum. Please use additional posts for more files.",
|
||||||
"file_upload.pasted": "Image Pasted at ",
|
"file_upload.pasted": "Image Pasted at ",
|
||||||
"filtered_channels_list.count": "{count} {count, plural, =0 {0 channels} one {channel} other {channels}}",
|
"filtered_channels_list.count": "{count} {count, plural, =0 {0 channels} one {channel} other {channels}}",
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import PDFJS from 'pdfjs-dist';
|
|||||||
|
|
||||||
import * as Websockets from 'actions/websocket_actions.jsx';
|
import * as Websockets from 'actions/websocket_actions.jsx';
|
||||||
import {loadMeAndConfig} from 'actions/user_actions.jsx';
|
import {loadMeAndConfig} from 'actions/user_actions.jsx';
|
||||||
import BrowserStore from 'stores/browser_store.jsx';
|
|
||||||
import ChannelStore from 'stores/channel_store.jsx';
|
import ChannelStore from 'stores/channel_store.jsx';
|
||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
import * as I18n from 'i18n/i18n.jsx';
|
import * as I18n from 'i18n/i18n.jsx';
|
||||||
@@ -86,7 +85,6 @@ function preRenderSetup(callwhendone) {
|
|||||||
() => {
|
() => {
|
||||||
// Turn off to prevent getting stuck in a loop
|
// Turn off to prevent getting stuck in a loop
|
||||||
$(window).off('beforeunload');
|
$(window).off('beforeunload');
|
||||||
BrowserStore.setLastServerVersion('');
|
|
||||||
if (UserStore.getCurrentUser()) {
|
if (UserStore.getCurrentUser()) {
|
||||||
viewChannel('', ChannelStore.getCurrentId() || '')(dispatch, getState);
|
viewChannel('', ChannelStore.getCurrentId() || '')(dispatch, getState);
|
||||||
}
|
}
|
||||||
@@ -120,6 +118,18 @@ function renderRootComponent() {
|
|||||||
document.getElementById('root'));
|
document.getElementById('root'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let serverVersion = '';
|
||||||
|
|
||||||
|
store.subscribe(() => {
|
||||||
|
const newServerVersion = getState().entities.general.serverVersion;
|
||||||
|
if (serverVersion && serverVersion !== newServerVersion) {
|
||||||
|
console.log('Detected version update refreshing the page'); //eslint-disable-line no-console
|
||||||
|
window.location.reload(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
serverVersion = newServerVersion;
|
||||||
|
});
|
||||||
|
|
||||||
global.window.setup_root = () => {
|
global.window.setup_root = () => {
|
||||||
// Do the pre-render setup and call renderRootComponent when done
|
// Do the pre-render setup and call renderRootComponent when done
|
||||||
preRenderSetup(renderRootComponent);
|
preRenderSetup(renderRootComponent);
|
||||||
|
|||||||
@@ -32,6 +32,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.post-create__container {
|
.post-create__container {
|
||||||
|
.post-create {
|
||||||
|
&.post-create--attachment-disabled {
|
||||||
|
.post-body__cell {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-create-footer {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
padding: .5em 0 0;
|
padding: .5em 0 0;
|
||||||
}
|
}
|
||||||
@@ -71,6 +83,10 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
top: auto;
|
top: auto;
|
||||||
width: 25px;
|
width: 25px;
|
||||||
|
|
||||||
|
.icon--emoji-picker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,14 +75,6 @@ class BrowserStoreClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getLastServerVersion() {
|
|
||||||
return this.getGlobalItem('last_server_version');
|
|
||||||
}
|
|
||||||
|
|
||||||
setLastServerVersion(version) {
|
|
||||||
this.setGlobalItem('last_server_version', version);
|
|
||||||
}
|
|
||||||
|
|
||||||
signalLogout() {
|
signalLogout() {
|
||||||
if (this.isLocalStorageSupported()) {
|
if (this.isLocalStorageSupported()) {
|
||||||
// PLT-1285 store an identifier in session storage so we can catch if the logout came from this tab on IE11
|
// PLT-1285 store an identifier in session storage so we can catch if the logout came from this tab on IE11
|
||||||
@@ -144,7 +136,6 @@ class BrowserStoreClass {
|
|||||||
clear() {
|
clear() {
|
||||||
// persist some values through logout since they're independent of which user is logged in
|
// persist some values through logout since they're independent of which user is logged in
|
||||||
const logoutId = sessionStorage.getItem('__logout__');
|
const logoutId = sessionStorage.getItem('__logout__');
|
||||||
const serverVersion = this.getLastServerVersion();
|
|
||||||
const landingPageSeen = this.hasSeenLandingPage();
|
const landingPageSeen = this.hasSeenLandingPage();
|
||||||
const selectedTeams = this.getItem('selected_teams');
|
const selectedTeams = this.getItem('selected_teams');
|
||||||
const recentEmojis = localStorage.getItem(Constants.RECENT_EMOJI_KEY);
|
const recentEmojis = localStorage.getItem(Constants.RECENT_EMOJI_KEY);
|
||||||
@@ -160,10 +151,6 @@ class BrowserStoreClass {
|
|||||||
sessionStorage.setItem('__logout__', logoutId);
|
sessionStorage.setItem('__logout__', logoutId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverVersion) {
|
|
||||||
this.setLastServerVersion(serverVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (landingPageSeen) {
|
if (landingPageSeen) {
|
||||||
this.setLandingPageSeen(landingPageSeen);
|
this.setLandingPageSeen(landingPageSeen);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See License.txt for license information.
|
// See License.txt for license information.
|
||||||
|
|
||||||
import BrowserStore from 'stores/browser_store.jsx';
|
|
||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
import TeamStore from 'stores/team_store.jsx';
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
|
|
||||||
@@ -21,6 +20,12 @@ const callTracker = {};
|
|||||||
|
|
||||||
const ASYNC_CLIENT_TIMEOUT = 5000;
|
const ASYNC_CLIENT_TIMEOUT = 5000;
|
||||||
|
|
||||||
|
// Redux actions
|
||||||
|
import store from 'stores/redux_store.jsx';
|
||||||
|
const dispatch = store.dispatch;
|
||||||
|
const getState = store.getState;
|
||||||
|
import {setServerVersion} from 'mattermost-redux/actions/general';
|
||||||
|
|
||||||
export function dispatchError(err, method) {
|
export function dispatchError(err, method) {
|
||||||
AppDispatcher.handleServerAction({
|
AppDispatcher.handleServerAction({
|
||||||
type: ActionTypes.RECEIVED_ERROR,
|
type: ActionTypes.RECEIVED_ERROR,
|
||||||
@@ -47,17 +52,7 @@ function isCallInProgress(callName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function checkVersion() {
|
export function checkVersion() {
|
||||||
var serverVersion = Client.getServerVersion();
|
setServerVersion(Client.getServerVersion())(dispatch, getState);
|
||||||
|
|
||||||
if (serverVersion !== BrowserStore.getLastServerVersion()) {
|
|
||||||
if (!BrowserStore.getLastServerVersion() || BrowserStore.getLastServerVersion() === '') {
|
|
||||||
BrowserStore.setLastServerVersion(serverVersion);
|
|
||||||
} else {
|
|
||||||
BrowserStore.setLastServerVersion(serverVersion);
|
|
||||||
window.location.reload(true);
|
|
||||||
console.log('Detected version update refreshing the page'); //eslint-disable-line no-console
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUser(userId, success, error) {
|
export function getUser(userId, success, error) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user