Add cmd interface

Code refactoring
This commit is contained in:
RainLoop Team 2016-08-24 01:17:50 +03:00
parent e6e1a19477
commit 962391e2a0
23 changed files with 180 additions and 223 deletions

View file

@ -90,7 +90,7 @@ module.exports = {
'no-lone-blocks': 2, 'no-lone-blocks': 2,
'no-loop-func': 2, 'no-loop-func': 2,
// 'no-magic-numbers': [2, { // 'no-magic-numbers': [2, {
// 'ignore': [-1, 0, 1], // 'ignore': [-1, 0, 1, 2],
// 'ignoreArrayIndexes': true // 'ignoreArrayIndexes': true
// }], // }],
'no-multi-spaces': 2, 'no-multi-spaces': 2,

View file

@ -15,12 +15,12 @@ import {
detectDropdownVisibility, windowResizeCallback detectDropdownVisibility, windowResizeCallback
} from 'Common/Utils'; } from 'Common/Utils';
import {KeyState} from 'Common/Enums'; import {KeyState, Magics} from 'Common/Enums';
import * as Links from 'Common/Links'; import {root, rootAdmin, rootUser, populateAuthSuffix} from 'Common/Links';
import * as Settings from 'Storage/Settings';
import * as Events from 'Common/Events';
import {initOnStartOrLangChange, initNotificationLanguage} from 'Common/Translator'; import {initOnStartOrLangChange, initNotificationLanguage} from 'Common/Translator';
import {toggle as toggleCmd} from 'Common/Cmd'; import {toggle as toggleCmd} from 'Common/Cmd';
import * as Events from 'Common/Events';
import * as Settings from 'Storage/Settings';
import {routeOff, setHash} from 'Knoin/Knoin'; import {routeOff, setHash} from 'Knoin/Knoin';
import {AbstractBoot} from 'Knoin/AbstractBoot'; import {AbstractBoot} from 'Knoin/AbstractBoot';
@ -83,7 +83,7 @@ class AbstractApp extends AbstractBoot
Events.pub('window.resize.real'); Events.pub('window.resize.real');
} }
}, 50)); }, Magics.Time50ms));
// DEBUG // DEBUG
// Events.sub({ // Events.sub({
@ -109,7 +109,7 @@ class AbstractApp extends AbstractBoot
$doc.on('mousemove keypress click', _.debounce(() => { $doc.on('mousemove keypress click', _.debounce(() => {
Events.pub('rl.auto-logout-refresh'); Events.pub('rl.auto-logout-refresh');
}, 5000)); }, Magics.Time5s));
key('esc, enter', KeyState.All, () => { key('esc, enter', KeyState.All, () => {
detectDropdownVisibility(); detectDropdownVisibility();
@ -201,8 +201,8 @@ class AbstractApp extends AbstractBoot
redirectToAdminPanel() { redirectToAdminPanel() {
_.delay(() => { _.delay(() => {
window.location.href = Links.rootAdmin(); window.location.href = rootAdmin();
}, 100); }, Magics.Time100ms);
} }
clearClientSideToken() { clearClientSideToken() {
@ -220,8 +220,8 @@ class AbstractApp extends AbstractBoot
{ {
window.__rlah_set(token); window.__rlah_set(token);
require('Storage/Settings').settingsSet('AuthAccountHash', token); Settings.settingsSet('AuthAccountHash', token);
require('Common/Links').populateAuthSuffix(); populateAuthSuffix();
} }
} }
@ -245,7 +245,7 @@ class AbstractApp extends AbstractBoot
window.close(); window.close();
} }
customLogoutLink = customLogoutLink || (admin ? Links.rootAdmin() : Links.rootUser()); customLogoutLink = customLogoutLink || (admin ? rootAdmin() : rootUser());
if (logout && window.location.href !== customLogoutLink) if (logout && window.location.href !== customLogoutLink)
{ {
@ -258,12 +258,12 @@ class AbstractApp extends AbstractBoot
{ {
window.location.href = customLogoutLink; window.location.href = customLogoutLink;
} }
}, 100); }, Magics.Time100ms);
} }
else else
{ {
routeOff(); routeOff();
setHash(Links.root(), true); setHash(root(), true);
routeOff(); routeOff();
_.delay(() => { _.delay(() => {
@ -275,7 +275,7 @@ class AbstractApp extends AbstractBoot
{ {
window.location.reload(); window.location.reload();
} }
}, 100); }, Magics.Time100ms);
} }
} }
@ -319,7 +319,7 @@ class AbstractApp extends AbstractBoot
initOnStartOrLangChange(initNotificationLanguage); initOnStartOrLangChange(initNotificationLanguage);
_.delay(windowResizeCallback, 1000); _.delay(windowResizeCallback, Magics.Time1s);
Events.sub('ssm.mobile-enter', () => { Events.sub('ssm.mobile-enter', () => {
leftPanelDisabled(true); leftPanelDisabled(true);
@ -347,10 +347,10 @@ class AbstractApp extends AbstractBoot
ssm.addState({ ssm.addState({
id: 'tablet', id: 'tablet',
query: '(min-width: 768px) and (max-width: 999px)', query: '(min-width: 768px) and (max-width: 999px)',
onEnter: function() { onEnter: () => {
$html.addClass('ssm-state-tablet'); $html.addClass('ssm-state-tablet');
}, },
onLeave: function() { onLeave: () => {
$html.removeClass('ssm-state-tablet'); $html.removeClass('ssm-state-tablet');
} }
}); });

View file

@ -12,7 +12,7 @@ import {
import { import {
Layout, Capa, StorageResultType, Notification, FolderType, Layout, Capa, StorageResultType, Notification, FolderType,
SetSystemFoldersNotification, MessageSetAction, ClientSideKeyName SetSystemFoldersNotification, MessageSetAction, ClientSideKeyName, Magics
} from 'Common/Enums'; } from 'Common/Enums';
import { import {
@ -51,6 +51,7 @@ import FolderStore from 'Stores/User/Folder';
import PgpStore from 'Stores/User/Pgp'; import PgpStore from 'Stores/User/Pgp';
import MessageStore from 'Stores/User/Message'; import MessageStore from 'Stores/User/Message';
import ContactStore from 'Stores/User/Contact'; import ContactStore from 'Stores/User/Contact';
import QuotaStore from 'Stores/User/Quota';
import * as Local from 'Storage/Client'; import * as Local from 'Storage/Client';
import * as Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
@ -84,23 +85,23 @@ class AppUser extends AbstractApp
this.moveCache = {}; this.moveCache = {};
this.quotaDebounce = _.debounce(this.quota, 1000 * 30); this.quotaDebounce = _.debounce(this.quota, Magics.Time30s);
this.moveOrDeleteResponseHelper = _.bind(this.moveOrDeleteResponseHelper, this); this.moveOrDeleteResponseHelper = _.bind(this.moveOrDeleteResponseHelper, this);
this.messagesMoveTrigger = _.debounce(this.messagesMoveTrigger, 500); this.messagesMoveTrigger = _.debounce(this.messagesMoveTrigger, 500);
window.setInterval(() => Events.pub('interval.30s'), 30000); window.setInterval(() => Events.pub('interval.30s'), Magics.Time30s);
window.setInterval(() => Events.pub('interval.1m'), 60000); window.setInterval(() => Events.pub('interval.1m'), Magics.Time1m);
window.setInterval(() => Events.pub('interval.2m'), 60000 * 2); window.setInterval(() => Events.pub('interval.2m'), Magics.Time2m);
window.setInterval(() => Events.pub('interval.3m'), 60000 * 3); window.setInterval(() => Events.pub('interval.3m'), Magics.Time3m);
window.setInterval(() => Events.pub('interval.5m'), 60000 * 5); window.setInterval(() => Events.pub('interval.5m'), Magics.Time5m);
window.setInterval(() => Events.pub('interval.10m'), 60000 * 10); window.setInterval(() => Events.pub('interval.10m'), Magics.Time10m);
window.setInterval(() => Events.pub('interval.15m'), 60000 * 15); window.setInterval(() => Events.pub('interval.15m'), Magics.Time15m);
window.setInterval(() => Events.pub('interval.20m'), 60000 * 15); window.setInterval(() => Events.pub('interval.20m'), Magics.Time20m);
window.setTimeout(() => window.setInterval(() => Events.pub('interval.2m-after5m'), 60000 * 2), 60000 * 5); window.setTimeout(() => window.setInterval(() => Events.pub('interval.2m-after5m'), Magics.Time2m), Magics.Time5m);
window.setTimeout(() => window.setInterval(() => Events.pub('interval.5m-after5m'), 60000 * 5), 60000 * 5); window.setTimeout(() => window.setInterval(() => Events.pub('interval.5m-after5m'), Magics.Time5m), Magics.Time5m);
window.setTimeout(() => window.setInterval(() => Events.pub('interval.10m-after5m'), 60000 * 10), 60000 * 5); window.setTimeout(() => window.setInterval(() => Events.pub('interval.10m-after5m'), Magics.Time10m), Magics.Time5m);
$.wakeUp(() => { $.wakeUp(() => {
if (checkTimestamp()) if (checkTimestamp())
@ -115,7 +116,7 @@ class AppUser extends AbstractApp
} }
}, Settings.appSettingsGet('version')); }, Settings.appSettingsGet('version'));
}, {}, 60 * 60 * 1000); }, {}, Magics.Time60m);
if (checkTimestamp()) if (checkTimestamp())
{ {
@ -128,12 +129,12 @@ class AppUser extends AbstractApp
$('#rl-bg') $('#rl-bg')
.attr('style', 'background-image: none !important;') .attr('style', 'background-image: none !important;')
.backstretch(userBackground(Settings.settingsGet('UserBackgroundHash')), { .backstretch(userBackground(Settings.settingsGet('UserBackgroundHash')), {
fade: bAnimationSupported ? 1000 : 0, fade: bAnimationSupported ? Magics.Time1s : 0,
centeredX: true, centeredX: true,
centeredY: true centeredY: true
}) })
.removeAttr('style'); .removeAttr('style');
}, 1000); }, Magics.Time1s);
} }
this.socialUsers = _.bind(this.socialUsers, this); this.socialUsers = _.bind(this.socialUsers, this);
@ -447,7 +448,6 @@ class AppUser extends AbstractApp
} }
foldersPromisesActionHelper(promise, errorDefCode) { foldersPromisesActionHelper(promise, errorDefCode) {
Promises Promises
.abort('Folders') .abort('Folders')
.fastResolve(true) .fastResolve(true)
@ -563,23 +563,23 @@ class AppUser extends AbstractApp
if (StorageResultType.Success === sResult && oData.Result) if (StorageResultType.Success === sResult && oData.Result)
{ {
const const
aCounts = {}, counts = {},
sAccountEmail = AccountStore.email(); sAccountEmail = AccountStore.email();
let let
sParentEmail = Settings.settingsGet('ParentEmail'); parentEmail = Settings.settingsGet('ParentEmail');
sParentEmail = '' === sParentEmail ? sAccountEmail : sParentEmail; parentEmail = '' === parentEmail ? sAccountEmail : parentEmail;
if (isArray(oData.Result.Accounts)) if (isArray(oData.Result.Accounts))
{ {
_.each(AccountStore.accounts(), (oAccount) => { _.each(AccountStore.accounts(), (oAccount) => {
aCounts[oAccount.email] = oAccount.count(); counts[oAccount.email] = oAccount.count();
}); });
delegateRunOnDestroy(AccountStore.accounts()); delegateRunOnDestroy(AccountStore.accounts());
AccountStore.accounts(_.map(oData.Result.Accounts, AccountStore.accounts(_.map(oData.Result.Accounts,
(sValue) => new AccountModel(sValue, sValue !== sParentEmail, aCounts[sValue] || 0))); (sValue) => new AccountModel(sValue, sValue !== parentEmail, counts[sValue] || 0)));
} }
if (isUnd(bBoot) ? false : !!bBoot) if (isUnd(bBoot) ? false : !!bBoot)
@ -592,20 +592,20 @@ class AppUser extends AbstractApp
{ {
delegateRunOnDestroy(IdentityStore.identities()); delegateRunOnDestroy(IdentityStore.identities());
IdentityStore.identities(_.map(oData.Result.Identities, (oIdentityData) => { IdentityStore.identities(_.map(oData.Result.Identities, (identityData) => {
const const
sId = pString(oIdentityData.Id), id = pString(identityData.Id),
sEmail = pString(oIdentityData.Email), email = pString(identityData.Email),
oIdentity = new IdentityModel(sId, sEmail); identity = new IdentityModel(id, email);
oIdentity.name(pString(oIdentityData.Name)); identity.name(pString(identityData.Name));
oIdentity.replyTo(pString(oIdentityData.ReplyTo)); identity.replyTo(pString(identityData.ReplyTo));
oIdentity.bcc(pString(oIdentityData.Bcc)); identity.bcc(pString(identityData.Bcc));
oIdentity.signature(pString(oIdentityData.Signature)); identity.signature(pString(identityData.Signature));
oIdentity.signatureInsertBefore(!!oIdentityData.SignatureInsertBefore); identity.signatureInsertBefore(!!identityData.SignatureInsertBefore);
return oIdentity; return identity;
})); }));
} }
} }
@ -639,8 +639,7 @@ class AppUser extends AbstractApp
isArray(data.Result) && 1 < data.Result.length && isArray(data.Result) && 1 < data.Result.length &&
isPosNumeric(data.Result[0], true) && isPosNumeric(data.Result[1], true)) isPosNumeric(data.Result[0], true) && isPosNumeric(data.Result[1], true))
{ {
require('Stores/User/Quota').populateData( QuotaStore.populateData(pInt(data.Result[1]), pInt(data.Result[0]));
pInt(data.Result[1]), pInt(data.Result[0]));
} }
}); });
} }
@ -747,11 +746,11 @@ class AppUser extends AbstractApp
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 = momentNowUnix();
_.each(oData.Result.List, (oItem) => { _.each(oData.Result.List, (item) => {
const const
hash = getFolderHash(oItem.Folder), hash = getFolderHash(item.Folder),
folder = getFolderFromCacheList(oItem.Folder); folder = getFolderFromCacheList(item.Folder);
let let
unreadCountChange = false; unreadCountChange = false;
@ -759,24 +758,24 @@ class AppUser extends AbstractApp
{ {
folder.interval = utc; folder.interval = utc;
if (oItem.Hash) if (item.Hash)
{ {
setFolderHash(oItem.Folder, oItem.Hash); setFolderHash(item.Folder, item.Hash);
} }
if (isNormal(oItem.MessageCount)) if (isNormal(item.MessageCount))
{ {
folder.messageCountAll(oItem.MessageCount); folder.messageCountAll(item.MessageCount);
} }
if (isNormal(oItem.MessageUnseenCount)) if (isNormal(item.MessageUnseenCount))
{ {
if (pInt(folder.messageCountUnread()) !== pInt(oItem.MessageUnseenCount)) if (pInt(folder.messageCountUnread()) !== pInt(item.MessageUnseenCount))
{ {
unreadCountChange = true; unreadCountChange = true;
} }
folder.messageCountUnread(oItem.MessageUnseenCount); folder.messageCountUnread(item.MessageUnseenCount);
} }
if (unreadCountChange) if (unreadCountChange)
@ -784,7 +783,7 @@ class AppUser extends AbstractApp
clearMessageFlagsFromCacheByFolder(folder.fullNameRaw); clearMessageFlagsFromCacheByFolder(folder.fullNameRaw);
} }
if (oItem.Hash !== hash || '' === hash) if (item.Hash !== hash || '' === hash)
{ {
if (folder.fullNameRaw === FolderStore.currentFolderFullNameRaw()) if (folder.fullNameRaw === FolderStore.currentFolderFullNameRaw())
{ {
@ -795,10 +794,10 @@ class AppUser extends AbstractApp
{ {
if (folder.fullNameRaw === FolderStore.currentFolderFullNameRaw()) if (folder.fullNameRaw === FolderStore.currentFolderFullNameRaw())
{ {
const aList = MessageStore.messageList(); const list = MessageStore.messageList();
if (isNonEmptyArray(aList)) if (isNonEmptyArray(list))
{ {
this.folderInformation(folder.fullNameRaw, aList); this.folderInformation(folder.fullNameRaw, list);
} }
} }
} }
@ -998,8 +997,8 @@ class AppUser extends AbstractApp
initHorizontalLayoutResizer(sClientSideKeyName) { initHorizontalLayoutResizer(sClientSideKeyName) {
let let
oTop = null, top = null,
oBottom = null; bottom = null;
const const
minHeight = 200, minHeight = 200,
@ -1007,14 +1006,14 @@ class AppUser extends AbstractApp
fSetHeight = (height) => { fSetHeight = (height) => {
if (height) if (height)
{ {
if (oTop) if (top)
{ {
oTop.attr('style', 'height:' + height + 'px'); top.attr('style', 'height:' + height + 'px');
} }
if (oBottom) if (bottom)
{ {
oBottom.attr('style', 'top:' + (55 /* top toolbar */ + height) + 'px'); bottom.attr('style', 'top:' + (55 /* top toolbar */ + height) + 'px');
} }
} }
}, },
@ -1066,26 +1065,26 @@ class AppUser extends AbstractApp
fDisable = (bDisable) => { fDisable = (bDisable) => {
if (bDisable) if (bDisable)
{ {
if (oTop && oTop.hasClass('ui-resizable')) if (top && top.hasClass('ui-resizable'))
{ {
oTop top
.resizable('destroy') .resizable('destroy')
.removeAttr('style'); .removeAttr('style');
} }
if (oBottom) if (bottom)
{ {
oBottom.removeAttr('style'); bottom.removeAttr('style');
} }
} }
else if ($html.hasClass('rl-bottom-preview-pane')) else if ($html.hasClass('rl-bottom-preview-pane'))
{ {
oTop = $('.b-message-list-wrapper'); top = $('.b-message-list-wrapper');
oBottom = $('.b-message-view-wrapper'); bottom = $('.b-message-view-wrapper');
if (!oTop.hasClass('ui-resizable')) if (!top.hasClass('ui-resizable'))
{ {
oTop.resizable(oOptions); top.resizable(oOptions);
} }
const iHeight = pInt(Local.get(sClientSideKeyName)) || 300; const iHeight = pInt(Local.get(sClientSideKeyName)) || 300;
@ -1141,10 +1140,10 @@ class AppUser extends AbstractApp
} }
}, },
fResizeCreateFunction = (oEvent) => { fResizeCreateFunction = (event) => {
if (oEvent && oEvent.target) if (event && event.target)
{ {
$(oEvent.target).find('.ui-resizable-handle') $(event.target).find('.ui-resizable-handle')
.on('mousedown', () => { .on('mousedown', () => {
$html.addClass('rl-resizer'); $html.addClass('rl-resizer');
}) })
@ -1159,16 +1158,16 @@ class AppUser extends AbstractApp
fResizeStartFunction = () => { fResizeStartFunction = () => {
$html.addClass('rl-resizer'); $html.addClass('rl-resizer');
}, },
fResizeStopFunction = (oEvent, oObject) => { fResizeStopFunction = (event, obj) => {
$html.removeClass('rl-resizer'); $html.removeClass('rl-resizer');
if (oObject && oObject.size && oObject.size.width) if (obj && obj.size && obj.size.width)
{ {
Local.set(sClientSideKeyName, oObject.size.width); Local.set(sClientSideKeyName, obj.size.width);
leftPanelWidth(oObject.size.width); leftPanelWidth(obj.size.width);
right.css({ right.css({
left: '' + oObject.size.width + 'px' left: '' + obj.size.width + 'px'
}); });
lLeft.css({ lLeft.css({
@ -1188,7 +1187,7 @@ class AppUser extends AbstractApp
lLeft.resizable({ lLeft.resizable({
helper: 'ui-resizable-helper-w', helper: 'ui-resizable-helper-w',
minWidth: minWidth, minWidth: minWidth,
maxWidth: 350, maxWidth: Magics.Size350px,
handles: 'e', handles: 'e',
create: fResizeCreateFunction, create: fResizeCreateFunction,
resize: fResizeResizeFunction, resize: fResizeResizeFunction,
@ -1386,8 +1385,8 @@ class AppUser extends AbstractApp
contactsSyncInterval = 5 <= contactsSyncInterval ? contactsSyncInterval : 20; contactsSyncInterval = 5 <= contactsSyncInterval ? contactsSyncInterval : 20;
contactsSyncInterval = 320 >= contactsSyncInterval ? contactsSyncInterval : 320; contactsSyncInterval = 320 >= contactsSyncInterval ? contactsSyncInterval : 320;
_.delay(() => this.contactsSync(), 10000); _.delay(() => this.contactsSync(), Magics.Time10s);
_.delay(() => this.folderInformationMultiply(true), 2000); _.delay(() => this.folderInformationMultiply(true), Magics.Time2s);
window.setInterval(() => this.contactsSync(), contactsSyncInterval * 60000 + 5000); window.setInterval(() => this.contactsSync(), contactsSyncInterval * 60000 + 5000);

View file

@ -424,12 +424,24 @@ export const Magics = {
'BitLength2048': 2048, 'BitLength2048': 2048,
'BitLength1024': 1024, 'BitLength1024': 1024,
'Size350px': 350,
'Size50px': 50, 'Size50px': 50,
'Size20px': 20, 'Size20px': 20,
'Size1px': 1, 'Size1px': 1,
'Time30mInMin': 30,
'Time60m': 60000 * 60,
'Time30m': 60000 * 30,
'Time20m': 60000 * 20,
'Time15m': 60000 * 15,
'Time10m': 60000 * 10,
'Time5m': 60000 * 5,
'Time3m': 60000 * 3,
'Time2m': 60000 * 2,
'Time1m': 60000, 'Time1m': 60000,
'Time30s': 30000, 'Time30s': 30000,
'Time10s': 10000,
'Time7s': 7000, 'Time7s': 7000,
'Time5s': 5000, 'Time5s': 5000,
'Time3s': 3000, 'Time3s': 3000,
@ -440,7 +452,9 @@ export const Magics = {
'Time200ms': 200, 'Time200ms': 200,
'Time100ms': 100, 'Time100ms': 100,
'Time50ms': 50, 'Time50ms': 50,
'Time20ms': 20 'Time20ms': 20,
'Time10ms': 10,
'Time1ms': 1
}; };
/** /**

View file

@ -76,33 +76,8 @@ class Selector
}, this); }, this);
this.selectedItem = this.selectedItem.extend({toggleSubscribe: [null, this.selectedItem = this.selectedItem.extend({toggleSubscribeProperty: [this, 'selected']});
(prev) => { this.focusedItem = this.focusedItem.extend({toggleSubscribeProperty: [null, 'focused']});
if (prev)
{
prev.selected(false);
}
}, (next) => {
if (next)
{
next.selected(true);
}
}
]});
this.focusedItem = this.focusedItem.extend({toggleSubscribe: [null,
(prev) => {
if (prev)
{
prev.focused(false);
}
}, (next) => {
if (next)
{
next.focused(true);
}
}
]});
this.iSelectNextHelper = 0; this.iSelectNextHelper = 0;
this.iFocusedNextHelper = 0; this.iFocusedNextHelper = 0;

17
dev/External/ko.js vendored
View file

@ -1195,22 +1195,7 @@ ko.observable.fn.validateSimpleEmail = function() {
}; };
ko.observable.fn.deleteAccessHelper = function() { ko.observable.fn.deleteAccessHelper = function() {
this.extend({falseTimeout: 3000}).extend({toggleSubscribe: [ this.extend({falseTimeout: 3000}).extend({toggleSubscribeProperty: [this, 'deleteAccess']});
null,
(prev) => {
if (prev && prev.deleteAccess)
{
prev.deleteAccess(false);
}
},
(next) => {
if (next && next.deleteAccess)
{
next.deleteAccess(true);
}
}
]});
return this; return this;
}; };

View file

@ -4,16 +4,18 @@
import _ from '_'; import _ from '_';
import ko from 'ko'; import ko from 'ko';
import {settingsSaveHelperSimpleFunction, trim} from 'Common/Utils'; import {Magics} from 'Common/Enums';
import {settingsSaveHelperSimpleFunction, trim, log} from 'Common/Utils';
import {i18n, trigger as translatorTrigger} from 'Common/Translator'; import {i18n, trigger as translatorTrigger} from 'Common/Translator';
import Remote from 'Remote/Admin/Ajax';
import AppStore from 'Stores/Admin/App';
import {settingsGet} from 'Storage/Settings'; import {settingsGet} from 'Storage/Settings';
class BrandingAdminSettings class BrandingAdminSettings
{ {
constructor() { constructor() {
const AppStore = require('Stores/Admin/App');
this.capa = AppStore.prem; this.capa = AppStore.prem;
this.title = ko.observable(settingsGet('Title')).idleTrigger(); this.title = ko.observable(settingsGet('Title')).idleTrigger();
@ -33,9 +35,9 @@ class BrandingAdminSettings
this.welcomePageDisplay.options = ko.computed(() => { this.welcomePageDisplay.options = ko.computed(() => {
translatorTrigger(); translatorTrigger();
return [ return [
{'optValue': 'none', 'optText': i18n('TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_NONE')}, {optValue: 'none', optText: i18n('TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_NONE')},
{'optValue': 'once', 'optText': i18n('TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_ONCE')}, {optValue: 'once', optText: i18n('TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_ONCE')},
{'optValue': 'always', 'optText': i18n('TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_ALWAYS')} {optValue: 'always', optText: i18n('TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_ALWAYS')}
]; ];
}); });
@ -46,7 +48,6 @@ class BrandingAdminSettings
onBuild() { onBuild() {
_.delay(() => { _.delay(() => {
const const
Remote = require('Remote/Admin/Ajax'),
f1 = settingsSaveHelperSimpleFunction(this.title.trigger, this), f1 = settingsSaveHelperSimpleFunction(this.title.trigger, this),
f2 = settingsSaveHelperSimpleFunction(this.loadingDesc.trigger, this), f2 = settingsSaveHelperSimpleFunction(this.loadingDesc.trigger, this),
f3 = settingsSaveHelperSimpleFunction(this.faviconUrl.trigger, this); f3 = settingsSaveHelperSimpleFunction(this.faviconUrl.trigger, this);
@ -68,7 +69,7 @@ class BrandingAdminSettings
'FaviconUrl': trim(value) 'FaviconUrl': trim(value)
}); });
}); });
}, 50); }, Magics.Time50ms);
} }
} }

View file

@ -71,8 +71,8 @@ class ContactsAdminSettings
this.contactsType = ko.observable(''); this.contactsType = ko.observable('');
this.mainContactsType = ko.computed({ this.mainContactsType = ko.computed({
'read': this.contactsType, read: this.contactsType,
'write': (value) => { write: (value) => {
if (value !== this.contactsType()) if (value !== this.contactsType())
{ {
if (-1 < inArray(value, supportedTypes)) if (-1 < inArray(value, supportedTypes))

View file

@ -1,19 +1,22 @@
import _ from '_'; import _ from '_';
import {settingsSaveHelperSimpleFunction, trim, boolToAjax} from 'Common/Utils'; import {settingsSaveHelperSimpleFunction, trim, boolToAjax} from 'Common/Utils';
import {Magics} from 'Common/Enums';
import Remote from 'Remote/Admin/Ajax';
import {BrandingAdminSettings} from 'Settings/Admin/Branding'; import {BrandingAdminSettings} from 'Settings/Admin/Branding';
class BrandingPremAdminSettings extends BrandingAdminSettings class BrandingPremAdminSettings extends BrandingAdminSettings
{ {
onBuild(oDom) { onBuild(dom) {
super.onBuild(oDom); super.onBuild(dom);
if (this.capa && this.capa() && !this.community) if (this.capa && this.capa() && !this.community)
{ {
_.delay(() => { _.delay(() => {
const const
Remote = require('Remote/Admin/Ajax'),
f1 = settingsSaveHelperSimpleFunction(this.loginLogo.trigger, this), f1 = settingsSaveHelperSimpleFunction(this.loginLogo.trigger, this),
f2 = settingsSaveHelperSimpleFunction(this.loginDescription.trigger, this), f2 = settingsSaveHelperSimpleFunction(this.loginDescription.trigger, this),
f3 = settingsSaveHelperSimpleFunction(this.loginCss.trigger, this), f3 = settingsSaveHelperSimpleFunction(this.loginCss.trigger, this),
@ -97,7 +100,8 @@ class BrandingPremAdminSettings extends BrandingAdminSettings
'LoginPowered': boolToAjax(value) 'LoginPowered': boolToAjax(value)
}); });
}); });
}, 50);
}, Magics.Time50ms);
} }
} }
} }

View file

@ -44,8 +44,7 @@ class FiltersUserSettings
this.filterRaw.allow = ko.observable(false); this.filterRaw.allow = ko.observable(false);
this.filterRaw.error = ko.observable(false); this.filterRaw.error = ko.observable(false);
this.filterForDeletion = ko.observable(null) this.filterForDeletion = ko.observable(null).deleteAccessHelper();
.extend({falseTimeout: 3000}).extend({toggleSubscribeProperty: [this, 'deleteAccess']});
this.saveChanges = createCommand(() => { this.saveChanges = createCommand(() => {
if (!this.filters.saving()) if (!this.filters.saving())

View file

@ -1,7 +1,7 @@
import ko from 'ko'; import ko from 'ko';
import {ClientSideKeyName, Notification} from 'Common/Enums'; import {ClientSideKeyName, Notification, Magics} from 'Common/Enums';
import {trim, noop} from 'Common/Utils'; import {trim, noop} from 'Common/Utils';
import {getNotification, i18n} from 'Common/Translator'; import {getNotification, i18n} from 'Common/Translator';
@ -25,33 +25,21 @@ class FoldersUserSettings
this.displaySpecSetting = FolderStore.displaySpecSetting; this.displaySpecSetting = FolderStore.displaySpecSetting;
this.folderList = FolderStore.folderList; this.folderList = FolderStore.folderList;
this.folderListHelp = ko.observable('').extend({throttle: 100}); this.folderListHelp = ko.observable('').extend({throttle: Magics.Time100ms});
this.loading = ko.computed(() => { this.loading = ko.computed(() => {
const const
bLoading = FolderStore.foldersLoading(), loading = FolderStore.foldersLoading(),
bCreating = FolderStore.foldersCreating(), creating = FolderStore.foldersCreating(),
bDeleting = FolderStore.foldersDeleting(), deleting = FolderStore.foldersDeleting(),
bRenaming = FolderStore.foldersRenaming(); renaming = FolderStore.foldersRenaming();
return bLoading || bCreating || bDeleting || bRenaming; return loading || creating || deleting || renaming;
}); });
this.folderForDeletion = ko.observable(null).deleteAccessHelper(); this.folderForDeletion = ko.observable(null).deleteAccessHelper();
this.folderForEdit = ko.observable(null).extend({toggleSubscribe: [this, this.folderForEdit = ko.observable(null).extend({toggleSubscribeProperty: [this, 'edited']});
(prev) => {
if (prev)
{
prev.edited(false);
}
}, (next) => {
if (next && next.canBeEdited())
{
next.edited(true);
}
}
]});
this.useImapSubscribe = !!appSettingsGet('useImapSubscribe'); this.useImapSubscribe = !!appSettingsGet('useImapSubscribe');
} }

View file

@ -61,7 +61,7 @@ class ThemesUserSettings
else else
{ {
$bg.attr('style', 'background-image: none !important;').backstretch(userBackground(value), { $bg.attr('style', 'background-image: none !important;').backstretch(userBackground(value), {
fade: 1000, centeredX: true, centeredY: true fade: Magics.Time1s, centeredX: true, centeredY: true
}).removeAttr('style'); }).removeAttr('style');
} }
}); });

View file

@ -1,6 +1,7 @@
import ko from 'ko'; import ko from 'ko';
import _ from '_'; import _ from '_';
import {Magics} from 'Common/Enums';
import * as Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
class AccountUserStore class AccountUserStore
@ -12,7 +13,7 @@ class AccountUserStore
this.signature = ko.observable(''); this.signature = ko.observable('');
this.accounts = ko.observableArray([]); this.accounts = ko.observableArray([]);
this.accounts.loading = ko.observable(false).extend({throttle: 100}); this.accounts.loading = ko.observable(false).extend({throttle: Magics.Time100ms});
this.computers(); this.computers();
} }

View file

@ -2,9 +2,10 @@
import ko from 'ko'; import ko from 'ko';
import {Focused, KeyState} from 'Common/Enums'; import {Focused, KeyState} from 'Common/Enums';
import {keyScope} from 'Common/Globals'; import {keyScope} from 'Common/Globals';
import * as Settings from 'Storage/Settings';
import {isNonEmptyArray} from 'Common/Utils'; import {isNonEmptyArray} from 'Common/Utils';
import * as Settings from 'Storage/Settings';
import {AbstractAppStore} from 'Stores/AbstractApp'; import {AbstractAppStore} from 'Stores/AbstractApp';
class AppUserStore extends AbstractAppStore class AppUserStore extends AbstractAppStore

View file

@ -1,16 +1,17 @@
import ko from 'ko'; import ko from 'ko';
import {Magics} from 'Common/Enums';
import * as Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
class ContactUserStore class ContactUserStore
{ {
constructor() { constructor() {
this.contacts = ko.observableArray([]); this.contacts = ko.observableArray([]);
this.contacts.loading = ko.observable(false).extend({'throttle': 200}); this.contacts.loading = ko.observable(false).extend({throttle: Magics.Time200ms});
this.contacts.importing = ko.observable(false).extend({'throttle': 200}); this.contacts.importing = ko.observable(false).extend({throttle: Magics.Time200ms});
this.contacts.syncing = ko.observable(false).extend({'throttle': 200}); this.contacts.syncing = ko.observable(false).extend({throttle: Magics.Time200ms});
this.contacts.exportingVcf = ko.observable(false).extend({'throttle': 200}); this.contacts.exportingVcf = ko.observable(false).extend({throttle: Magics.Time200ms});
this.contacts.exportingCsv = ko.observable(false).extend({'throttle': 200}); this.contacts.exportingCsv = ko.observable(false).extend({throttle: Magics.Time200ms});
this.allowContactsSync = ko.observable(false); this.allowContactsSync = ko.observable(false);
this.enableContactsSync = ko.observable(false); this.enableContactsSync = ko.observable(false);

View file

@ -1,5 +1,6 @@
import ko from 'ko'; import ko from 'ko';
import {Magics} from 'Common/Enums';
class FilterUserStore class FilterUserStore
{ {
@ -9,8 +10,8 @@ class FilterUserStore
this.filters = ko.observableArray([]); this.filters = ko.observableArray([]);
this.filters.loading = ko.observable(false).extend({throttle: 200}); this.filters.loading = ko.observable(false).extend({throttle: Magics.Time200ms});
this.filters.saving = ko.observable(false).extend({throttle: 200}); this.filters.saving = ko.observable(false).extend({throttle: Magics.Time200ms});
this.raw = ko.observable(''); this.raw = ko.observable('');
} }

View file

@ -31,19 +31,7 @@ class FolderUserStore
this.foldersInboxUnreadCount = ko.observable(0); this.foldersInboxUnreadCount = ko.observable(0);
this.currentFolder = ko.observable(null).extend({toggleSubscribe: [ this.currentFolder = ko.observable(null).extend({toggleSubscribeProperty: [this, 'selected']});
null,
(prev) => {
if (prev) {
prev.selected(false);
}
},
(next) => {
if (next) {
next.selected(true);
}
}
]});
this.computers(); this.computers();
this.subscribers(); this.subscribers();

View file

@ -2,6 +2,8 @@
import window from 'window'; import window from 'window';
import ko from 'ko'; import ko from 'ko';
import {Magics} from 'Common/Enums';
class QuotaUserStore class QuotaUserStore
{ {
constructor() { constructor() {
@ -24,8 +26,8 @@ class QuotaUserStore
* @param {number} usage * @param {number} usage
*/ */
populateData(quota, usage) { populateData(quota, usage) {
this.quota(quota * 1024); this.quota(quota * Magics.BitLength1024);
this.usage(usage * 1024); this.usage(usage * Magics.BitLength1024);
} }
} }

View file

@ -33,7 +33,7 @@ class SettingsUserStore
this.useThreads = ko.observable(false); this.useThreads = ko.observable(false);
this.replySameFolder = ko.observable(false); this.replySameFolder = ko.observable(false);
this.autoLogout = ko.observable(30); this.autoLogout = ko.observable(Magics.Time30mInMin);
this.computers(); this.computers();
this.subscribers(); this.subscribers();
@ -44,11 +44,11 @@ class SettingsUserStore
} }
subscribers() { subscribers() {
this.layout.subscribe((nValue) => { this.layout.subscribe((value) => {
$html.toggleClass('rl-no-preview-pane', Layout.NoPreview === nValue); $html.toggleClass('rl-no-preview-pane', Layout.NoPreview === value);
$html.toggleClass('rl-side-preview-pane', Layout.SidePreview === nValue); $html.toggleClass('rl-side-preview-pane', Layout.SidePreview === value);
$html.toggleClass('rl-bottom-preview-pane', Layout.BottomPreview === nValue); $html.toggleClass('rl-bottom-preview-pane', Layout.BottomPreview === value);
Events.pub('layout', [nValue]); Events.pub('layout', [value]);
}); });
} }

View file

@ -20,6 +20,8 @@ import {EmailModel} from 'Model/Email';
import {view, ViewType} from 'Knoin/Knoin'; import {view, ViewType} from 'Knoin/Knoin';
import {AbstractViewNext} from 'Knoin/AbstractViewNext'; import {AbstractViewNext} from 'Knoin/AbstractViewNext';
const KEY_NAME_SUBSTR = -8;
@view({ @view({
name: 'View/Popup/ComposeOpenPgp', name: 'View/Popup/ComposeOpenPgp',
type: ViewType.Popup, type: ViewType.Popup,
@ -61,7 +63,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext
} }
return _.map(oKey.users, (user) => ({ return _.map(oKey.users, (user) => ({
'id': oKey.guid, 'id': oKey.guid,
'name': '(' + oKey.id.substr(-8).toUpperCase() + ') ' + user, 'name': '(' + oKey.id.substr(KEY_NAME_SUBSTR).toUpperCase() + ') ' + user,
'key': oKey, 'key': oKey,
'class': iIndex % 2 ? 'odd' : 'even' 'class': iIndex % 2 ? 'odd' : 'even'
})); }));
@ -78,7 +80,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext
} }
return _.map(oKey.users, (user) => ({ return _.map(oKey.users, (user) => ({
'id': oKey.guid, 'id': oKey.guid,
'name': '(' + oKey.id.substr(-8).toUpperCase() + ') ' + user, 'name': '(' + oKey.id.substr(KEY_NAME_SUBSTR).toUpperCase() + ') ' + user,
'key': oKey, 'key': oKey,
'class': index % 2 ? 'odd' : 'even' 'class': index % 2 ? 'odd' : 'even'
})); }));
@ -252,7 +254,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext
const const
keyId = this.selectedPrivateKey(), keyId = this.selectedPrivateKey(),
option = keyId ? _.find(this.privateKeysOptions(), (oItem) => oItem && keyId === oItem.id) : null; option = keyId ? _.find(this.privateKeysOptions(), (item) => item && keyId === item.id) : null;
if (option) if (option)
{ {
@ -260,7 +262,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext
'empty': !option.key, 'empty': !option.key,
'selected': ko.observable(!!option.key), 'selected': ko.observable(!!option.key),
'users': option.key.users, 'users': option.key.users,
'hash': option.key.id.substr(-8).toUpperCase(), 'hash': option.key.id.substr(KEY_NAME_SUBSTR).toUpperCase(),
'key': option.key 'key': option.key
}); });
} }
@ -280,7 +282,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext
'selected': ko.observable(!!option.key), 'selected': ko.observable(!!option.key),
'removable': ko.observable(!this.sign() || !this.signKey() || this.signKey().key.id !== option.key.id), 'removable': ko.observable(!this.sign() || !this.signKey() || this.signKey().key.id !== option.key.id),
'users': option.key.users, 'users': option.key.users,
'hash': option.key.id.substr(-8).toUpperCase(), 'hash': option.key.id.substr(KEY_NAME_SUBSTR).toUpperCase(),
'key': option.key 'key': option.key
}); });
@ -422,7 +424,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext
{ {
this.signKey({ this.signKey({
'users': keys[0].users || [emailLine], 'users': keys[0].users || [emailLine],
'hash': keys[0].id.substr(-8).toUpperCase(), 'hash': keys[0].id.substr(KEY_NAME_SUBSTR).toUpperCase(),
'key': keys[0] 'key': keys[0]
}); });
} }
@ -437,13 +439,13 @@ class ComposeOpenPgpPopupView extends AbstractViewNext
{ {
this.encryptKeys(_.uniq(_.compact(_.flatten(_.map(rec, (recEmail) => { this.encryptKeys(_.uniq(_.compact(_.flatten(_.map(rec, (recEmail) => {
const keys = PgpStore.findAllPublicKeysByEmailNotNative(recEmail); const keys = PgpStore.findAllPublicKeysByEmailNotNative(recEmail);
return keys ? _.map(keys, (oKey) => ({ return keys ? _.map(keys, (publicKey) => ({
'empty': !oKey, 'empty': !publicKey,
'selected': ko.observable(!!oKey), 'selected': ko.observable(!!publicKey),
'removable': ko.observable(!this.sign() || !this.signKey() || this.signKey().key.id !== oKey.id), 'removable': ko.observable(!this.sign() || !this.signKey() || this.signKey().key.id !== publicKey.id),
'users': oKey ? (oKey.users || [recEmail]) : [recEmail], 'users': publicKey ? (publicKey.users || [recEmail]) : [recEmail],
'hash': oKey ? oKey.id.substr(-8).toUpperCase() : '', 'hash': publicKey ? publicKey.id.substr(KEY_NAME_SUBSTR).toUpperCase() : '',
'key': oKey 'key': publicKey
})) : []; })) : [];
}), true)), (encryptKey) => encryptKey.hash)); }), true)), (encryptKey) => encryptKey.hash));

4
dev/bootstrap.js vendored
View file

@ -60,7 +60,7 @@ export default (App) => {
App.bootstart(); App.bootstart();
}, 10); }, Enums.Magics.Time10ms);
} }
else else
{ {
@ -69,7 +69,7 @@ export default (App) => {
window.__APP_BOOT = null; window.__APP_BOOT = null;
}, 10); }, Enums.Magics.Time10ms);
}); });
}; };

View file

@ -622,14 +622,10 @@ gulp.task('default', function(callback) {
}); });
// watch // watch
gulp.task('css:watch', ['css:main'], function() { gulp.task('watch', ['css:watch', 'js:validate:watch'], function() {
cfg.watch = true; cfg.watch = true;
livereload.listen(); livereload.listen();
gulp.watch(cfg.paths.less.main.watch, {interval: cfg.watchInterval}, ['css:main']); gulp.watch(cfg.paths.less.main.watch, {interval: cfg.watchInterval}, ['css:main']);
});
gulp.task('js:validate:watch', ['js:validate'], function() {
cfg.watch = true;
gulp.watch(cfg.paths.globjs, {interval: cfg.watchInterval}, ['js:validate']); gulp.watch(cfg.paths.globjs, {interval: cfg.watchInterval}, ['js:validate']);
}); });

View file

@ -95,7 +95,7 @@ module.exports = function(publicPath, pro, es6) {
// stage-2 // stage-2
"transform-class-properties", "transform-class-properties",
"transform-object-rest-spread", "transform-object-rest-spread",
// "transform-decorators", // "transform-decorators", // -> transform-decorators-legacy
// stage-3 // stage-3
"syntax-trailing-function-commas", "syntax-trailing-function-commas",