mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-25 18:19:22 +03:00
Bugfix boostrap alerts.less was accidentally removed
Bugfix Date.fromNow('past'/'future') reversed
Replace Events[pub/sub]('interval.*') with setInterval()
Events[pub/sub] to native
Cleanup knockout extensions
Replaced momentToNode with proper HTML5 <time>
Cleanup Momentor
This commit is contained in:
parent
6541a1de7c
commit
9f1ea1a0fd
44 changed files with 539 additions and 1126 deletions
35
README.md
35
README.md
|
|
@ -59,7 +59,7 @@ This fork uses downsized/simplified versions of scripts and has no support for I
|
||||||
|
|
||||||
The result is faster and smaller download code (good for mobile networks).
|
The result is faster and smaller download code (good for mobile networks).
|
||||||
|
|
||||||
Things might work in Edge 15-18, Firefox 47-62 and Chrome 54-68 due to one polyfill for array.flat().
|
Things might work in Edge 16-18, Firefox 50-62 and Chrome 54-68 due to one polyfill for array.flat().
|
||||||
|
|
||||||
* Replaced jQuery with jQuery.slim
|
* Replaced jQuery with jQuery.slim
|
||||||
* Replaced ProgressJS with simple native dropin
|
* Replaced ProgressJS with simple native dropin
|
||||||
|
|
@ -75,32 +75,33 @@ Things might work in Edge 15-18, Firefox 47-62 and Chrome 54-68 due to one polyf
|
||||||
* Removed opentip (use CSS)
|
* Removed opentip (use CSS)
|
||||||
* Replaced Autolinker with simple https/email detection
|
* Replaced Autolinker with simple https/email detection
|
||||||
* Replaced ifvisible.js with simple drop-in replacement
|
* Replaced ifvisible.js with simple drop-in replacement
|
||||||
|
* Replaced momentToNode with proper HTML5 <time>
|
||||||
|
|
||||||
|js/* |1.14.0 |native |gzip 1.14 |gzip |
|
|js/* |1.14.0 |native |
|
||||||
|----------- |--------: |--------: |--------: |--------: |
|
|----------- |--------: |--------: |
|
||||||
|admin.js |2.130.942 |1.119.128 | 485.481 | 271.258 |
|
|admin.js |2.130.942 |1.090.923 |
|
||||||
|app.js |4.184.455 |2.829.541 | 932.725 | 659.696 |
|
|app.js |4.184.455 |2.775.561 |
|
||||||
|boot.js | 671.522 | 44.029 | 169.502 | 15.460 |
|
|boot.js | 671.522 | 44.029 |
|
||||||
|libs.js | 647.614 | 316.107 | 194.728 | 98.214 |
|
|libs.js | 647.614 | 316.107 |
|
||||||
|polyfills.js | 325.834 | 0 | 71.825 | 0 |
|
|polyfills.js | 325.834 | 0 |
|
||||||
|TOTAL js |7.960.367 |4.308.805 |1.854.261 |1.044.628 |
|
|TOTAL |7.960.367 |4.226.620 |
|
||||||
|
|
||||||
|js/min/* |1.14.0 |native |gzip 1.14 |gzip |
|
|js/min/* |1.14.0 |native |gzip 1.14 |gzip |
|
||||||
|--------------- |--------: |--------: |--------: |--------: |
|
|--------------- |--------: |--------: |--------: |--------: |
|
||||||
|admin.min.js | 252.147 | 151.632 | 73.657 | 43.313 |
|
|admin.min.js | 252.147 | 148.293 | 73.657 | 42.376 |
|
||||||
|app.min.js | 511.202 | 377.163 |140.462 | 99.062 |
|
|app.min.js | 511.202 | 371.757 |140.462 | 97.432 |
|
||||||
|boot.min.js | 66.007 | 5.589 | 22.567 | 2.333 |
|
|boot.min.js | 66.007 | 5.589 | 22.567 | 2.332 |
|
||||||
|libs.min.js | 572.545 | 300.211 |176.720 | 92.698 |
|
|libs.min.js | 572.545 | 300.211 |176.720 | 92.699 |
|
||||||
|polyfills.min.js | 32.452 | 0 | 11.312 | 0 |
|
|polyfills.min.js | 32.452 | 0 | 11.312 | 0 |
|
||||||
|TOTAL js/min |1.434.353 | 834.595 |424.718 |237.406 |
|
|TOTAL |1.434.353 | 825.850 |424.718 |234.839 |
|
||||||
|
|
||||||
599.758 bytes (187.312 gzip) is not much, but it feels faster.
|
604.051 bytes (188.978 gzip) is not much, but it feels faster.
|
||||||
|
|
||||||
|
|
||||||
|css/* |1.14.0 |native |
|
|css/* |1.14.0 |native |
|
||||||
|-------------- |--------: |--------: |
|
|-------------- |--------: |--------: |
|
||||||
|app.css | 340.334 | 267.507 |
|
|app.css | 340.334 | 266.796 |
|
||||||
|app.min.css | 274.791 | 212.244 |
|
|app.min.css | 274.791 | 211.638 |
|
||||||
|
|
||||||
|
|
||||||
### PHP73 branch
|
### PHP73 branch
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import { isNormal, pString, detectDropdownVisibility, windowResizeCallback } fro
|
||||||
import { KeyState } from 'Common/Enums';
|
import { KeyState } from 'Common/Enums';
|
||||||
import { root, rootAdmin, rootUser, populateAuthSuffix } from 'Common/Links';
|
import { root, rootAdmin, rootUser, populateAuthSuffix } from 'Common/Links';
|
||||||
import { initOnStartOrLangChange, initNotificationLanguage } from 'Common/Translator';
|
import { initOnStartOrLangChange, initNotificationLanguage } from 'Common/Translator';
|
||||||
import * as Events from 'Common/Events';
|
|
||||||
import * as Settings from 'Storage/Settings';
|
import * as Settings from 'Storage/Settings';
|
||||||
|
|
||||||
import LanguageStore from 'Stores/Language';
|
import LanguageStore from 'Stores/Language';
|
||||||
|
|
@ -32,11 +31,9 @@ class AbstractApp extends AbstractBoot {
|
||||||
this.isLocalAutocomplete = true;
|
this.isLocalAutocomplete = true;
|
||||||
this.lastErrorTime = 0;
|
this.lastErrorTime = 0;
|
||||||
|
|
||||||
addEventListener('resize', () => Events.pub('window.resize'));
|
|
||||||
|
|
||||||
var t;
|
var t;
|
||||||
Events.sub(
|
addEventListener(
|
||||||
'window.resize',
|
'resize',
|
||||||
()=>{
|
()=>{
|
||||||
// throttle
|
// throttle
|
||||||
if (!t) {
|
if (!t) {
|
||||||
|
|
@ -47,8 +44,7 @@ class AbstractApp extends AbstractBoot {
|
||||||
if ($win.__sizes[0] !== iH || $win.__sizes[1] !== iW) {
|
if ($win.__sizes[0] !== iH || $win.__sizes[1] !== iW) {
|
||||||
$win.__sizes[0] = iH;
|
$win.__sizes[0] = iH;
|
||||||
$win.__sizes[1] = iW;
|
$win.__sizes[1] = iW;
|
||||||
|
dispatchEvent(new CustomEvent('resize.real'));
|
||||||
Events.pub('window.resize.real');
|
|
||||||
}
|
}
|
||||||
t = 0;
|
t = 0;
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
@ -56,16 +52,6 @@ class AbstractApp extends AbstractBoot {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
// Events.sub({
|
|
||||||
// 'window.resize': function() {
|
|
||||||
// console.log('window.resize');
|
|
||||||
// },
|
|
||||||
// 'window.resize.real': function() {
|
|
||||||
// console.log('window.resize.real');
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
const $doc = document;
|
const $doc = document;
|
||||||
$doc.addEventListener('keydown', (event) => {
|
$doc.addEventListener('keydown', (event) => {
|
||||||
if (event && event.ctrlKey) {
|
if (event && event.ctrlKey) {
|
||||||
|
|
@ -81,8 +67,8 @@ class AbstractApp extends AbstractBoot {
|
||||||
var d;
|
var d;
|
||||||
const fn = ()=>{
|
const fn = ()=>{
|
||||||
// debounce
|
// debounce
|
||||||
d && clearTimeout(d);
|
clearTimeout(d);
|
||||||
d = setTimeout(()=>Events.pub('rl.auto-logout-refresh'), 5000);
|
d = setTimeout(()=>dispatchEvent(new CustomEvent('rl.auto-logout-refresh')), 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
$doc.addEventListener('mousemove', fn);
|
$doc.addEventListener('mousemove', fn);
|
||||||
|
|
@ -211,8 +197,6 @@ class AbstractApp extends AbstractBoot {
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstart() {
|
bootstart() {
|
||||||
Events.pub('rl.bootstart');
|
|
||||||
|
|
||||||
const mobile = Settings.appSettingsGet('mobile');
|
const mobile = Settings.appSettingsGet('mobile');
|
||||||
|
|
||||||
ko.components.register('SaveTrigger', require('Component/SaveTrigger').default);
|
ko.components.register('SaveTrigger', require('Component/SaveTrigger').default);
|
||||||
|
|
@ -239,10 +223,6 @@ class AbstractApp extends AbstractBoot {
|
||||||
|
|
||||||
setTimeout(windowResizeCallback, 1000);
|
setTimeout(windowResizeCallback, 1000);
|
||||||
|
|
||||||
Events.sub('ssm.mobile-enter', () => leftPanelDisabled(true));
|
|
||||||
|
|
||||||
Events.sub('ssm.mobile-leave', () => leftPanelDisabled(false));
|
|
||||||
|
|
||||||
if (!mobile) {
|
if (!mobile) {
|
||||||
$htmlCL.add('rl-desktop');
|
$htmlCL.add('rl-desktop');
|
||||||
|
|
||||||
|
|
@ -251,11 +231,11 @@ class AbstractApp extends AbstractBoot {
|
||||||
query: '(max-width: 767px)',
|
query: '(max-width: 767px)',
|
||||||
onEnter: () => {
|
onEnter: () => {
|
||||||
$htmlCL.add('ssm-state-mobile');
|
$htmlCL.add('ssm-state-mobile');
|
||||||
Events.pub('ssm.mobile-enter');
|
leftPanelDisabled(true);
|
||||||
},
|
},
|
||||||
onLeave: () => {
|
onLeave: () => {
|
||||||
$htmlCL.remove('ssm-state-mobile');
|
$htmlCL.remove('ssm-state-mobile');
|
||||||
Events.pub('ssm.mobile-leave');
|
leftPanelDisabled(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -281,7 +261,7 @@ class AbstractApp extends AbstractBoot {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
$htmlCL.add('ssm-state-mobile', 'rl-mobile');
|
$htmlCL.add('ssm-state-mobile', 'rl-mobile');
|
||||||
Events.pub('ssm.mobile-enter');
|
leftPanelDisabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
leftPanelDisabled.subscribe((bValue) => {
|
leftPanelDisabled.subscribe((bValue) => {
|
||||||
|
|
|
||||||
119
dev/App/User.js
119
dev/App/User.js
|
|
@ -23,7 +23,7 @@ import { $htmlCL, leftPanelDisabled, bMobileDevice } from 'Common/Globals';
|
||||||
|
|
||||||
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
||||||
import { runHook } from 'Common/Plugins';
|
import { runHook } from 'Common/Plugins';
|
||||||
import { momentNowUnix, reload as momentReload } from 'Common/Momentor';
|
import { reload as momentReload } from 'Common/Momentor';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
initMessageFlagsFromCache,
|
initMessageFlagsFromCache,
|
||||||
|
|
@ -44,8 +44,6 @@ import {
|
||||||
openPgpJs
|
openPgpJs
|
||||||
} from 'Common/Links';
|
} from 'Common/Links';
|
||||||
|
|
||||||
import * as Events from 'Common/Events';
|
|
||||||
|
|
||||||
import { getNotification, i18n } from 'Common/Translator';
|
import { getNotification, i18n } from 'Common/Translator';
|
||||||
|
|
||||||
import AppStore from 'Stores/User/App';
|
import AppStore from 'Stores/User/App';
|
||||||
|
|
@ -85,22 +83,19 @@ import { AbstractApp } from 'App/Abstract';
|
||||||
const doc = document;
|
const doc = document;
|
||||||
|
|
||||||
if (!window.ResizeObserver) {
|
if (!window.ResizeObserver) {
|
||||||
|
let rot;
|
||||||
window.ResizeObserver = class {
|
window.ResizeObserver = class {
|
||||||
constructor(callback) {
|
constructor(callback) {
|
||||||
this.observer = new MutationObserver(mutations => {
|
this.observer = new MutationObserver(mutations => {
|
||||||
let entries = [];
|
let i = mutations.length;
|
||||||
mutations.forEach(mutation => {
|
while (i--) {
|
||||||
if ('style' == mutation.attributeName) {
|
if ('style' == mutations[i].attributeName) {
|
||||||
entries.push({
|
// debounce
|
||||||
contentRect: {
|
clearTimeout(rot);
|
||||||
width: mutation.target.offsetWidth,
|
rot = setTimeout(callback, 250);
|
||||||
height: mutation.target.offsetHeight
|
break;
|
||||||
},
|
|
||||||
target: mutation.target
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
callback(entries);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,25 +118,12 @@ class AppUser extends AbstractApp {
|
||||||
let qd, o = this;
|
let qd, o = this;
|
||||||
this.quotaDebounce = ()=>{
|
this.quotaDebounce = ()=>{
|
||||||
// debounce
|
// debounce
|
||||||
qd && clearTimeout(qd);
|
clearTimeout(qd);
|
||||||
qd = setTimeout(o.quota, 30000);
|
qd = setTimeout(o.quota, 30000);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.moveOrDeleteResponseHelper = this.moveOrDeleteResponseHelper.bind(this);
|
this.moveOrDeleteResponseHelper = this.moveOrDeleteResponseHelper.bind(this);
|
||||||
|
|
||||||
setInterval(() => Events.pub('interval.30s'), 30000);
|
|
||||||
setInterval(() => Events.pub('interval.1m'), 60000);
|
|
||||||
setInterval(() => Events.pub('interval.2m'), 120000);
|
|
||||||
setInterval(() => Events.pub('interval.3m'), 180000);
|
|
||||||
setInterval(() => Events.pub('interval.5m'), 300000);
|
|
||||||
setInterval(() => Events.pub('interval.10m'), 600000);
|
|
||||||
setInterval(() => Events.pub('interval.15m'), 900000);
|
|
||||||
setInterval(() => Events.pub('interval.20m'), 1200000);
|
|
||||||
|
|
||||||
setTimeout(() => setInterval(() => Events.pub('interval.2m-after5m'), 120000), 300000);
|
|
||||||
setTimeout(() => setInterval(() => Events.pub('interval.5m-after5m'), 300000), 300000);
|
|
||||||
setTimeout(() => setInterval(() => Events.pub('interval.10m-after5m'), 600000), 300000);
|
|
||||||
|
|
||||||
// wakeUp
|
// wakeUp
|
||||||
const interval = 3600000; // 60m
|
const interval = 3600000; // 60m
|
||||||
var lastTime = (new Date()).getTime();
|
var lastTime = (new Date()).getTime();
|
||||||
|
|
@ -284,7 +266,7 @@ class AppUser extends AbstractApp {
|
||||||
messagesMoveTrigger() {
|
messagesMoveTrigger() {
|
||||||
// debounce
|
// debounce
|
||||||
const o = this;
|
const o = this;
|
||||||
o.mt && clearTimeout(o.mt);
|
clearTimeout(o.mt);
|
||||||
o.mt = setTimeout(()=>{
|
o.mt = setTimeout(()=>{
|
||||||
const sTrashFolder = FolderStore.trashFolder(),
|
const sTrashFolder = FolderStore.trashFolder(),
|
||||||
sSpamFolder = FolderStore.spamFolder();
|
sSpamFolder = FolderStore.spamFolder();
|
||||||
|
|
@ -537,37 +519,7 @@ class AppUser extends AbstractApp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
accountsCounts() {
|
accountsAndIdentities() {
|
||||||
return false;
|
|
||||||
// AccountStore.accounts.loading(true);
|
|
||||||
//
|
|
||||||
// Remote.accountsCounts((sResult, oData) => {
|
|
||||||
//
|
|
||||||
// AccountStore.accounts.loading(false);
|
|
||||||
//
|
|
||||||
// if (StorageResultType.Success === sResult && oData.Result && oData.Result['Counts'])
|
|
||||||
// {
|
|
||||||
// var
|
|
||||||
// sEmail = AccountStore.email(),
|
|
||||||
// aAcounts = AccountStore.accounts()
|
|
||||||
// ;
|
|
||||||
//
|
|
||||||
// oData.Result['Counts'].find(oItem => {
|
|
||||||
//
|
|
||||||
// var oAccount = aAcounts.find(oAccount => {
|
|
||||||
// return oAccount && oItem[0] === oAccount.email && sEmail !== oAccount.email;
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// if (oAccount)
|
|
||||||
// {
|
|
||||||
// oAccount.count(pInt(oItem[1]));
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
accountsAndIdentities(bBoot) {
|
|
||||||
AccountStore.accounts.loading(true);
|
AccountStore.accounts.loading(true);
|
||||||
IdentityStore.identities.loading(true);
|
IdentityStore.identities.loading(true);
|
||||||
|
|
||||||
|
|
@ -594,11 +546,6 @@ class AppUser extends AbstractApp {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (undefined === bBoot ? false : !!bBoot) {
|
|
||||||
setTimeout(() => this.accountsCounts(), 1000 * 5);
|
|
||||||
Events.sub('interval.10m-after5m', () => this.accountsCounts());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(oData.Result.Identities)) {
|
if (Array.isArray(oData.Result.Identities)) {
|
||||||
delegateRunOnDestroy(IdentityStore.identities());
|
delegateRunOnDestroy(IdentityStore.identities());
|
||||||
|
|
||||||
|
|
@ -673,7 +620,7 @@ class AppUser extends AbstractApp {
|
||||||
|
|
||||||
const folderFromCache = getFolderFromCacheList(data.Result.Folder);
|
const folderFromCache = getFolderFromCacheList(data.Result.Folder);
|
||||||
if (folderFromCache) {
|
if (folderFromCache) {
|
||||||
folderFromCache.interval = momentNowUnix();
|
folderFromCache.interval = Date.now() / 1000;
|
||||||
|
|
||||||
if (data.Result.Hash) {
|
if (data.Result.Hash) {
|
||||||
setFolderHash(data.Result.Folder, data.Result.Hash);
|
setFolderHash(data.Result.Folder, data.Result.Hash);
|
||||||
|
|
@ -748,7 +695,7 @@ class AppUser extends AbstractApp {
|
||||||
Remote.folderInformationMultiply((sResult, oData) => {
|
Remote.folderInformationMultiply((sResult, oData) => {
|
||||||
if (StorageResultType.Success === sResult) {
|
if (StorageResultType.Success === sResult) {
|
||||||
if (oData && oData.Result && oData.Result.List && isNonEmptyArray(oData.Result.List)) {
|
if (oData && oData.Result && oData.Result.List && isNonEmptyArray(oData.Result.List)) {
|
||||||
const utc = momentNowUnix();
|
const utc = Date.now() / 1000;
|
||||||
oData.Result.List.forEach(item => {
|
oData.Result.List.forEach(item => {
|
||||||
const hash = getFolderHash(item.Folder),
|
const hash = getFolderHash(item.Folder),
|
||||||
folder = getFolderFromCacheList(item.Folder);
|
folder = getFolderFromCacheList(item.Folder);
|
||||||
|
|
@ -974,7 +921,7 @@ class AppUser extends AbstractApp {
|
||||||
};
|
};
|
||||||
if (top && bottom) {
|
if (top && bottom) {
|
||||||
fDisable(false);
|
fDisable(false);
|
||||||
Events.sub('layout', layout => fDisable(Layout.BottomPreview !== layout));
|
addEventListener('rl-layout', e => fDisable(Layout.BottomPreview !== e.detail));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -986,8 +933,7 @@ class AppUser extends AbstractApp {
|
||||||
};
|
};
|
||||||
if (left && right) {
|
if (left && right) {
|
||||||
fDisable(false);
|
fDisable(false);
|
||||||
Events.sub('left-panel.off', () => fDisable(true));
|
leftPanelDisabled.subscribe(value => fDisable(value));
|
||||||
Events.sub('left-panel.on', () => fDisable(false));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1018,7 +964,6 @@ class AppUser extends AbstractApp {
|
||||||
startScreens([LoginUserScreen]);
|
startScreens([LoginUserScreen]);
|
||||||
|
|
||||||
runHook('rl-start-login-screens');
|
runHook('rl-start-login-screens');
|
||||||
Events.pub('rl.bootstart-login-screens');
|
|
||||||
} else {
|
} else {
|
||||||
routeOff();
|
routeOff();
|
||||||
setHash(root(), true);
|
setHash(root(), true);
|
||||||
|
|
@ -1054,10 +999,6 @@ class AppUser extends AbstractApp {
|
||||||
progressJs.set(90);
|
progressJs.set(90);
|
||||||
}
|
}
|
||||||
|
|
||||||
leftPanelDisabled.subscribe((value) => {
|
|
||||||
Events.pub('left-panel.' + (value ? 'off' : 'on'));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setWindowTitle('');
|
this.setWindowTitle('');
|
||||||
if (Settings.settingsGet('Auth')) {
|
if (Settings.settingsGet('Auth')) {
|
||||||
$htmlCL.add('rl-user-auth');
|
$htmlCL.add('rl-user-auth');
|
||||||
|
|
@ -1102,8 +1043,6 @@ class AppUser extends AbstractApp {
|
||||||
PgpStore.openpgpKeyring = new openpgp.Keyring();
|
PgpStore.openpgpKeyring = new openpgp.Keyring();
|
||||||
PgpStore.capaOpenPGP(true);
|
PgpStore.capaOpenPGP(true);
|
||||||
|
|
||||||
Events.pub('openpgp.init');
|
|
||||||
|
|
||||||
this.reloadOpenPgpKeys();
|
this.reloadOpenPgpKeys();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1126,25 +1065,25 @@ class AppUser extends AbstractApp {
|
||||||
// false ? AboutUserScreen : null
|
// false ? AboutUserScreen : null
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Events.sub('interval.2m', () => this.folderInformation(getFolderInboxName()));
|
setInterval(() => this.folderInformation(getFolderInboxName()), 120000);
|
||||||
Events.sub('interval.3m', () => {
|
setInterval(() => {
|
||||||
const sF = FolderStore.currentFolderFullNameRaw();
|
const sF = FolderStore.currentFolderFullNameRaw();
|
||||||
if (getFolderInboxName() !== sF) {
|
if (getFolderInboxName() !== sF) {
|
||||||
this.folderInformation(sF);
|
this.folderInformation(sF);
|
||||||
}
|
}
|
||||||
});
|
}, 180000);
|
||||||
|
|
||||||
Events.sub('interval.2m-after5m', () => this.folderInformationMultiply());
|
setTimeout(() => setInterval(this.folderInformationMultiply, 120000), 300000);
|
||||||
Events.sub('interval.15m', () => this.quota());
|
setInterval(this.quota, 900000);
|
||||||
Events.sub('interval.20m', () => this.foldersReload());
|
setInterval(this.foldersReload, 1200000);
|
||||||
|
|
||||||
contactsSyncInterval = 5 <= contactsSyncInterval ? contactsSyncInterval : 20;
|
contactsSyncInterval = 5 <= contactsSyncInterval ? contactsSyncInterval : 20;
|
||||||
contactsSyncInterval = 320 >= contactsSyncInterval ? contactsSyncInterval : 320;
|
contactsSyncInterval = 320 >= contactsSyncInterval ? contactsSyncInterval : 320;
|
||||||
|
|
||||||
setTimeout(() => this.contactsSync(), 10000);
|
setTimeout(this.contactsSync, 10000);
|
||||||
setTimeout(() => this.folderInformationMultiply(true), 2000);
|
setTimeout(() => this.folderInformationMultiply(true), 2000);
|
||||||
|
|
||||||
setInterval(() => this.contactsSync(), contactsSyncInterval * 60000 + 5000);
|
setInterval(this.contactsSync, contactsSyncInterval * 60000 + 5000);
|
||||||
|
|
||||||
this.accountsAndIdentities(true);
|
this.accountsAndIdentities(true);
|
||||||
|
|
||||||
|
|
@ -1155,13 +1094,12 @@ class AppUser extends AbstractApp {
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
setTimeout(() => this.quota(), 5000);
|
setTimeout(this.quota, 5000);
|
||||||
setTimeout(() => Remote.appDelayStart(()=>{}), 35000);
|
setTimeout(() => Remote.appDelayStart(()=>{}), 35000);
|
||||||
|
|
||||||
Events.sub('rl.auto-logout', () => this.logout());
|
addEventListener('rl.auto-logout', () => this.logout());
|
||||||
|
|
||||||
runHook('rl-start-user-screens');
|
runHook('rl-start-user-screens');
|
||||||
Events.pub('rl.bootstart-user-screens');
|
|
||||||
|
|
||||||
if (Settings.settingsGet('WelcomePageUrl')) {
|
if (Settings.settingsGet('WelcomePageUrl')) {
|
||||||
setTimeout(() => this.bootstartWelcomePopup(Settings.settingsGet('WelcomePageUrl')), 1000);
|
setTimeout(() => this.bootstartWelcomePopup(Settings.settingsGet('WelcomePageUrl')), 1000);
|
||||||
|
|
@ -1203,10 +1141,9 @@ class AppUser extends AbstractApp {
|
||||||
this.bootstartLoginScreen();
|
this.bootstartLoginScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
Events.sub('interval.1m', () => momentReload());
|
setInterval(momentReload, 60000);
|
||||||
|
|
||||||
runHook('rl-start-screens');
|
runHook('rl-start-screens');
|
||||||
Events.pub('rl.bootstart-end');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import * as Links from 'Common/Links';
|
import * as Links from 'Common/Links';
|
||||||
import * as Events from 'Common/Events';
|
|
||||||
|
|
||||||
class Audio {
|
class Audio {
|
||||||
notificator = null;
|
notificator = null;
|
||||||
|
|
@ -37,7 +36,7 @@ class Audio {
|
||||||
this.player.addEventListener('ended', stopFn);
|
this.player.addEventListener('ended', stopFn);
|
||||||
this.player.addEventListener('error', stopFn);
|
this.player.addEventListener('error', stopFn);
|
||||||
|
|
||||||
Events.sub('audio.api.stop', stopFn);
|
addEventListener('audio.api.stop', stopFn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,7 +65,7 @@ class Audio {
|
||||||
this.player.pause();
|
this.player.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
Events.pub('audio.stop');
|
dispatchEvent(new CustomEvent('audio.stop'));
|
||||||
}
|
}
|
||||||
|
|
||||||
pause() {
|
pause() {
|
||||||
|
|
@ -87,7 +86,7 @@ class Audio {
|
||||||
this.player.src = url;
|
this.player.src = url;
|
||||||
this.player.play();
|
this.player.play();
|
||||||
|
|
||||||
Events.pub('audio.start', [this.clearName(name, 'mp3'), 'mp3']);
|
dispatchEvent(new CustomEvent('audio.start', {detail:this.clearName(name, 'mp3')}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,7 +98,7 @@ class Audio {
|
||||||
name = this.clearName(name, 'oga');
|
name = this.clearName(name, 'oga');
|
||||||
name = this.clearName(name, 'ogg');
|
name = this.clearName(name, 'ogg');
|
||||||
|
|
||||||
Events.pub('audio.start', [name, 'ogg']);
|
dispatchEvent(new CustomEvent('audio.start', {detail:name}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,7 +107,7 @@ class Audio {
|
||||||
this.player.src = url;
|
this.player.src = url;
|
||||||
this.player.play();
|
this.player.play();
|
||||||
|
|
||||||
Events.pub('audio.start', [this.clearName(name, 'wav'), 'wav']);
|
dispatchEvent(new CustomEvent('audio.start', {detail:this.clearName(name, 'wav')}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,21 @@
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const FileType = {
|
export const FileType = {
|
||||||
'Unknown': 'unknown',
|
Unknown: 'unknown',
|
||||||
'Text': 'text',
|
Text: 'text',
|
||||||
'Html': 'html',
|
Html: 'html',
|
||||||
'Code': 'code',
|
Code: 'code',
|
||||||
'Eml': 'eml',
|
Eml: 'eml',
|
||||||
'WordText': 'word-text',
|
WordText: 'word-text',
|
||||||
'Pdf': 'pdf',
|
Pdf: 'pdf',
|
||||||
'Image': 'image',
|
Image: 'image',
|
||||||
'Audio': 'audio',
|
Audio: 'audio',
|
||||||
'Video': 'video',
|
Video: 'video',
|
||||||
'Sheet': 'sheet',
|
Sheet: 'sheet',
|
||||||
'Presentation': 'presentation',
|
Presentation: 'presentation',
|
||||||
'Certificate': 'certificate',
|
Certificate: 'certificate',
|
||||||
'CertificateBin': 'certificate-bin',
|
CertificateBin: 'certificate-bin',
|
||||||
'Archive': 'archive',
|
Archive: 'archive',
|
||||||
|
|
||||||
getIconClass: function(type) {
|
getIconClass: function(type) {
|
||||||
let result = ['icon-file', ''];
|
let result = ['icon-file', ''];
|
||||||
|
|
@ -67,483 +67,483 @@ export const FileType = {
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const StorageResultType = {
|
export const StorageResultType = {
|
||||||
'Success': 'success',
|
Success: 'success',
|
||||||
'Abort': 'abort',
|
Abort: 'abort',
|
||||||
'Error': 'error',
|
Error: 'error',
|
||||||
'Unload': 'unload'
|
Unload: 'unload'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const Focused = {
|
export const Focused = {
|
||||||
'None': 'none',
|
None: 'none',
|
||||||
'MessageList': 'message-list',
|
MessageList: 'message-list',
|
||||||
'MessageView': 'message-view',
|
MessageView: 'message-view',
|
||||||
'FolderList': 'folder-list'
|
FolderList: 'folder-list'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const State = {
|
export const State = {
|
||||||
'Empty': 10,
|
Empty: 10,
|
||||||
'Login': 20,
|
Login: 20,
|
||||||
'Auth': 30
|
Auth: 30
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const StateType = {
|
export const StateType = {
|
||||||
'Webmail': 0,
|
Webmail: 0,
|
||||||
'Admin': 1
|
Admin: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const Capa = {
|
export const Capa = {
|
||||||
'TwoFactor': 'TWO_FACTOR',
|
TwoFactor: 'TWO_FACTOR',
|
||||||
'TwoFactorForce': 'TWO_FACTOR_FORCE',
|
TwoFactorForce: 'TWO_FACTOR_FORCE',
|
||||||
'OpenPGP': 'OPEN_PGP',
|
OpenPGP: 'OPEN_PGP',
|
||||||
'Prefetch': 'PREFETCH',
|
Prefetch: 'PREFETCH',
|
||||||
'Gravatar': 'GRAVATAR',
|
Gravatar: 'GRAVATAR',
|
||||||
'Folders': 'FOLDERS',
|
Folders: 'FOLDERS',
|
||||||
'Composer': 'COMPOSER',
|
Composer: 'COMPOSER',
|
||||||
'Contacts': 'CONTACTS',
|
Contacts: 'CONTACTS',
|
||||||
'Reload': 'RELOAD',
|
Reload: 'RELOAD',
|
||||||
'Search': 'SEARCH',
|
Search: 'SEARCH',
|
||||||
'SearchAdv': 'SEARCH_ADV',
|
SearchAdv: 'SEARCH_ADV',
|
||||||
'MessageActions': 'MESSAGE_ACTIONS',
|
MessageActions: 'MESSAGE_ACTIONS',
|
||||||
'MessageListActions': 'MESSAGELIST_ACTIONS',
|
MessageListActions: 'MESSAGELIST_ACTIONS',
|
||||||
'AttachmentsActions': 'ATTACHMENTS_ACTIONS',
|
AttachmentsActions: 'ATTACHMENTS_ACTIONS',
|
||||||
'DangerousActions': 'DANGEROUS_ACTIONS',
|
DangerousActions: 'DANGEROUS_ACTIONS',
|
||||||
'Settings': 'SETTINGS',
|
Settings: 'SETTINGS',
|
||||||
'Help': 'HELP',
|
Help: 'HELP',
|
||||||
'Themes': 'THEMES',
|
Themes: 'THEMES',
|
||||||
'UserBackground': 'USER_BACKGROUND',
|
UserBackground: 'USER_BACKGROUND',
|
||||||
'Sieve': 'SIEVE',
|
Sieve: 'SIEVE',
|
||||||
'Filters': 'FILTERS',
|
Filters: 'FILTERS',
|
||||||
'AttachmentThumbnails': 'ATTACHMENT_THUMBNAILS',
|
AttachmentThumbnails: 'ATTACHMENT_THUMBNAILS',
|
||||||
'Templates': 'TEMPLATES',
|
Templates: 'TEMPLATES',
|
||||||
'AutoLogout': 'AUTOLOGOUT',
|
AutoLogout: 'AUTOLOGOUT',
|
||||||
'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS',
|
AdditionalAccounts: 'ADDITIONAL_ACCOUNTS',
|
||||||
'Identities': 'IDENTITIES'
|
Identities: 'IDENTITIES'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const KeyState = {
|
export const KeyState = {
|
||||||
'All': 'all',
|
All: 'all',
|
||||||
'None': 'none',
|
None: 'none',
|
||||||
'ContactList': 'contact-list',
|
ContactList: 'contact-list',
|
||||||
'MessageList': 'message-list',
|
MessageList: 'message-list',
|
||||||
'FolderList': 'folder-list',
|
FolderList: 'folder-list',
|
||||||
'MessageView': 'message-view',
|
MessageView: 'message-view',
|
||||||
'Compose': 'compose',
|
Compose: 'compose',
|
||||||
'Settings': 'settings',
|
Settings: 'settings',
|
||||||
'Menu': 'menu',
|
Menu: 'menu',
|
||||||
'PopupComposeOpenPGP': 'compose-open-pgp',
|
PopupComposeOpenPGP: 'compose-open-pgp',
|
||||||
'PopupMessageOpenPGP': 'message-open-pgp',
|
PopupMessageOpenPGP: 'message-open-pgp',
|
||||||
'PopupViewOpenPGP': 'view-open-pgp',
|
PopupViewOpenPGP: 'view-open-pgp',
|
||||||
'PopupKeyboardShortcutsHelp': 'popup-keyboard-shortcuts-help',
|
PopupKeyboardShortcutsHelp: 'popup-keyboard-shortcuts-help',
|
||||||
'PopupAsk': 'popup-ask'
|
PopupAsk: 'popup-ask'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const FolderType = {
|
export const FolderType = {
|
||||||
'Inbox': 10,
|
Inbox: 10,
|
||||||
'SentItems': 11,
|
SentItems: 11,
|
||||||
'Draft': 12,
|
Draft: 12,
|
||||||
'Trash': 13,
|
Trash: 13,
|
||||||
'Spam': 14,
|
Spam: 14,
|
||||||
'Archive': 15,
|
Archive: 15,
|
||||||
'NotSpam': 80,
|
NotSpam: 80,
|
||||||
'User': 99
|
User: 99
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const ServerFolderType = {
|
export const ServerFolderType = {
|
||||||
'USER': 0,
|
USER: 0,
|
||||||
'INBOX': 1,
|
INBOX: 1,
|
||||||
'SENT': 2,
|
SENT: 2,
|
||||||
'DRAFTS': 3,
|
DRAFTS: 3,
|
||||||
'JUNK': 4,
|
JUNK: 4,
|
||||||
'TRASH': 5,
|
TRASH: 5,
|
||||||
'IMPORTANT': 10,
|
IMPORTANT: 10,
|
||||||
'FLAGGED': 11,
|
FLAGGED: 11,
|
||||||
'ALL': 12
|
ALL: 12
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const LoginSignMeTypeAsString = {
|
export const LoginSignMeTypeAsString = {
|
||||||
'DefaultOff': 'defaultoff',
|
DefaultOff: 'defaultoff',
|
||||||
'DefaultOn': 'defaulton',
|
DefaultOn: 'defaulton',
|
||||||
'Unused': 'unused'
|
Unused: 'unused'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const LoginSignMeType = {
|
export const LoginSignMeType = {
|
||||||
'DefaultOff': 0,
|
DefaultOff: 0,
|
||||||
'DefaultOn': 1,
|
DefaultOn: 1,
|
||||||
'Unused': 2
|
Unused: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const ComposeType = {
|
export const ComposeType = {
|
||||||
'Empty': 'empty',
|
Empty: 'empty',
|
||||||
'Reply': 'reply',
|
Reply: 'reply',
|
||||||
'ReplyAll': 'replyall',
|
ReplyAll: 'replyall',
|
||||||
'Forward': 'forward',
|
Forward: 'forward',
|
||||||
'ForwardAsAttachment': 'forward-as-attachment',
|
ForwardAsAttachment: 'forward-as-attachment',
|
||||||
'Draft': 'draft',
|
Draft: 'draft',
|
||||||
'EditAsNew': 'editasnew'
|
EditAsNew: 'editasnew'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const UploadErrorCode = {
|
export const UploadErrorCode = {
|
||||||
'Normal': 0,
|
Normal: 0,
|
||||||
'FileIsTooBig': 1,
|
FileIsTooBig: 1,
|
||||||
'FilePartiallyUploaded': 2,
|
FilePartiallyUploaded: 2,
|
||||||
'FileNoUploaded': 3,
|
FileNoUploaded: 3,
|
||||||
'MissingTempFolder': 4,
|
MissingTempFolder: 4,
|
||||||
'FileOnSaveingError': 5,
|
FileOnSaveingError: 5,
|
||||||
'FileType': 98,
|
FileType: 98,
|
||||||
'Unknown': 99
|
Unknown: 99
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const SetSystemFoldersNotification = {
|
export const SetSystemFoldersNotification = {
|
||||||
'None': 0,
|
None: 0,
|
||||||
'Sent': 1,
|
Sent: 1,
|
||||||
'Draft': 2,
|
Draft: 2,
|
||||||
'Spam': 3,
|
Spam: 3,
|
||||||
'Trash': 4,
|
Trash: 4,
|
||||||
'Archive': 5
|
Archive: 5
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const ClientSideKeyName = {
|
export const ClientSideKeyName = {
|
||||||
'FoldersLashHash': 0,
|
FoldersLashHash: 0,
|
||||||
'MessagesInboxLastHash': 1,
|
MessagesInboxLastHash: 1,
|
||||||
'MailBoxListSize': 2,
|
MailBoxListSize: 2,
|
||||||
'ExpandedFolders': 3,
|
ExpandedFolders: 3,
|
||||||
'FolderListSize': 4,
|
FolderListSize: 4,
|
||||||
'MessageListSize': 5,
|
MessageListSize: 5,
|
||||||
'LastReplyAction': 6,
|
LastReplyAction: 6,
|
||||||
'LastSignMe': 7,
|
LastSignMe: 7,
|
||||||
'ComposeLastIdentityID': 8,
|
ComposeLastIdentityID: 8,
|
||||||
'MessageHeaderFullInfo': 9,
|
MessageHeaderFullInfo: 9,
|
||||||
'MessageAttachmnetControls': 10
|
MessageAttachmnetControls: 10
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const EventKeyCode = {
|
export const EventKeyCode = {
|
||||||
'Backspace': 8,
|
Backspace: 8,
|
||||||
'Tab': 9,
|
Tab: 9,
|
||||||
'Enter': 13,
|
Enter: 13,
|
||||||
'Esc': 27,
|
Esc: 27,
|
||||||
'PageUp': 33,
|
PageUp: 33,
|
||||||
'PageDown': 34,
|
PageDown: 34,
|
||||||
'Left': 37,
|
Left: 37,
|
||||||
'Right': 39,
|
Right: 39,
|
||||||
'Up': 38,
|
Up: 38,
|
||||||
'Down': 40,
|
Down: 40,
|
||||||
'End': 35,
|
End: 35,
|
||||||
'Home': 36,
|
Home: 36,
|
||||||
'Space': 32,
|
Space: 32,
|
||||||
'Insert': 45,
|
Insert: 45,
|
||||||
'Delete': 46,
|
Delete: 46,
|
||||||
'A': 65,
|
A: 65,
|
||||||
'S': 83
|
S: 83
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const MessageSetAction = {
|
export const MessageSetAction = {
|
||||||
'SetSeen': 0,
|
SetSeen: 0,
|
||||||
'UnsetSeen': 1,
|
UnsetSeen: 1,
|
||||||
'SetFlag': 2,
|
SetFlag: 2,
|
||||||
'UnsetFlag': 3
|
UnsetFlag: 3
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const MessageSelectAction = {
|
export const MessageSelectAction = {
|
||||||
'All': 0,
|
All: 0,
|
||||||
'None': 1,
|
None: 1,
|
||||||
'Invert': 2,
|
Invert: 2,
|
||||||
'Unseen': 3,
|
Unseen: 3,
|
||||||
'Seen': 4,
|
Seen: 4,
|
||||||
'Flagged': 5,
|
Flagged: 5,
|
||||||
'Unflagged': 6
|
Unflagged: 6
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const DesktopNotification = {
|
export const DesktopNotification = {
|
||||||
'Allowed': 0,
|
Allowed: 0,
|
||||||
'NotAllowed': 1,
|
NotAllowed: 1,
|
||||||
'Denied': 2,
|
Denied: 2,
|
||||||
'NotSupported': 9
|
NotSupported: 9
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const MessagePriority = {
|
export const MessagePriority = {
|
||||||
'Low': 5,
|
Low: 5,
|
||||||
'Normal': 3,
|
Normal: 3,
|
||||||
'High': 1
|
High: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const EditorDefaultType = {
|
export const EditorDefaultType = {
|
||||||
'Html': 'Html',
|
Html: 'Html',
|
||||||
'Plain': 'Plain',
|
Plain: 'Plain',
|
||||||
'HtmlForced': 'HtmlForced',
|
HtmlForced: 'HtmlForced',
|
||||||
'PlainForced': 'PlainForced'
|
PlainForced: 'PlainForced'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const ServerSecure = {
|
export const ServerSecure = {
|
||||||
'None': 0,
|
None: 0,
|
||||||
'SSL': 1,
|
SSL: 1,
|
||||||
'TLS': 2
|
TLS: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const SearchDateType = {
|
export const SearchDateType = {
|
||||||
'All': -1,
|
All: -1,
|
||||||
'Days3': 3,
|
Days3: 3,
|
||||||
'Days7': 7,
|
Days7: 7,
|
||||||
'Month': 30
|
Month: 30
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const SaveSettingsStep = {
|
export const SaveSettingsStep = {
|
||||||
'Animate': -2,
|
Animate: -2,
|
||||||
'Idle': -1,
|
Idle: -1,
|
||||||
'TrueResult': 1,
|
TrueResult: 1,
|
||||||
'FalseResult': 0
|
FalseResult: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const Layout = {
|
export const Layout = {
|
||||||
'NoPreview': 0,
|
NoPreview: 0,
|
||||||
'SidePreview': 1,
|
SidePreview: 1,
|
||||||
'BottomPreview': 2
|
BottomPreview: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const FilterConditionField = {
|
export const FilterConditionField = {
|
||||||
'From': 'From',
|
From: 'From',
|
||||||
'Recipient': 'Recipient',
|
Recipient: 'Recipient',
|
||||||
'Subject': 'Subject',
|
Subject: 'Subject',
|
||||||
'Header': 'Header',
|
Header: 'Header',
|
||||||
'Size': 'Size'
|
Size: 'Size'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const FilterConditionType = {
|
export const FilterConditionType = {
|
||||||
'Contains': 'Contains',
|
Contains: 'Contains',
|
||||||
'NotContains': 'NotContains',
|
NotContains: 'NotContains',
|
||||||
'EqualTo': 'EqualTo',
|
EqualTo: 'EqualTo',
|
||||||
'NotEqualTo': 'NotEqualTo',
|
NotEqualTo: 'NotEqualTo',
|
||||||
'Regex': 'Regex',
|
Regex: 'Regex',
|
||||||
'Over': 'Over',
|
Over: 'Over',
|
||||||
'Under': 'Under'
|
Under: 'Under'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const FiltersAction = {
|
export const FiltersAction = {
|
||||||
'None': 'None',
|
None: 'None',
|
||||||
'MoveTo': 'MoveTo',
|
MoveTo: 'MoveTo',
|
||||||
'Discard': 'Discard',
|
Discard: 'Discard',
|
||||||
'Vacation': 'Vacation',
|
Vacation: 'Vacation',
|
||||||
'Reject': 'Reject',
|
Reject: 'Reject',
|
||||||
'Forward': 'Forward'
|
Forward: 'Forward'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export const FilterRulesType = {
|
export const FilterRulesType = {
|
||||||
'All': 'All',
|
All: 'All',
|
||||||
'Any': 'Any'
|
Any: 'Any'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const SignedVerifyStatus = {
|
export const SignedVerifyStatus = {
|
||||||
'UnknownPublicKeys': -4,
|
UnknownPublicKeys: -4,
|
||||||
'UnknownPrivateKey': -3,
|
UnknownPrivateKey: -3,
|
||||||
'Unverified': -2,
|
Unverified: -2,
|
||||||
'Error': -1,
|
Error: -1,
|
||||||
'None': 0,
|
None: 0,
|
||||||
'Success': 1
|
Success: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const ContactPropertyType = {
|
export const ContactPropertyType = {
|
||||||
'Unknown': 0,
|
Unknown: 0,
|
||||||
|
|
||||||
'FullName': 10,
|
FullName: 10,
|
||||||
|
|
||||||
'FirstName': 15,
|
FirstName: 15,
|
||||||
'LastName': 16,
|
LastName: 16,
|
||||||
'MiddleName': 16,
|
MiddleName: 16,
|
||||||
'Nick': 18,
|
Nick: 18,
|
||||||
|
|
||||||
'NamePrefix': 20,
|
NamePrefix: 20,
|
||||||
'NameSuffix': 21,
|
NameSuffix: 21,
|
||||||
|
|
||||||
'Email': 30,
|
Email: 30,
|
||||||
'Phone': 31,
|
Phone: 31,
|
||||||
'Web': 32,
|
Web: 32,
|
||||||
|
|
||||||
'Birthday': 40,
|
Birthday: 40,
|
||||||
|
|
||||||
'Facebook': 90,
|
Facebook: 90,
|
||||||
'Skype': 91,
|
Skype: 91,
|
||||||
'GitHub': 92,
|
GitHub: 92,
|
||||||
|
|
||||||
'Note': 110,
|
Note: 110,
|
||||||
|
|
||||||
'Custom': 250
|
Custom: 250
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const Ports = {
|
export const Ports = {
|
||||||
'Imap': 143,
|
Imap: 143,
|
||||||
'ImapSsl': 993,
|
ImapSsl: 993,
|
||||||
'Smtp': 25,
|
Smtp: 25,
|
||||||
'SmtpSsl': 465,
|
SmtpSsl: 465,
|
||||||
'SmtpStartTls': 587
|
SmtpStartTls: 587
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const Notification = {
|
export const Notification = {
|
||||||
'InvalidToken': 101,
|
InvalidToken: 101,
|
||||||
'AuthError': 102,
|
AuthError: 102,
|
||||||
'AccessError': 103,
|
AccessError: 103,
|
||||||
'ConnectionError': 104,
|
ConnectionError: 104,
|
||||||
'CaptchaError': 105,
|
CaptchaError: 105,
|
||||||
'SocialFacebookLoginAccessDisable': 106,
|
SocialFacebookLoginAccessDisable: 106,
|
||||||
'SocialTwitterLoginAccessDisable': 107,
|
SocialTwitterLoginAccessDisable: 107,
|
||||||
'SocialGoogleLoginAccessDisable': 108,
|
SocialGoogleLoginAccessDisable: 108,
|
||||||
'DomainNotAllowed': 109,
|
DomainNotAllowed: 109,
|
||||||
'AccountNotAllowed': 110,
|
AccountNotAllowed: 110,
|
||||||
|
|
||||||
'AccountTwoFactorAuthRequired': 120,
|
AccountTwoFactorAuthRequired: 120,
|
||||||
'AccountTwoFactorAuthError': 121,
|
AccountTwoFactorAuthError: 121,
|
||||||
|
|
||||||
'CouldNotSaveNewPassword': 130,
|
CouldNotSaveNewPassword: 130,
|
||||||
'CurrentPasswordIncorrect': 131,
|
CurrentPasswordIncorrect: 131,
|
||||||
'NewPasswordShort': 132,
|
NewPasswordShort: 132,
|
||||||
'NewPasswordWeak': 133,
|
NewPasswordWeak: 133,
|
||||||
'NewPasswordForbidden': 134,
|
NewPasswordForbidden: 134,
|
||||||
|
|
||||||
'ContactsSyncError': 140,
|
ContactsSyncError: 140,
|
||||||
|
|
||||||
'CantGetMessageList': 201,
|
CantGetMessageList: 201,
|
||||||
'CantGetMessage': 202,
|
CantGetMessage: 202,
|
||||||
'CantDeleteMessage': 203,
|
CantDeleteMessage: 203,
|
||||||
'CantMoveMessage': 204,
|
CantMoveMessage: 204,
|
||||||
'CantCopyMessage': 205,
|
CantCopyMessage: 205,
|
||||||
|
|
||||||
'CantSaveMessage': 301,
|
CantSaveMessage: 301,
|
||||||
'CantSendMessage': 302,
|
CantSendMessage: 302,
|
||||||
'InvalidRecipients': 303,
|
InvalidRecipients: 303,
|
||||||
|
|
||||||
'CantSaveFilters': 351,
|
CantSaveFilters: 351,
|
||||||
'CantGetFilters': 352,
|
CantGetFilters: 352,
|
||||||
'FiltersAreNotCorrect': 355,
|
FiltersAreNotCorrect: 355,
|
||||||
|
|
||||||
'CantCreateFolder': 400,
|
CantCreateFolder: 400,
|
||||||
'CantRenameFolder': 401,
|
CantRenameFolder: 401,
|
||||||
'CantDeleteFolder': 402,
|
CantDeleteFolder: 402,
|
||||||
'CantSubscribeFolder': 403,
|
CantSubscribeFolder: 403,
|
||||||
'CantUnsubscribeFolder': 404,
|
CantUnsubscribeFolder: 404,
|
||||||
'CantDeleteNonEmptyFolder': 405,
|
CantDeleteNonEmptyFolder: 405,
|
||||||
|
|
||||||
'CantSaveSettings': 501,
|
CantSaveSettings: 501,
|
||||||
'CantSavePluginSettings': 502,
|
CantSavePluginSettings: 502,
|
||||||
|
|
||||||
'DomainAlreadyExists': 601,
|
DomainAlreadyExists: 601,
|
||||||
|
|
||||||
'CantInstallPackage': 701,
|
CantInstallPackage: 701,
|
||||||
'CantDeletePackage': 702,
|
CantDeletePackage: 702,
|
||||||
'InvalidPluginPackage': 703,
|
InvalidPluginPackage: 703,
|
||||||
'UnsupportedPluginPackage': 704,
|
UnsupportedPluginPackage: 704,
|
||||||
|
|
||||||
'LicensingServerIsUnavailable': 710,
|
LicensingServerIsUnavailable: 710,
|
||||||
'LicensingExpired': 711,
|
LicensingExpired: 711,
|
||||||
'LicensingBanned': 712,
|
LicensingBanned: 712,
|
||||||
|
|
||||||
'DemoSendMessageError': 750,
|
DemoSendMessageError: 750,
|
||||||
'DemoAccountError': 751,
|
DemoAccountError: 751,
|
||||||
|
|
||||||
'AccountAlreadyExists': 801,
|
AccountAlreadyExists: 801,
|
||||||
'AccountDoesNotExist': 802,
|
AccountDoesNotExist: 802,
|
||||||
|
|
||||||
'MailServerError': 901,
|
MailServerError: 901,
|
||||||
'ClientViewError': 902,
|
ClientViewError: 902,
|
||||||
'InvalidInputArgument': 903,
|
InvalidInputArgument: 903,
|
||||||
|
|
||||||
'AjaxFalse': 950,
|
AjaxFalse: 950,
|
||||||
'AjaxAbort': 951,
|
AjaxAbort: 951,
|
||||||
'AjaxParse': 952,
|
AjaxParse: 952,
|
||||||
'AjaxTimeout': 953,
|
AjaxTimeout: 953,
|
||||||
|
|
||||||
'UnknownNotification': 999,
|
UnknownNotification: 999,
|
||||||
'UnknownError': 999
|
UnknownError: 999
|
||||||
|
|
||||||
,getKeyByValue: function(v) { return Object.keys(this).find(key => this[key] === v); }
|
,getKeyByValue: function(v) { return Object.keys(this).find(key => this[key] === v); }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
import * as Plugins from 'Common/Plugins';
|
|
||||||
|
|
||||||
const SUBS = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string|Object} name
|
|
||||||
* @param {Function} func
|
|
||||||
* @param {Object=} context
|
|
||||||
*/
|
|
||||||
export function sub(name, func, context) {
|
|
||||||
if (typeof name === 'object') {
|
|
||||||
context = func || null;
|
|
||||||
func = null;
|
|
||||||
|
|
||||||
Object.entries(name).forEach(([subFunc, subName]) => {
|
|
||||||
sub(subName, subFunc, context);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (undefined === SUBS[name]) {
|
|
||||||
SUBS[name] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
SUBS[name].push([func, context]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} name
|
|
||||||
* @param {Array=} args
|
|
||||||
*/
|
|
||||||
export function pub(name, args) {
|
|
||||||
Plugins.runHook('rl-pub', [name, args]);
|
|
||||||
|
|
||||||
if (undefined !== SUBS[name]) {
|
|
||||||
SUBS[name].forEach(items => {
|
|
||||||
if (items[0]) {
|
|
||||||
items[0].apply(items[1] || null, args || []);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,114 +1,65 @@
|
||||||
import { i18n } from 'Common/Translator';
|
import { i18n } from 'Common/Translator';
|
||||||
|
|
||||||
let _moment = null;
|
let d,
|
||||||
let d;
|
_moment = null,
|
||||||
|
momentNow = () => {
|
||||||
/**
|
if (!d) {
|
||||||
* @returns {moment}
|
d = setTimeout(()=>d=0, 500);
|
||||||
*/
|
_moment = new Date();
|
||||||
function momentNow() {
|
|
||||||
if (!d) {
|
|
||||||
d = setTimeout(()=>d=0, 500);
|
|
||||||
_moment = new Date();
|
|
||||||
}
|
|
||||||
return _moment;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
export function momentNowUnix() {
|
|
||||||
return momentNow().getTime() / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Object} m
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function formatCustomShortDate(m) {
|
|
||||||
const now = momentNow();
|
|
||||||
if (m && now) {
|
|
||||||
switch (true) {
|
|
||||||
case 4 >= (now.getTime() - m.getTime()) / 3600000:
|
|
||||||
return m.fromNow();
|
|
||||||
case now.format('L') === m.format('L'):
|
|
||||||
return i18n('MESSAGE_LIST/TODAY_AT', {
|
|
||||||
TIME: m.format('LT')
|
|
||||||
});
|
|
||||||
case new Date(now.getTime() - 86400000) // subtract 1 day
|
|
||||||
.format('L') === m.format('L'):
|
|
||||||
return i18n('MESSAGE_LIST/YESTERDAY_AT', {
|
|
||||||
TIME: m.format('LT')
|
|
||||||
});
|
|
||||||
case now.getFullYear() === m.getFullYear():
|
|
||||||
return m.format('d M.');
|
|
||||||
// no default
|
|
||||||
}
|
}
|
||||||
}
|
return _moment;
|
||||||
|
};
|
||||||
|
|
||||||
return m ? m.format('LL') : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} timeStampInUTC
|
|
||||||
* @param {string} formatStr
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
export function format(timeStampInUTC, formatStr) {
|
export function format(timeStampInUTC, formatStr) {
|
||||||
let m = null,
|
const now = Date.now() / 1000;
|
||||||
result = '';
|
|
||||||
|
|
||||||
const now = momentNowUnix();
|
timeStampInUTC = 0 < timeStampInUTC ? Math.min(now, timeStampInUTC) : (0 === timeStampInUTC ? now : 0);
|
||||||
|
|
||||||
timeStampInUTC = 0 < timeStampInUTC ? timeStampInUTC : 0 === timeStampInUTC ? now : 0;
|
if (31536000 < timeStampInUTC) {
|
||||||
timeStampInUTC = now < timeStampInUTC ? now : timeStampInUTC;
|
const m = new Date(timeStampInUTC * 1000);
|
||||||
|
|
||||||
m = 0 < timeStampInUTC ? new Date(timeStampInUTC * 1000) : null;
|
|
||||||
|
|
||||||
if (m && 1970 === m.getFullYear()) {
|
|
||||||
m = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m) {
|
|
||||||
switch (formatStr) {
|
switch (formatStr) {
|
||||||
case 'FROMNOW':
|
case 'FROMNOW':
|
||||||
result = m.fromNow();
|
return m.fromNow();
|
||||||
break;
|
|
||||||
case 'SHORT':
|
case 'SHORT':
|
||||||
result = formatCustomShortDate(m);
|
if (4 >= (now - timeStampInUTC) / 3600)
|
||||||
break;
|
return m.fromNow();
|
||||||
|
if (momentNow().format('Ymd') === m.format('Ymd'))
|
||||||
|
return i18n('MESSAGE_LIST/TODAY_AT', {TIME: m.format('LT')});
|
||||||
|
if (new Date((now - 86400) * 1000).format('Ymd') === m.format('Ymd'))
|
||||||
|
return i18n('MESSAGE_LIST/YESTERDAY_AT', {TIME: m.format('LT')});
|
||||||
|
if (momentNow().getFullYear() === m.getFullYear())
|
||||||
|
return m.format('d M.');
|
||||||
|
return m.format('LL');
|
||||||
case 'FULL':
|
case 'FULL':
|
||||||
result = m.format('LLL');
|
return m.format('LLL');
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
result = m.format(formatStr);
|
return m.format(formatStr);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export function timeToNode(element, time) {
|
||||||
* @param {Object} element
|
try {
|
||||||
* @returns {void}
|
time = time || (Date.parse(element.dateTime) / 1000);
|
||||||
*/
|
if (time) {
|
||||||
export function momentToNode(element) {
|
let key, m = new Date(time * 1000);
|
||||||
let key = '',
|
element.dateTime = m.format('Y-m-d\\TH:i:s');
|
||||||
time = 0;
|
|
||||||
const $el = jQuery(element);
|
|
||||||
|
|
||||||
time = $el.data('moment-time');
|
key = element.dataset.momentFormat;
|
||||||
if (time) {
|
if (key) {
|
||||||
key = $el.data('moment-format');
|
element.textContent = format(time, key);
|
||||||
if (key) {
|
}
|
||||||
$el.text(format(time, key));
|
|
||||||
}
|
|
||||||
|
|
||||||
key = $el.data('moment-format-title');
|
key = element.dataset.momentFormatTitle;
|
||||||
if (key) {
|
if (key) {
|
||||||
$el.attr('title', format(time, key));
|
element.title = format(time, key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// prevent knockout crashes
|
||||||
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,8 +68,6 @@ export function momentToNode(element) {
|
||||||
*/
|
*/
|
||||||
export function reload() {
|
export function reload() {
|
||||||
setTimeout(() =>
|
setTimeout(() =>
|
||||||
jQuery('.moment', document).each((index, item) => {
|
document.querySelectorAll('[data-bind*="moment:"]').forEach(element => timeToNode(element))
|
||||||
momentToNode(item);
|
|
||||||
})
|
|
||||||
, 1);
|
, 1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class Selector {
|
||||||
var d, o = this;
|
var d, o = this;
|
||||||
this.itemSelectedThrottle = (item)=>{
|
this.itemSelectedThrottle = (item)=>{
|
||||||
// debounce
|
// debounce
|
||||||
d && clearTimeout(d);
|
clearTimeout(d);
|
||||||
d = setTimeout(()=>o.itemSelected(item), 300);
|
d = setTimeout(()=>o.itemSelected(item), 300);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -845,7 +845,7 @@ export function selectElement(element) {
|
||||||
var dv;
|
var dv;
|
||||||
export const detectDropdownVisibility = ()=>{
|
export const detectDropdownVisibility = ()=>{
|
||||||
// leading debounce
|
// leading debounce
|
||||||
dv && clearTimeout(dv);
|
clearTimeout(dv);
|
||||||
dv = setTimeout(()=>
|
dv = setTimeout(()=>
|
||||||
dropdownVisibility(!!GlobalsData.aBootstrapDropdowns.find(item => item.hasClass('open')))
|
dropdownVisibility(!!GlobalsData.aBootstrapDropdowns.find(item => item.hasClass('open')))
|
||||||
, 50);
|
, 50);
|
||||||
|
|
@ -1223,7 +1223,7 @@ export function mailToHelper(mailToUrl, PopupComposeViewModel) {
|
||||||
|
|
||||||
var wr;
|
var wr;
|
||||||
export const windowResize = timeout => {
|
export const windowResize = timeout => {
|
||||||
wr && clearTimeout(wr);
|
clearTimeout(wr);
|
||||||
if (undefined === timeout || null === timeout) {
|
if (undefined === timeout || null === timeout) {
|
||||||
$win.trigger('resize');
|
$win.trigger('resize');
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
323
dev/External/ko.js
vendored
323
dev/External/ko.js
vendored
|
|
@ -12,16 +12,8 @@ ko.bindingHandlers.editor = {
|
||||||
|
|
||||||
const fValue = fValueAccessor(),
|
const fValue = fValueAccessor(),
|
||||||
HtmlEditor = require('Common/HtmlEditor').default,
|
HtmlEditor = require('Common/HtmlEditor').default,
|
||||||
fUpdateEditorValue = () => {
|
fUpdateEditorValue = () => fValue && fValue.__editor && fValue.__editor.setHtmlOrPlain(fValue()),
|
||||||
if (fValue && fValue.__editor) {
|
fUpdateKoValue = () => fValue && fValue.__editor && fValue(fValue.__editor.getDataWithHtmlMark()),
|
||||||
fValue.__editor.setHtmlOrPlain(fValue());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fUpdateKoValue = () => {
|
|
||||||
if (fValue && fValue.__editor) {
|
|
||||||
fValue(fValue.__editor.getDataWithHtmlMark());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fOnReady = () => {
|
fOnReady = () => {
|
||||||
fValue.__editor = editor;
|
fValue.__editor = editor;
|
||||||
fUpdateEditorValue();
|
fUpdateEditorValue();
|
||||||
|
|
@ -40,66 +32,9 @@ ko.bindingHandlers.editor = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.json = {
|
|
||||||
init: (element, fValueAccessor) => {
|
|
||||||
$(element).text(JSON.stringify(ko.unwrap(fValueAccessor())));
|
|
||||||
},
|
|
||||||
update: (element, fValueAccessor) => {
|
|
||||||
$(element).text(JSON.stringify(ko.unwrap(fValueAccessor())));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ko.bindingHandlers.scrollerShadows = {
|
|
||||||
init: (element) => {
|
|
||||||
var t;
|
|
||||||
const limit = 8,
|
|
||||||
$el = $(element),
|
|
||||||
cont = $el.find('[data-scroller-shadows-content]')[0] || null,
|
|
||||||
// throttle
|
|
||||||
fFunc = ()=>{
|
|
||||||
if (!t) {
|
|
||||||
t = setTimeout(()=>{
|
|
||||||
$el
|
|
||||||
.toggleClass('scroller-shadow-top', limit < cont.scrollTop)
|
|
||||||
.toggleClass('scroller-shadow-bottom', cont.scrollTop + limit < cont.scrollHeight - cont.clientHeight);
|
|
||||||
t = 0;
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (cont) {
|
|
||||||
$(cont).on('scroll resize', fFunc);
|
|
||||||
addEventListener('resize', fFunc);
|
|
||||||
|
|
||||||
ko.utils.domNodeDisposal.addDisposeCallback(cont, () => {
|
|
||||||
$(cont).off();
|
|
||||||
removeEventListener('resize', fFunc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ko.bindingHandlers.visibleAnimated = {
|
ko.bindingHandlers.visibleAnimated = {
|
||||||
init: (element, fValueAccessor) => {
|
init: (element, fValueAccessor) => element.hidden = !ko.unwrap(fValueAccessor()),
|
||||||
const $el = $(element);
|
update: (element, fValueAccessor) => element.hidden = !ko.unwrap(fValueAccessor())
|
||||||
$el.addClass('rl-animated-inited');
|
|
||||||
if (ko.unwrap(fValueAccessor())) {
|
|
||||||
$el.show();
|
|
||||||
} else {
|
|
||||||
$el.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
update: (element, fValueAccessor) => {
|
|
||||||
const $el = $(element);
|
|
||||||
if (ko.unwrap(fValueAccessor())) {
|
|
||||||
$el.addClass('rl-animated-hidden').show();
|
|
||||||
setTimeout(() => {
|
|
||||||
$el.removeClass('rl-animated-hidden');
|
|
||||||
}, 10);
|
|
||||||
} else {
|
|
||||||
$el.hide().removeClass('rl-animated-hidden');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.tooltip = {
|
ko.bindingHandlers.tooltip = {
|
||||||
|
|
@ -139,13 +74,9 @@ ko.bindingHandlers.tooltip = {
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.tooltipErrorTip = {
|
ko.bindingHandlers.tooltipErrorTip = {
|
||||||
init: function(element) {
|
init: element => {
|
||||||
$(document).on('click', () => {
|
document.addEventListener('click', () => element.removeAttribute('data-rainloopErrorTip'));
|
||||||
element.removeAttribute('data-rainloopErrorTip')
|
ko.utils.domNodeDisposal.addDisposeCallback(element, () => element.removeAttribute('data-rainloopErrorTip'));
|
||||||
});
|
|
||||||
ko.utils.domNodeDisposal.addDisposeCallback(element, () => {
|
|
||||||
element.removeAttribute('data-rainloopErrorTip')
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
update: (element, fValueAccessor) => {
|
update: (element, fValueAccessor) => {
|
||||||
const fValue = fValueAccessor(),
|
const fValue = fValueAccessor(),
|
||||||
|
|
@ -164,13 +95,7 @@ ko.bindingHandlers.registrateBootstrapDropdown = {
|
||||||
const Globals = require('Common/Globals');
|
const Globals = require('Common/Globals');
|
||||||
if (Globals && Globals.data.aBootstrapDropdowns) {
|
if (Globals && Globals.data.aBootstrapDropdowns) {
|
||||||
Globals.data.aBootstrapDropdowns.push($(element));
|
Globals.data.aBootstrapDropdowns.push($(element));
|
||||||
|
element.addEventListener('click', () => require('Common/Utils').detectDropdownVisibility());
|
||||||
$(element).click(() => {
|
|
||||||
require('Common/Utils').detectDropdownVisibility();
|
|
||||||
});
|
|
||||||
|
|
||||||
// ko.utils.domNodeDisposal.addDisposeCallback(element, () => {
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -178,12 +103,12 @@ ko.bindingHandlers.registrateBootstrapDropdown = {
|
||||||
ko.bindingHandlers.openDropdownTrigger = {
|
ko.bindingHandlers.openDropdownTrigger = {
|
||||||
update: (element, fValueAccessor) => {
|
update: (element, fValueAccessor) => {
|
||||||
if (ko.unwrap(fValueAccessor())) {
|
if (ko.unwrap(fValueAccessor())) {
|
||||||
const $el = $(element);
|
const $el = $(element), t = $el.find('.dropdown-toggle');
|
||||||
if (!$el.hasClass('open')) {
|
if (!$el.hasClass('open')) {
|
||||||
$el.find('.dropdown-toggle').dropdown('toggle');
|
t.dropdown('toggle');
|
||||||
}
|
}
|
||||||
|
|
||||||
$el.find('.dropdown-toggle').focus();
|
t.focus();
|
||||||
|
|
||||||
require('Common/Utils').detectDropdownVisibility();
|
require('Common/Utils').detectDropdownVisibility();
|
||||||
fValueAccessor()(false);
|
fValueAccessor()(false);
|
||||||
|
|
@ -192,17 +117,15 @@ ko.bindingHandlers.openDropdownTrigger = {
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.dropdownCloser = {
|
ko.bindingHandlers.dropdownCloser = {
|
||||||
init: (element) => {
|
init: element => $(element)
|
||||||
$(element)
|
.closest('.dropdown')
|
||||||
.closest('.dropdown')
|
.on('click', '.e-item', () => {
|
||||||
.on('click', '.e-item', () => {
|
$(element).dropdown('toggle');
|
||||||
$(element).dropdown('toggle');
|
})
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.popover = {
|
ko.bindingHandlers.popover = {
|
||||||
init: function(element, fValueAccessor) {
|
init: (element, fValueAccessor) => {
|
||||||
console.log('TODO: $(element).popover removed', element, fValueAccessor);
|
console.log('TODO: $(element).popover removed', element, fValueAccessor);
|
||||||
/*
|
/*
|
||||||
$(element).popover(ko.unwrap(fValueAccessor()));
|
$(element).popover(ko.unwrap(fValueAccessor()));
|
||||||
|
|
@ -213,22 +136,6 @@ ko.bindingHandlers.popover = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.onKeyDown = {
|
|
||||||
init: (element, fValueAccessor, fAllBindingsAccessor, viewModel) => {
|
|
||||||
$(element).on('keydown.koOnKeyDown', (event) => {
|
|
||||||
if (event) {
|
|
||||||
return fValueAccessor().call(viewModel, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
ko.utils.domNodeDisposal.addDisposeCallback(element, () => {
|
|
||||||
$(element).off('keydown.koOnKeyDown');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ko.bindingHandlers.onEnter = {
|
ko.bindingHandlers.onEnter = {
|
||||||
init: (element, fValueAccessor, fAllBindingsAccessor, viewModel) => {
|
init: (element, fValueAccessor, fAllBindingsAccessor, viewModel) => {
|
||||||
$(element).on('keypress.koOnEnter', (event) => {
|
$(element).on('keypress.koOnEnter', (event) => {
|
||||||
|
|
@ -258,21 +165,6 @@ ko.bindingHandlers.onSpace = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.onTab = {
|
|
||||||
init: (element, fValueAccessor, fAllBindingsAccessor, viewModel) => {
|
|
||||||
$(element).on('keydown.koOnTab', (event) => {
|
|
||||||
if (event && 9 === parseInt(event.keyCode, 10)) {
|
|
||||||
return fValueAccessor().call(viewModel, !!event.shiftKey);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
ko.utils.domNodeDisposal.addDisposeCallback(element, () => {
|
|
||||||
$(element).off('keydown.koOnTab');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ko.bindingHandlers.onEsc = {
|
ko.bindingHandlers.onEsc = {
|
||||||
init: (element, fValueAccessor, fAllBindingsAccessor, viewModel) => {
|
init: (element, fValueAccessor, fAllBindingsAccessor, viewModel) => {
|
||||||
$(element).on('keyup.koOnEsc', (event) => {
|
$(element).on('keyup.koOnEsc', (event) => {
|
||||||
|
|
@ -288,14 +180,6 @@ ko.bindingHandlers.onEsc = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.clickOnTrue = {
|
|
||||||
update: (element, fValueAccessor) => {
|
|
||||||
if (ko.unwrap(fValueAccessor())) {
|
|
||||||
$(element).click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ko.bindingHandlers.modal = {
|
ko.bindingHandlers.modal = {
|
||||||
init: (element, fValueAccessor) => {
|
init: (element, fValueAccessor) => {
|
||||||
const Globals = require('Common/Globals'),
|
const Globals = require('Common/Globals'),
|
||||||
|
|
@ -327,117 +211,52 @@ ko.bindingHandlers.modal = {
|
||||||
|
|
||||||
if (Globals.$htmlCL.contains('rl-anim')) {
|
if (Globals.$htmlCL.contains('rl-anim')) {
|
||||||
Globals.$htmlCL.add('rl-modal-animation');
|
Globals.$htmlCL.add('rl-modal-animation');
|
||||||
setTimeout(() => {
|
setTimeout(() => Globals.$htmlCL.remove('rl-modal-animation'), 500);
|
||||||
Globals.$htmlCL.remove('rl-modal-animation');
|
|
||||||
}, 500);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let ttn = (element, fValueAccessor) => require('Common/Momentor').timeToNode(element, ko.unwrap(fValueAccessor()));
|
||||||
ko.bindingHandlers.moment = {
|
ko.bindingHandlers.moment = {
|
||||||
init: (element, fValueAccessor) => {
|
init: ttn,
|
||||||
require('Common/Momentor').momentToNode(
|
update: ttn
|
||||||
$(element)
|
|
||||||
.addClass('moment')
|
|
||||||
.data('moment-time', ko.unwrap(fValueAccessor()))
|
|
||||||
);
|
|
||||||
},
|
|
||||||
update: (element, fValueAccessor) => {
|
|
||||||
require('Common/Momentor').momentToNode($(element).data('moment-time', ko.unwrap(fValueAccessor())));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.i18nInit = {
|
ko.bindingHandlers.i18nInit = {
|
||||||
init: (element) => {
|
init: element => Translator().i18nToNodes(element)
|
||||||
require('Common/Translator').i18nToNodes(element);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ko.bindingHandlers.translatorInit = {
|
|
||||||
init: (element) => {
|
|
||||||
require('Common/Translator').i18nToNodes(element);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.i18nUpdate = {
|
ko.bindingHandlers.i18nUpdate = {
|
||||||
update: (element, fValueAccessor) => {
|
update: (element, fValueAccessor) => {
|
||||||
ko.unwrap(fValueAccessor());
|
ko.unwrap(fValueAccessor());
|
||||||
require('Common/Translator').i18nToNodes(element);
|
Translator().i18nToNodes(element);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.link = {
|
ko.bindingHandlers.link = {
|
||||||
update: function(element, fValueAccessor) {
|
update: (element, fValueAccessor) => element.setAttribute('href', ko.unwrap(fValueAccessor()))
|
||||||
$(element).attr('href', ko.unwrap(fValueAccessor()));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.title = {
|
ko.bindingHandlers.title = {
|
||||||
update: function(element, fValueAccessor) {
|
update: (element, fValueAccessor) => element.setAttribute('title', ko.unwrap(fValueAccessor()))
|
||||||
$(element).attr('title', ko.unwrap(fValueAccessor()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ko.bindingHandlers.textF = {
|
|
||||||
init: function(element, fValueAccessor) {
|
|
||||||
$(element).text(ko.unwrap(fValueAccessor()));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.initDom = {
|
ko.bindingHandlers.initDom = {
|
||||||
init: function(element, fValueAccessor) {
|
init: (element, fValueAccessor) => fValueAccessor()(element)
|
||||||
fValueAccessor()(element);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ko.bindingHandlers.initFixedTrigger = {
|
|
||||||
init: (element, fValueAccessor) => {
|
|
||||||
const values = ko.unwrap(fValueAccessor()),
|
|
||||||
$el = $(element),
|
|
||||||
top = values[1] || 0;
|
|
||||||
|
|
||||||
let $container = $(values[0] || null);
|
|
||||||
$container = $container[0] ? $container : null;
|
|
||||||
if ($container) {
|
|
||||||
addEventListener('resize', () => {
|
|
||||||
const offset = $container ? $container.offset() : null;
|
|
||||||
if (offset && offset.top) {
|
|
||||||
$el.css('top', offset.top + top);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.initResizeTrigger = {
|
ko.bindingHandlers.initResizeTrigger = {
|
||||||
init: (element, fValueAccessor) => {
|
init: (element, fValueAccessor) =>
|
||||||
|
element.style.height = element.style.minHeight = ko.unwrap(fValueAccessor())[1] + 'px',
|
||||||
|
update: (element, fValueAccessor) => {
|
||||||
const values = ko.unwrap(fValueAccessor());
|
const values = ko.unwrap(fValueAccessor());
|
||||||
$(element).css({
|
let offset = element.getBoundingClientRect().top + pageYOffset;
|
||||||
'height': values[1],
|
|
||||||
'min-height': values[1]
|
|
||||||
});
|
|
||||||
},
|
|
||||||
update: (oElement, fValueAccessor) => {
|
|
||||||
const Utils = require('Common/Utils'),
|
|
||||||
Globals = require('Common/Globals'),
|
|
||||||
values = ko.unwrap(fValueAccessor());
|
|
||||||
|
|
||||||
let value = Utils.pInt(values[1]),
|
|
||||||
size = 0,
|
|
||||||
offset = $(oElement).offset().top;
|
|
||||||
|
|
||||||
if (0 < offset) {
|
if (0 < offset) {
|
||||||
offset += Utils.pInt(values[2]);
|
offset += parseInt(values[2], 10) || 0;
|
||||||
size = Globals.$win.height() - offset;
|
element.style.height = element.style.minHeight = Math.max(
|
||||||
|
parseInt(values[1], 10) || 0,
|
||||||
if (value < size) {
|
window.innerHeight - offset
|
||||||
value = size;
|
) + 'px';
|
||||||
}
|
|
||||||
|
|
||||||
$(oElement).css({
|
|
||||||
'height': value,
|
|
||||||
'min-height': value
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -720,8 +539,7 @@ ko.bindingHandlers.emailsTags = {
|
||||||
|
|
||||||
ko.bindingHandlers.command = {
|
ko.bindingHandlers.command = {
|
||||||
init: (element, fValueAccessor, fAllBindingsAccessor, viewModel, bindingContext) => {
|
init: (element, fValueAccessor, fAllBindingsAccessor, viewModel, bindingContext) => {
|
||||||
const jqElement = $(element),
|
const command = fValueAccessor();
|
||||||
command = fValueAccessor();
|
|
||||||
|
|
||||||
if (!command || !command.isCommand) {
|
if (!command || !command.isCommand) {
|
||||||
throw new Error('Value should be a command');
|
throw new Error('Value should be a command');
|
||||||
|
|
@ -740,8 +558,8 @@ ko.bindingHandlers.command = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jqElement.addClass('command');
|
element.classList.add('command');
|
||||||
ko.bindingHandlers[jqElement.is('form') ? 'submit' : 'click'].init(
|
ko.bindingHandlers[element.tagName.match(/FORM/i) ? 'submit' : 'click'].init(
|
||||||
element,
|
element,
|
||||||
fValueAccessor,
|
fValueAccessor,
|
||||||
fAllBindingsAccessor,
|
fAllBindingsAccessor,
|
||||||
|
|
@ -750,40 +568,29 @@ ko.bindingHandlers.command = {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
update: (element, fValueAccessor) => {
|
update: (element, fValueAccessor) => {
|
||||||
const jqElement = $(element),
|
const cl = element.classList,
|
||||||
command = fValueAccessor();
|
command = fValueAccessor();
|
||||||
|
|
||||||
let result = command.enabled();
|
let result = command.enabled();
|
||||||
|
|
||||||
jqElement.toggleClass('command-not-enabled', !result);
|
cl.toggle('command-not-enabled', !result);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
result = command.canExecute();
|
result = command.canExecute();
|
||||||
jqElement.toggleClass('command-can-not-be-execute', !result);
|
cl.toggle('command-can-not-be-execute', !result);
|
||||||
}
|
}
|
||||||
|
|
||||||
jqElement.toggleClass('command-disabled disable disabled', !result).toggleClass('no-disabled', !!result);
|
['command-disabled','disable','disabled'].forEach(s=>cl.toggle(s, !result));
|
||||||
|
cl.toggle('no-disabled', !!result);
|
||||||
|
|
||||||
if (jqElement.is('input') || jqElement.is('button')) {
|
if (element.tagName.match(/INPUT|TEXTAREA|BUTTON/i)) {
|
||||||
jqElement.prop('disabled', !result);
|
element.disabled = !result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// extenders
|
// extenders
|
||||||
|
|
||||||
ko.extenders.trimmer = (target) => {
|
|
||||||
const result = ko.computed({
|
|
||||||
read: target,
|
|
||||||
write: (newValue) => {
|
|
||||||
target(newValue.toString().trim());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
result(target());
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
ko.extenders.posInterer = (target, defaultVal) => {
|
ko.extenders.posInterer = (target, defaultVal) => {
|
||||||
const Utils = require('Common/Utils'),
|
const Utils = require('Common/Utils'),
|
||||||
result = ko.computed({
|
result = ko.computed({
|
||||||
|
|
@ -834,9 +641,7 @@ ko.extenders.limitedList = (target, limitedList) => {
|
||||||
result(target());
|
result(target());
|
||||||
|
|
||||||
if (!result.valueHasMutated) {
|
if (!result.valueHasMutated) {
|
||||||
result.valueHasMutated = () => {
|
result.valueHasMutated = () => target.valueHasMutated();
|
||||||
target.valueHasMutated();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -845,13 +650,9 @@ ko.extenders.limitedList = (target, limitedList) => {
|
||||||
ko.extenders.reversible = (target) => {
|
ko.extenders.reversible = (target) => {
|
||||||
let value = target();
|
let value = target();
|
||||||
|
|
||||||
target.commit = () => {
|
target.commit = () => value = target();
|
||||||
value = target();
|
|
||||||
};
|
|
||||||
|
|
||||||
target.reverse = () => {
|
target.reverse = () => target(value);
|
||||||
target(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
target.commitedValue = () => value;
|
target.commitedValue = () => value;
|
||||||
return target;
|
return target;
|
||||||
|
|
@ -867,20 +668,12 @@ ko.extenders.toggleSubscribeProperty = (target, options) => {
|
||||||
const prop = options[1];
|
const prop = options[1];
|
||||||
if (prop) {
|
if (prop) {
|
||||||
target.subscribe(
|
target.subscribe(
|
||||||
(prev) => {
|
prev => prev && prev[prop] && prev[prop](false),
|
||||||
if (prev && prev[prop]) {
|
|
||||||
prev[prop](false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
options[0],
|
options[0],
|
||||||
'beforeChange'
|
'beforeChange'
|
||||||
);
|
);
|
||||||
|
|
||||||
target.subscribe((next) => {
|
target.subscribe(next => next && next[prop] && next[prop](true), options[0]);
|
||||||
if (next && next[prop]) {
|
|
||||||
next[prop](true);
|
|
||||||
}
|
|
||||||
}, options[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
|
|
@ -888,13 +681,13 @@ ko.extenders.toggleSubscribeProperty = (target, options) => {
|
||||||
|
|
||||||
ko.extenders.falseTimeout = (target, option) => {
|
ko.extenders.falseTimeout = (target, option) => {
|
||||||
target.iFalseTimeoutTimeout = 0;
|
target.iFalseTimeoutTimeout = 0;
|
||||||
target.subscribe((value) => {
|
target.subscribe(value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
clearTimeout(target.iFalseTimeoutTimeout);
|
clearTimeout(target.iFalseTimeoutTimeout);
|
||||||
target.iFalseTimeoutTimeout = setTimeout(() => {
|
target.iFalseTimeoutTimeout = setTimeout(() => {
|
||||||
target(false);
|
target(false);
|
||||||
target.iFalseTimeoutTimeout = 0;
|
target.iFalseTimeoutTimeout = 0;
|
||||||
}, require('Common/Utils').pInt(option));
|
}, parseInt(option, 10) || 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -949,9 +742,7 @@ ko.observable.fn.validateNone = function() {
|
||||||
ko.observable.fn.validateEmail = function() {
|
ko.observable.fn.validateEmail = function() {
|
||||||
this.hasError = ko.observable(false);
|
this.hasError = ko.observable(false);
|
||||||
|
|
||||||
this.subscribe((value) => {
|
this.subscribe(value => this.hasError(value && !/^[^@\s]+@[^@\s]+$/.test(value)));
|
||||||
this.hasError(value && !/^[^@\s]+@[^@\s]+$/.test(value));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.valueHasMutated();
|
this.valueHasMutated();
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -960,9 +751,7 @@ ko.observable.fn.validateEmail = function() {
|
||||||
ko.observable.fn.validateSimpleEmail = function() {
|
ko.observable.fn.validateSimpleEmail = function() {
|
||||||
this.hasError = ko.observable(false);
|
this.hasError = ko.observable(false);
|
||||||
|
|
||||||
this.subscribe((value) => {
|
this.subscribe(value => this.hasError(value && !/^.+@.+$/.test(value)));
|
||||||
this.hasError(value && !/^.+@.+$/.test(value));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.valueHasMutated();
|
this.valueHasMutated();
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -977,9 +766,7 @@ ko.observable.fn.validateFunc = function(fFunc) {
|
||||||
this.hasFuncError = ko.observable(false);
|
this.hasFuncError = ko.observable(false);
|
||||||
|
|
||||||
if (isFunction(fFunc)) {
|
if (isFunction(fFunc)) {
|
||||||
this.subscribe((value) => {
|
this.subscribe(value => this.hasFuncError(!fFunc(value)));
|
||||||
this.hasFuncError(!fFunc(value));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.valueHasMutated();
|
this.valueHasMutated();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ export function buildViewModel(ViewModelClass, vmScreen) {
|
||||||
ko.applyBindingAccessorsToNode(
|
ko.applyBindingAccessorsToNode(
|
||||||
vmDom[0],
|
vmDom[0],
|
||||||
{
|
{
|
||||||
translatorInit: true,
|
i18nInit: true,
|
||||||
template: () => ({ name: vm.viewModelTemplateID })
|
template: () => ({ name: vm.viewModelTemplateID })
|
||||||
},
|
},
|
||||||
vm
|
vm
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import { FolderType } from 'Common/Enums';
|
||||||
import { isPosNumeric } from 'Common/Utils';
|
import { isPosNumeric } from 'Common/Utils';
|
||||||
import { i18n, trigger as translatorTrigger } from 'Common/Translator';
|
import { i18n, trigger as translatorTrigger } from 'Common/Translator';
|
||||||
import { getFolderInboxName } from 'Common/Cache';
|
import { getFolderInboxName } from 'Common/Cache';
|
||||||
import * as Events from 'Common/Events';
|
|
||||||
|
|
||||||
import { AbstractModel } from 'Knoin/AbstractModel';
|
import { AbstractModel } from 'Knoin/AbstractModel';
|
||||||
|
|
||||||
|
|
@ -234,19 +233,13 @@ class FolderModel extends AbstractModel {
|
||||||
);
|
);
|
||||||
|
|
||||||
// subscribe
|
// subscribe
|
||||||
this.name.subscribe((value) => {
|
this.name.subscribe(value => this.nameForEdit(value));
|
||||||
this.nameForEdit(value);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.edited.subscribe((value) => {
|
this.edited.subscribe(value => value && this.nameForEdit(this.name()));
|
||||||
if (value) {
|
|
||||||
this.nameForEdit(this.name());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.messageCountUnread.subscribe((unread) => {
|
this.messageCountUnread.subscribe((unread) => {
|
||||||
if (FolderType.Inbox === this.type()) {
|
if (FolderType.Inbox === this.type()) {
|
||||||
Events.pub('mailbox.inbox-unread-count', [unread]);
|
dispatchEvent(new CustomEvent('mailbox.inbox-unread-count', {detail:unread}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -228,13 +228,6 @@ class RemoteUserAjax extends AbstractAjaxRemote {
|
||||||
this.defaultRequest(fCallback, 'AccountsAndIdentities');
|
this.defaultRequest(fCallback, 'AccountsAndIdentities');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {?Function} fCallback
|
|
||||||
*/
|
|
||||||
accountsCounts(fCallback) {
|
|
||||||
this.defaultRequest(fCallback, 'AccountsCounts');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {?Function} fCallback
|
* @param {?Function} fCallback
|
||||||
* @param {Array} filters
|
* @param {Array} filters
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ class AbstractSettingsScreen extends AbstractScreen {
|
||||||
ko.applyBindingAccessorsToNode(
|
ko.applyBindingAccessorsToNode(
|
||||||
viewModelDom[0],
|
viewModelDom[0],
|
||||||
{
|
{
|
||||||
translatorInit: true,
|
i18nInit: true,
|
||||||
template: () => tmpl
|
template: () => tmpl
|
||||||
},
|
},
|
||||||
settingsScreen
|
settingsScreen
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import { pString, pInt, windowResizeCallback } from 'Common/Utils';
|
||||||
import { getFolderFromCacheList, getFolderFullNameRaw, getFolderInboxName } from 'Common/Cache';
|
import { getFolderFromCacheList, getFolderFullNameRaw, getFolderInboxName } from 'Common/Cache';
|
||||||
import { i18n } from 'Common/Translator';
|
import { i18n } from 'Common/Translator';
|
||||||
|
|
||||||
import * as Events from 'Common/Events';
|
|
||||||
import * as Settings from 'Storage/Settings';
|
import * as Settings from 'Storage/Settings';
|
||||||
|
|
||||||
import AppStore from 'Stores/User/App';
|
import AppStore from 'Stores/User/App';
|
||||||
|
|
@ -110,13 +109,13 @@ class MailBoxUserScreen extends AbstractScreen {
|
||||||
setTimeout(() => SettingsStore.layout.valueHasMutated(), 50);
|
setTimeout(() => SettingsStore.layout.valueHasMutated(), 50);
|
||||||
setTimeout(() => warmUpScreenPopup(require('View/Popup/Compose')), 500);
|
setTimeout(() => warmUpScreenPopup(require('View/Popup/Compose')), 500);
|
||||||
|
|
||||||
Events.sub('mailbox.inbox-unread-count', (count) => {
|
addEventListener('mailbox.inbox-unread-count', e => {
|
||||||
FolderStore.foldersInboxUnreadCount(count);
|
FolderStore.foldersInboxUnreadCount(e.detail);
|
||||||
|
|
||||||
const email = AccountStore.email();
|
const email = AccountStore.email();
|
||||||
AccountStore.accounts().forEach(item => {
|
AccountStore.accounts().forEach(item => {
|
||||||
if (item && email === item.email) {
|
if (item && email === item.email) {
|
||||||
item.count(count);
|
item.count(e.detail);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
||||||
import { folderListOptionsBuilder } from 'Common/Utils';
|
import { folderListOptionsBuilder } from 'Common/Utils';
|
||||||
import { getFolderInboxName, getFolderFromCacheList } from 'Common/Cache';
|
import { getFolderInboxName, getFolderFromCacheList } from 'Common/Cache';
|
||||||
|
|
||||||
import { momentNowUnix } from 'Common/Momentor';
|
|
||||||
|
|
||||||
class FolderUserStore {
|
class FolderUserStore {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.displaySpecSetting = ko.observable(true);
|
this.displaySpecSetting = ko.observable(true);
|
||||||
|
|
@ -157,7 +155,7 @@ class FolderUserStore {
|
||||||
getNextFolderNames() {
|
getNextFolderNames() {
|
||||||
const result = [],
|
const result = [],
|
||||||
limit = 5,
|
limit = 5,
|
||||||
utc = momentNowUnix(),
|
utc = Date.now() / 1000,
|
||||||
timeout = utc - 60 * 5,
|
timeout = utc - 60 * 5,
|
||||||
timeouts = [],
|
timeouts = [],
|
||||||
inboxFolderName = getFolderInboxName(),
|
inboxFolderName = getFolderInboxName(),
|
||||||
|
|
@ -182,15 +180,7 @@ class FolderUserStore {
|
||||||
|
|
||||||
fSearchFunction(this.folderList());
|
fSearchFunction(this.folderList());
|
||||||
|
|
||||||
timeouts.sort((a, b) => {
|
timeouts.sort((a, b) => (a[0] < b[0]) ? -1 : (a[0] > b[0] ? 1 : 0));
|
||||||
if (a[0] < b[0]) {
|
|
||||||
return -1;
|
|
||||||
} else if (a[0] > b[0]) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
timeouts.find(aItem => {
|
timeouts.find(aItem => {
|
||||||
const folder = getFolderFromCacheList(aItem[1]);
|
const folder = getFolderFromCacheList(aItem[1]);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ import { MESSAGE_BODY_CACHE_LIMIT } from 'Common/Consts';
|
||||||
import { data as GlobalsData } from 'Common/Globals';
|
import { data as GlobalsData } from 'Common/Globals';
|
||||||
import { mailBox, notificationMailIcon } from 'Common/Links';
|
import { mailBox, notificationMailIcon } from 'Common/Links';
|
||||||
import { i18n, getNotification } from 'Common/Translator';
|
import { i18n, getNotification } from 'Common/Translator';
|
||||||
import { momentNowUnix } from 'Common/Momentor';
|
|
||||||
|
|
||||||
import * as MessageHelper from 'Helper/Message';
|
import * as MessageHelper from 'Helper/Message';
|
||||||
import { MessageModel } from 'Model/Message';
|
import { MessageModel } from 'Model/Message';
|
||||||
|
|
@ -209,7 +208,7 @@ class MessageUserStore {
|
||||||
this.messageList.subscribe(
|
this.messageList.subscribe(
|
||||||
(list)=>{
|
(list)=>{
|
||||||
// debounce
|
// debounce
|
||||||
d && clearTimeout(d);
|
clearTimeout(d);
|
||||||
d = setTimeout(()=>list.forEach(item => {
|
d = setTimeout(()=>list.forEach(item => {
|
||||||
if (item && item.newForAnimation()) {
|
if (item && item.newForAnimation()) {
|
||||||
item.newForAnimation(false);
|
item.newForAnimation(false);
|
||||||
|
|
@ -750,7 +749,7 @@ class MessageUserStore {
|
||||||
const folder = getFolderFromCacheList(isNormal(data.Result.Folder) ? data.Result.Folder : '');
|
const folder = getFolderFromCacheList(isNormal(data.Result.Folder) ? data.Result.Folder : '');
|
||||||
|
|
||||||
if (folder && !cached) {
|
if (folder && !cached) {
|
||||||
folder.interval = momentNowUnix();
|
folder.interval = Date.now() / 1000;
|
||||||
|
|
||||||
setFolderHash(data.Result.Folder, data.Result.FolderHash);
|
setFolderHash(data.Result.Folder, data.Result.FolderHash);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import ko from 'ko';
|
import ko from 'ko';
|
||||||
|
|
||||||
import { DesktopNotification } from 'Common/Enums';
|
import { DesktopNotification } from 'Common/Enums';
|
||||||
import * as Events from 'Common/Events';
|
|
||||||
import Audio from 'Common/Audio';
|
import Audio from 'Common/Audio';
|
||||||
|
|
||||||
import * as Settings from 'Storage/Settings';
|
import * as Settings from 'Storage/Settings';
|
||||||
|
|
@ -118,7 +117,7 @@ class NotificationUserStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
displayDesktopNotification(imageSrc, title, text, nessageData) {
|
displayDesktopNotification(imageSrc, title, text, messageData) {
|
||||||
if (this.enableDesktopNotification()) {
|
if (this.enableDesktopNotification()) {
|
||||||
const NotificationClass = this.notificationClass(),
|
const NotificationClass = this.notificationClass(),
|
||||||
notification = NotificationClass
|
notification = NotificationClass
|
||||||
|
|
@ -133,12 +132,12 @@ class NotificationUserStore {
|
||||||
notification.show();
|
notification.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nessageData) {
|
if (messageData) {
|
||||||
notification.onclick = () => {
|
notification.onclick = () => {
|
||||||
focus();
|
focus();
|
||||||
|
|
||||||
if (nessageData.Folder && nessageData.Uid) {
|
if (messageData.Folder && messageData.Uid) {
|
||||||
Events.pub('mailbox.message.show', [nessageData.Folder, nessageData.Uid]);
|
dispatchEvent(new CustomEvent('mailbox.message.show', {detail:messageData}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import { MESSAGES_PER_PAGE, MESSAGES_PER_PAGE_VALUES } from 'Common/Consts';
|
||||||
import { Layout, EditorDefaultType } from 'Common/Enums';
|
import { Layout, EditorDefaultType } from 'Common/Enums';
|
||||||
import { $htmlCL } from 'Common/Globals';
|
import { $htmlCL } from 'Common/Globals';
|
||||||
import { pInt } from 'Common/Utils';
|
import { pInt } from 'Common/Utils';
|
||||||
import * as Events from 'Common/Events';
|
|
||||||
|
|
||||||
import * as Settings from 'Storage/Settings';
|
import * as Settings from 'Storage/Settings';
|
||||||
|
|
||||||
|
|
@ -48,7 +47,7 @@ class SettingsUserStore {
|
||||||
$htmlCL.toggle('rl-no-preview-pane', Layout.NoPreview === value);
|
$htmlCL.toggle('rl-no-preview-pane', Layout.NoPreview === value);
|
||||||
$htmlCL.toggle('rl-side-preview-pane', Layout.SidePreview === value);
|
$htmlCL.toggle('rl-side-preview-pane', Layout.SidePreview === value);
|
||||||
$htmlCL.toggle('rl-bottom-preview-pane', Layout.BottomPreview === value);
|
$htmlCL.toggle('rl-bottom-preview-pane', Layout.BottomPreview === value);
|
||||||
Events.pub('layout', [value]);
|
dispatchEvent(new CustomEvent('rl-layout', {detail:value}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,16 +64,16 @@ class SettingsUserStore {
|
||||||
this.useThreads(!!Settings.settingsGet('UseThreads'));
|
this.useThreads(!!Settings.settingsGet('UseThreads'));
|
||||||
this.replySameFolder(!!Settings.settingsGet('ReplySameFolder'));
|
this.replySameFolder(!!Settings.settingsGet('ReplySameFolder'));
|
||||||
|
|
||||||
Events.sub('rl.auto-logout-refresh', () => {
|
const refresh = () => {
|
||||||
clearTimeout(this.iAutoLogoutTimer);
|
clearTimeout(this.iAutoLogoutTimer);
|
||||||
if (0 < this.autoLogout() && !Settings.settingsGet('AccountSignMe')) {
|
if (0 < this.autoLogout() && !Settings.settingsGet('AccountSignMe')) {
|
||||||
this.iAutoLogoutTimer = setTimeout(() => {
|
this.iAutoLogoutTimer = setTimeout(() =>
|
||||||
Events.pub('rl.auto-logout');
|
dispatchEvent(new CustomEvent('rl.auto-logout'))
|
||||||
}, this.autoLogout() * 60000);
|
, this.autoLogout() * 60000);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
addEventListener('rl.auto-logout-refresh', refresh);
|
||||||
Events.pub('rl.auto-logout-refresh');
|
refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
@import "../../vendors/bootstrap/less/buttons.less";
|
@import "../../vendors/bootstrap/less/buttons.less";
|
||||||
@import "../../vendors/bootstrap/less/button-groups.less";
|
@import "../../vendors/bootstrap/less/button-groups.less";
|
||||||
|
@import "../../vendors/bootstrap/less/alerts.less";
|
||||||
|
|
||||||
@import "../../vendors/bootstrap/less/navs.less";
|
@import "../../vendors/bootstrap/less/navs.less";
|
||||||
|
|
||||||
|
|
@ -80,7 +81,5 @@
|
||||||
@import "SettingsThemes.less";
|
@import "SettingsThemes.less";
|
||||||
@import "SettingsFilters.less";
|
@import "SettingsFilters.less";
|
||||||
|
|
||||||
@import "Cmd.less";
|
|
||||||
|
|
||||||
@import "Animations.less";
|
@import "Animations.less";
|
||||||
@import "_End.less";
|
@import "_End.less";
|
||||||
|
|
|
||||||
|
|
@ -73,11 +73,13 @@ html {
|
||||||
|
|
||||||
html.rl-anim {
|
html.rl-anim {
|
||||||
|
|
||||||
.rl-animated-inited {
|
.b-login-content {
|
||||||
opacity: 1;
|
.alertError {
|
||||||
.transition(opacity 0.5s linear);
|
display: block;
|
||||||
|
opacity: 1;
|
||||||
&.rl-animated-hidden {
|
.transition(opacity 0.5s linear);
|
||||||
|
}
|
||||||
|
.alertError[hidden] {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
|
|
||||||
.rl-cmd {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: auto;
|
|
||||||
height: 0;
|
|
||||||
z-index: 10000;
|
|
||||||
|
|
||||||
background: rgba(0, 0, 0, .85);
|
|
||||||
border-top: 1px solid #000;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
font-family: monospace;
|
|
||||||
|
|
||||||
.transition(height 0.1s ease-out);
|
|
||||||
|
|
||||||
&.opened {
|
|
||||||
height: 250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rl-cmd-clr-error {
|
|
||||||
color: #CD3131;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rl-cmd-clr-info {
|
|
||||||
color: #BFBF00;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rl-cmd-clr-success {
|
|
||||||
color: #31FF40;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rl-cmd-wrp {
|
|
||||||
position: relative;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rl-cmd-input-helper {
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rl-cmd-input-prefix {
|
|
||||||
color: #31FF40;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rl-cmd-input-wrp {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 10px;
|
|
||||||
right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rl-cmd-input {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
color: white;
|
|
||||||
display: inline-block;
|
|
||||||
width: calc(~'100% - 30px');
|
|
||||||
font-family: monospace;
|
|
||||||
|
|
||||||
&:focus{
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.rl-cmd-history {
|
|
||||||
color: white;
|
|
||||||
font-family: monospace;
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
bottom: 60px;
|
|
||||||
left: 10px;
|
|
||||||
right: -30px;
|
|
||||||
overflow: hidden;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -649,20 +649,12 @@ html .messageItem {
|
||||||
.buttonUp, .buttonUp {
|
.buttonUp, .buttonUp {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
&.scroller-shadow-top .buttonUp {
|
|
||||||
display: inline-block !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html.rl-desktop .messageItem {
|
html.rl-desktop .messageItem {
|
||||||
.buttonUp, .buttonFull {
|
.buttonUp, .buttonFull {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
&:hover {
|
|
||||||
&.scroller-shadow-top .buttonUp, .buttonFull {
|
|
||||||
display: inline-block !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html.rl-message-fullscreen .messageItem {
|
html.rl-message-fullscreen .messageItem {
|
||||||
|
|
@ -675,7 +667,4 @@ html.rl-message-fullscreen .messageItem {
|
||||||
.buttonUp {
|
.buttonUp {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
&.scroller-shadow-top .buttonUp {
|
|
||||||
display: inline-block !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ import MessageStore from 'Stores/User/Message';
|
||||||
import Remote from 'Remote/User/Ajax';
|
import Remote from 'Remote/User/Ajax';
|
||||||
|
|
||||||
import * as Settings from 'Storage/Settings';
|
import * as Settings from 'Storage/Settings';
|
||||||
import * as Events from 'Common/Events';
|
|
||||||
|
|
||||||
import { ComposeAttachmentModel } from 'Model/ComposeAttachment';
|
import { ComposeAttachmentModel } from 'Model/ComposeAttachment';
|
||||||
|
|
||||||
|
|
@ -164,7 +163,9 @@ class ComposePopupView extends AbstractViewNext {
|
||||||
|
|
||||||
this.savedTime = ko.observable(0);
|
this.savedTime = ko.observable(0);
|
||||||
this.savedTimeText = ko.computed(() =>
|
this.savedTimeText = ko.computed(() =>
|
||||||
0 < this.savedTime() ? i18n('COMPOSE/SAVED_TIME', { 'TIME': momentorFormat(this.savedTime() - 1, 'LT') }) : ''
|
this.savedTime()
|
||||||
|
? i18n('COMPOSE/SAVED_TIME', { 'TIME': this.savedTime().format('LT') })
|
||||||
|
: ''
|
||||||
);
|
);
|
||||||
|
|
||||||
this.emptyToError = ko.observable(false);
|
this.emptyToError = ko.observable(false);
|
||||||
|
|
@ -300,7 +301,7 @@ class ComposePopupView extends AbstractViewNext {
|
||||||
this.sendMessageResponse = this.sendMessageResponse.bind(this);
|
this.sendMessageResponse = this.sendMessageResponse.bind(this);
|
||||||
this.saveMessageResponse = this.saveMessageResponse.bind(this);
|
this.saveMessageResponse = this.saveMessageResponse.bind(this);
|
||||||
|
|
||||||
Events.sub('interval.2m', () => {
|
setInterval(() => {
|
||||||
if (
|
if (
|
||||||
this.modalVisibility() &&
|
this.modalVisibility() &&
|
||||||
!FolderStore.draftFolderNotEnabled() &&
|
!FolderStore.draftFolderNotEnabled() &&
|
||||||
|
|
@ -312,7 +313,7 @@ class ComposePopupView extends AbstractViewNext {
|
||||||
) {
|
) {
|
||||||
this.saveCommand();
|
this.saveCommand();
|
||||||
}
|
}
|
||||||
});
|
}, 120000);
|
||||||
|
|
||||||
this.showCc.subscribe(this.resizerTrigger);
|
this.showCc.subscribe(this.resizerTrigger);
|
||||||
this.showBcc.subscribe(this.resizerTrigger);
|
this.showBcc.subscribe(this.resizerTrigger);
|
||||||
|
|
@ -326,7 +327,7 @@ class ComposePopupView extends AbstractViewNext {
|
||||||
// debounce
|
// debounce
|
||||||
var d, fn = this.tryToClosePopup.bind(this);
|
var d, fn = this.tryToClosePopup.bind(this);
|
||||||
this.tryToClosePopup = ()=>{
|
this.tryToClosePopup = ()=>{
|
||||||
d && clearTimeout(d);
|
clearTimeout(d);
|
||||||
d = setTimeout(fn, 200);
|
d = setTimeout(fn, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -667,7 +668,7 @@ class ComposePopupView extends AbstractViewNext {
|
||||||
this.draftFolder(oData.Result.NewFolder);
|
this.draftFolder(oData.Result.NewFolder);
|
||||||
this.draftUid(oData.Result.NewUid);
|
this.draftUid(oData.Result.NewUid);
|
||||||
|
|
||||||
this.savedTime(Math.round(new Date().getTime() / 1000));
|
this.savedTime(new Date);
|
||||||
|
|
||||||
if (this.bFromDraft) {
|
if (this.bFromDraft) {
|
||||||
setFolderHash(this.draftFolder(), '');
|
setFolderHash(this.draftFolder(), '');
|
||||||
|
|
@ -722,15 +723,9 @@ class ComposePopupView extends AbstractViewNext {
|
||||||
}
|
}
|
||||||
|
|
||||||
converSignature(signature) {
|
converSignature(signature) {
|
||||||
let limit = 10,
|
|
||||||
fromLine = '';
|
|
||||||
|
|
||||||
const moments = [],
|
|
||||||
momentRegx = /{{MOMENT:([^}]+)}}/g;
|
|
||||||
|
|
||||||
signature = signature.replace(/[\r]/g, '');
|
signature = signature.replace(/[\r]/g, '');
|
||||||
|
|
||||||
fromLine = this.oLastMessage ? this.emailArrayToStringLineHelper(this.oLastMessage.from, true) : '';
|
let fromLine = this.oLastMessage ? this.emailArrayToStringLineHelper(this.oLastMessage.from, true) : '';
|
||||||
if (fromLine) {
|
if (fromLine) {
|
||||||
signature = signature.replace(/{{FROM-FULL}}/g, fromLine);
|
signature = signature.replace(/{{FROM-FULL}}/g, fromLine);
|
||||||
|
|
||||||
|
|
@ -748,36 +743,14 @@ class ComposePopupView extends AbstractViewNext {
|
||||||
signature = signature.replace(/{{FROM-FULL}}/g, '');
|
signature = signature.replace(/{{FROM-FULL}}/g, '');
|
||||||
|
|
||||||
if (signature.includes('{{DATE}}')) {
|
if (signature.includes('{{DATE}}')) {
|
||||||
signature = signature.replace(/{{DATE}}/g, momentorFormat(0, 'llll'));
|
signature = signature.replace(/{{DATE}}/g, new Date().format('LLLL'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signature.includes('{{TIME}}')) {
|
if (signature.includes('{{TIME}}')) {
|
||||||
signature = signature.replace(/{{TIME}}/g, momentorFormat(0, 'LT'));
|
signature = signature.replace(/{{TIME}}/g, new Date().format('LT'));
|
||||||
}
|
}
|
||||||
if (signature.includes('{{MOMENT:')) {
|
|
||||||
try {
|
|
||||||
let match = null;
|
|
||||||
while (null !== (match = momentRegx.exec(signature))) {
|
|
||||||
// eslint-disable-line no-cond-assign
|
|
||||||
if (match && match[0] && match[1]) {
|
|
||||||
moments.push([match[0], match[1]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
limit -= 1;
|
signature = signature.replace(/{{MOMENT:[^}]+}}/g, '');
|
||||||
if (0 === limit) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moments) {
|
|
||||||
moments.forEach(data => {
|
|
||||||
signature = signature.replace(data[0], momentorFormat(0, data[1]));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
signature = signature.replace(/{{MOMENT:[^}]+}}/g, '');
|
|
||||||
} catch (e) {} // eslint-disable-line no-empty
|
|
||||||
}
|
|
||||||
|
|
||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
@ -1244,11 +1217,10 @@ class ComposePopupView extends AbstractViewNext {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.sub('window.resize.real', this.resizerTrigger);
|
|
||||||
var d, o = this;
|
var d, o = this;
|
||||||
Events.sub('window.resize.real', ()=>{
|
addEventListener('resize.real', ()=>{
|
||||||
// debounce
|
// debounce
|
||||||
d && clearTimeout(d);
|
clearTimeout(d);
|
||||||
d = setTimeout(o.resizerTrigger, 50);
|
d = setTimeout(o.resizerTrigger, 50);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ class FolderSystemPopupView extends AbstractViewNext {
|
||||||
},
|
},
|
||||||
fSaveSystemFolders = ()=>{
|
fSaveSystemFolders = ()=>{
|
||||||
// debounce
|
// debounce
|
||||||
d && clearTimeout(d);
|
clearTimeout(d);
|
||||||
d = setTimeout(()=>{
|
d = setTimeout(()=>{
|
||||||
fSetSystemFolders();
|
fSetSystemFolders();
|
||||||
Remote.saveSystemFolders(()=>{}, {
|
Remote.saveSystemFolders(()=>{}, {
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ class PluginPopupView extends AbstractViewNext {
|
||||||
var d, fn = this.tryToClosePopup.bind(this);
|
var d, fn = this.tryToClosePopup.bind(this);
|
||||||
this.tryToClosePopup = ()=>{
|
this.tryToClosePopup = ()=>{
|
||||||
// debounce
|
// debounce
|
||||||
d && clearTimeout(d);
|
clearTimeout(d);
|
||||||
d = setTimeout(fn, 200);
|
d = setTimeout(fn, 200);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import MessageStore from 'Stores/User/Message';
|
||||||
import { Capa, KeyState } from 'Common/Enums';
|
import { Capa, KeyState } from 'Common/Enums';
|
||||||
import { settings } from 'Common/Links';
|
import { settings } from 'Common/Links';
|
||||||
|
|
||||||
import * as Events from 'Common/Events';
|
|
||||||
import * as Settings from 'Storage/Settings';
|
import * as Settings from 'Storage/Settings';
|
||||||
|
|
||||||
import { getApp } from 'Helper/Apps/User';
|
import { getApp } from 'Helper/Apps/User';
|
||||||
|
|
@ -40,12 +39,12 @@ class AbstractSystemDropDownUserView extends AbstractViewNext {
|
||||||
|
|
||||||
this.addAccountClick = this.addAccountClick.bind(this);
|
this.addAccountClick = this.addAccountClick.bind(this);
|
||||||
|
|
||||||
Events.sub('audio.stop', () => AppStore.currentAudio(''));
|
addEventListener('audio.stop', () => AppStore.currentAudio(''));
|
||||||
Events.sub('audio.start', (name) => AppStore.currentAudio(name));
|
addEventListener('audio.start', e => AppStore.currentAudio(e.detail));
|
||||||
}
|
}
|
||||||
|
|
||||||
stopPlay() {
|
stopPlay() {
|
||||||
Events.pub('audio.api.stop');
|
dispatchEvent(new CustomEvent('audio.api.stop'));
|
||||||
}
|
}
|
||||||
|
|
||||||
accountClick(account, event) {
|
accountClick(account, event) {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ import { computedPagenatorHelper, draggablePlace, friendlySize } from 'Common/Ut
|
||||||
|
|
||||||
import { mailBox, append } from 'Common/Links';
|
import { mailBox, append } from 'Common/Links';
|
||||||
import { Selector } from 'Common/Selector';
|
import { Selector } from 'Common/Selector';
|
||||||
import * as Events from 'Common/Events';
|
|
||||||
|
|
||||||
import { i18n, initOnStartOrLangChange } from 'Common/Translator';
|
import { i18n, initOnStartOrLangChange } from 'Common/Translator';
|
||||||
|
|
||||||
|
|
@ -238,15 +237,17 @@ class MessageListMailBoxUserView extends AbstractViewNext {
|
||||||
this.goToUpUpOrDownDown(v);
|
this.goToUpUpOrDownDown(v);
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.sub('mailbox.message-list.selector.go-down', (select) => {
|
addEventListener('mailbox.message-list.selector.go-down', e => {
|
||||||
this.selector.goDown(select);
|
this.selector.goDown(e.detail);
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.sub('mailbox.message-list.selector.go-up', (select) => {
|
addEventListener('mailbox.message-list.selector.go-up', e => {
|
||||||
this.selector.goUp(select);
|
this.selector.goUp(e.detail);
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.sub('mailbox.message.show', (sFolder, sUid) => {
|
addEventListener('mailbox.message.show', e => {
|
||||||
|
const sFolder = e.detail.Folder, sUid = e.detail.Uid;
|
||||||
|
|
||||||
const message = this.messageList().find(
|
const message = this.messageList().find(
|
||||||
item => item && sFolder === item.folderFullNameRaw && sUid === item.uid
|
item => item && sFolder === item.folderFullNameRaw && sUid === item.uid
|
||||||
);
|
);
|
||||||
|
|
@ -781,7 +782,7 @@ class MessageListMailBoxUserView extends AbstractViewNext {
|
||||||
initShortcuts() {
|
initShortcuts() {
|
||||||
key('enter', KeyState.MessageList, () => {
|
key('enter', KeyState.MessageList, () => {
|
||||||
if (this.message() && this.useAutoSelect()) {
|
if (this.message() && this.useAutoSelect()) {
|
||||||
Events.pub('mailbox.message-view.toggle-full-screen');
|
dispatchEvent(new CustomEvent('mailbox.message-view.toggle-full-screen'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import {
|
||||||
} from 'Common/Utils';
|
} from 'Common/Utils';
|
||||||
|
|
||||||
import Audio from 'Common/Audio';
|
import Audio from 'Common/Audio';
|
||||||
import * as Events from 'Common/Events';
|
|
||||||
|
|
||||||
import { i18n } from 'Common/Translator';
|
import { i18n } from 'Common/Translator';
|
||||||
import { attachmentDownload } from 'Common/Links';
|
import { attachmentDownload } from 'Common/Links';
|
||||||
|
|
@ -328,7 +327,7 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
|
||||||
() => MessageStore.messageListCompleteLoadingThrottle() || MessageStore.messageLoadingThrottle()
|
() => MessageStore.messageListCompleteLoadingThrottle() || MessageStore.messageLoadingThrottle()
|
||||||
);
|
);
|
||||||
|
|
||||||
Events.sub('mailbox.message-view.toggle-full-screen', () => {
|
addEventListener('mailbox.message-view.toggle-full-screen', () => {
|
||||||
this.toggleFullScreen();
|
this.toggleFullScreen();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -350,12 +349,16 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
|
||||||
|
|
||||||
@command((self) => !self.messageListAndMessageViewLoading())
|
@command((self) => !self.messageListAndMessageViewLoading())
|
||||||
goUpCommand() {
|
goUpCommand() {
|
||||||
Events.pub('mailbox.message-list.selector.go-up', [Layout.NoPreview === this.layout() ? !!this.message() : true]);
|
dispatchEvent(new CustomEvent('mailbox.message-list.selector.go-up',
|
||||||
|
{detail:Layout.NoPreview === this.layout() ? !!this.message() : true}
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@command((self) => !self.messageListAndMessageViewLoading())
|
@command((self) => !self.messageListAndMessageViewLoading())
|
||||||
goDownCommand() {
|
goDownCommand() {
|
||||||
Events.pub('mailbox.message-list.selector.go-down', [Layout.NoPreview === this.layout() ? !!this.message() : true]);
|
dispatchEvent(new CustomEvent('mailbox.message-list.selector.go-up',
|
||||||
|
{detail:Layout.NoPreview === this.layout() ? !!this.message() : true}
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
detectDomBackgroundColor(dom) {
|
detectDomBackgroundColor(dom) {
|
||||||
|
|
@ -537,8 +540,8 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
|
||||||
this.message.subscribe(fCheckHeaderHeight);
|
this.message.subscribe(fCheckHeaderHeight);
|
||||||
|
|
||||||
var t;
|
var t;
|
||||||
Events.sub(
|
addEventListener(
|
||||||
'window.resize',
|
'resize',
|
||||||
()=>{
|
()=>{
|
||||||
// throttle
|
// throttle
|
||||||
if (!t) {
|
if (!t) {
|
||||||
|
|
|
||||||
2
dev/prototype-date.js
vendored
2
dev/prototype-date.js
vendored
|
|
@ -168,7 +168,7 @@
|
||||||
Date.prototype.fromNow = function() {
|
Date.prototype.fromNow = function() {
|
||||||
let format,
|
let format,
|
||||||
seconds = ((new Date()).getTime() - this.getTime()) / 1000,
|
seconds = ((new Date()).getTime() - this.getTime()) / 1000,
|
||||||
str = locale.relativeTime[0 < seconds ? 'future' : 'past'];
|
str = locale.relativeTime[0 < seconds ? 'past' : 'future'];
|
||||||
seconds = Math.abs(seconds);
|
seconds = Math.abs(seconds);
|
||||||
if (60 > seconds) {
|
if (60 > seconds) {
|
||||||
format = 's';
|
format = 's';
|
||||||
|
|
|
||||||
|
|
@ -2844,49 +2844,6 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack
|
||||||
return $iResult;
|
return $iResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws \MailSo\Base\Exceptions\Exception
|
|
||||||
*/
|
|
||||||
public function DoAccountsCounts() : array
|
|
||||||
{
|
|
||||||
$oAccount = $this->getAccountFromToken();
|
|
||||||
|
|
||||||
$bComplete = true;
|
|
||||||
$aCounts = array();
|
|
||||||
|
|
||||||
if ($this->GetCapa(false, false, Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount))
|
|
||||||
{
|
|
||||||
$iLimit = 7;
|
|
||||||
$aAccounts = $this->GetAccounts($oAccount);
|
|
||||||
if ($aAccounts)
|
|
||||||
{
|
|
||||||
if ($iLimit > \count($aAccounts))
|
|
||||||
{
|
|
||||||
$aAccounts = \array_slice($aAccounts, 0, $iLimit);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$bComplete = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($aAccounts as $sEmail => $sHash)
|
|
||||||
{
|
|
||||||
$aCounts[] = array(\MailSo\Base\Utils::IdnToUtf8($sEmail),
|
|
||||||
$oAccount->Email() === $sEmail ? 0 : $this->getAccountUnreadCountFromHash($sHash));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$aCounts[] = array(\MailSo\Base\Utils::IdnToUtf8($oAccount->Email()), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->DefaultResponse(__FUNCTION__, array(
|
|
||||||
'Complete' => $bComplete,
|
|
||||||
'Counts' => $aCounts
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ClearSignMeData(Model\Account $oAccount) : void
|
public function ClearSignMeData(Model\Account $oAccount) : void
|
||||||
{
|
{
|
||||||
if ($oAccount)
|
if ($oAccount)
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ nl_NL:
|
||||||
ATTACHMENTS_ERROR_DESC: "Waarschuwing! Nog niet alle bijlagen zijn klaar met uploaden"
|
ATTACHMENTS_ERROR_DESC: "Waarschuwing! Nog niet alle bijlagen zijn klaar met uploaden"
|
||||||
ATTACHMENTS_UPLOAD_ERROR_DESC: "Toevoegen van bijlage(n) is nog niet gereed"
|
ATTACHMENTS_UPLOAD_ERROR_DESC: "Toevoegen van bijlage(n) is nog niet gereed"
|
||||||
BUTTON_REQUEST_READ_RECEIPT: "Leesbevestiging vragen"
|
BUTTON_REQUEST_READ_RECEIPT: "Leesbevestiging vragen"
|
||||||
BUTTON_MARK_AS_IMPORTANT: "Marker als belangrijk"
|
BUTTON_MARK_AS_IMPORTANT: "Markeer als belangrijk"
|
||||||
BUTTON_OPEN_PGP: "OpenPGP (allen bij Platte Tekst)"
|
BUTTON_OPEN_PGP: "OpenPGP (allen bij Platte Tekst)"
|
||||||
BUTTON_REQUEST_DSN: "Ontvangstbevestiging vragen"
|
BUTTON_REQUEST_DSN: "Ontvangstbevestiging vragen"
|
||||||
POPUPS_WELCOME_PAGE:
|
POPUPS_WELCOME_PAGE:
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="b-content" data-bind="nano: true, scrollerShadows: true">
|
<div class="b-content">
|
||||||
<div class="content g-scrollbox" data-scroller-shadows-content>
|
<div class="content g-scrollbox">
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<div id="rl-settings-subscreen" class="b-settings-content" style="position: relative; z-index: 2"></div>
|
<div id="rl-settings-subscreen" class="b-settings-content" style="position: relative; z-index: 2"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<div class="rl-cmd" data-bind="css: {opened: opened}, click: function() { focused(true) }">
|
|
||||||
<div class="rl-cmd-wrp">
|
|
||||||
<div class="rl-cmd-history"><div class="rl-cmd-history-data"></div></div>
|
|
||||||
<div class="rl-cmd-input-wrp">
|
|
||||||
<div class="rl-cmd-input-helper" data-bind="text: cmdHelper"></div>
|
|
||||||
<div class="rl-cmd-input-prefix">#</div>
|
|
||||||
<input type="text" class="rl-cmd-input" data-bind="textInput: cmd, hasFocus: focused, onEnter: onEnter, onKeyDown: onKeyDown, onEsc: onEsc, onTab: onTab" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
<span class="desc" data-bind="text: loginDescription"></span>
|
<span class="desc" data-bind="text: loginDescription"></span>
|
||||||
</div>
|
</div>
|
||||||
{{INCLUDE/AfterLogo/PLACE}}
|
{{INCLUDE/AfterLogo/PLACE}}
|
||||||
<div class="alert alertError" data-bind="visibleAnimated: '' !== submitError()">
|
<div class="alert alertError" data-bind="visibleAnimated: '' !== submitError()" hidden="">
|
||||||
<button type="button" class="close" data-bind="click: function () { submitError('') }">×</button>
|
<button type="button" class="close" data-bind="click: function () { submitError('') }">×</button>
|
||||||
<span data-bind="text: submitError"></span>
|
<span data-bind="text: submitError"></span>
|
||||||
<div data-bind="visible: '' !== submitErrorAddidional()">
|
<div data-bind="visible: '' !== submitErrorAddidional()">
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
<i class="icon-address-book"></i>
|
<i class="icon-address-book"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="b-content opacity-on-panel-disabled" data-bind="visible: allowFolders, nano: true, scrollerShadows: true, css: {'inbox-is-starred': isInboxStarred}">
|
<div class="b-content opacity-on-panel-disabled" data-bind="visible: allowFolders, css: {'inbox-is-starred': isInboxStarred}">
|
||||||
<div class="content g-scrollbox" data-scroller-shadows-content>
|
<div class="content g-scrollbox">
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<div class="b-folders-system" data-bind="template: { name: 'MailFolderListSystemItem', foreach: folderListSystem }"></div>
|
<div class="b-folders-system" data-bind="template: { name: 'MailFolderListSystemItem', foreach: folderListSystem }"></div>
|
||||||
<hr class="b-list-delimiter" />
|
<hr class="b-list-delimiter" />
|
||||||
|
|
@ -36,4 +36,4 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -166,8 +166,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="line-loading e-strip-animation" data-bind="visible: messageListCompleteLoadingThrottle"></div>
|
<div class="line-loading e-strip-animation" data-bind="visible: messageListCompleteLoadingThrottle"></div>
|
||||||
<div class="mainDelimiter toolbarDelimiter"></div>
|
<div class="mainDelimiter toolbarDelimiter"></div>
|
||||||
<div class="b-content" data-bind="nano: true, scrollerShadows: true, initDom: dragOverBodyArea">
|
<div class="b-content" data-bind="initDom: dragOverBodyArea">
|
||||||
<div class="content g-scrollbox" data-scroller-shadows-content>
|
<div class="content g-scrollbox">
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<div class="listThreadUidDesc" data-bind="visible: '' !== messageListEndThreadUid(), click: cancelThreadUid">
|
<div class="listThreadUidDesc" data-bind="visible: '' !== messageListEndThreadUid(), click: cancelThreadUid">
|
||||||
<i class="icon-left" data-bind="click: cancelThreadUid"></i>
|
<i class="icon-left" data-bind="click: cancelThreadUid"></i>
|
||||||
|
|
@ -215,4 +215,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="dateParent actionHandle dragHandle">
|
<div class="dateParent actionHandle dragHandle">
|
||||||
<span class="date" data-moment-format="SHORT" data-moment-format-title="FULL" data-bind="moment: dateTimeStampInUTC"></span>
|
<time class="date" data-moment-format="SHORT" data-moment-format-title="FULL" data-bind="moment: dateTimeStampInUTC"></time>
|
||||||
</div>
|
</div>
|
||||||
<div class="threadsParent" data-bind="visible: 1 < threadsLen()">
|
<div class="threadsParent" data-bind="visible: 1 < threadsLen()">
|
||||||
<span class="threads-len">
|
<span class="threads-len">
|
||||||
|
|
@ -46,4 +46,4 @@
|
||||||
<span class="subject-prefix" data-bind="text: subjectPrefix"></span><span class="subject-suffix" data-bind="text: subjectSuffix"></span>
|
<span class="subject-prefix" data-bind="text: subjectPrefix"></span><span class="subject-suffix" data-bind="text: subjectSuffix"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<div class="delimiter"></div>
|
<div class="delimiter"></div>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="dateParent actionHandle dragHandle">
|
<div class="dateParent actionHandle dragHandle">
|
||||||
<span class="date" data-moment-format="SHORT" data-moment-format-title="FULL" data-bind="moment: dateTimeStampInUTC"></span>
|
<time class="date" data-moment-format="SHORT" data-moment-format-title="FULL" data-bind="moment: dateTimeStampInUTC"></time>
|
||||||
</div>
|
</div>
|
||||||
<div class="threadsParent" data-bind="visible: 1 < threadsLen()">
|
<div class="threadsParent" data-bind="visible: 1 < threadsLen()">
|
||||||
<span class="threads-len">
|
<span class="threads-len">
|
||||||
|
|
@ -47,4 +47,4 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,7 @@
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span data-bind="visible: 0 < viewTimeStamp()">
|
<span data-bind="visible: 0 < viewTimeStamp()">
|
||||||
(<span class="date" data-moment-format="FULL" data-bind="moment: viewTimeStamp"></span>)
|
(<time class="date" data-moment-format="FULL" data-bind="moment: viewTimeStamp"></time>)
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="informationShortWrp">
|
<div class="informationShortWrp">
|
||||||
|
|
@ -296,17 +296,17 @@
|
||||||
<tr data-bind="visible: 0 < viewTimeStamp()">
|
<tr data-bind="visible: 0 < viewTimeStamp()">
|
||||||
<td><span class="i18n uiLabel" data-i18n="MESSAGE/LABEL_DATE"></span></td>
|
<td><span class="i18n uiLabel" data-i18n="MESSAGE/LABEL_DATE"></span></td>
|
||||||
<td>
|
<td>
|
||||||
<span class="date uiLabelValue" data-moment-format="FULL" data-bind="moment: viewTimeStamp"></span>
|
<time class="date uiLabelValue" data-moment-format="FULL" data-bind="moment: viewTimeStamp"></time>
|
||||||
|
|
||||||
(<span class="date uiLabelValue" data-moment-format="FROMNOW" data-bind="moment: viewTimeStamp"></span>)
|
(<time class="date uiLabelValue" data-moment-format="FROMNOW" data-bind="moment: viewTimeStamp"></time>)
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="messageItem fixIndex" data-bind="css: viewLineAsCss(), nano: true, scrollerShadows: true, attr: {'style': 'top:' + viewBodyTopValue() + 'px' }">
|
<div class="messageItem fixIndex" data-bind="css: viewLineAsCss(), attr: {'style': 'top:' + viewBodyTopValue() + 'px' }">
|
||||||
<div class="content g-scrollbox" tabindex="0" data-scroller-shadows-content data-bind="hasfocus: messageDomFocused, css: { 'focused': messageDomFocused },
|
<div class="content g-scrollbox" tabindex="0" data-bind="hasfocus: messageDomFocused, css: { 'focused': messageDomFocused },
|
||||||
style: {'background-color': messageLoadingThrottle() ? '' : bodyBackgroundColor()}">
|
style: {'background-color': messageLoadingThrottle() ? '' : bodyBackgroundColor()}">
|
||||||
|
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
|
|
|
||||||
|
|
@ -185,8 +185,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="attachmentAreaParent b-content" style="height: 200px; min-height: 200px" data-bind="nano: true, scrollerShadows: true, visible: attachmentsPlace, initResizeTrigger: [resizer(), 200, 57]">
|
<div class="attachmentAreaParent b-content" style="height: 200px; min-height: 200px" data-bind="visible: attachmentsPlace, initResizeTrigger: [resizer(), 200, 57]">
|
||||||
<div class="content g-scrollbox" data-scroller-shadows-content>
|
<div class="content g-scrollbox">
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<div class="b-attachment-place" data-bind="visible: addAttachmentEnabled() && dragAndDropEnabled() && dragAndDropVisible(), initDom: composeUploaderDropPlace, css: {'dragAndDropOver': dragAndDropOver}">
|
<div class="b-attachment-place" data-bind="visible: addAttachmentEnabled() && dragAndDropEnabled() && dragAndDropVisible(), initDom: composeUploaderDropPlace, css: {'dragAndDropOver': dragAndDropOver}">
|
||||||
<span class="i18n" data-i18n="COMPOSE/ATTACH_DROP_FILES_DESC"></span>
|
<span class="i18n" data-i18n="COMPOSE/ATTACH_DROP_FILES_DESC"></span>
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,8 @@
|
||||||
<div class="b-list-toolbar">
|
<div class="b-list-toolbar">
|
||||||
<input type="text" class="i18n span3 e-search" placeholder="Search" autocorrect="off" autocapitalize="off" data-i18n="[placeholder]CONTACTS/SEARCH_INPUT_PLACEHOLDER" data-bind="value: search" />
|
<input type="text" class="i18n span3 e-search" placeholder="Search" autocorrect="off" autocapitalize="off" data-i18n="[placeholder]CONTACTS/SEARCH_INPUT_PLACEHOLDER" data-bind="value: search" />
|
||||||
</div>
|
</div>
|
||||||
<div class="b-list-content g-ui-user-select-none" data-bind="nano: true, scrollerShadows: true, css: {'hideContactListCheckbox': !useCheckboxesInList()}">
|
<div class="b-list-content g-ui-user-select-none" data-bind="css: {'hideContactListCheckbox': !useCheckboxesInList()}">
|
||||||
<div class="content g-scrollbox" data-scroller-shadows-content>
|
<div class="content g-scrollbox">
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<div class="listClear" data-bind="visible: viewClearSearch() && '' !== search()">
|
<div class="listClear" data-bind="visible: viewClearSearch() && '' !== search()">
|
||||||
<span class="g-ui-link i18n" data-i18n="CONTACTS/CLEAR_SEARCH" data-bind="command: clearCommand"></span>
|
<span class="g-ui-link i18n" data-i18n="CONTACTS/CLEAR_SEARCH" data-bind="command: clearCommand"></span>
|
||||||
|
|
@ -167,8 +167,8 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="b-view-content" data-bind="nano: true, scrollerShadows: true, css: {'read-only': viewReadOnly}">
|
<div class="b-view-content" data-bind="css: {'read-only': viewReadOnly}">
|
||||||
<div class="content g-scrollbox" data-scroller-shadows-content>
|
<div class="content g-scrollbox">
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<div class="b-contact-view-desc" data-bind="visible: emptySelection">
|
<div class="b-contact-view-desc" data-bind="visible: emptySelection">
|
||||||
<span class="i18n" data-i18n="CONTACTS/CONTACT_VIEW_DESC"></span>
|
<span class="i18n" data-i18n="CONTACTS/CONTACT_VIEW_DESC"></span>
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--<div data-bind="json: $data"></div>-->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="b-content" data-bind="nano: true, scrollerShadows: true">
|
<div class="b-content">
|
||||||
<div class="content g-scrollbox" data-scroller-shadows-content>
|
<div class="content g-scrollbox">
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<div id="rl-settings-subscreen" class="b-settings-content" style="position: relative; z-index: 2"></div>
|
<div id="rl-settings-subscreen" class="b-settings-content" style="position: relative; z-index: 2"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue