|
1
|
|
|
|
|
2
|
|
|
import window from 'window'; |
|
3
|
|
|
import _ from '_'; |
|
4
|
|
|
import $ from '$'; |
|
5
|
|
|
import ko from 'ko'; |
|
6
|
|
|
import {Notification, UploadErrorCode} from 'Common/Enums'; |
|
7
|
|
|
import {pInt, isUnd, isNull, has, microtime, inArray} from 'Common/Utils'; |
|
8
|
|
|
import {$html, bAnimationSupported} from 'Common/Globals'; |
|
9
|
|
|
import {reload as momentorReload} from 'Common/Momentor'; |
|
10
|
|
|
import {langLink} from 'Common/Links'; |
|
11
|
|
|
import Promise from 'Promise'; |
|
12
|
|
|
|
|
13
|
|
|
let I18N_DATA = window.rainloopI18N || {}; |
|
14
|
|
|
|
|
15
|
|
|
const I18N_NOTIFICATION_DATA = {}; |
|
16
|
|
|
const I18N_NOTIFICATION_MAP = [ |
|
17
|
|
|
[Notification.InvalidToken, 'NOTIFICATIONS/INVALID_TOKEN'], |
|
18
|
|
|
[Notification.InvalidToken, 'NOTIFICATIONS/INVALID_TOKEN'], |
|
19
|
|
|
[Notification.AuthError, 'NOTIFICATIONS/AUTH_ERROR'], |
|
20
|
|
|
[Notification.AccessError, 'NOTIFICATIONS/ACCESS_ERROR'], |
|
21
|
|
|
[Notification.ConnectionError, 'NOTIFICATIONS/CONNECTION_ERROR'], |
|
22
|
|
|
[Notification.CaptchaError, 'NOTIFICATIONS/CAPTCHA_ERROR'], |
|
23
|
|
|
[Notification.SocialFacebookLoginAccessDisable, 'NOTIFICATIONS/SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE'], |
|
24
|
|
|
[Notification.SocialTwitterLoginAccessDisable, 'NOTIFICATIONS/SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE'], |
|
25
|
|
|
[Notification.SocialGoogleLoginAccessDisable, 'NOTIFICATIONS/SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE'], |
|
26
|
|
|
[Notification.DomainNotAllowed, 'NOTIFICATIONS/DOMAIN_NOT_ALLOWED'], |
|
27
|
|
|
[Notification.AccountNotAllowed, 'NOTIFICATIONS/ACCOUNT_NOT_ALLOWED'], |
|
28
|
|
|
|
|
29
|
|
|
[Notification.AccountTwoFactorAuthRequired, 'NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_REQUIRED'], |
|
30
|
|
|
[Notification.AccountTwoFactorAuthError, 'NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_ERROR'], |
|
31
|
|
|
|
|
32
|
|
|
[Notification.CouldNotSaveNewPassword, 'NOTIFICATIONS/COULD_NOT_SAVE_NEW_PASSWORD'], |
|
33
|
|
|
[Notification.CurrentPasswordIncorrect, 'NOTIFICATIONS/CURRENT_PASSWORD_INCORRECT'], |
|
34
|
|
|
[Notification.NewPasswordShort, 'NOTIFICATIONS/NEW_PASSWORD_SHORT'], |
|
35
|
|
|
[Notification.NewPasswordWeak, 'NOTIFICATIONS/NEW_PASSWORD_WEAK'], |
|
36
|
|
|
[Notification.NewPasswordForbidden, 'NOTIFICATIONS/NEW_PASSWORD_FORBIDDENT'], |
|
37
|
|
|
|
|
38
|
|
|
[Notification.ContactsSyncError, 'NOTIFICATIONS/CONTACTS_SYNC_ERROR'], |
|
39
|
|
|
|
|
40
|
|
|
[Notification.CantGetMessageList, 'NOTIFICATIONS/CANT_GET_MESSAGE_LIST'], |
|
41
|
|
|
[Notification.CantGetMessage, 'NOTIFICATIONS/CANT_GET_MESSAGE'], |
|
42
|
|
|
[Notification.CantDeleteMessage, 'NOTIFICATIONS/CANT_DELETE_MESSAGE'], |
|
43
|
|
|
[Notification.CantMoveMessage, 'NOTIFICATIONS/CANT_MOVE_MESSAGE'], |
|
44
|
|
|
[Notification.CantCopyMessage, 'NOTIFICATIONS/CANT_MOVE_MESSAGE'], |
|
45
|
|
|
|
|
46
|
|
|
[Notification.CantSaveMessage, 'NOTIFICATIONS/CANT_SAVE_MESSAGE'], |
|
47
|
|
|
[Notification.CantSendMessage, 'NOTIFICATIONS/CANT_SEND_MESSAGE'], |
|
48
|
|
|
[Notification.InvalidRecipients, 'NOTIFICATIONS/INVALID_RECIPIENTS'], |
|
49
|
|
|
|
|
50
|
|
|
[Notification.CantSaveFilters, 'NOTIFICATIONS/CANT_SAVE_FILTERS'], |
|
51
|
|
|
[Notification.CantGetFilters, 'NOTIFICATIONS/CANT_GET_FILTERS'], |
|
52
|
|
|
[Notification.FiltersAreNotCorrect, 'NOTIFICATIONS/FILTERS_ARE_NOT_CORRECT'], |
|
53
|
|
|
|
|
54
|
|
|
[Notification.CantCreateFolder, 'NOTIFICATIONS/CANT_CREATE_FOLDER'], |
|
55
|
|
|
[Notification.CantRenameFolder, 'NOTIFICATIONS/CANT_RENAME_FOLDER'], |
|
56
|
|
|
[Notification.CantDeleteFolder, 'NOTIFICATIONS/CANT_DELETE_FOLDER'], |
|
57
|
|
|
[Notification.CantDeleteNonEmptyFolder, 'NOTIFICATIONS/CANT_DELETE_NON_EMPTY_FOLDER'], |
|
58
|
|
|
[Notification.CantSubscribeFolder, 'NOTIFICATIONS/CANT_SUBSCRIBE_FOLDER'], |
|
59
|
|
|
[Notification.CantUnsubscribeFolder, 'NOTIFICATIONS/CANT_UNSUBSCRIBE_FOLDER'], |
|
60
|
|
|
|
|
61
|
|
|
[Notification.CantSaveSettings, 'NOTIFICATIONS/CANT_SAVE_SETTINGS'], |
|
62
|
|
|
[Notification.CantSavePluginSettings, 'NOTIFICATIONS/CANT_SAVE_PLUGIN_SETTINGS'], |
|
63
|
|
|
|
|
64
|
|
|
[Notification.DomainAlreadyExists, 'NOTIFICATIONS/DOMAIN_ALREADY_EXISTS'], |
|
65
|
|
|
|
|
66
|
|
|
[Notification.CantInstallPackage, 'NOTIFICATIONS/CANT_INSTALL_PACKAGE'], |
|
67
|
|
|
[Notification.CantDeletePackage, 'NOTIFICATIONS/CANT_DELETE_PACKAGE'], |
|
68
|
|
|
[Notification.InvalidPluginPackage, 'NOTIFICATIONS/INVALID_PLUGIN_PACKAGE'], |
|
69
|
|
|
[Notification.UnsupportedPluginPackage, 'NOTIFICATIONS/UNSUPPORTED_PLUGIN_PACKAGE'], |
|
70
|
|
|
|
|
71
|
|
|
[Notification.LicensingServerIsUnavailable, 'NOTIFICATIONS/LICENSING_SERVER_IS_UNAVAILABLE'], |
|
72
|
|
|
[Notification.LicensingExpired, 'NOTIFICATIONS/LICENSING_EXPIRED'], |
|
73
|
|
|
[Notification.LicensingBanned, 'NOTIFICATIONS/LICENSING_BANNED'], |
|
74
|
|
|
|
|
75
|
|
|
[Notification.DemoSendMessageError, 'NOTIFICATIONS/DEMO_SEND_MESSAGE_ERROR'], |
|
76
|
|
|
[Notification.DemoAccountError, 'NOTIFICATIONS/DEMO_ACCOUNT_ERROR'], |
|
77
|
|
|
|
|
78
|
|
|
[Notification.AccountAlreadyExists, 'NOTIFICATIONS/ACCOUNT_ALREADY_EXISTS'], |
|
79
|
|
|
[Notification.AccountDoesNotExist, 'NOTIFICATIONS/ACCOUNT_DOES_NOT_EXIST'], |
|
80
|
|
|
|
|
81
|
|
|
[Notification.MailServerError, 'NOTIFICATIONS/MAIL_SERVER_ERROR'], |
|
82
|
|
|
[Notification.InvalidInputArgument, 'NOTIFICATIONS/INVALID_INPUT_ARGUMENT'], |
|
83
|
|
|
[Notification.UnknownNotification, 'NOTIFICATIONS/UNKNOWN_ERROR'], |
|
84
|
|
|
[Notification.UnknownError, 'NOTIFICATIONS/UNKNOWN_ERROR'] |
|
85
|
|
|
]; |
|
86
|
|
|
|
|
87
|
|
|
export const trigger = ko.observable(false); |
|
88
|
|
|
|
|
89
|
|
|
/** |
|
90
|
|
|
* @param {string} key |
|
91
|
|
|
* @param {Object=} valueList |
|
92
|
|
|
* @param {string=} defaulValue |
|
93
|
|
|
* @returns {string} |
|
94
|
|
|
*/ |
|
95
|
|
|
export function i18n(key, valueList, defaulValue) |
|
96
|
|
|
{ |
|
97
|
|
|
let |
|
98
|
|
|
valueName = '', |
|
99
|
|
|
result = I18N_DATA[key]; |
|
100
|
|
|
|
|
101
|
|
|
if (isUnd(result)) |
|
102
|
|
|
{ |
|
103
|
|
|
result = isUnd(defaulValue) ? key : defaulValue; |
|
104
|
|
|
} |
|
105
|
|
|
|
|
106
|
|
|
if (!isUnd(valueList) && !isNull(valueList)) |
|
107
|
|
|
{ |
|
108
|
|
|
for (valueName in valueList) |
|
109
|
|
|
{ |
|
110
|
|
|
if (has(valueList, valueName)) |
|
111
|
|
|
{ |
|
112
|
|
|
result = result.replace('%' + valueName + '%', valueList[valueName]); |
|
113
|
|
|
} |
|
114
|
|
|
} |
|
115
|
|
|
} |
|
116
|
|
|
|
|
117
|
|
|
return result; |
|
118
|
|
|
} |
|
119
|
|
|
|
|
120
|
|
|
const i18nToNode = (element) => { |
|
121
|
|
|
|
|
122
|
|
|
const |
|
123
|
|
|
$el = $(element), |
|
124
|
|
|
key = $el.data('i18n'); |
|
125
|
|
|
|
|
126
|
|
|
if (key) |
|
127
|
|
|
{ |
|
128
|
|
|
if ('[' === key.substr(0, 1)) |
|
129
|
|
|
{ |
|
130
|
|
|
switch (key.substr(0, 6)) |
|
131
|
|
|
{ |
|
132
|
|
|
case '[html]': |
|
133
|
|
|
$el.html(i18n(key.substr(6))); |
|
134
|
|
|
break; |
|
135
|
|
|
case '[place': |
|
136
|
|
|
$el.attr('placeholder', i18n(key.substr(13))); |
|
137
|
|
|
break; |
|
138
|
|
|
case '[title': |
|
139
|
|
|
$el.attr('title', i18n(key.substr(7))); |
|
140
|
|
|
break; |
|
141
|
|
|
// no default |
|
142
|
|
|
} |
|
143
|
|
|
} |
|
144
|
|
|
else |
|
145
|
|
|
{ |
|
146
|
|
|
$el.text(i18n(key)); |
|
147
|
|
|
} |
|
148
|
|
|
} |
|
149
|
|
|
}; |
|
150
|
|
|
|
|
151
|
|
|
/** |
|
152
|
|
|
* @param {Object} elements |
|
153
|
|
|
* @param {boolean=} animate = false |
|
154
|
|
|
*/ |
|
155
|
|
|
export function i18nToNodes(elements, animate = false) |
|
156
|
|
|
{ |
|
157
|
|
|
_.defer(() => { |
|
158
|
|
|
|
|
159
|
|
|
$('[data-i18n]', elements).each((index, item) => { |
|
160
|
|
|
i18nToNode(item); |
|
161
|
|
|
}); |
|
162
|
|
|
|
|
163
|
|
|
if (animate && bAnimationSupported) |
|
164
|
|
|
{ |
|
165
|
|
|
$('.i18n-animation[data-i18n]', elements).letterfx({ |
|
166
|
|
|
'fx': 'fall fade', |
|
167
|
|
|
'backwards': false, |
|
168
|
|
|
'timing': 50, |
|
169
|
|
|
'fx_duration': '50ms', |
|
170
|
|
|
'letter_end': 'restore', |
|
171
|
|
|
'element_end': 'restore' |
|
172
|
|
|
}); |
|
173
|
|
|
} |
|
174
|
|
|
}); |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
const reloadData = () => { |
|
178
|
|
|
if (window.rainloopI18N) |
|
179
|
|
|
{ |
|
180
|
|
|
I18N_DATA = window.rainloopI18N || {}; |
|
181
|
|
|
|
|
182
|
|
|
i18nToNodes(window.document, true); |
|
183
|
|
|
|
|
184
|
|
|
momentorReload(); |
|
185
|
|
|
trigger(!trigger()); |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
window.rainloopI18N = null; |
|
189
|
|
|
}; |
|
190
|
|
|
|
|
191
|
|
|
/** |
|
192
|
|
|
* @returns {void} |
|
193
|
|
|
*/ |
|
194
|
|
|
export function initNotificationLanguage() |
|
195
|
|
|
{ |
|
196
|
|
|
I18N_NOTIFICATION_MAP.forEach((item) => { |
|
197
|
|
|
I18N_NOTIFICATION_DATA[item[0]] = i18n(item[1]); |
|
198
|
|
|
}); |
|
199
|
|
|
} |
|
200
|
|
|
|
|
201
|
|
|
/** |
|
202
|
|
|
* @param {Function} startCallback |
|
203
|
|
|
* @param {Function=} langCallback = null |
|
204
|
|
|
*/ |
|
205
|
|
|
export function initOnStartOrLangChange(startCallback, langCallback = null) |
|
206
|
|
|
{ |
|
207
|
|
|
if (startCallback) |
|
208
|
|
|
{ |
|
209
|
|
|
startCallback(); |
|
210
|
|
|
} |
|
211
|
|
|
|
|
212
|
|
|
if (langCallback) |
|
213
|
|
|
{ |
|
214
|
|
|
trigger.subscribe(() => { |
|
215
|
|
|
if (startCallback) |
|
216
|
|
|
{ |
|
217
|
|
|
startCallback(); |
|
218
|
|
|
} |
|
219
|
|
|
|
|
220
|
|
|
langCallback(); |
|
221
|
|
|
}); |
|
222
|
|
|
} |
|
223
|
|
|
else if (startCallback) |
|
224
|
|
|
{ |
|
225
|
|
|
trigger.subscribe(startCallback); |
|
226
|
|
|
} |
|
227
|
|
|
} |
|
228
|
|
|
|
|
229
|
|
|
/** |
|
230
|
|
|
* @param {number} code |
|
231
|
|
|
* @param {*=} message = '' |
|
232
|
|
|
* @param {*=} defCode = null |
|
233
|
|
|
* @returns {string} |
|
234
|
|
|
*/ |
|
235
|
|
|
export function getNotification(code, message = '', defCode = null) |
|
236
|
|
|
{ |
|
237
|
|
|
code = window.parseInt(code, 10) || 0; |
|
238
|
|
|
if (Notification.ClientViewError === code && message) |
|
239
|
|
|
{ |
|
240
|
|
|
return message; |
|
241
|
|
|
} |
|
242
|
|
|
|
|
243
|
|
|
defCode = defCode ? (window.parseInt(defCode, 10)) || 0 : 0; |
|
244
|
|
|
return isUnd(I18N_NOTIFICATION_DATA[code]) ? ( |
|
245
|
|
|
defCode && isUnd(I18N_NOTIFICATION_DATA[defCode]) ? I18N_NOTIFICATION_DATA[defCode] : '' |
|
246
|
|
|
) : I18N_NOTIFICATION_DATA[code]; |
|
247
|
|
|
} |
|
248
|
|
|
|
|
249
|
|
|
/** |
|
250
|
|
|
* @param {object} response |
|
251
|
|
|
* @param {number} defCode = Notification.UnknownNotification |
|
252
|
|
|
* @returns {string} |
|
253
|
|
|
*/ |
|
254
|
|
|
export function getNotificationFromResponse(response, defCode = Notification.UnknownNotification) |
|
255
|
|
|
{ |
|
256
|
|
|
return response && response.ErrorCode ? |
|
257
|
|
|
getNotification(pInt(response.ErrorCode), response.ErrorMessage || '') : getNotification(defCode); |
|
258
|
|
|
} |
|
259
|
|
|
|
|
260
|
|
|
/** |
|
261
|
|
|
* @param {*} code |
|
262
|
|
|
* @returns {string} |
|
263
|
|
|
*/ |
|
264
|
|
|
export function getUploadErrorDescByCode(code) |
|
265
|
|
|
{ |
|
266
|
|
|
let result = ''; |
|
267
|
|
|
switch (window.parseInt(code, 10) || 0) |
|
268
|
|
|
{ |
|
269
|
|
|
case UploadErrorCode.FileIsTooBig: |
|
270
|
|
|
result = i18n('UPLOAD/ERROR_FILE_IS_TOO_BIG'); |
|
271
|
|
|
break; |
|
272
|
|
|
case UploadErrorCode.FilePartiallyUploaded: |
|
273
|
|
|
result = i18n('UPLOAD/ERROR_FILE_PARTIALLY_UPLOADED'); |
|
274
|
|
|
break; |
|
275
|
|
|
case UploadErrorCode.FileNoUploaded: |
|
276
|
|
|
result = i18n('UPLOAD/ERROR_NO_FILE_UPLOADED'); |
|
277
|
|
|
break; |
|
278
|
|
|
case UploadErrorCode.MissingTempFolder: |
|
279
|
|
|
result = i18n('UPLOAD/ERROR_MISSING_TEMP_FOLDER'); |
|
280
|
|
|
break; |
|
281
|
|
|
case UploadErrorCode.FileOnSaveingError: |
|
282
|
|
|
result = i18n('UPLOAD/ERROR_ON_SAVING_FILE'); |
|
283
|
|
|
break; |
|
284
|
|
|
case UploadErrorCode.FileType: |
|
285
|
|
|
result = i18n('UPLOAD/ERROR_FILE_TYPE'); |
|
286
|
|
|
break; |
|
287
|
|
|
default: |
|
288
|
|
|
result = i18n('UPLOAD/ERROR_UNKNOWN'); |
|
289
|
|
|
break; |
|
290
|
|
|
} |
|
291
|
|
|
|
|
292
|
|
|
return result; |
|
293
|
|
|
} |
|
294
|
|
|
|
|
295
|
|
|
/** |
|
296
|
|
|
* @param {boolean} admin |
|
297
|
|
|
* @param {string} language |
|
298
|
|
|
*/ |
|
299
|
|
|
export function reload(admin, language) |
|
300
|
|
|
{ |
|
301
|
|
|
const start = microtime(); |
|
302
|
|
|
|
|
303
|
|
|
$html.addClass('rl-changing-language'); |
|
304
|
|
|
|
|
305
|
|
|
return new Promise((resolve, reject) => { |
|
306
|
|
|
$.ajax({ |
|
307
|
|
|
url: langLink(language, admin), |
|
308
|
|
|
dataType: 'script', |
|
309
|
|
|
cache: true |
|
310
|
|
|
}).then(() => { |
|
311
|
|
|
_.delay(() => { |
|
312
|
|
|
|
|
313
|
|
|
reloadData(); |
|
314
|
|
|
|
|
315
|
|
|
const isRtl = -1 < inArray((language || '').toLowerCase(), ['ar', 'ar_sa', 'he', 'he_he', 'ur', 'ur_ir']); |
|
316
|
|
|
|
|
317
|
|
|
$html |
|
318
|
|
|
.removeClass('rl-changing-language') |
|
319
|
|
|
.removeClass('rl-rtl rl-ltr') |
|
320
|
|
|
// .attr('dir', isRtl ? 'rtl' : 'ltr') |
|
321
|
|
|
.addClass(isRtl ? 'rl-rtl' : 'rl-ltr'); |
|
322
|
|
|
|
|
323
|
|
|
resolve(); |
|
324
|
|
|
|
|
325
|
|
|
}, 500 < microtime() - start ? 1 : 500); |
|
326
|
|
|
}, () => { |
|
327
|
|
|
$html.removeClass('rl-changing-language'); |
|
328
|
|
|
window.rainloopI18N = null; |
|
329
|
|
|
reject(); |
|
330
|
|
|
}); |
|
331
|
|
|
}); |
|
332
|
|
|
} |
|
333
|
|
|
|
|
334
|
|
|
// init section |
|
335
|
|
|
$html.addClass('rl-' + ($html.attr('dir') || 'ltr')); |
|
336
|
|
|
|