@scaleflex/widget-core 4.4.0 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/style.css +229 -0
- package/dist/style.min.css +1 -0
- package/lib/Client.js +390 -0
- package/lib/Plugin.js +298 -0
- package/lib/Providers.js +112 -0
- package/lib/SassKeyRenewer.js +332 -0
- package/lib/createStore.js +45 -0
- package/lib/defaultLocale.js +75 -0
- package/lib/hooks/index.js +7 -0
- package/lib/hooks/useContextMenu.js +42 -0
- package/lib/hooks/useContextMenuData.js +17 -0
- package/lib/hooks/useCore.js +10 -0
- package/lib/hooks/useModal.js +72 -0
- package/lib/hooks/useModalData.js +7 -0
- package/lib/hooks/usePlugin.js +20 -0
- package/lib/hooks/usePluginsType.js +18 -0
- package/lib/index.js +1932 -0
- package/lib/loggers.js +45 -0
- package/lib/slices/common.slice.js +90 -0
- package/lib/slices/index.js +12 -0
- package/lib/slices/info.slice.js +52 -0
- package/lib/slices/uploads.slice.js +294 -0
- package/lib/slices/user.slice.js +256 -0
- package/lib/supportsUploadProgress.js +42 -0
- package/lib/utils/calculateTotalEta.js +21 -0
- package/package.json +3 -3
package/lib/index.js
ADDED
|
@@ -0,0 +1,1932 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
3
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
5
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
6
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
7
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
8
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
9
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
10
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
11
|
+
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
12
|
+
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
13
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
14
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
15
|
+
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
16
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
17
|
+
function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
|
|
18
|
+
function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
|
|
19
|
+
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
|
|
20
|
+
function _wrapNativeSuper(t) { var r = "function" == typeof Map ? new Map() : void 0; return _wrapNativeSuper = function _wrapNativeSuper(t) { if (null === t || !_isNativeFunction(t)) return t; if ("function" != typeof t) throw new TypeError("Super expression must either be null or a function"); if (void 0 !== r) { if (r.has(t)) return r.get(t); r.set(t, Wrapper); } function Wrapper() { return _construct(t, arguments, _getPrototypeOf(this).constructor); } return Wrapper.prototype = Object.create(t.prototype, { constructor: { value: Wrapper, enumerable: !1, writable: !0, configurable: !0 } }), _setPrototypeOf(Wrapper, t); }, _wrapNativeSuper(t); }
|
|
21
|
+
function _construct(t, e, r) { if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); var o = [null]; o.push.apply(o, e); var p = new (t.bind.apply(t, o))(); return r && _setPrototypeOf(p, r.prototype), p; }
|
|
22
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
23
|
+
function _isNativeFunction(t) { try { return -1 !== Function.toString.call(t).indexOf("[native code]"); } catch (n) { return "function" == typeof t; } }
|
|
24
|
+
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
|
|
25
|
+
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
|
|
26
|
+
import React from 'react';
|
|
27
|
+
import ReactDOM from 'react-dom';
|
|
28
|
+
import ee from 'namespace-emitter';
|
|
29
|
+
import cuid from 'cuid';
|
|
30
|
+
import prettierBytes from '@transloadit/prettier-bytes';
|
|
31
|
+
import match from 'mime-match';
|
|
32
|
+
import getFileType from '@scaleflex/widget-utils/lib/getFileType';
|
|
33
|
+
import Translator from '@scaleflex/widget-utils/lib/Translator';
|
|
34
|
+
import getFileNameAndExtension from '@scaleflex/widget-utils/lib/getFileNameAndExtension';
|
|
35
|
+
import generateFileId from '@scaleflex/widget-utils/lib/generateFileId';
|
|
36
|
+
import checkConnection from '@scaleflex/widget-utils/lib/checkConnection';
|
|
37
|
+
import handlePromise from '@scaleflex/widget-utils/lib/handlePromise';
|
|
38
|
+
import { PERMISSIONS, RESTRICTED_FILES_EXTENISONS, PLUGINS_IDS, FILE_UPLOAD_STATUS, PROGRESS_PANEL_ACTIVITY, ABORTED_ERROR } from '@scaleflex/widget-utils/lib/constants';
|
|
39
|
+
import { getBackendTranslations } from '@scaleflex/widget-utils/lib/i18n.client';
|
|
40
|
+
import extractFileDataNoBlob from '@scaleflex/widget-utils/lib/extractFileDataNoBlob';
|
|
41
|
+
import getFileExtension from '@scaleflex/widget-utils/lib/getFileExtension';
|
|
42
|
+
import convertBytesToMb from '@scaleflex/widget-utils/lib/convertBytesToMb';
|
|
43
|
+
import { justErrorsLogger, debugLogger } from './loggers';
|
|
44
|
+
import Plugin from './Plugin'; // Exported from here.
|
|
45
|
+
import defaultLocale from './defaultLocale';
|
|
46
|
+
import createStore from './createStore';
|
|
47
|
+
import { uploadUpdated, selectUploadById, selectUploads, selectUploadsArray, selectUploadCapabilities, uploadCapabilitiesUpdated, updateUploadInfoMetaTags, uploadsAdded, uploadsRemoved, allUploadsCancelled, allUploadsRemoved } from './slices/uploads.slice';
|
|
48
|
+
import { fetchUserAuthState, generateUserKey as _generateUserKey, saveUserSassKey, selectUserPermissions, selectUserSassKey, selectUserSecurityData, userInfoUpdated } from './slices/user.slice';
|
|
49
|
+
import { infoHid, infoSet } from './slices/info.slice';
|
|
50
|
+
import { coreCommonStateUpdated, selectCommonState, selectCoreLoading, selectCurrentFolderPath } from './slices/common.slice';
|
|
51
|
+
import Client from './Client';
|
|
52
|
+
import SassKeyRenewer from './SassKeyRenewer';
|
|
53
|
+
|
|
54
|
+
// TODO: find a way to show version of the current plugin
|
|
55
|
+
// why solution below isn't good?
|
|
56
|
+
// first import doesn't work with webpack 5 as it was deprecated
|
|
57
|
+
// second import fixes webpack 5 issue as it was mentioned in their docs
|
|
58
|
+
// but it exposes our package.json to the client and it is mentioned as security rist in mutiple places
|
|
59
|
+
// https://github.com/axelpale/genversion
|
|
60
|
+
// https://stackoverflow.com/questions/64993118/error-should-not-import-the-named-export-version-imported-as-version
|
|
61
|
+
// https://stackoverflow.com/questions/9153571/is-there-a-way-to-get-version-from-package-json-in-nodejs-code/10855054#10855054
|
|
62
|
+
// import { version } from '../package.json'
|
|
63
|
+
// import packageInfo from '../package.json'
|
|
64
|
+
|
|
65
|
+
// HACK until this issue fixed -- https://scaleflexhq.atlassian.net/browse/FRA-1673
|
|
66
|
+
window.React = React;
|
|
67
|
+
window.ReactDOM = ReactDOM;
|
|
68
|
+
var RestrictionError = /*#__PURE__*/function (_Error) {
|
|
69
|
+
function RestrictionError() {
|
|
70
|
+
var _this;
|
|
71
|
+
_classCallCheck(this, RestrictionError);
|
|
72
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
73
|
+
args[_key] = arguments[_key];
|
|
74
|
+
}
|
|
75
|
+
_this = _callSuper(this, RestrictionError, [].concat(args));
|
|
76
|
+
_this.isRestriction = true;
|
|
77
|
+
return _this;
|
|
78
|
+
}
|
|
79
|
+
_inherits(RestrictionError, _Error);
|
|
80
|
+
return _createClass(RestrictionError);
|
|
81
|
+
}(/*#__PURE__*/_wrapNativeSuper(Error));
|
|
82
|
+
/**
|
|
83
|
+
* filerobot Core module.
|
|
84
|
+
* Manages plugins, state updates, acts as an event bus,
|
|
85
|
+
* adds/removes files and metadata.
|
|
86
|
+
*/
|
|
87
|
+
var ScaleflexWidget = /*#__PURE__*/function () {
|
|
88
|
+
/**
|
|
89
|
+
* Instantiate filerobot
|
|
90
|
+
*
|
|
91
|
+
* @param {object} opts — filerobot options
|
|
92
|
+
*/
|
|
93
|
+
function ScaleflexWidget(opts) {
|
|
94
|
+
var _this2 = this;
|
|
95
|
+
_classCallCheck(this, ScaleflexWidget);
|
|
96
|
+
_defineProperty(this, "loadBackendTranslations", function () {
|
|
97
|
+
if (!_this2.backendTranslations) {
|
|
98
|
+
handlePromise(getBackendTranslations({
|
|
99
|
+
i18nFetchApiEndpoint: _this2.opts.i18nFetchApiEndpoint
|
|
100
|
+
}), function (translations) {
|
|
101
|
+
var _this2$currLngBackend;
|
|
102
|
+
if (!((_this2$currLngBackend = _this2.currLngBackendTranslations) !== null && _this2$currLngBackend !== void 0 && _this2$currLngBackend.strings)) {
|
|
103
|
+
_this2.currLngBackendTranslations = {
|
|
104
|
+
strings: {}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
_this2.backendTranslations = translations;
|
|
108
|
+
_this2.updateCurrLngBackendTranslations();
|
|
109
|
+
}, function () {
|
|
110
|
+
var _this2$currLngBackend2;
|
|
111
|
+
if (!((_this2$currLngBackend2 = _this2.currLngBackendTranslations) !== null && _this2$currLngBackend2 !== void 0 && _this2$currLngBackend2.strings)) {
|
|
112
|
+
_this2.currLngBackendTranslations = {
|
|
113
|
+
strings: {}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
_this2.updateCurrLngBackendTranslations();
|
|
117
|
+
_this2.info.apply(_this2, arguments);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
_defineProperty(this, "updateCurrLngBackendTranslations", function () {
|
|
122
|
+
var _ref = _this2.opts || {},
|
|
123
|
+
language = _ref.language;
|
|
124
|
+
if (!language) return;
|
|
125
|
+
var currentLanguage = language.toLowerCase();
|
|
126
|
+
Translator.LANGUAGE = currentLanguage;
|
|
127
|
+
var backendTranslations = _this2.backendTranslations || [];
|
|
128
|
+
backendTranslations.forEach(function (translation) {
|
|
129
|
+
_this2.currLngBackendTranslations.strings[translation.translation_key] = translation.translations[currentLanguage];
|
|
130
|
+
});
|
|
131
|
+
_this2.i18nInit();
|
|
132
|
+
_this2.updateAllPluginsI18n();
|
|
133
|
+
_this2.refreshPluginsOptions();
|
|
134
|
+
});
|
|
135
|
+
_defineProperty(this, "updateAllPluginsI18n", function () {
|
|
136
|
+
_this2.iteratePlugins(function (plugin) {
|
|
137
|
+
if (typeof plugin.i18nInit === 'function') {
|
|
138
|
+
plugin.i18nInit();
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
_defineProperty(this, "_getInstalledPkgs", function () {
|
|
143
|
+
// We are always returning a new reference from plugins object, incase of using memoized value for the reference of the object
|
|
144
|
+
// So that we guarantee a rerender in all cases whether memoized or not.
|
|
145
|
+
return {
|
|
146
|
+
filerobot: _this2,
|
|
147
|
+
plugins: _objectSpread({}, _this2.plugins)
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
_defineProperty(this, "refreshPluginsOptions", function () {
|
|
151
|
+
_this2.emit('opts-updated', _this2._getInstalledPkgs());
|
|
152
|
+
});
|
|
153
|
+
// TODO: [Relevance] remove show/hide relevance when BE is done
|
|
154
|
+
_defineProperty(this, "showRelevance", function () {
|
|
155
|
+
_this2.setCoreCommonState({
|
|
156
|
+
isRelevanceAvailable: true
|
|
157
|
+
});
|
|
158
|
+
localStorage.setItem('show-relevance', 'true');
|
|
159
|
+
return 'Relevance activated, search by something to view relevance badge';
|
|
160
|
+
});
|
|
161
|
+
_defineProperty(this, "hideRelevance", function () {
|
|
162
|
+
_this2.setCoreCommonState({
|
|
163
|
+
isRelevanceAvailable: false
|
|
164
|
+
});
|
|
165
|
+
localStorage.removeItem('show-relevance');
|
|
166
|
+
return 'Relevance deactivated, search by something to hide relevance badge';
|
|
167
|
+
});
|
|
168
|
+
_defineProperty(this, "enableSearchDebugging", function () {
|
|
169
|
+
localStorage.setItem('debug_search', true);
|
|
170
|
+
return 'Search debugging enabled, hover on any asset to show debug info';
|
|
171
|
+
});
|
|
172
|
+
_defineProperty(this, "disableSearchDebugging", function () {
|
|
173
|
+
localStorage.setItem('debug_search', false);
|
|
174
|
+
return 'Search debugging disabled';
|
|
175
|
+
});
|
|
176
|
+
this.defaultLocale = {
|
|
177
|
+
strings: defaultLocale
|
|
178
|
+
};
|
|
179
|
+
this.timeoutNoPermissionsInfoId = null;
|
|
180
|
+
var defaultOptions = {
|
|
181
|
+
id: 'scaleflexWidget',
|
|
182
|
+
autoProceed: false,
|
|
183
|
+
allowMultipleUploads: true,
|
|
184
|
+
debug: false,
|
|
185
|
+
restrictions: {
|
|
186
|
+
maxFileSize: null,
|
|
187
|
+
maxTotalFilesSize: null,
|
|
188
|
+
maxNumberOfFiles: null,
|
|
189
|
+
minNumberOfFiles: null,
|
|
190
|
+
allowedFileTypes: null,
|
|
191
|
+
maxItemsSizeForCompression: null,
|
|
192
|
+
hideRestrictionsInformer: false,
|
|
193
|
+
// Folder import restrictions in remote uploads (GoogleDrive...etc.)
|
|
194
|
+
remoteMaxFolderImportCount: 500,
|
|
195
|
+
remoteMaxFolderImportSize: 10737418240,
|
|
196
|
+
// 10 GB in bytes
|
|
197
|
+
remoteMaxFolderDepth: 5,
|
|
198
|
+
remoteMaxFolderCount: 100
|
|
199
|
+
},
|
|
200
|
+
customUploadedFilesSizeInMb: 0,
|
|
201
|
+
onBeforeFileAdded: function onBeforeFileAdded(currentFile, files) {
|
|
202
|
+
return currentFile;
|
|
203
|
+
},
|
|
204
|
+
onBeforeUpload: function onBeforeUpload(files) {
|
|
205
|
+
return files;
|
|
206
|
+
},
|
|
207
|
+
logger: justErrorsLogger,
|
|
208
|
+
dev: false,
|
|
209
|
+
container: undefined,
|
|
210
|
+
securityTemplateId: undefined,
|
|
211
|
+
akamaiMode: false,
|
|
212
|
+
userPermissions: [],
|
|
213
|
+
userFoldersScope: [],
|
|
214
|
+
apiEndpoint: '',
|
|
215
|
+
skipApiEndpointToken: false,
|
|
216
|
+
apiEndpointVersion: 'v5',
|
|
217
|
+
adminApiEndpoint: '',
|
|
218
|
+
i18nFetchApiEndpoint: 'https://i18n-fastly.ultrafast.io/api',
|
|
219
|
+
shareApiEndpoint: '',
|
|
220
|
+
videoApiEndpoint: '',
|
|
221
|
+
language: 'en',
|
|
222
|
+
theme: {
|
|
223
|
+
breakpoints: {
|
|
224
|
+
values: {
|
|
225
|
+
xs: 0,
|
|
226
|
+
sm: 576,
|
|
227
|
+
md: 768,
|
|
228
|
+
lg: 1084,
|
|
229
|
+
xl: 1342,
|
|
230
|
+
xxl: 1600,
|
|
231
|
+
xxxl: 1920
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
userInfo: {
|
|
236
|
+
email: '',
|
|
237
|
+
name: '',
|
|
238
|
+
photo_uri: '',
|
|
239
|
+
uuid: ''
|
|
240
|
+
},
|
|
241
|
+
sassKeyRenewerEnabled: true
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
// Merge default options with the ones set by user,
|
|
245
|
+
// making sure to merge restrictions too
|
|
246
|
+
this.opts = _objectSpread(_objectSpread(_objectSpread({}, defaultOptions), opts), {}, {
|
|
247
|
+
securityTemplateId: opts.securityTemplateId || opts.securityTemplateID || defaultOptions.securityTemplateId,
|
|
248
|
+
// Old config name alias securityTemplateID->securityTemplateId. DEPRECATE SOON!
|
|
249
|
+
restrictions: _objectSpread(_objectSpread({}, defaultOptions.restrictions), opts && opts.restrictions),
|
|
250
|
+
userInfo: _objectSpread(_objectSpread({}, defaultOptions.userInfo), (opts === null || opts === void 0 ? void 0 : opts.userInfo) || {})
|
|
251
|
+
});
|
|
252
|
+
this.opts.apiEndpoint = (this.opts.apiEndpoint || '').trim().replace(/\/$/, '');
|
|
253
|
+
this.opts.adminApiEndpoint = (this.opts.adminApiEndpoint || '').trim().replace(/\/$/, '');
|
|
254
|
+
this.opts.shareApiEndpoint = (this.opts.shareApiEndpoint || '').trim().replace(/\/$/, '');
|
|
255
|
+
this.opts.videoApiEndpoint = (this.opts.videoApiEndpoint || '').trim().replace(/\/$/, '');
|
|
256
|
+
this.opts.i18nFetchApiEndpoint = (this.opts.i18nFetchApiEndpoint || '').trim().replace(/\/$/, '');
|
|
257
|
+
if (!this.opts.apiEndpoint) {
|
|
258
|
+
this.opts.apiEndpoint = this.opts.dev ? 'https://api-dev.filerobot.com' : 'https://api.filerobot.com';
|
|
259
|
+
}
|
|
260
|
+
if (!this.opts.adminApiEndpoint) {
|
|
261
|
+
this.opts.adminApiEndpoint = this.opts.dev ? 'https://hub-dev.filerobot.com/api' : 'https://hub.filerobot.com/api';
|
|
262
|
+
}
|
|
263
|
+
if (!this.opts.shareApiEndpoint) {
|
|
264
|
+
this.opts.shareApiEndpoint = this.opts.dev ? 'https://share-dev.filerobot.com' : 'https://share.filerobot.com';
|
|
265
|
+
}
|
|
266
|
+
if (!this.opts.videoApiEndpoint) {
|
|
267
|
+
this.opts.videoApiEndpoint = 'https://api.filerobot.com/videos/v2';
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Separate option for easier usage as it respects skipApiEndpointToken (no need to check in each use case)
|
|
271
|
+
this.opts.apiEndpointWithContainer = "".concat(this.opts.apiEndpoint).concat(!this.opts.skipApiEndpointToken && this.opts.container ? "/".concat(this.opts.container) : '');
|
|
272
|
+
|
|
273
|
+
// opts instead of this.opts to avoid comparing objects — we set logger: justErrorsLogger in defaultOptions
|
|
274
|
+
if (opts && opts.logger && opts.debug) {
|
|
275
|
+
this.log('You are using a custom `logger`, but also set `debug: true`, which uses built-in logger to output logs to console. Ignoring `debug: true` and using your custom `logger`.', 'warning');
|
|
276
|
+
} else if (opts && opts.debug) {
|
|
277
|
+
this.opts.logger = debugLogger;
|
|
278
|
+
}
|
|
279
|
+
if (!opts.container) {
|
|
280
|
+
throw new Error('`container` is required for having the widget works properly.');
|
|
281
|
+
}
|
|
282
|
+
if (this.log) {
|
|
283
|
+
this.log("Using Core v".concat(this.constructor.VERSION));
|
|
284
|
+
}
|
|
285
|
+
if (this.opts.restrictions.allowedFileTypes && this.opts.restrictions.allowedFileTypes !== null && !Array.isArray(this.opts.restrictions.allowedFileTypes)) {
|
|
286
|
+
throw new TypeError('`restrictions.allowedFileTypes` must be an array');
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* saveMissing translations is temporary disabled. Until we find a good solution how to improve automation.
|
|
291
|
+
* Previous approach doesn't work thus we switched to manual translations adding to Wordplex directly by developers.
|
|
292
|
+
*/
|
|
293
|
+
// Translator.IS_DEV = this.opts.dev
|
|
294
|
+
|
|
295
|
+
this.i18nInit();
|
|
296
|
+
|
|
297
|
+
// Container for different types of plugins
|
|
298
|
+
this.plugins = {};
|
|
299
|
+
/*
|
|
300
|
+
* Container for the current uploads operations
|
|
301
|
+
* (not files but the upload process/operation itself that can contain multiple files)
|
|
302
|
+
* made as a property in the class as it doesn't need to cause a render or accessed externally.
|
|
303
|
+
*/
|
|
304
|
+
this.uploadOperations = {};
|
|
305
|
+
this.getGlobalState = this.getGlobalState.bind(this);
|
|
306
|
+
this.getPlugin = this.getPlugin.bind(this);
|
|
307
|
+
this.removePlugin = this.removePlugin.bind(this);
|
|
308
|
+
this.getPreProcessors = this.getPreProcessors.bind(this);
|
|
309
|
+
this.getPostProcessors = this.getPostProcessors.bind(this);
|
|
310
|
+
this.setFilesInfoMetaTags = this.setFilesInfoMetaTags.bind(this);
|
|
311
|
+
this.showRelevance = this.showRelevance.bind(this);
|
|
312
|
+
this.hideRelevance = this.hideRelevance.bind(this);
|
|
313
|
+
this.setFileStateBeforeUpload = this.setFileStateBeforeUpload.bind(this);
|
|
314
|
+
this.getFileUploading = this.getFileUploading.bind(this);
|
|
315
|
+
this.setFileUploadingState = this.setFileUploadingState.bind(this);
|
|
316
|
+
this.setUploadPanelFileState = this.setUploadPanelFileState.bind(this);
|
|
317
|
+
this.setFileState = this.setFileState.bind(this);
|
|
318
|
+
this.setProgressPanelFileState = this.setProgressPanelFileState.bind(this);
|
|
319
|
+
this.log = this.log.bind(this);
|
|
320
|
+
this.use = this.use.bind(this);
|
|
321
|
+
this.info = this.info.bind(this);
|
|
322
|
+
this.hideInfo = this.hideInfo.bind(this);
|
|
323
|
+
this.addFile = this.addFile.bind(this);
|
|
324
|
+
this.removeFile = this.removeFile.bind(this);
|
|
325
|
+
this.removeUploads = this.removeUploads.bind(this);
|
|
326
|
+
this.pauseResume = this.pauseResume.bind(this);
|
|
327
|
+
this.checkUserPermissions = this.checkUserPermissions.bind(this);
|
|
328
|
+
this.generateUserKey = this.generateUserKey.bind(this);
|
|
329
|
+
this.checkPluginTypeExistence = this.checkPluginTypeExistence.bind(this);
|
|
330
|
+
this.initUserAuthState = this.initUserAuthState.bind(this);
|
|
331
|
+
this.enableSearchDebugging = this.enableSearchDebugging.bind(this);
|
|
332
|
+
this.disableSearchDebugging = this.disableSearchDebugging.bind(this);
|
|
333
|
+
this.isFileRestrictedToGetAdded = this.isFileRestrictedToGetAdded.bind(this);
|
|
334
|
+
window.enableSearchDebugging = this.enableSearchDebugging;
|
|
335
|
+
window.disableSearchDebugging = this.disableSearchDebugging;
|
|
336
|
+
this.updateOnlineStatus = this.updateOnlineStatus.bind(this);
|
|
337
|
+
this.cancelUploads = this.cancelUploads.bind(this);
|
|
338
|
+
this.retryUpload = this.retryUpload.bind(this);
|
|
339
|
+
this.upload = this.upload.bind(this);
|
|
340
|
+
this.pauseAll = this.pauseAll.bind(this);
|
|
341
|
+
this.resumeAll = this.resumeAll.bind(this);
|
|
342
|
+
this.retryAll = this.retryAll.bind(this);
|
|
343
|
+
this.cancelAll = this.cancelAll.bind(this);
|
|
344
|
+
this.emitter = ee();
|
|
345
|
+
this.on = this.on.bind(this);
|
|
346
|
+
this.off = this.off.bind(this);
|
|
347
|
+
this.once = this.emitter.once.bind(this.emitter);
|
|
348
|
+
this.emit = this.emitter.emit.bind(this.emitter);
|
|
349
|
+
|
|
350
|
+
// { process: processingFn, render: renderingFn }
|
|
351
|
+
this.preProcessors = [];
|
|
352
|
+
this.filerobots = [];
|
|
353
|
+
// { process: processingFn, render: renderingFn }
|
|
354
|
+
this.postProcessors = [];
|
|
355
|
+
this._storeInit();
|
|
356
|
+
this._storeUnsubscribe = this.store.subscribe(function () {});
|
|
357
|
+
if (this.opts.sassKeyRenewerEnabled) {
|
|
358
|
+
this._sassKeyRenewerUnsubscribe = this.sassKeyRenewer.subscribe();
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Exposing filerobot object on window for debugging and testing
|
|
362
|
+
if (this.opts.debug && typeof window !== 'undefined') {
|
|
363
|
+
window[this.opts.id] = this;
|
|
364
|
+
}
|
|
365
|
+
this.loadBackendTranslations();
|
|
366
|
+
this._addListeners();
|
|
367
|
+
if (!this.opts.sassKey) {
|
|
368
|
+
if (this.opts.securityTemplateId) {
|
|
369
|
+
this.generateUserKey();
|
|
370
|
+
} else {
|
|
371
|
+
if (this.opts.dev) {
|
|
372
|
+
console.warn('Core: `securityTemplateId` property is required if you don\'t want to use login (email&pass) mode. (this warning is shown in development mode only)');
|
|
373
|
+
}
|
|
374
|
+
this.initUserAuthState();
|
|
375
|
+
}
|
|
376
|
+
} else {
|
|
377
|
+
this.initUserAuthState(this.opts.sassKey);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return _createClass(ScaleflexWidget, [{
|
|
381
|
+
key: "on",
|
|
382
|
+
value: function on(event, callback) {
|
|
383
|
+
this.emitter.on(event, callback);
|
|
384
|
+
return this;
|
|
385
|
+
}
|
|
386
|
+
}, {
|
|
387
|
+
key: "off",
|
|
388
|
+
value: function off(event, callback) {
|
|
389
|
+
this.emitter.off(event, callback);
|
|
390
|
+
return this;
|
|
391
|
+
}
|
|
392
|
+
}, {
|
|
393
|
+
key: "initUserAuthState",
|
|
394
|
+
value: function initUserAuthState(sassKey) {
|
|
395
|
+
if (!sassKey) return this.setCoreCommonState({
|
|
396
|
+
loading: false
|
|
397
|
+
});
|
|
398
|
+
this.dispatch(userInfoUpdated(_objectSpread(_objectSpread({}, this.opts.userInfo), {}, {
|
|
399
|
+
sessionUuid: this.opts.sessionToken
|
|
400
|
+
})));
|
|
401
|
+
return this.dispatch(fetchUserAuthState({
|
|
402
|
+
userSassKey: sassKey
|
|
403
|
+
}));
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Iterate on all plugins and run `update` on them.
|
|
408
|
+
* Called each time state changes.
|
|
409
|
+
*
|
|
410
|
+
*/
|
|
411
|
+
}, {
|
|
412
|
+
key: "updateAll",
|
|
413
|
+
value: function updateAll(state) {
|
|
414
|
+
this.iteratePlugins(function (plugin) {
|
|
415
|
+
plugin.update(state);
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* creates & assigns the redux store
|
|
421
|
+
*
|
|
422
|
+
*/
|
|
423
|
+
}, {
|
|
424
|
+
key: "_storeInit",
|
|
425
|
+
value: function _storeInit() {
|
|
426
|
+
var client = new Client(this, this.opts);
|
|
427
|
+
this.store = createStore(client, [], this);
|
|
428
|
+
this.setCoreCommonState({
|
|
429
|
+
isDevEnv: this.opts.dev
|
|
430
|
+
});
|
|
431
|
+
if (this.opts.sassKeyRenewerEnabled) {
|
|
432
|
+
this.sassKeyRenewer = new SassKeyRenewer(this, client);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* injects a sub-reducer into the root reducer (mostly used for injecting a plugin's reducer)
|
|
438
|
+
*
|
|
439
|
+
*/
|
|
440
|
+
}, {
|
|
441
|
+
key: "_injectReducer",
|
|
442
|
+
value: function _injectReducer(key, reducerFn) {
|
|
443
|
+
this.store.injectReducer(key, reducerFn);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* injects a sub-reducer into the root reducer (mostly used for injecting a plugin's reducer)
|
|
448
|
+
*
|
|
449
|
+
*/
|
|
450
|
+
}, {
|
|
451
|
+
key: "_removeReducer",
|
|
452
|
+
value: function _removeReducer(key) {
|
|
453
|
+
this.store.removeReducer(key);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Triggers the action to call store's reducers
|
|
458
|
+
* @param {Function} actionCreator
|
|
459
|
+
*/
|
|
460
|
+
}, {
|
|
461
|
+
key: "dispatch",
|
|
462
|
+
value: function dispatch(actionCreator) {
|
|
463
|
+
return this.store.dispatch(actionCreator);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Updates common state with a patch
|
|
468
|
+
* any state that not organized in a sub-reducer/slice
|
|
469
|
+
*
|
|
470
|
+
* @param {object} patch {foo: 'bar'}
|
|
471
|
+
// * TODO: To check it
|
|
472
|
+
*/
|
|
473
|
+
}, {
|
|
474
|
+
key: "setCoreCommonState",
|
|
475
|
+
value: function setCoreCommonState(patch) {
|
|
476
|
+
this.dispatch(coreCommonStateUpdated(patch));
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Returns current state of whole redux's store (global state).
|
|
481
|
+
*
|
|
482
|
+
* @returns {object}
|
|
483
|
+
*/
|
|
484
|
+
}, {
|
|
485
|
+
key: "getGlobalState",
|
|
486
|
+
value: function getGlobalState() {
|
|
487
|
+
return this.store.getState();
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Returns current core's slice state.
|
|
492
|
+
*
|
|
493
|
+
* @returns {object}
|
|
494
|
+
*/
|
|
495
|
+
}, {
|
|
496
|
+
key: "getCoreState",
|
|
497
|
+
value: function getCoreState() {
|
|
498
|
+
return this.getGlobalState()[PLUGINS_IDS.CORE];
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Returns current core's slice state.
|
|
503
|
+
*
|
|
504
|
+
* @returns {object}
|
|
505
|
+
*/
|
|
506
|
+
}, {
|
|
507
|
+
key: "getCoreCommonState",
|
|
508
|
+
value: function getCoreCommonState() {
|
|
509
|
+
return selectCommonState(this.getGlobalState());
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Returns current uploads
|
|
514
|
+
*
|
|
515
|
+
* @returns {object}
|
|
516
|
+
*/
|
|
517
|
+
}, {
|
|
518
|
+
key: "getUploadOperations",
|
|
519
|
+
value: function getUploadOperations() {
|
|
520
|
+
return this.uploadOperations;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Returns current uploads' meta
|
|
525
|
+
*
|
|
526
|
+
* @returns {object}
|
|
527
|
+
*/
|
|
528
|
+
}, {
|
|
529
|
+
key: "getUploadCapabilities",
|
|
530
|
+
value: function getUploadCapabilities() {
|
|
531
|
+
return selectUploadCapabilities(this.getGlobalState());
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Returns the current files that will get uploaded
|
|
536
|
+
*
|
|
537
|
+
* @returns {object}
|
|
538
|
+
*/
|
|
539
|
+
}, {
|
|
540
|
+
key: "getUploads",
|
|
541
|
+
value: function getUploads() {
|
|
542
|
+
var files = _objectSpread({}, selectUploads(this.getGlobalState()));
|
|
543
|
+
Object.keys(files).forEach(function (fileId) {
|
|
544
|
+
files[fileId] = _objectSpread(_objectSpread({}, files[fileId]), {}, {
|
|
545
|
+
data: ScaleflexWidget.uploadFilesData[fileId]
|
|
546
|
+
});
|
|
547
|
+
});
|
|
548
|
+
return files;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Returns the current files that will get uploaded in a type of array
|
|
553
|
+
*
|
|
554
|
+
* @returns {Array}
|
|
555
|
+
*/
|
|
556
|
+
}, {
|
|
557
|
+
key: "getUploadsArray",
|
|
558
|
+
value: function getUploadsArray() {
|
|
559
|
+
return selectUploadsArray(this.getGlobalState());
|
|
560
|
+
}
|
|
561
|
+
}, {
|
|
562
|
+
key: "setUploadPanelFileState",
|
|
563
|
+
value: function setUploadPanelFileState() {
|
|
564
|
+
// This method is deprecated
|
|
565
|
+
// TODO: remove completely after a while
|
|
566
|
+
this.log('This method is deprecated, please use setFileStateBeforeUpload instead');
|
|
567
|
+
}
|
|
568
|
+
}, {
|
|
569
|
+
key: "setFileState",
|
|
570
|
+
value: function setFileState() {
|
|
571
|
+
// This method is deprecated
|
|
572
|
+
// TODO: remove completely after a while
|
|
573
|
+
this.log('This method is deprecated, please use setFileStateBeforeUpload instead');
|
|
574
|
+
this.setFileStateBeforeUpload.apply(this, arguments);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Shorthand to set state for a specific file.
|
|
579
|
+
*/
|
|
580
|
+
}, {
|
|
581
|
+
key: "setFileStateBeforeUpload",
|
|
582
|
+
value: function setFileStateBeforeUpload(fileId, state) {
|
|
583
|
+
if (!this.getFileBeforeUpload(fileId)) {
|
|
584
|
+
if (this.opts.autoProceed) {
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
throw new Error("Can\u2019t set state for ".concat(fileId, " (the file could have been removed)"));
|
|
588
|
+
}
|
|
589
|
+
var fileState = _objectSpread(_objectSpread({}, state), {}, {
|
|
590
|
+
id: fileId
|
|
591
|
+
});
|
|
592
|
+
if (state.data) {
|
|
593
|
+
ScaleflexWidget.uploadFilesData[fileId] = state.data;
|
|
594
|
+
fileState.data = extractFileDataNoBlob(state.data);
|
|
595
|
+
}
|
|
596
|
+
this.dispatch(uploadUpdated(_objectSpread(_objectSpread({}, fileState), {}, {
|
|
597
|
+
id: fileId
|
|
598
|
+
})));
|
|
599
|
+
}
|
|
600
|
+
}, {
|
|
601
|
+
key: "i18nInit",
|
|
602
|
+
value: function i18nInit() {
|
|
603
|
+
if (!Translator.BACKEND_TRANSLATIONS) {
|
|
604
|
+
var _this$currLngBackendT;
|
|
605
|
+
Translator.BACKEND_TRANSLATIONS = (_this$currLngBackendT = this.currLngBackendTranslations) === null || _this$currLngBackendT === void 0 ? void 0 : _this$currLngBackendT.strings;
|
|
606
|
+
}
|
|
607
|
+
this.translator = new Translator([this.defaultLocale, this.currLngBackendTranslations, this.opts.locale]);
|
|
608
|
+
this.locale = this.translator.locale;
|
|
609
|
+
this.i18n = this.translator.translate.bind(this.translator);
|
|
610
|
+
this.i18nArray = this.translator.translateArray.bind(this.translator);
|
|
611
|
+
}
|
|
612
|
+
}, {
|
|
613
|
+
key: "setOptions",
|
|
614
|
+
value: function setOptions() {
|
|
615
|
+
var newOpts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
616
|
+
if (typeof newOpts.sassKey !== 'undefined' && newOpts.sassKey !== this.opts.sassKey) {
|
|
617
|
+
var _explorerPlugin$opts;
|
|
618
|
+
var explorerPlugin = this.getPlugin(PLUGINS_IDS.EXPLORER);
|
|
619
|
+
if (!explorerPlugin || !((_explorerPlugin$opts = explorerPlugin.opts) !== null && _explorerPlugin$opts !== void 0 && _explorerPlugin$opts.ExploreViewComponent)) {
|
|
620
|
+
this.dispatch(saveUserSassKey(newOpts.sassKey));
|
|
621
|
+
} else {
|
|
622
|
+
this.initUserAuthState(newOpts.sassKey);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
this.opts = _objectSpread(_objectSpread(_objectSpread({}, this.opts), newOpts), {}, {
|
|
626
|
+
restrictions: _objectSpread(_objectSpread({}, this.opts.restrictions), newOpts && newOpts.restrictions)
|
|
627
|
+
});
|
|
628
|
+
if (newOpts.locale) {
|
|
629
|
+
this.i18nInit();
|
|
630
|
+
}
|
|
631
|
+
if (newOpts.language) {
|
|
632
|
+
this.updateCurrLngBackendTranslations();
|
|
633
|
+
}
|
|
634
|
+
if (typeof newOpts.dev !== 'undefined') {
|
|
635
|
+
this.setCoreCommonState({
|
|
636
|
+
isDevEnv: this.opts.dev
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// Already the opts object of the plugin is updated, so we need only to emit a new object's reference
|
|
641
|
+
// and handle rerendering in the plugins' providers so that it causes rerender.
|
|
642
|
+
this.emit('opts-updated', this._getInstalledPkgs());
|
|
643
|
+
}
|
|
644
|
+
}, {
|
|
645
|
+
key: "addPreProcessor",
|
|
646
|
+
value: function addPreProcessor(processor) {
|
|
647
|
+
this.preProcessors.push(processor);
|
|
648
|
+
}
|
|
649
|
+
}, {
|
|
650
|
+
key: "removePreProcessor",
|
|
651
|
+
value: function removePreProcessor(processor) {
|
|
652
|
+
var i = this.preProcessors.indexOf(processor);
|
|
653
|
+
if (i !== -1) {
|
|
654
|
+
this.preProcessors.splice(i, 1);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}, {
|
|
658
|
+
key: "addPostProcessor",
|
|
659
|
+
value: function addPostProcessor(processor) {
|
|
660
|
+
this.postProcessors.push(processor);
|
|
661
|
+
}
|
|
662
|
+
}, {
|
|
663
|
+
key: "removePostProcessor",
|
|
664
|
+
value: function removePostProcessor(processor) {
|
|
665
|
+
var i = this.postProcessors.indexOf(processor);
|
|
666
|
+
if (i !== -1) {
|
|
667
|
+
this.postProcessors.splice(i, 1);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}, {
|
|
671
|
+
key: "addFilerobot",
|
|
672
|
+
value: function addFilerobot(fn) {
|
|
673
|
+
this.filerobots.push(fn);
|
|
674
|
+
}
|
|
675
|
+
}, {
|
|
676
|
+
key: "removeFilerobot",
|
|
677
|
+
value: function removeFilerobot(fn) {
|
|
678
|
+
var i = this.filerobots.indexOf(fn);
|
|
679
|
+
if (i !== -1) {
|
|
680
|
+
this.filerobots.splice(i, 1);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}, {
|
|
684
|
+
key: "setFilesInfoMetaTags",
|
|
685
|
+
value: function setFilesInfoMetaTags(_ref2) {
|
|
686
|
+
var filesIds = _ref2.filesIds,
|
|
687
|
+
meta = _ref2.meta,
|
|
688
|
+
tags = _ref2.tags,
|
|
689
|
+
info = _ref2.info,
|
|
690
|
+
tagsForceUpdate = _ref2.tagsForceUpdate;
|
|
691
|
+
return this.dispatch(updateUploadInfoMetaTags({
|
|
692
|
+
filesIds: filesIds,
|
|
693
|
+
meta: meta,
|
|
694
|
+
tags: tags,
|
|
695
|
+
info: info,
|
|
696
|
+
tagsForceUpdate: tagsForceUpdate
|
|
697
|
+
}));
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Get file uploading object.
|
|
702
|
+
*
|
|
703
|
+
* @param {string} fileId The ID of the file object to return.
|
|
704
|
+
*/
|
|
705
|
+
}, {
|
|
706
|
+
key: "getFileUploading",
|
|
707
|
+
value: function getFileUploading(fileId) {
|
|
708
|
+
var uploadOperations = this.getUploadOperations();
|
|
709
|
+
var uploadOperationId = Object.keys(uploadOperations).find(function (uploadId) {
|
|
710
|
+
return uploadOperations[uploadId].files[fileId];
|
|
711
|
+
});
|
|
712
|
+
if (!uploadOperationId) {
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
return _objectSpread(_objectSpread({}, uploadOperations[uploadOperationId].files[fileId]), {}, {
|
|
716
|
+
uploadId: uploadOperationId,
|
|
717
|
+
data: ScaleflexWidget.uploadFilesData[fileId]
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Get a file object before upload.
|
|
723
|
+
*
|
|
724
|
+
* @param {string} fileId The ID of the file object to return.
|
|
725
|
+
*/
|
|
726
|
+
}, {
|
|
727
|
+
key: "getFileBeforeUpload",
|
|
728
|
+
value: function getFileBeforeUpload(fileId) {
|
|
729
|
+
return selectUploadById(this.getGlobalState(), fileId);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Check if minNumberOfFiles restriction is reached before uploading.
|
|
734
|
+
*
|
|
735
|
+
* @private
|
|
736
|
+
*/
|
|
737
|
+
}, {
|
|
738
|
+
key: "_checkMinNumberOfFiles",
|
|
739
|
+
value: function _checkMinNumberOfFiles(files) {
|
|
740
|
+
var minNumberOfFiles = this.opts.restrictions.minNumberOfFiles;
|
|
741
|
+
if (Object.keys(files).length < minNumberOfFiles) {
|
|
742
|
+
throw new RestrictionError("".concat(this.i18n('filerobotYouHaveToAtLeastSelectXError', {
|
|
743
|
+
smart_count: minNumberOfFiles
|
|
744
|
+
})));
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Check if file passes a set of restrictions set in options: maxFileSize,
|
|
750
|
+
* maxNumberOfFiles and allowedFileTypes.
|
|
751
|
+
*
|
|
752
|
+
* @param {object} files Object of files already added
|
|
753
|
+
* @param {object} file object to check
|
|
754
|
+
* @private
|
|
755
|
+
*/
|
|
756
|
+
}, {
|
|
757
|
+
key: "_checkRestrictions",
|
|
758
|
+
value: function _checkRestrictions(files, file) {
|
|
759
|
+
var _this3 = this,
|
|
760
|
+
_file$data;
|
|
761
|
+
var dontCheckFileType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
762
|
+
var customUploadedFilesSizeInMb = this.opts.customUploadedFilesSizeInMb;
|
|
763
|
+
var _this$opts$restrictio = this.opts.restrictions,
|
|
764
|
+
maxFileSize = _this$opts$restrictio.maxFileSize,
|
|
765
|
+
maxNumberOfFiles = _this$opts$restrictio.maxNumberOfFiles,
|
|
766
|
+
allowedFileTypes = _this$opts$restrictio.allowedFileTypes,
|
|
767
|
+
maxTotalFilesSize = _this$opts$restrictio.maxTotalFilesSize;
|
|
768
|
+
var _selectUserSecurityDa = selectUserSecurityData(this.getGlobalState()),
|
|
769
|
+
_selectUserSecurityDa2 = _selectUserSecurityDa.upload_scope,
|
|
770
|
+
allowedFoldersToUploadTo = _selectUserSecurityDa2 === void 0 ? this.opts.userFoldersScope : _selectUserSecurityDa2;
|
|
771
|
+
if (allowedFoldersToUploadTo && allowedFoldersToUploadTo.length > 0) {
|
|
772
|
+
this.plugins.uploader.forEach(function (plugin) {
|
|
773
|
+
var folderPath = (file.toFolder || plugin.opts.uploadToFolderPath || selectCurrentFolderPath(_this3.getGlobalState()) || '').toLowerCase().replace(/\/$/, '') || '/';
|
|
774
|
+
var foundAllowedFolderScope = allowedFoldersToUploadTo.some(function (f) {
|
|
775
|
+
var folderNameWithNoSlashStar = f.toLowerCase().replace(/\/\*?$/, '');
|
|
776
|
+
if (folderPath === folderNameWithNoSlashStar || f.endsWith('/*') && folderPath.includes("".concat(folderNameWithNoSlashStar, "/"))) {
|
|
777
|
+
return true;
|
|
778
|
+
}
|
|
779
|
+
return false;
|
|
780
|
+
});
|
|
781
|
+
if (!foundAllowedFolderScope) {
|
|
782
|
+
throw new RestrictionError("".concat(_this3.i18n('filerobotFolderUploadingNotAllowedError', {
|
|
783
|
+
folder: folderPath
|
|
784
|
+
})));
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
if (!this.checkUserPermissions([PERMISSIONS.UPLOAD])) {
|
|
789
|
+
throw new Error("".concat(this.i18n('filerobotInvalidPermissionError')));
|
|
790
|
+
}
|
|
791
|
+
if (typeof maxNumberOfFiles === 'number') {
|
|
792
|
+
if (Object.keys(files).length + 1 > maxNumberOfFiles) {
|
|
793
|
+
throw new RestrictionError("".concat(this.i18n('filerobotYouCanOnlyUploadXError', {
|
|
794
|
+
smart_count: maxNumberOfFiles
|
|
795
|
+
})));
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
if (!dontCheckFileType && allowedFileTypes) {
|
|
799
|
+
var fileType = file.type || file.mimeType;
|
|
800
|
+
var isCorrectFileType = allowedFileTypes.some(function (type) {
|
|
801
|
+
var _file$extension;
|
|
802
|
+
// is this is a mime-type
|
|
803
|
+
if (type.indexOf('/') > -1) {
|
|
804
|
+
if (!fileType) return false;
|
|
805
|
+
return match(fileType.replace(/;.*?$/, ''), type);
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// otherwise this is likely an extension
|
|
809
|
+
var fileExtension = type[0] === '.' && ((_file$extension = file.extension) !== null && _file$extension !== void 0 ? _file$extension : getFileExtension(file));
|
|
810
|
+
if (fileExtension) {
|
|
811
|
+
return fileExtension.toLowerCase() === type.substr(1).toLowerCase();
|
|
812
|
+
}
|
|
813
|
+
return false;
|
|
814
|
+
});
|
|
815
|
+
if (!isCorrectFileType) {
|
|
816
|
+
var allowedFileTypesString = allowedFileTypes.join(', ');
|
|
817
|
+
throw new RestrictionError(this.i18n('filerobotYouCanOnlyUploadFileTypesError', {
|
|
818
|
+
types: allowedFileTypesString
|
|
819
|
+
}));
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// We can't check maxFileSize if the size is unknown.
|
|
824
|
+
var fileSize = ((_file$data = file.data) === null || _file$data === void 0 ? void 0 : _file$data.size) || file.size;
|
|
825
|
+
if (maxTotalFilesSize) {
|
|
826
|
+
var totalFilesSize = [].concat(_toConsumableArray(Object.values(files)), [file]).reduce(function (totalSize, file) {
|
|
827
|
+
var _file$data2;
|
|
828
|
+
totalSize += ((_file$data2 = file.data) === null || _file$data2 === void 0 ? void 0 : _file$data2.size) || file.size || 0;
|
|
829
|
+
return totalSize;
|
|
830
|
+
}, 0);
|
|
831
|
+
if (convertBytesToMb(totalFilesSize) + customUploadedFilesSizeInMb > maxTotalFilesSize) {
|
|
832
|
+
throw new RestrictionError(this.i18n('filerobotFilesExceedsSizeError', {
|
|
833
|
+
size: maxTotalFilesSize
|
|
834
|
+
}));
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
if (maxFileSize && fileSize != null) {
|
|
838
|
+
if (fileSize > maxFileSize) {
|
|
839
|
+
throw new RestrictionError(this.i18n('filerobotExceedsSizeError', {
|
|
840
|
+
size: prettierBytes(maxFileSize)
|
|
841
|
+
}));
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* Logs an error, sets Informer message, then throws the error.
|
|
848
|
+
* Emits a 'restriction-failed' event if it’s a restriction error
|
|
849
|
+
*
|
|
850
|
+
* @param {object | string} err — Error object or plain string message
|
|
851
|
+
* @param {object} [options]
|
|
852
|
+
* @param {boolean} [options.showInformer=true] — Sometimes developer might want to show Informer manually
|
|
853
|
+
* @param {object} [options.file=null] — File object used to emit the restriction error
|
|
854
|
+
* @param {boolean} [options.throwErr=true] — Errors shouldn’t be thrown, for example, in `upload-error` event
|
|
855
|
+
* @private
|
|
856
|
+
*/
|
|
857
|
+
}, {
|
|
858
|
+
key: "_showOrLogErrorAndThrow",
|
|
859
|
+
value: function _showOrLogErrorAndThrow(err) {
|
|
860
|
+
var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
861
|
+
_ref3$showInformer = _ref3.showInformer,
|
|
862
|
+
showInformer = _ref3$showInformer === void 0 ? true : _ref3$showInformer,
|
|
863
|
+
_ref3$file = _ref3.file,
|
|
864
|
+
file = _ref3$file === void 0 ? null : _ref3$file,
|
|
865
|
+
_ref3$throwErr = _ref3.throwErr,
|
|
866
|
+
throwErr = _ref3$throwErr === void 0 ? true : _ref3$throwErr;
|
|
867
|
+
var message = _typeof(err) === 'object' ? err.message : err;
|
|
868
|
+
var details = _typeof(err) === 'object' && err.details ? err.details : '';
|
|
869
|
+
var hideRestrictionsInformer = this.opts.restrictions.hideRestrictionsInformer;
|
|
870
|
+
|
|
871
|
+
// Restriction errors should be logged, but not as errors,
|
|
872
|
+
// as they are expected and shown in the UI.
|
|
873
|
+
var logMessageWithDetails = message;
|
|
874
|
+
if (details) {
|
|
875
|
+
logMessageWithDetails += ' ' + details;
|
|
876
|
+
}
|
|
877
|
+
if (err.isRestriction) {
|
|
878
|
+
this.log(logMessageWithDetails);
|
|
879
|
+
this.emit('restriction-failed', file, err);
|
|
880
|
+
} else {
|
|
881
|
+
this.log(logMessageWithDetails, 'error');
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// Sometimes informer has to be shown manually by the developer,
|
|
885
|
+
// for example, in `onBeforeFileAdded`.
|
|
886
|
+
if (showInformer && !hideRestrictionsInformer) {
|
|
887
|
+
this.info({
|
|
888
|
+
message: message,
|
|
889
|
+
details: details
|
|
890
|
+
}, 'error', 5000);
|
|
891
|
+
}
|
|
892
|
+
if (throwErr) {
|
|
893
|
+
throw _typeof(err) === 'object' ? err : new Error(err);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
}, {
|
|
897
|
+
key: "_assertNewUploadAllowed",
|
|
898
|
+
value: function _assertNewUploadAllowed(file) {
|
|
899
|
+
var _this$getUploadCapabi = this.getUploadCapabilities(),
|
|
900
|
+
allowNewUpload = _this$getUploadCapabi.allowNewUpload;
|
|
901
|
+
if (allowNewUpload === false) {
|
|
902
|
+
this._showOrLogErrorAndThrow(new RestrictionError(this.i18n('filerobotNoNewAlreadyUploadingError')), {
|
|
903
|
+
file: file
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* Create a file state object based on user-provided `addFile()` options.
|
|
910
|
+
*
|
|
911
|
+
* Note this is extremely side-effectful and should only be done when a file state object will be added to state immediately afterward!
|
|
912
|
+
*
|
|
913
|
+
* The `files` value is passed in because it may be updated by the caller without updating the store.
|
|
914
|
+
*/
|
|
915
|
+
}, {
|
|
916
|
+
key: "_checkAndCreateFileStateObject",
|
|
917
|
+
value: function _checkAndCreateFileStateObject(files, checkedFile) {
|
|
918
|
+
var _file$data3, _file$data4;
|
|
919
|
+
var fileType = getFileType(checkedFile);
|
|
920
|
+
var file = _objectSpread(_objectSpread({}, checkedFile), {}, {
|
|
921
|
+
type: fileType
|
|
922
|
+
});
|
|
923
|
+
var onBeforeFileAddedResult = this.opts.onBeforeFileAdded(file, files);
|
|
924
|
+
if (onBeforeFileAddedResult === false) {
|
|
925
|
+
// Don’t show UI info for this error, as it should be done by the developer
|
|
926
|
+
this._showOrLogErrorAndThrow(new RestrictionError('Cannot add the file because onBeforeFileAdded returned false.'), {
|
|
927
|
+
showInformer: false,
|
|
928
|
+
file: file
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
if (_typeof(onBeforeFileAddedResult) === 'object' && onBeforeFileAddedResult) {
|
|
932
|
+
file = onBeforeFileAddedResult;
|
|
933
|
+
}
|
|
934
|
+
var fileName;
|
|
935
|
+
if (file.name) {
|
|
936
|
+
fileName = file.name;
|
|
937
|
+
} else if (fileType.split('/')[0] === 'image') {
|
|
938
|
+
fileName = fileType.split('/')[0] + '.' + fileType.split('/')[1];
|
|
939
|
+
} else {
|
|
940
|
+
fileName = 'noname';
|
|
941
|
+
}
|
|
942
|
+
var fileExtension = getFileNameAndExtension(fileName, fileType).extension;
|
|
943
|
+
var isRemote = file.isRemote || false;
|
|
944
|
+
var fileId = generateFileId(file);
|
|
945
|
+
if (files[fileId]) {
|
|
946
|
+
this._showOrLogErrorAndThrow(new RestrictionError(this.i18n('filerobotNoDuplicatesError', {
|
|
947
|
+
fileName: fileName
|
|
948
|
+
})), {
|
|
949
|
+
file: file
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
var fileInfo = file.info || {};
|
|
953
|
+
fileInfo.name = fileName;
|
|
954
|
+
fileInfo.type = fileType;
|
|
955
|
+
// `null` means the size is unknown.
|
|
956
|
+
var size = isFinite((_file$data3 = file.data) === null || _file$data3 === void 0 ? void 0 : _file$data3.size) ? (_file$data4 = file.data) === null || _file$data4 === void 0 ? void 0 : _file$data4.size : null;
|
|
957
|
+
var newFile = {
|
|
958
|
+
source: file.source || '',
|
|
959
|
+
id: fileId,
|
|
960
|
+
name: fileName,
|
|
961
|
+
extension: fileExtension || '',
|
|
962
|
+
info: fileInfo,
|
|
963
|
+
meta: file.meta || {},
|
|
964
|
+
product: file.product || {},
|
|
965
|
+
type: fileType,
|
|
966
|
+
blob: file.data instanceof File || file.data instanceof Blob ? URL.createObjectURL(file.data) : null,
|
|
967
|
+
data: extractFileDataNoBlob(file.data),
|
|
968
|
+
progress: {
|
|
969
|
+
type: PROGRESS_PANEL_ACTIVITY.UPLOAD,
|
|
970
|
+
percentage: 0,
|
|
971
|
+
bytesFinished: 0,
|
|
972
|
+
bytesTotal: size,
|
|
973
|
+
startedAt: null,
|
|
974
|
+
status: FILE_UPLOAD_STATUS.PREPARING
|
|
975
|
+
},
|
|
976
|
+
size: size,
|
|
977
|
+
isRemote: isRemote,
|
|
978
|
+
remote: file.remote || '',
|
|
979
|
+
preview: file.preview,
|
|
980
|
+
toFolder: file.toFolder || selectCurrentFolderPath(this.getGlobalState()),
|
|
981
|
+
xhrQueryParams: file.xhrQueryParams,
|
|
982
|
+
xhrHeaders: file.xhrHeaders,
|
|
983
|
+
uploadStep: true,
|
|
984
|
+
visibility: file.visibility,
|
|
985
|
+
uploadUrl: file.uploadUrl,
|
|
986
|
+
currentUploadId: file.currentUploadId
|
|
987
|
+
};
|
|
988
|
+
try {
|
|
989
|
+
this._checkRestrictions(files, newFile);
|
|
990
|
+
} catch (err) {
|
|
991
|
+
this._showOrLogErrorAndThrow(err, {
|
|
992
|
+
file: newFile
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
if (file.data) {
|
|
996
|
+
ScaleflexWidget.uploadFilesData[newFile.id] = file.data;
|
|
997
|
+
}
|
|
998
|
+
return newFile;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
/**
|
|
1002
|
+
* check if file is available and if not it will throw an error
|
|
1003
|
+
*
|
|
1004
|
+
* @param {string} error — Error message
|
|
1005
|
+
* @param {object} file — File object
|
|
1006
|
+
* @private
|
|
1007
|
+
*/
|
|
1008
|
+
}, {
|
|
1009
|
+
key: "_checkIfFileIsAvailable",
|
|
1010
|
+
value: function _checkIfFileIsAvailable(file, error) {
|
|
1011
|
+
if (!file) {
|
|
1012
|
+
throw new Error(error);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
}, {
|
|
1016
|
+
key: "isFileRestrictedToGetAdded",
|
|
1017
|
+
value: function isFileRestrictedToGetAdded(files, file) {
|
|
1018
|
+
var dontCheckFileType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
1019
|
+
try {
|
|
1020
|
+
this._checkRestrictions(files, file, dontCheckFileType);
|
|
1021
|
+
return false;
|
|
1022
|
+
} catch (err) {
|
|
1023
|
+
this._showOrLogErrorAndThrow(err, {
|
|
1024
|
+
file: file,
|
|
1025
|
+
throwErr: false
|
|
1026
|
+
});
|
|
1027
|
+
return true;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// Schedule an upload if `autoProceed` is enabled.
|
|
1032
|
+
}, {
|
|
1033
|
+
key: "_startIfAutoProceed",
|
|
1034
|
+
value: function _startIfAutoProceed() {
|
|
1035
|
+
var _this4 = this;
|
|
1036
|
+
var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
1037
|
+
_ref4$forceAutoProcee = _ref4.forceAutoProceed,
|
|
1038
|
+
forceAutoProceed = _ref4$forceAutoProcee === void 0 ? false : _ref4$forceAutoProcee,
|
|
1039
|
+
onUpload = _ref4.onUpload,
|
|
1040
|
+
newFile = _ref4.newFile,
|
|
1041
|
+
newFiles = _ref4.newFiles;
|
|
1042
|
+
if ((this.opts.autoProceed || forceAutoProceed) && !this.scheduledAutoProceed) {
|
|
1043
|
+
this.scheduledAutoProceed = setTimeout(function () {
|
|
1044
|
+
_this4.scheduledAutoProceed = null;
|
|
1045
|
+
_this4.upload()["catch"](function (err) {
|
|
1046
|
+
if (!err.isRestriction) {
|
|
1047
|
+
_this4.log(err.stack || err.message || err);
|
|
1048
|
+
}
|
|
1049
|
+
});
|
|
1050
|
+
if (typeof onUpload === 'function') {
|
|
1051
|
+
onUpload(newFile);
|
|
1052
|
+
}
|
|
1053
|
+
if (_this4.opts.autoProceed && Array.isArray(newFiles) && newFiles.length > 0) {
|
|
1054
|
+
var explorerInstance = _this4.getPlugin(PLUGINS_IDS.EXPLORER);
|
|
1055
|
+
if (explorerInstance) {
|
|
1056
|
+
explorerInstance.triggerProgressPanelActivities(newFiles);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}, 4);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* Add a new file to `state.files`. This will run `onBeforeFileAdded`,
|
|
1065
|
+
* try to guess file type in a clever way, check file against restrictions,
|
|
1066
|
+
* and start an upload if `autoProceed === true`.
|
|
1067
|
+
*
|
|
1068
|
+
* @param {object} file object to add
|
|
1069
|
+
* @returns {string} id for the added file
|
|
1070
|
+
*/
|
|
1071
|
+
}, {
|
|
1072
|
+
key: "addFile",
|
|
1073
|
+
value: function addFile(file) {
|
|
1074
|
+
var forceAutoProceed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1075
|
+
var onUpload = arguments.length > 2 ? arguments[2] : undefined;
|
|
1076
|
+
var fileExtension = getFileNameAndExtension(file.name, file.type).extension;
|
|
1077
|
+
var isRestrictedFileExtension = RESTRICTED_FILES_EXTENISONS.includes(fileExtension);
|
|
1078
|
+
if (isRestrictedFileExtension) {
|
|
1079
|
+
return this.info({
|
|
1080
|
+
message: this.i18n('filerobotRestrictedFileError', {
|
|
1081
|
+
file_extension: fileExtension
|
|
1082
|
+
})
|
|
1083
|
+
}, 'error', 5000);
|
|
1084
|
+
}
|
|
1085
|
+
this._assertNewUploadAllowed(file);
|
|
1086
|
+
var files = this.getUploads();
|
|
1087
|
+
var newFile = this._checkAndCreateFileStateObject(files, file);
|
|
1088
|
+
this.dispatch(uploadsAdded({
|
|
1089
|
+
files: [newFile],
|
|
1090
|
+
skipOpenUploadsPanel: forceAutoProceed
|
|
1091
|
+
}));
|
|
1092
|
+
this.emit('file-added', _objectSpread(_objectSpread({}, newFile), {}, {
|
|
1093
|
+
data: ScaleflexWidget.uploadFilesData[newFile.id]
|
|
1094
|
+
}));
|
|
1095
|
+
this.log("Added file: ".concat(newFile.name, ", ").concat(newFile.id, ", mime type: ").concat(newFile.type));
|
|
1096
|
+
this._startIfAutoProceed({
|
|
1097
|
+
forceAutoProceed: forceAutoProceed,
|
|
1098
|
+
onUpload: onUpload,
|
|
1099
|
+
newFile: newFile
|
|
1100
|
+
});
|
|
1101
|
+
return newFile.id;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
/**
|
|
1105
|
+
* Add multiple files to `state.files`. See the `addFile()` documentation.
|
|
1106
|
+
*
|
|
1107
|
+
* This cuts some corners for performance, so should typically only be used in cases where there may be a lot of files.
|
|
1108
|
+
*
|
|
1109
|
+
* If an error occurs while adding a file, it is logged and the user is notified. This is good for UI plugins, but not for programmatic use. Programmatic users should usually still use `addFile()` on individual files.
|
|
1110
|
+
*/
|
|
1111
|
+
}, {
|
|
1112
|
+
key: "addFiles",
|
|
1113
|
+
value: function addFiles(fileDescriptors, forceAutoProceed, _onUpload) {
|
|
1114
|
+
var _this5 = this;
|
|
1115
|
+
var _fileDescriptors = fileDescriptors.filter(function (_ref5) {
|
|
1116
|
+
var name = _ref5.name;
|
|
1117
|
+
return !RESTRICTED_FILES_EXTENISONS.includes(getFileNameAndExtension(name).extension);
|
|
1118
|
+
});
|
|
1119
|
+
this._assertNewUploadAllowed();
|
|
1120
|
+
|
|
1121
|
+
// create a copy of the files object only once
|
|
1122
|
+
var currentAndNewPassedFiles = this.getUploads();
|
|
1123
|
+
var newFiles = [];
|
|
1124
|
+
var errors = [];
|
|
1125
|
+
for (var i = 0; i < _fileDescriptors.length; i++) {
|
|
1126
|
+
try {
|
|
1127
|
+
var newFile = this._checkAndCreateFileStateObject(currentAndNewPassedFiles, _fileDescriptors[i]);
|
|
1128
|
+
newFiles.push(newFile);
|
|
1129
|
+
// We are adding the passed files into the object in every loop step, for considering them in the restrictions counts.
|
|
1130
|
+
currentAndNewPassedFiles[newFile.id] = newFile;
|
|
1131
|
+
} catch (err) {
|
|
1132
|
+
if (!err.isRestriction) {
|
|
1133
|
+
errors.push(err);
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
this.dispatch(uploadsAdded({
|
|
1138
|
+
files: newFiles,
|
|
1139
|
+
skipOpenUploadsPanel: forceAutoProceed
|
|
1140
|
+
}));
|
|
1141
|
+
newFiles.forEach(function (newFile) {
|
|
1142
|
+
_this5.emit('file-added', _objectSpread(_objectSpread({}, newFile), {}, {
|
|
1143
|
+
data: ScaleflexWidget.uploadFilesData[newFile.id]
|
|
1144
|
+
}));
|
|
1145
|
+
});
|
|
1146
|
+
if (newFiles.length > 5) {
|
|
1147
|
+
this.log("Added batch of ".concat(newFiles.length, " files"));
|
|
1148
|
+
} else {
|
|
1149
|
+
newFiles.forEach(function (file) {
|
|
1150
|
+
_this5.log("Added file: ".concat(file.name, "\n id: ").concat(file.id, "\n type: ").concat(file.type));
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
if (newFiles.length > 0) {
|
|
1154
|
+
this._startIfAutoProceed({
|
|
1155
|
+
forceAutoProceed: forceAutoProceed,
|
|
1156
|
+
onUpload: function onUpload() {
|
|
1157
|
+
return _onUpload && _onUpload(newFiles);
|
|
1158
|
+
},
|
|
1159
|
+
newFiles: newFiles
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
if (errors.length > 0) {
|
|
1163
|
+
var message = 'Multiple errors occurred while adding files:\n';
|
|
1164
|
+
errors.forEach(function (subError) {
|
|
1165
|
+
message += "\n * ".concat(subError.message);
|
|
1166
|
+
});
|
|
1167
|
+
this.info({
|
|
1168
|
+
message: this.i18n('addBulkFilesFailedMessage', {
|
|
1169
|
+
smart_count: errors.length
|
|
1170
|
+
}),
|
|
1171
|
+
details: message
|
|
1172
|
+
}, 'error', 5000);
|
|
1173
|
+
var err = new Error(message);
|
|
1174
|
+
err.errors = errors;
|
|
1175
|
+
throw err;
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}, {
|
|
1179
|
+
key: "removeUploads",
|
|
1180
|
+
value: function removeUploads(filesIds) {
|
|
1181
|
+
this.dispatch(uploadsRemoved(filesIds));
|
|
1182
|
+
}
|
|
1183
|
+
}, {
|
|
1184
|
+
key: "removeFile",
|
|
1185
|
+
value: function removeFile(fileId) {
|
|
1186
|
+
var reason = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
1187
|
+
var fileBeforeRemove = this.getFileUploading(fileId);
|
|
1188
|
+
if (!fileBeforeRemove) {
|
|
1189
|
+
throw new Error("Can\u2019t remove ".concat(fileId, " (the file could have been removed)"));
|
|
1190
|
+
}
|
|
1191
|
+
var uploadOperationId = fileBeforeRemove.uploadId;
|
|
1192
|
+
var currentUploadOperation = this.uploadOperations[uploadOperationId];
|
|
1193
|
+
var notRemovedFileIds = function notRemovedFileIds(uploadFileId) {
|
|
1194
|
+
return uploadFileId !== fileId;
|
|
1195
|
+
};
|
|
1196
|
+
if (currentUploadOperation && uploadOperationId) {
|
|
1197
|
+
var newFileIds = currentUploadOperation.filesIds.filter(notRemovedFileIds);
|
|
1198
|
+
delete currentUploadOperation.files[fileId];
|
|
1199
|
+
delete ScaleflexWidget.uploadFilesData[fileId];
|
|
1200
|
+
this.emit('file-removed', fileBeforeRemove, reason);
|
|
1201
|
+
this.log("Removed file: ".concat(fileId));
|
|
1202
|
+
if (newFileIds.length === 0) {
|
|
1203
|
+
delete this.uploadOperations[uploadOperationId];
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1206
|
+
this.uploadOperations[uploadOperationId] = _objectSpread(_objectSpread({}, currentUploadOperation), {}, {
|
|
1207
|
+
filesIds: newFileIds
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
}, {
|
|
1212
|
+
key: "pauseResume",
|
|
1213
|
+
value: function pauseResume(fileId) {
|
|
1214
|
+
if (!this.getUploadCapabilities().allowResumableUploads) {
|
|
1215
|
+
return;
|
|
1216
|
+
}
|
|
1217
|
+
var file = this.getFileUploading(fileId);
|
|
1218
|
+
this._checkIfFileIsAvailable(file, "can't pause or resume for a file that has been removed: ".concat(fileId));
|
|
1219
|
+
var wasPaused = file.progress.status === FILE_UPLOAD_STATUS.PAUSED || false;
|
|
1220
|
+
var isPaused = !wasPaused;
|
|
1221
|
+
var status = isPaused ? FILE_UPLOAD_STATUS.PAUSED : FILE_UPLOAD_STATUS.PROGRESSING;
|
|
1222
|
+
this.emit('activity-update', {
|
|
1223
|
+
id: file.id,
|
|
1224
|
+
progress: {
|
|
1225
|
+
status: status
|
|
1226
|
+
}
|
|
1227
|
+
});
|
|
1228
|
+
this.setFileUploadingState(fileId, file.uploadId, {
|
|
1229
|
+
progress: _objectSpread(_objectSpread({}, file.progress), {}, {
|
|
1230
|
+
status: status
|
|
1231
|
+
})
|
|
1232
|
+
});
|
|
1233
|
+
this.emit('upload-pause', fileId, isPaused);
|
|
1234
|
+
}
|
|
1235
|
+
}, {
|
|
1236
|
+
key: "pauseAll",
|
|
1237
|
+
value: function pauseAll() {
|
|
1238
|
+
// This method is deprecated
|
|
1239
|
+
// TODO: remove completely after a while
|
|
1240
|
+
this.log('This method is deprecated');
|
|
1241
|
+
}
|
|
1242
|
+
}, {
|
|
1243
|
+
key: "resumeAll",
|
|
1244
|
+
value: function resumeAll() {
|
|
1245
|
+
// This method is deprecated
|
|
1246
|
+
// TODO: remove completely after a while
|
|
1247
|
+
this.log('This method is deprecated');
|
|
1248
|
+
}
|
|
1249
|
+
}, {
|
|
1250
|
+
key: "retryAll",
|
|
1251
|
+
value: function retryAll() {
|
|
1252
|
+
// This method is deprecated
|
|
1253
|
+
// TODO: remove completely after a while
|
|
1254
|
+
this.log('This method is deprecated');
|
|
1255
|
+
}
|
|
1256
|
+
}, {
|
|
1257
|
+
key: "cancelAll",
|
|
1258
|
+
value: function cancelAll() {
|
|
1259
|
+
// This method is deprecated
|
|
1260
|
+
// TODO: remove completely after a while
|
|
1261
|
+
this.log('This method is deprecated');
|
|
1262
|
+
}
|
|
1263
|
+
}, {
|
|
1264
|
+
key: "cancelUploads",
|
|
1265
|
+
value: function cancelUploads() {
|
|
1266
|
+
this.emit('cancel-uploads');
|
|
1267
|
+
this.uploadOperations = {};
|
|
1268
|
+
this.dispatch(allUploadsCancelled({
|
|
1269
|
+
capabilities: {
|
|
1270
|
+
allowResumableUploads: Boolean(this.getPlugin(PLUGINS_IDS.TUS))
|
|
1271
|
+
}
|
|
1272
|
+
}));
|
|
1273
|
+
}
|
|
1274
|
+
}, {
|
|
1275
|
+
key: "retryUpload",
|
|
1276
|
+
value: function retryUpload(fileId, fallbackFile) {
|
|
1277
|
+
var file = this.getFileUploading(fileId);
|
|
1278
|
+
if (!file && fallbackFile) {
|
|
1279
|
+
return this.retryRemovedUpload(fallbackFile);
|
|
1280
|
+
}
|
|
1281
|
+
this._checkIfFileIsAvailable(file, "can't retry a file that has been removed: ".concat(fileId));
|
|
1282
|
+
this.setFileUploadingState(fileId, file.uploadId, {
|
|
1283
|
+
error: null
|
|
1284
|
+
});
|
|
1285
|
+
this.emit('upload-retry', fileId);
|
|
1286
|
+
return this._runUploadOperation(file.uploadId);
|
|
1287
|
+
}
|
|
1288
|
+
}, {
|
|
1289
|
+
key: "retryRemovedUpload",
|
|
1290
|
+
value: function retryRemovedUpload(file) {
|
|
1291
|
+
if (!file || _typeof(file) !== 'object') {
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
this.emit('upload-retry', file.id);
|
|
1295
|
+
return this.upload(_defineProperty({}, file.id, file));
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
/**
|
|
1299
|
+
* Registers listeners for all global actions, like:
|
|
1300
|
+
* `error`, `file-removed`, `upload-progress`
|
|
1301
|
+
*/
|
|
1302
|
+
}, {
|
|
1303
|
+
key: "_addListeners",
|
|
1304
|
+
value: function _addListeners() {
|
|
1305
|
+
var _this6 = this;
|
|
1306
|
+
this.on('error', function (filesIds, error, _ref6) {
|
|
1307
|
+
var uploadId = _ref6.uploadId;
|
|
1308
|
+
var errorMsg = 'Unknown error';
|
|
1309
|
+
if (error.message) {
|
|
1310
|
+
errorMsg = error.message;
|
|
1311
|
+
}
|
|
1312
|
+
if (error.details) {
|
|
1313
|
+
errorMsg += ' ' + error.details;
|
|
1314
|
+
}
|
|
1315
|
+
filesIds.forEach(function (fileId) {
|
|
1316
|
+
var file = _this6.getFileUploading(fileId);
|
|
1317
|
+
_this6.setFileUploadingState(fileId, uploadId, {
|
|
1318
|
+
progress: _objectSpread(_objectSpread({}, file.progress), {}, {
|
|
1319
|
+
status: FILE_UPLOAD_STATUS.ERROR
|
|
1320
|
+
}),
|
|
1321
|
+
error: errorMsg
|
|
1322
|
+
});
|
|
1323
|
+
_this6.emit('activity-error', {
|
|
1324
|
+
id: file.id,
|
|
1325
|
+
error: errorMsg
|
|
1326
|
+
});
|
|
1327
|
+
});
|
|
1328
|
+
});
|
|
1329
|
+
|
|
1330
|
+
// show informer if offline
|
|
1331
|
+
if (typeof window !== 'undefined' && window.addEventListener) {
|
|
1332
|
+
window.addEventListener('online', function () {
|
|
1333
|
+
return _this6.updateOnlineStatus();
|
|
1334
|
+
});
|
|
1335
|
+
window.addEventListener('offline', function () {
|
|
1336
|
+
return _this6.updateOnlineStatus();
|
|
1337
|
+
});
|
|
1338
|
+
setTimeout(function () {
|
|
1339
|
+
return _this6.updateOnlineStatus();
|
|
1340
|
+
}, 3000);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
}, {
|
|
1344
|
+
key: "updateOnlineStatus",
|
|
1345
|
+
value: function updateOnlineStatus() {
|
|
1346
|
+
var isOnline = checkConnection();
|
|
1347
|
+
if (!isOnline) {
|
|
1348
|
+
this.emit('is-offline');
|
|
1349
|
+
this.info(this.i18n('filerobotNoInternetConnectionInfo'), 'error', 5000);
|
|
1350
|
+
this.wasOffline = true;
|
|
1351
|
+
} else {
|
|
1352
|
+
this.emit('is-online');
|
|
1353
|
+
if (this.wasOffline) {
|
|
1354
|
+
this.emit('back-online');
|
|
1355
|
+
this.info(this.i18n('filerobotConnectedToInternetInfo'), 'success', 3000);
|
|
1356
|
+
this.wasOffline = false;
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
}, {
|
|
1361
|
+
key: "generateUserKey",
|
|
1362
|
+
value: function generateUserKey() {
|
|
1363
|
+
return this.dispatch(_generateUserKey());
|
|
1364
|
+
}
|
|
1365
|
+
}, {
|
|
1366
|
+
key: "checkUserPermissions",
|
|
1367
|
+
value: function checkUserPermissions() {
|
|
1368
|
+
var _this7 = this;
|
|
1369
|
+
var permissionsToCheck = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
1370
|
+
var showMsg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1371
|
+
var state = this.getGlobalState();
|
|
1372
|
+
var permissions = selectUserPermissions(state);
|
|
1373
|
+
var loading = selectCoreLoading(state);
|
|
1374
|
+
var isSasskeyGenerated = !!selectUserSassKey(state);
|
|
1375
|
+
if (Object.keys(permissions).length === 0 && isSasskeyGenerated) {
|
|
1376
|
+
if (!loading) {
|
|
1377
|
+
// Show warning only when permissions are missing after core loading
|
|
1378
|
+
setTimeout(function () {
|
|
1379
|
+
_this7.info(_this7.i18n('filerobotNoPermissionsInfo'), 'error', 5000);
|
|
1380
|
+
}, 0);
|
|
1381
|
+
}
|
|
1382
|
+
return false;
|
|
1383
|
+
}
|
|
1384
|
+
var areAllPermissionsValid = !permissionsToCheck.some(function (permission) {
|
|
1385
|
+
return permission && !permissions[permission];
|
|
1386
|
+
});
|
|
1387
|
+
if (showMsg && !areAllPermissionsValid) {
|
|
1388
|
+
this.info(this.i18n('filerobotInvalidPermissionError'), 'error', 4000);
|
|
1389
|
+
return false;
|
|
1390
|
+
}
|
|
1391
|
+
return areAllPermissionsValid;
|
|
1392
|
+
}
|
|
1393
|
+
}, {
|
|
1394
|
+
key: "getId",
|
|
1395
|
+
value: function getId() {
|
|
1396
|
+
return this.opts.id;
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
/**
|
|
1400
|
+
* Registers a plugin with Core.
|
|
1401
|
+
*
|
|
1402
|
+
* @param {object} Plugin object
|
|
1403
|
+
* @param {object} [opts] object with options to be passed to Plugin
|
|
1404
|
+
* @returns {object} self for chaining
|
|
1405
|
+
*/
|
|
1406
|
+
}, {
|
|
1407
|
+
key: "use",
|
|
1408
|
+
value: function use(Plugin, opts) {
|
|
1409
|
+
if (typeof Plugin !== 'function') {
|
|
1410
|
+
var msg = "Expected a plugin class, but got ".concat(Plugin === null ? 'null' : _typeof(Plugin), ".") + ' Please verify that the plugin was imported and spelled correctly.';
|
|
1411
|
+
throw new TypeError(msg);
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
// Instantiate
|
|
1415
|
+
var plugin = new Plugin(this, opts);
|
|
1416
|
+
var pluginId = plugin.id;
|
|
1417
|
+
this.plugins[plugin.type] = this.plugins[plugin.type] || [];
|
|
1418
|
+
if (!pluginId) {
|
|
1419
|
+
throw new Error('Your plugin must have an id');
|
|
1420
|
+
}
|
|
1421
|
+
if (!plugin.type) {
|
|
1422
|
+
throw new Error('Your plugin must have a type');
|
|
1423
|
+
}
|
|
1424
|
+
var existsPluginAlready = this.getPlugin(pluginId);
|
|
1425
|
+
if (existsPluginAlready) {
|
|
1426
|
+
var _msg = "Already found a plugin named '".concat(existsPluginAlready.id, "'. ") + "Tried to use: '".concat(pluginId, "'.\n") + 'filerobot plugins must have unique `id` options.';
|
|
1427
|
+
throw new Error(_msg);
|
|
1428
|
+
}
|
|
1429
|
+
if (Plugin.VERSION) {
|
|
1430
|
+
this.log("Using ".concat(pluginId, " v").concat(Plugin.VERSION));
|
|
1431
|
+
}
|
|
1432
|
+
var pluginReducer = plugin.getPluginReducer();
|
|
1433
|
+
if (typeof pluginReducer === 'function') {
|
|
1434
|
+
this._injectReducer(pluginId, pluginReducer);
|
|
1435
|
+
}
|
|
1436
|
+
this.plugins[plugin.type].push(plugin);
|
|
1437
|
+
plugin.install();
|
|
1438
|
+
this.emit('plugins-updated', this._getInstalledPkgs());
|
|
1439
|
+
return this;
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
/**
|
|
1443
|
+
* Find one Plugin by name.
|
|
1444
|
+
*
|
|
1445
|
+
* @param {string} id plugin id
|
|
1446
|
+
* @returns {object|boolean}
|
|
1447
|
+
*/
|
|
1448
|
+
}, {
|
|
1449
|
+
key: "getPlugin",
|
|
1450
|
+
value: function getPlugin(id) {
|
|
1451
|
+
var foundPlugin = null;
|
|
1452
|
+
this.iteratePlugins(function (plugin) {
|
|
1453
|
+
if (plugin.id === id) {
|
|
1454
|
+
foundPlugin = plugin;
|
|
1455
|
+
return false;
|
|
1456
|
+
}
|
|
1457
|
+
});
|
|
1458
|
+
return foundPlugin;
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
/**
|
|
1462
|
+
* Get all the pre-processor plugins
|
|
1463
|
+
*
|
|
1464
|
+
* @returns array
|
|
1465
|
+
*/
|
|
1466
|
+
}, {
|
|
1467
|
+
key: "getPreProcessors",
|
|
1468
|
+
value: function getPreProcessors() {
|
|
1469
|
+
return this.preProcessors;
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
/**
|
|
1473
|
+
* Get all the post-processor plugins
|
|
1474
|
+
*
|
|
1475
|
+
* @returns array
|
|
1476
|
+
*/
|
|
1477
|
+
}, {
|
|
1478
|
+
key: "getPostProcessors",
|
|
1479
|
+
value: function getPostProcessors() {
|
|
1480
|
+
return this.postProcessors;
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
/**
|
|
1484
|
+
* Iterate through all `use`d plugins.
|
|
1485
|
+
*
|
|
1486
|
+
* @param {Function} method that will be run on each plugin
|
|
1487
|
+
*/
|
|
1488
|
+
}, {
|
|
1489
|
+
key: "iteratePlugins",
|
|
1490
|
+
value: function iteratePlugins(method) {
|
|
1491
|
+
var _this8 = this;
|
|
1492
|
+
Object.keys(this.plugins).forEach(function (pluginType) {
|
|
1493
|
+
_this8.plugins[pluginType].forEach(method);
|
|
1494
|
+
});
|
|
1495
|
+
}
|
|
1496
|
+
}, {
|
|
1497
|
+
key: "checkPluginTypeExistence",
|
|
1498
|
+
value: function checkPluginTypeExistence() {
|
|
1499
|
+
var pluginTypeToCheck = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
1500
|
+
var pluginTypeLoweredCase = pluginTypeToCheck.toLowerCase();
|
|
1501
|
+
if (!pluginTypeLoweredCase) {
|
|
1502
|
+
return;
|
|
1503
|
+
}
|
|
1504
|
+
return Object.keys(this.plugins).includes(pluginTypeLoweredCase) && this.plugins[pluginTypeLoweredCase].length > 0;
|
|
1505
|
+
}
|
|
1506
|
+
}, {
|
|
1507
|
+
key: "checkPluginExistence",
|
|
1508
|
+
value: function checkPluginExistence() {
|
|
1509
|
+
var pluginIdToCheck = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
1510
|
+
if (!pluginIdToCheck) {
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
return Boolean(this.getPlugin(pluginIdToCheck));
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
/**
|
|
1517
|
+
* Uninstall and remove a plugin.
|
|
1518
|
+
*
|
|
1519
|
+
* @param {object} instance The plugin instance to remove.
|
|
1520
|
+
*/
|
|
1521
|
+
}, {
|
|
1522
|
+
key: "removePlugin",
|
|
1523
|
+
value: function removePlugin(instance) {
|
|
1524
|
+
this.log("Removing plugin ".concat(instance.id));
|
|
1525
|
+
if (instance.uninstall) {
|
|
1526
|
+
instance.uninstall();
|
|
1527
|
+
}
|
|
1528
|
+
var list = this.plugins[instance.type].slice();
|
|
1529
|
+
var index = list.indexOf(instance);
|
|
1530
|
+
if (index !== -1) {
|
|
1531
|
+
list.splice(index, 1);
|
|
1532
|
+
this._removeReducer(instance.id);
|
|
1533
|
+
this.plugins[instance.type] = list;
|
|
1534
|
+
}
|
|
1535
|
+
this.emit('plugin-remove', instance);
|
|
1536
|
+
this.emit('plugins-updated', this._getInstalledPkgs());
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
/**
|
|
1540
|
+
* Uninstall all plugins and close down this filerobot instance.
|
|
1541
|
+
*/
|
|
1542
|
+
}, {
|
|
1543
|
+
key: "close",
|
|
1544
|
+
value: function close() {
|
|
1545
|
+
var _this9 = this;
|
|
1546
|
+
this.log("Closing filerobot instance ".concat(this.opts.id, ": removing all files and uninstalling plugins"));
|
|
1547
|
+
this._storeUnsubscribe();
|
|
1548
|
+
if (this.opts.sassKeyRenewerEnabled) {
|
|
1549
|
+
this._sassKeyRenewerUnsubscribe();
|
|
1550
|
+
}
|
|
1551
|
+
this.iteratePlugins(function (plugin) {
|
|
1552
|
+
_this9.removePlugin(plugin);
|
|
1553
|
+
});
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
/**
|
|
1557
|
+
* Set info message in `state.info`, so that UI plugins like `Informer`
|
|
1558
|
+
* can display the message.
|
|
1559
|
+
*
|
|
1560
|
+
* @param {string | object} message Message to be displayed by the informer
|
|
1561
|
+
* @param {string} [type]
|
|
1562
|
+
* @param {number} [duration]
|
|
1563
|
+
*/
|
|
1564
|
+
}, {
|
|
1565
|
+
key: "info",
|
|
1566
|
+
value: function info(message) {
|
|
1567
|
+
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'info';
|
|
1568
|
+
var duration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 3000;
|
|
1569
|
+
// Avoid showing aborted/cancelled request feedback to the user.
|
|
1570
|
+
if (message === ABORTED_ERROR || message === (ABORTED_ERROR === null || ABORTED_ERROR === void 0 ? void 0 : ABORTED_ERROR.message)) {
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1573
|
+
var isComplexMessage = _typeof(message) === 'object';
|
|
1574
|
+
var toStringIfObj = function toStringIfObj(data) {
|
|
1575
|
+
return _typeof(data) === 'object' ? data.toString() : data;
|
|
1576
|
+
};
|
|
1577
|
+
this.dispatch(infoSet({
|
|
1578
|
+
isHidden: false,
|
|
1579
|
+
type: type,
|
|
1580
|
+
message: isComplexMessage ? toStringIfObj(message.message) : message,
|
|
1581
|
+
details: isComplexMessage ? toStringIfObj(message.details) : null,
|
|
1582
|
+
errors: message.errors
|
|
1583
|
+
}));
|
|
1584
|
+
this.emit('info-visible');
|
|
1585
|
+
clearTimeout(this.infoTimeoutId);
|
|
1586
|
+
if (duration === 0) {
|
|
1587
|
+
this.infoTimeoutId = undefined;
|
|
1588
|
+
return;
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
// hide the informer after `duration` milliseconds
|
|
1592
|
+
this.infoTimeoutId = setTimeout(this.hideInfo, duration);
|
|
1593
|
+
}
|
|
1594
|
+
}, {
|
|
1595
|
+
key: "hideInfo",
|
|
1596
|
+
value: function hideInfo() {
|
|
1597
|
+
this.dispatch(infoHid());
|
|
1598
|
+
this.emit('info-hidden');
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
/**
|
|
1602
|
+
* Passes messages to a function, provided in `opts.logger`.
|
|
1603
|
+
* If `opts.logger: filerobot.debugLogger` or `opts.debug: true`, logs to the browser console.
|
|
1604
|
+
*
|
|
1605
|
+
* @param {string|object} message to log
|
|
1606
|
+
* @param {string} [type] optional `error` or `warning`
|
|
1607
|
+
*/
|
|
1608
|
+
}, {
|
|
1609
|
+
key: "log",
|
|
1610
|
+
value: function log(message, type) {
|
|
1611
|
+
var logger = this.opts.logger;
|
|
1612
|
+
if (!logger) {
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
switch (type) {
|
|
1616
|
+
case 'error':
|
|
1617
|
+
logger.error(message);
|
|
1618
|
+
break;
|
|
1619
|
+
case 'warning':
|
|
1620
|
+
logger.warn(message);
|
|
1621
|
+
break;
|
|
1622
|
+
default:
|
|
1623
|
+
logger.debug(message);
|
|
1624
|
+
break;
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
/**
|
|
1629
|
+
* Obsolete, event listeners are now added in the constructor.
|
|
1630
|
+
*/
|
|
1631
|
+
}, {
|
|
1632
|
+
key: "run",
|
|
1633
|
+
value: function run() {
|
|
1634
|
+
this.log('Calling run() is no longer necessary.', 'warning');
|
|
1635
|
+
return this;
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
/**
|
|
1639
|
+
* Restore an upload by its ID.
|
|
1640
|
+
*/
|
|
1641
|
+
}, {
|
|
1642
|
+
key: "restore",
|
|
1643
|
+
value: function restore(uploadId) {
|
|
1644
|
+
this.log("Core: attempting to restore upload \"".concat(uploadId, "\""));
|
|
1645
|
+
if (!this.getUploadOperation(uploadId)) {
|
|
1646
|
+
this._removeUploadOperation(uploadId);
|
|
1647
|
+
return Promise.reject(new Error('Nonexistent upload'));
|
|
1648
|
+
}
|
|
1649
|
+
return this._runUploadOperation(uploadId);
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
/**
|
|
1653
|
+
* Create an upload for a bunch of files.
|
|
1654
|
+
*
|
|
1655
|
+
* @param {Object} files Files to include in this upload.
|
|
1656
|
+
* @returns {string} ID of this upload.
|
|
1657
|
+
*/
|
|
1658
|
+
}, {
|
|
1659
|
+
key: "_createUploadOperation",
|
|
1660
|
+
value: function _createUploadOperation(files) {
|
|
1661
|
+
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1662
|
+
var _opts$forceAllowNewUp = opts.forceAllowNewUpload,
|
|
1663
|
+
forceAllowNewUpload = _opts$forceAllowNewUp === void 0 ? false : _opts$forceAllowNewUp;
|
|
1664
|
+
var _this$getUploadCapabi2 = this.getUploadCapabilities(),
|
|
1665
|
+
allowNewUpload = _this$getUploadCapabi2.allowNewUpload;
|
|
1666
|
+
if (!allowNewUpload && !forceAllowNewUpload) {
|
|
1667
|
+
throw new Error('Cannot create a new upload: already uploading.');
|
|
1668
|
+
}
|
|
1669
|
+
var uploadId = cuid();
|
|
1670
|
+
var filesIds = Object.keys(files);
|
|
1671
|
+
this.emit('upload', {
|
|
1672
|
+
id: uploadId,
|
|
1673
|
+
filesIds: filesIds,
|
|
1674
|
+
files: files
|
|
1675
|
+
});
|
|
1676
|
+
this.dispatch(uploadCapabilitiesUpdated({
|
|
1677
|
+
allowMultipleUploads: this.opts.allowMultipleUploads,
|
|
1678
|
+
allowNewUpload: this.opts.allowMultipleUploads !== false
|
|
1679
|
+
}));
|
|
1680
|
+
this.uploadOperations[uploadId] = {
|
|
1681
|
+
id: uploadId,
|
|
1682
|
+
filesIds: filesIds,
|
|
1683
|
+
files: files,
|
|
1684
|
+
step: 0,
|
|
1685
|
+
result: {}
|
|
1686
|
+
};
|
|
1687
|
+
return uploadId;
|
|
1688
|
+
}
|
|
1689
|
+
}, {
|
|
1690
|
+
key: "getUploadOperation",
|
|
1691
|
+
value: function getUploadOperation(uploadId) {
|
|
1692
|
+
return this.getUploadOperations()[uploadId];
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
/**
|
|
1696
|
+
* Add data to an upload's result object.
|
|
1697
|
+
*
|
|
1698
|
+
* @param {string} uploadId The ID of the upload.
|
|
1699
|
+
* @param {object} data Data properties to add to the result object.
|
|
1700
|
+
*/
|
|
1701
|
+
}, {
|
|
1702
|
+
key: "addResultData",
|
|
1703
|
+
value: function addResultData(uploadId, data) {
|
|
1704
|
+
if (!this.getUploadOperation(uploadId)) {
|
|
1705
|
+
this.log("Not setting result for an upload that has been removed: ".concat(uploadId));
|
|
1706
|
+
return;
|
|
1707
|
+
}
|
|
1708
|
+
var currentUploadOperation = this.getUploadOperation(uploadId);
|
|
1709
|
+
this._updateUploadOperation({
|
|
1710
|
+
id: uploadId,
|
|
1711
|
+
result: _objectSpread(_objectSpread({}, currentUploadOperation.result), data)
|
|
1712
|
+
});
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
/**
|
|
1716
|
+
* Remove an upload, eg. if it has been canceled or completed.
|
|
1717
|
+
*
|
|
1718
|
+
* @param {string} uploadId The ID of the upload.
|
|
1719
|
+
*/
|
|
1720
|
+
}, {
|
|
1721
|
+
key: "_removeUploadOperation",
|
|
1722
|
+
value: function _removeUploadOperation(uploadId) {
|
|
1723
|
+
delete this.uploadOperations[uploadId];
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
/**
|
|
1727
|
+
* Edit an upload, eg. if its step/phase is being updated.
|
|
1728
|
+
*
|
|
1729
|
+
* @param {string} updatedUpload - the updated/changed upload operation must contain `id` for the upload's id to be changed.
|
|
1730
|
+
*/
|
|
1731
|
+
}, {
|
|
1732
|
+
key: "_updateUploadOperation",
|
|
1733
|
+
value: function _updateUploadOperation(updatedUpload) {
|
|
1734
|
+
this.uploadOperations[updatedUpload.id] = _objectSpread(_objectSpread({}, this.uploadOperations[updatedUpload.id]), updatedUpload);
|
|
1735
|
+
}
|
|
1736
|
+
}, {
|
|
1737
|
+
key: "setProgressPanelFileState",
|
|
1738
|
+
value: function setProgressPanelFileState() {
|
|
1739
|
+
// This method is deprecated
|
|
1740
|
+
// TODO: remove completely after a while
|
|
1741
|
+
this.log('This method is deprecated, please use setFileUploadingState instead');
|
|
1742
|
+
}
|
|
1743
|
+
}, {
|
|
1744
|
+
key: "setFileUploadingState",
|
|
1745
|
+
value: function setFileUploadingState(fileId, uploadId, state) {
|
|
1746
|
+
var _this$uploadOperation;
|
|
1747
|
+
if (!this.getFileUploading(fileId)) {
|
|
1748
|
+
throw new Error("Can\u2019t set state for ".concat(fileId, " (the file could have been removed)"));
|
|
1749
|
+
}
|
|
1750
|
+
var fileState = _objectSpread(_objectSpread({}, state), {}, {
|
|
1751
|
+
id: fileId
|
|
1752
|
+
});
|
|
1753
|
+
var currentFiles = (_this$uploadOperation = this.uploadOperations[uploadId]) === null || _this$uploadOperation === void 0 ? void 0 : _this$uploadOperation.files;
|
|
1754
|
+
var currentFile = currentFiles === null || currentFiles === void 0 ? void 0 : currentFiles[fileId];
|
|
1755
|
+
this._updateUploadOperation({
|
|
1756
|
+
id: uploadId,
|
|
1757
|
+
files: _objectSpread(_objectSpread({}, currentFiles), {}, _defineProperty({}, fileId, _objectSpread(_objectSpread({}, currentFile), fileState)))
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
/**
|
|
1762
|
+
* Run an upload. This picks up where it left off in case the upload is being restored.
|
|
1763
|
+
*
|
|
1764
|
+
* @private
|
|
1765
|
+
*/
|
|
1766
|
+
}, {
|
|
1767
|
+
key: "_runUploadOperation",
|
|
1768
|
+
value: function _runUploadOperation(uploadId) {
|
|
1769
|
+
var _this10 = this;
|
|
1770
|
+
var uploadData = this.getUploadOperation(uploadId);
|
|
1771
|
+
var restoreStep = uploadData.step;
|
|
1772
|
+
var steps = [].concat(_toConsumableArray(this.preProcessors), _toConsumableArray(this.filerobots), _toConsumableArray(this.postProcessors));
|
|
1773
|
+
var lastStep = Promise.resolve();
|
|
1774
|
+
steps.forEach(function (fn, step) {
|
|
1775
|
+
// Skip this step if we are restoring and have already completed this step before.
|
|
1776
|
+
if (step < restoreStep) {
|
|
1777
|
+
return;
|
|
1778
|
+
}
|
|
1779
|
+
lastStep = lastStep.then(function () {
|
|
1780
|
+
var currentUploadOperation = _this10.getUploadOperation(uploadId);
|
|
1781
|
+
if (!currentUploadOperation) {
|
|
1782
|
+
return;
|
|
1783
|
+
}
|
|
1784
|
+
var updatedUploadSlice = {
|
|
1785
|
+
id: uploadId,
|
|
1786
|
+
step: step
|
|
1787
|
+
};
|
|
1788
|
+
_this10._updateUploadOperation(updatedUploadSlice);
|
|
1789
|
+
// The processor is an object { process: fn, render: fn } which contains process function
|
|
1790
|
+
// otherwise would be the uploading process function.
|
|
1791
|
+
return fn ? (fn.process || fn)(currentUploadOperation.filesIds, uploadId) : Promise.resolve();
|
|
1792
|
+
}).then(function (result) {
|
|
1793
|
+
return null;
|
|
1794
|
+
});
|
|
1795
|
+
});
|
|
1796
|
+
|
|
1797
|
+
// Not returning the `catch`ed promise, because we still want to return a rejected
|
|
1798
|
+
// promise from this method if the upload failed.
|
|
1799
|
+
lastStep["catch"](function (error) {
|
|
1800
|
+
var currentUploadOperation = _this10.getUploadOperation(uploadId);
|
|
1801
|
+
var filesIds = currentUploadOperation.filesIds;
|
|
1802
|
+
_this10.emit('error', filesIds, error, {
|
|
1803
|
+
uploadId: uploadId
|
|
1804
|
+
});
|
|
1805
|
+
_this10._removeUploadOperation(uploadId);
|
|
1806
|
+
});
|
|
1807
|
+
return lastStep.then(function () {
|
|
1808
|
+
// Set result data.
|
|
1809
|
+
var currentUploadOperation = _this10.getUploadOperation(uploadId);
|
|
1810
|
+
if (!currentUploadOperation) {
|
|
1811
|
+
return;
|
|
1812
|
+
}
|
|
1813
|
+
var files = currentUploadOperation.filesIds.map(function (fileId) {
|
|
1814
|
+
return _this10.getFileUploading(fileId);
|
|
1815
|
+
});
|
|
1816
|
+
var successful = files.filter(function (file) {
|
|
1817
|
+
return (file === null || file === void 0 ? void 0 : file.progress.status) !== FILE_UPLOAD_STATUS.ERROR;
|
|
1818
|
+
});
|
|
1819
|
+
var failed = files.filter(function (file) {
|
|
1820
|
+
return (file === null || file === void 0 ? void 0 : file.progress.status) === FILE_UPLOAD_STATUS.ERROR;
|
|
1821
|
+
});
|
|
1822
|
+
_this10.addResultData(uploadId, {
|
|
1823
|
+
successful: successful,
|
|
1824
|
+
failed: failed,
|
|
1825
|
+
uploadId: uploadId
|
|
1826
|
+
});
|
|
1827
|
+
}).then(function () {
|
|
1828
|
+
// Emit completion events.
|
|
1829
|
+
// This is in a separate function so that the `currentUploadOperations` variable
|
|
1830
|
+
// always refers to the latest state. In the handler right above it refers
|
|
1831
|
+
// to an outdated object without the `.result` property.
|
|
1832
|
+
var currentUploadOperation = _this10.getUploadOperation(uploadId);
|
|
1833
|
+
if (!currentUploadOperation) {
|
|
1834
|
+
return;
|
|
1835
|
+
}
|
|
1836
|
+
var result = currentUploadOperation.result;
|
|
1837
|
+
_this10.emit('complete', result);
|
|
1838
|
+
_this10._removeUploadOperation(uploadId);
|
|
1839
|
+
return result;
|
|
1840
|
+
}).then(function (result) {
|
|
1841
|
+
if (result == null) {
|
|
1842
|
+
_this10.log("Not setting result for an upload that has been removed: ".concat(uploadId));
|
|
1843
|
+
}
|
|
1844
|
+
return result;
|
|
1845
|
+
});
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
/**
|
|
1849
|
+
* Start an upload for all the files that are not currently being uploaded.
|
|
1850
|
+
*
|
|
1851
|
+
* @returns {Promise}
|
|
1852
|
+
*/
|
|
1853
|
+
}, {
|
|
1854
|
+
key: "upload",
|
|
1855
|
+
value: function upload(files, callback) {
|
|
1856
|
+
var _this11 = this;
|
|
1857
|
+
if (!this.plugins.uploader) {
|
|
1858
|
+
this.log('No filerobot type plugins are used', 'warning');
|
|
1859
|
+
}
|
|
1860
|
+
var filesToUpload = files || selectUploads(this.getGlobalState());
|
|
1861
|
+
var onBeforeUploadResult = this.opts.onBeforeUpload(filesToUpload);
|
|
1862
|
+
if (onBeforeUploadResult === false) {
|
|
1863
|
+
return Promise.reject(new Error('Not starting the upload because onBeforeUpload returned false'));
|
|
1864
|
+
}
|
|
1865
|
+
if (onBeforeUploadResult && _typeof(onBeforeUploadResult) === 'object') {
|
|
1866
|
+
filesToUpload = onBeforeUploadResult;
|
|
1867
|
+
}
|
|
1868
|
+
return Promise.resolve().then(function () {
|
|
1869
|
+
return _this11._checkMinNumberOfFiles(filesToUpload);
|
|
1870
|
+
})["catch"](function (err) {
|
|
1871
|
+
_this11._showOrLogErrorAndThrow(err);
|
|
1872
|
+
}).then(function () {
|
|
1873
|
+
if (typeof callback === 'function') {
|
|
1874
|
+
callback(filesToUpload);
|
|
1875
|
+
}
|
|
1876
|
+
_this11.dispatch(allUploadsRemoved());
|
|
1877
|
+
var currentUploadOperations = _this11.getUploadOperations();
|
|
1878
|
+
// get a list of files that are currently assigned to uploads
|
|
1879
|
+
var currentlyUploadingFiles = Object.keys(currentUploadOperations).reduce(function (prev, curr) {
|
|
1880
|
+
return prev.concat(currentUploadOperations[curr].filesIds);
|
|
1881
|
+
}, []);
|
|
1882
|
+
var waitingFiles = {};
|
|
1883
|
+
Object.keys(filesToUpload).forEach(function (fileId) {
|
|
1884
|
+
// if the file hasn't started uploading
|
|
1885
|
+
if (currentlyUploadingFiles.indexOf(fileId) === -1) {
|
|
1886
|
+
waitingFiles[fileId] = _objectSpread({}, filesToUpload[fileId]);
|
|
1887
|
+
}
|
|
1888
|
+
});
|
|
1889
|
+
var uploadId = _this11._createUploadOperation(waitingFiles);
|
|
1890
|
+
return _this11._runUploadOperation(uploadId);
|
|
1891
|
+
})["catch"](function (err) {
|
|
1892
|
+
_this11._showOrLogErrorAndThrow(err, {
|
|
1893
|
+
showInformer: false
|
|
1894
|
+
});
|
|
1895
|
+
});
|
|
1896
|
+
}
|
|
1897
|
+
}, {
|
|
1898
|
+
key: "getRemoteUploadFolder",
|
|
1899
|
+
value: function getRemoteUploadFolder() {
|
|
1900
|
+
var _ref7 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
1901
|
+
_ref7$file = _ref7.file,
|
|
1902
|
+
file = _ref7$file === void 0 ? {} : _ref7$file,
|
|
1903
|
+
opts = _ref7.opts;
|
|
1904
|
+
var _this$getCoreCommonSt = this.getCoreCommonState(),
|
|
1905
|
+
dndTargetFolderPath = _this$getCoreCommonSt.dndTargetFolderPath,
|
|
1906
|
+
_this$getCoreCommonSt2 = _this$getCoreCommonSt.isDragging,
|
|
1907
|
+
isDragging = _this$getCoreCommonSt2 === void 0 ? false : _this$getCoreCommonSt2,
|
|
1908
|
+
_this$getCoreCommonSt3 = _this$getCoreCommonSt.xhrUpload,
|
|
1909
|
+
xhrUpload = _this$getCoreCommonSt3 === void 0 ? {} : _this$getCoreCommonSt3;
|
|
1910
|
+
var _ref8 = opts || _objectSpread(_objectSpread(_objectSpread({}, this.opts), xhrUpload), file === null || file === void 0 ? void 0 : file.xhrUpload),
|
|
1911
|
+
uploadToFolderPath = _ref8.uploadToFolderPath,
|
|
1912
|
+
_ref8$uploadQueryPara = _ref8.uploadQueryParams,
|
|
1913
|
+
uploadQueryParams = _ref8$uploadQueryPara === void 0 ? '' : _ref8$uploadQueryPara;
|
|
1914
|
+
var isFolderInUploadParams = (uploadQueryParams === null || uploadQueryParams === void 0 ? void 0 : uploadQueryParams.search('(^|&)folder=')) > -1;
|
|
1915
|
+
var path = '/';
|
|
1916
|
+
if (isFolderInUploadParams) path = uploadQueryParams.match(/folder=([^&]*)/)[1];else if (uploadToFolderPath) path = uploadToFolderPath;else if (isDragging) path = dndTargetFolderPath;else if (file !== null && file !== void 0 && file.toFolder) path = file.toFolder;
|
|
1917
|
+
return decodeURIComponent(path);
|
|
1918
|
+
}
|
|
1919
|
+
}]);
|
|
1920
|
+
}();
|
|
1921
|
+
// static VERSION = version
|
|
1922
|
+
// This property contains the data File class instance of the uploads' files, mapped through the file id,
|
|
1923
|
+
// as `File` class is not serializable data type so we are not saving it into redux, and keeping it in sync with related upload/file object.
|
|
1924
|
+
_defineProperty(ScaleflexWidget, "uploadFilesData", {
|
|
1925
|
+
// [fileId]: { [File/Blob instance] }
|
|
1926
|
+
});
|
|
1927
|
+
export default function (opts) {
|
|
1928
|
+
return new ScaleflexWidget(opts);
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
// Expose class constructor.
|
|
1932
|
+
export { ScaleflexWidget, Plugin, debugLogger };
|