mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-29 03:59:21 +03:00
Merge branch 'master' into plugin-2fa
This commit is contained in:
commit
7985eaa23a
303 changed files with 51374 additions and 11952 deletions
|
|
@ -28,7 +28,6 @@ export class AbstractApp {
|
|||
logoutReload(close = false) {
|
||||
const url = logoutLink();
|
||||
|
||||
rl.hash.clear();
|
||||
close && window.close && window.close();
|
||||
|
||||
if (location.href !== url) {
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@ class AdminApp extends AbstractApp {
|
|||
|
||||
bootstart() {
|
||||
super.bootstart();
|
||||
|
||||
this.hideLoading();
|
||||
|
||||
if (!Settings.app('allowAdminPanel')) {
|
||||
rl.route.root();
|
||||
setTimeout(() => location.href = '/', 1);
|
||||
|
|
@ -30,8 +27,7 @@ class AdminApp extends AbstractApp {
|
|||
} else {
|
||||
startScreens([LoginAdminScreen]);
|
||||
}
|
||||
|
||||
progressJs.end();
|
||||
this.hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { isPosNumeric, delegateRunOnDestroy, mailToHelper } from 'Common/UtilsUs
|
|||
|
||||
import {
|
||||
Capa,
|
||||
Notification,
|
||||
Scope
|
||||
} from 'Common/Enums';
|
||||
|
||||
|
|
@ -100,9 +101,6 @@ class AppUser extends AbstractApp {
|
|||
setInterval(() => {
|
||||
const currentTime = Date.now();
|
||||
if (currentTime > (lastTime + interval + 1000)) {
|
||||
if (rl.hash.check()) {
|
||||
this.reload();
|
||||
}
|
||||
Remote.jsVersion(iError => {
|
||||
if (100 < iError) {
|
||||
this.reload();
|
||||
|
|
@ -112,10 +110,6 @@ class AppUser extends AbstractApp {
|
|||
lastTime = currentTime;
|
||||
}, interval);
|
||||
|
||||
if (rl.hash.check()) {
|
||||
this.reload();
|
||||
}
|
||||
|
||||
if (SettingsGet('UserBackgroundHash')) {
|
||||
setTimeout(() => {
|
||||
const img = userBackground(SettingsGet('UserBackgroundHash'));
|
||||
|
|
@ -886,12 +880,7 @@ class AppUser extends AbstractApp {
|
|||
}
|
||||
|
||||
logout() {
|
||||
Remote.logout(() => this.logoutReload((SettingsGet('ParentEmail')||{length:0}).length));
|
||||
}
|
||||
|
||||
bootend() {
|
||||
progressJs.end();
|
||||
this.hideLoading();
|
||||
Remote.logout(() => rl.logoutReload((SettingsGet('ParentEmail')||{length:0}).length));
|
||||
}
|
||||
|
||||
bootstart() {
|
||||
|
|
@ -907,16 +896,12 @@ class AppUser extends AbstractApp {
|
|||
|
||||
const startupUrl = pString(SettingsGet('StartupUrl'));
|
||||
|
||||
progressJs.set(90);
|
||||
|
||||
rl.setWindowTitle();
|
||||
if (SettingsGet('Auth')) {
|
||||
rl.setWindowTitle(i18n('GLOBAL/LOADING'));
|
||||
|
||||
this.foldersReload(value => {
|
||||
try {
|
||||
this.bootend();
|
||||
|
||||
if (value) {
|
||||
if (startupUrl) {
|
||||
rl.route.setHash(root(startupUrl), true);
|
||||
|
|
@ -960,6 +945,7 @@ class AppUser extends AbstractApp {
|
|||
Settings.capa(Capa.Settings) ? SettingsUserScreen : null
|
||||
// false ? AboutUserScreen : null
|
||||
]);
|
||||
this.hideLoading();
|
||||
|
||||
setInterval(() => {
|
||||
const cF = FolderUserStore.currentFolderFullNameRaw(),
|
||||
|
|
@ -1030,8 +1016,8 @@ class AppUser extends AbstractApp {
|
|||
});
|
||||
|
||||
} else {
|
||||
this.bootend();
|
||||
startScreens([LoginUserScreen]);
|
||||
this.hideLoading();
|
||||
}
|
||||
|
||||
setInterval(() => dispatchEvent(new CustomEvent('reload-time')), 60000);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
import { pString, pInt } from 'Common/Utils';
|
||||
import { Settings, SettingsGet } from 'Common/Globals';
|
||||
import { Settings } from 'Common/Globals';
|
||||
|
||||
const
|
||||
ROOT = './',
|
||||
HASH_PREFIX = '#/',
|
||||
SERVER_PREFIX = './?',
|
||||
VERSION = Settings.app('version'),
|
||||
VERSION_PREFIX = Settings.app('webVersionPath') || 'snappymail/v/' + VERSION + '/',
|
||||
|
||||
getHash = () => SettingsGet('AuthAccountHash') || '0';
|
||||
VERSION_PREFIX = Settings.app('webVersionPath') || 'snappymail/v/' + VERSION + '/';
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
|
|
@ -40,7 +38,7 @@ export function logoutLink() {
|
|||
*/
|
||||
export function serverRequestRaw(type, hash, customSpecSuffix) {
|
||||
return SERVER_PREFIX + '/Raw/' + SUB_QUERY_PREFIX + '/'
|
||||
+ (null == customSpecSuffix ? getHash() : customSpecSuffix) + '/'
|
||||
+ (null == customSpecSuffix ? '0' : customSpecSuffix) + '/'
|
||||
+ (type
|
||||
? type + '/' + (hash ? SUB_QUERY_PREFIX + '/' + hash : '')
|
||||
: '')
|
||||
|
|
@ -61,7 +59,7 @@ export function attachmentDownload(download, customSpecSuffix) {
|
|||
* @returns {string}
|
||||
*/
|
||||
export function serverRequest(type) {
|
||||
return SERVER_PREFIX + '/' + type + '/' + SUB_QUERY_PREFIX + '/' + getHash() + '/';
|
||||
return SERVER_PREFIX + '/' + type + '/' + SUB_QUERY_PREFIX + '/0/';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Notification, UploadErrorCode } from 'Common/Enums';
|
|||
import { langLink } from 'Common/Links';
|
||||
import { doc, createElement } from 'Common/Globals';
|
||||
|
||||
let I18N_DATA = window.snappymailI18N || {};
|
||||
let I18N_DATA = {};
|
||||
|
||||
export const trigger = ko.observable(false);
|
||||
|
||||
|
|
@ -49,10 +49,21 @@ const i18nToNode = element => {
|
|||
}
|
||||
},
|
||||
|
||||
init = () => {
|
||||
if (rl.I18N) {
|
||||
I18N_DATA = rl.I18N;
|
||||
Date.defineRelativeTimeFormat(rl.relativeTime || {});
|
||||
rl.I18N = null;
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
|
||||
i18nKey = key => key.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase(),
|
||||
|
||||
getKeyByValue = (o, v) => Object.keys(o).find(key => o[key] === v);
|
||||
|
||||
init();
|
||||
|
||||
/**
|
||||
* @param {Object} elements
|
||||
* @param {boolean=} animate = false
|
||||
|
|
@ -127,13 +138,11 @@ export function reload(admin, language) {
|
|||
const script = createElement('script');
|
||||
script.onload = () => {
|
||||
// reload the data
|
||||
if (window.snappymailI18N) {
|
||||
I18N_DATA = window.snappymailI18N;
|
||||
if (init()) {
|
||||
i18nToNodes(doc);
|
||||
dispatchEvent(new CustomEvent('reload-time'));
|
||||
trigger(!trigger());
|
||||
}
|
||||
window.snappymailI18N = null;
|
||||
script.remove();
|
||||
resolve();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { SaveSettingsStep } from 'Common/Enums';
|
||||
import { doc, createElement, elementById } from 'Common/Globals';
|
||||
import { doc, elementById } from 'Common/Globals';
|
||||
|
||||
export const
|
||||
isArray = Array.isArray,
|
||||
|
|
@ -84,14 +84,13 @@ let __themeTimer = 0,
|
|||
* @returns {void}
|
||||
*/
|
||||
export function changeTheme(value, themeTrigger = ()=>{}) {
|
||||
const themeLink = elementById('app-theme-link'),
|
||||
const themeStyle = elementById('app-theme-style'),
|
||||
clearTimer = () => {
|
||||
__themeTimer = setTimeout(() => themeTrigger(SaveSettingsStep.Idle), 1000);
|
||||
__themeJson = null;
|
||||
};
|
||||
|
||||
let themeStyle = elementById('app-theme-style'),
|
||||
url = (themeLink && themeLink.href) || (themeStyle && themeStyle.dataset.href);
|
||||
let url = themeStyle.dataset.href;
|
||||
|
||||
if (url) {
|
||||
url = url.toString()
|
||||
|
|
@ -118,19 +117,9 @@ export function changeTheme(value, themeTrigger = ()=>{}) {
|
|||
rl.fetchJSON(url, init)
|
||||
.then(data => {
|
||||
if (data && isArray(data) && 2 === data.length) {
|
||||
if (themeLink && !themeStyle) {
|
||||
themeStyle = createElement('style');
|
||||
themeStyle.id = 'app-theme-style';
|
||||
themeLink.after(themeStyle);
|
||||
themeLink.remove();
|
||||
}
|
||||
|
||||
if (themeStyle) {
|
||||
themeStyle.textContent = data[1];
|
||||
themeStyle.dataset.href = url;
|
||||
themeStyle.dataset.theme = data[0];
|
||||
}
|
||||
|
||||
themeStyle.textContent = data[1];
|
||||
themeStyle.dataset.href = url;
|
||||
themeStyle.dataset.theme = data[0];
|
||||
themeTrigger(SaveSettingsStep.TrueResult);
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -11,31 +11,18 @@ export class CheckboxMaterialDesignComponent extends AbstractCheckbox {
|
|||
this.animationBox = ko.observable(false).extend({ falseTimeout: 200 });
|
||||
this.animationCheckmark = ko.observable(false).extend({ falseTimeout: 200 });
|
||||
|
||||
this.animationBoxSetTrue = this.animationBoxSetTrue.bind(this);
|
||||
this.animationCheckmarkSetTrue = this.animationCheckmarkSetTrue.bind(this);
|
||||
|
||||
this.disposable.push(
|
||||
this.value.subscribe((value) => {
|
||||
this.triggerAnimation(value);
|
||||
}, this)
|
||||
this.value.subscribe(value => this.triggerAnimation(value), this)
|
||||
);
|
||||
}
|
||||
|
||||
animationBoxSetTrue() {
|
||||
this.animationBox(true);
|
||||
}
|
||||
|
||||
animationCheckmarkSetTrue() {
|
||||
this.animationCheckmark(true);
|
||||
}
|
||||
|
||||
triggerAnimation(box) {
|
||||
if (box) {
|
||||
this.animationBoxSetTrue();
|
||||
setTimeout(this.animationCheckmarkSetTrue, 200);
|
||||
this.animationBox(true);
|
||||
setTimeout(()=>this.animationCheckmark(true), 200);
|
||||
} else {
|
||||
this.animationCheckmarkSetTrue();
|
||||
setTimeout(this.animationBoxSetTrue, 200);
|
||||
this.animationCheckmark(true);
|
||||
setTimeout(()=>this.animationBox(true), 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
dev/External/SquireUI.js
vendored
1
dev/External/SquireUI.js
vendored
|
|
@ -412,6 +412,7 @@ class SquireUI
|
|||
input.title = ctrlKey + cfg.key;
|
||||
}
|
||||
input.dataset.action = action;
|
||||
input.tabIndex = -1;
|
||||
cfg.input = input;
|
||||
toolgroup.append(input);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ export class AbstractViewCenter extends AbstractView
|
|||
{
|
||||
constructor(name, templateID)
|
||||
{
|
||||
super(name, templateID, ViewType.Center);
|
||||
super(name, templateID, ViewType.Content);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export const ViewType = {
|
|||
Popup: 'Popups',
|
||||
Left: 'Left',
|
||||
Right: 'Right',
|
||||
Center: 'Center'
|
||||
Content: 'Content'
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -76,7 +76,7 @@ function buildViewModel(ViewModelClass, vmScreen) {
|
|||
let vmDom = null;
|
||||
const vm = new ViewModelClass(vmScreen),
|
||||
position = vm.viewModelPosition || '',
|
||||
vmPlace = position ? doc.querySelector('#rl-content #rl-' + position.toLowerCase()) : null;
|
||||
vmPlace = position ? doc.getElementById('rl-' + position.toLowerCase()) : null;
|
||||
|
||||
ViewModelClass.__builded = true;
|
||||
ViewModelClass.__vm = vm;
|
||||
|
|
@ -145,6 +145,8 @@ function buildViewModel(ViewModelClass, vmScreen) {
|
|||
if (vm && ViewType.Popup === position) {
|
||||
vm.registerPopupKeyDown();
|
||||
}
|
||||
|
||||
dispatchEvent(new CustomEvent('rl-view-model', {detail:vm}));
|
||||
} else {
|
||||
console.log('Cannot find view model position: ' + position);
|
||||
}
|
||||
|
|
@ -153,7 +155,7 @@ function buildViewModel(ViewModelClass, vmScreen) {
|
|||
return ViewModelClass && ViewModelClass.__vm;
|
||||
}
|
||||
|
||||
function getScreenPopupViewModel(ViewModelClassToShow) {
|
||||
export function getScreenPopupViewModel(ViewModelClassToShow) {
|
||||
return (buildViewModel(ViewModelClassToShow) && ViewModelClassToShow.__dom) && ViewModelClassToShow.__vm;
|
||||
}
|
||||
|
||||
|
|
@ -175,15 +177,6 @@ export function showScreenPopup(ViewModelClassToShow, params = []) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Function} ViewModelClassToShow
|
||||
* @returns {void}
|
||||
*/
|
||||
export function warmUpScreenPopup(ViewModelClassToShow) {
|
||||
const vm = getScreenPopupViewModel(ViewModelClassToShow);
|
||||
vm && vm.onWarmUp && vm.onWarmUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Function} ViewModelClassToShow
|
||||
* @returns {boolean}
|
||||
|
|
|
|||
|
|
@ -100,10 +100,8 @@ export class FolderCollectionModel extends AbstractCollectionModel
|
|||
storeIt() {
|
||||
const cnt = pInt(this.CountRec);
|
||||
|
||||
let limit = pInt(Settings.app('folderSpecLimit'));
|
||||
limit = 100 < limit ? 100 : 10 > limit ? 10 : limit;
|
||||
|
||||
FolderUserStore.displaySpecSetting(0 >= cnt || limit < cnt);
|
||||
FolderUserStore.displaySpecSetting(0 >= cnt
|
||||
|| Math.max(10, Math.min(100, pInt(Settings.app('folderSpecLimit')))) < cnt);
|
||||
|
||||
FolderUserStore.folderList(this);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { Notification } from 'Common/Enums';
|
||||
import { Settings } from 'Common/Globals';
|
||||
import { isArray, pInt, pString } from 'Common/Utils';
|
||||
import { serverRequest } from 'Common/Links';
|
||||
|
||||
|
|
@ -8,13 +7,6 @@ let iJsonErrorCount = 0,
|
|||
|
||||
const getURL = (add = '') => serverRequest('Json') + add,
|
||||
|
||||
updateToken = data => {
|
||||
if (data.UpdateToken) {
|
||||
rl.hash.set();
|
||||
Settings.set('AuthAccountHash', data.UpdateToken);
|
||||
}
|
||||
},
|
||||
|
||||
checkResponseError = data => {
|
||||
const err = data ? data.ErrorCode : null;
|
||||
if (Notification.InvalidToken === err && 10 < ++iTokenErrorCount) {
|
||||
|
|
@ -32,9 +24,8 @@ checkResponseError = data => {
|
|||
) {
|
||||
++iJsonErrorCount;
|
||||
}
|
||||
if (data.ClearAuth || data.Logout || 7 < iJsonErrorCount) {
|
||||
rl.hash.clear();
|
||||
data.ClearAuth || rl.logoutReload();
|
||||
if (data.Logout || 7 < iJsonErrorCount) {
|
||||
rl.logoutReload();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -97,12 +88,8 @@ export class AbstractFetchRemote
|
|||
undefined === iTimeout ? 30000 : pInt(iTimeout),
|
||||
data => {
|
||||
let cached = false;
|
||||
if (data) {
|
||||
if (data.Time) {
|
||||
cached = pInt(data.Time) > Date.now() - start;
|
||||
}
|
||||
|
||||
updateToken(data);
|
||||
if (data && data.Time) {
|
||||
cached = pInt(data.Time) > Date.now() - start;
|
||||
}
|
||||
|
||||
let iError = 0;
|
||||
|
|
@ -188,8 +175,6 @@ export class AbstractFetchRemote
|
|||
if (!data) {
|
||||
return Promise.reject(Notification.JsonParse);
|
||||
}
|
||||
|
||||
updateToken(data);
|
||||
/*
|
||||
let isCached = false, type = '';
|
||||
if (data && data.Time) {
|
||||
|
|
|
|||
|
|
@ -126,8 +126,7 @@ export class AbstractSettingsScreen extends AbstractScreen {
|
|||
this.menu.push({
|
||||
route: SettingsViewModel.__rlSettingsData.Route,
|
||||
label: SettingsViewModel.__rlSettingsData.Label,
|
||||
selected: ko.observable(false),
|
||||
disabled: false
|
||||
selected: ko.observable(false)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { FolderListMailBoxUserView } from 'View/User/MailBox/FolderList';
|
|||
import { MessageListMailBoxUserView } from 'View/User/MailBox/MessageList';
|
||||
import { MessageViewMailBoxUserView } from 'View/User/MailBox/MessageView';
|
||||
|
||||
import { warmUpScreenPopup } from 'Knoin/Knoin';
|
||||
import { getScreenPopupViewModel } from 'Knoin/Knoin';
|
||||
|
||||
import { AbstractScreen } from 'Knoin/AbstractScreen';
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ export class MailBoxUserScreen extends AbstractScreen {
|
|||
onStart() {
|
||||
if (!this.__started) {
|
||||
super.onStart();
|
||||
setTimeout(() => warmUpScreenPopup(ComposePopupView), 500);
|
||||
setTimeout(() => getScreenPopupViewModel(ComposePopupView), 500);
|
||||
|
||||
addEventListener('mailbox.inbox-unread-count', e => {
|
||||
FolderUserStore.foldersInboxUnreadCount(e.detail);
|
||||
|
|
|
|||
|
|
@ -105,8 +105,6 @@ export class ContactsAdminSettings {
|
|||
})
|
||||
})
|
||||
|
||||
this.onTestContactsResponse = this.onTestContactsResponse.bind(this);
|
||||
|
||||
decorateKoCommands(this, {
|
||||
testContactsCommand: self => self.pdoDsn() && self.pdoUser()
|
||||
});
|
||||
|
|
@ -118,7 +116,24 @@ export class ContactsAdminSettings {
|
|||
this.testContactsErrorMessage('');
|
||||
this.testing(true);
|
||||
|
||||
Remote.testContacts(this.onTestContactsResponse, {
|
||||
Remote.testContacts((iError, data) => {
|
||||
this.testContactsSuccess(false);
|
||||
this.testContactsError(false);
|
||||
this.testContactsErrorMessage('');
|
||||
|
||||
if (!iError && data.Result.Result) {
|
||||
this.testContactsSuccess(true);
|
||||
} else {
|
||||
this.testContactsError(true);
|
||||
if (data && data.Result) {
|
||||
this.testContactsErrorMessage(data.Result.Message || '');
|
||||
} else {
|
||||
this.testContactsErrorMessage('');
|
||||
}
|
||||
}
|
||||
|
||||
this.testing(false);
|
||||
}, {
|
||||
ContactsPdoType: this.contactsType(),
|
||||
ContactsPdoDsn: this.pdoDsn(),
|
||||
ContactsPdoUser: this.pdoUser(),
|
||||
|
|
@ -126,25 +141,6 @@ export class ContactsAdminSettings {
|
|||
});
|
||||
}
|
||||
|
||||
onTestContactsResponse(iError, data) {
|
||||
this.testContactsSuccess(false);
|
||||
this.testContactsError(false);
|
||||
this.testContactsErrorMessage('');
|
||||
|
||||
if (!iError && data.Result.Result) {
|
||||
this.testContactsSuccess(true);
|
||||
} else {
|
||||
this.testContactsError(true);
|
||||
if (data && data.Result) {
|
||||
this.testContactsErrorMessage(data.Result.Message || '');
|
||||
} else {
|
||||
this.testContactsErrorMessage('');
|
||||
}
|
||||
}
|
||||
|
||||
this.testing(false);
|
||||
}
|
||||
|
||||
onShow() {
|
||||
this.testContactsSuccess(false);
|
||||
this.testContactsError(false);
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ export class DomainsAdminSettings {
|
|||
this.domains = DomainAdminStore;
|
||||
|
||||
this.domainForDeletion = ko.observable(null).deleteAccessHelper();
|
||||
|
||||
this.onDomainListChangeRequest = this.onDomainListChangeRequest.bind(this);
|
||||
this.onDomainLoadRequest = this.onDomainLoadRequest.bind(this);
|
||||
}
|
||||
|
||||
createDomain() {
|
||||
|
|
@ -28,30 +25,22 @@ export class DomainsAdminSettings {
|
|||
|
||||
deleteDomain(domain) {
|
||||
DomainAdminStore.remove(domain);
|
||||
Remote.domainDelete(this.onDomainListChangeRequest, domain.name);
|
||||
Remote.domainDelete(DomainAdminStore.fetch, domain.name);
|
||||
}
|
||||
|
||||
disableDomain(domain) {
|
||||
domain.disabled(!domain.disabled());
|
||||
Remote.domainDisable(this.onDomainListChangeRequest, domain.name, domain.disabled());
|
||||
Remote.domainDisable(DomainAdminStore.fetch, domain.name, domain.disabled());
|
||||
}
|
||||
|
||||
onBuild(oDom) {
|
||||
oDom.addEventListener('click', event => {
|
||||
let el = event.target.closestWithin('.b-admin-domains-list-table .e-item .e-action', oDom);
|
||||
el && ko.dataFor(el) && Remote.domain(this.onDomainLoadRequest, ko.dataFor(el).name);
|
||||
let el = event.target.closestWithin('.b-admin-domains-list-table .e-action', oDom);
|
||||
el && ko.dataFor(el) && Remote.domain(
|
||||
(iError, oData) => iError || showScreenPopup(DomainPopupView, [oData.Result]), ko.dataFor(el).name
|
||||
);
|
||||
});
|
||||
|
||||
DomainAdminStore.fetch();
|
||||
}
|
||||
|
||||
onDomainLoadRequest(iError, oData) {
|
||||
if (!iError) {
|
||||
showScreenPopup(DomainPopupView, [oData.Result]);
|
||||
}
|
||||
}
|
||||
|
||||
onDomainListChangeRequest() {
|
||||
DomainAdminStore.fetch();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,16 +12,14 @@ import Remote from 'Remote/Admin/Fetch';
|
|||
|
||||
import { PluginPopupView } from 'View/Popup/Plugin';
|
||||
|
||||
export class PluginsAdminSettings {
|
||||
export class PluginsAdminSettings
|
||||
{
|
||||
constructor() {
|
||||
this.enabledPlugins = ko.observable(!!SettingsGet('EnabledPlugins'));
|
||||
|
||||
this.plugins = PluginAdminStore;
|
||||
this.pluginsError = PluginAdminStore.error;
|
||||
|
||||
this.onPluginLoadRequest = this.onPluginLoadRequest.bind(this);
|
||||
this.onPluginDisableRequest = this.onPluginDisableRequest.bind(this);
|
||||
|
||||
this.enabledPlugins.subscribe(value =>
|
||||
Remote.saveAdminConfig(null, {
|
||||
EnabledPlugins: value ? 1 : 0
|
||||
|
|
@ -30,20 +28,30 @@ export class PluginsAdminSettings {
|
|||
}
|
||||
|
||||
disablePlugin(plugin) {
|
||||
plugin.disabled(!plugin.disabled());
|
||||
Remote.pluginDisable(this.onPluginDisableRequest, plugin.name, plugin.disabled());
|
||||
let b = !plugin.disabled();
|
||||
plugin.disabled(b);
|
||||
Remote.pluginDisable((iError, data) => {
|
||||
if (iError) {
|
||||
PluginAdminStore.error(
|
||||
(Notification.UnsupportedPluginPackage === iError && data && data.ErrorMessage)
|
||||
? data.ErrorMessage
|
||||
: getNotification(iError)
|
||||
);
|
||||
}
|
||||
PluginAdminStore.fetch();
|
||||
}, plugin.name, b);
|
||||
}
|
||||
|
||||
configurePlugin(plugin) {
|
||||
Remote.plugin(this.onPluginLoadRequest, plugin.name);
|
||||
Remote.plugin((iError, data) => iError || showScreenPopup(PluginPopupView, [data.Result]), plugin.name);
|
||||
}
|
||||
|
||||
onBuild(oDom) {
|
||||
oDom.addEventListener('click', event => {
|
||||
let el = event.target.closestWithin('.e-item .configure-plugin-action', oDom);
|
||||
let el = event.target.closestWithin('.configure-plugin-action', oDom);
|
||||
el && ko.dataFor(el) && this.configurePlugin(ko.dataFor(el));
|
||||
|
||||
el = event.target.closestWithin('.e-item .disabled-plugin', oDom);
|
||||
el = event.target.closestWithin('.disabled-plugin', oDom);
|
||||
el && ko.dataFor(el) && this.disablePlugin(ko.dataFor(el));
|
||||
});
|
||||
}
|
||||
|
|
@ -52,22 +60,4 @@ export class PluginsAdminSettings {
|
|||
PluginAdminStore.error('');
|
||||
PluginAdminStore.fetch();
|
||||
}
|
||||
|
||||
onPluginLoadRequest(iError, data) {
|
||||
if (!iError) {
|
||||
showScreenPopup(PluginPopupView, [data.Result]);
|
||||
}
|
||||
}
|
||||
|
||||
onPluginDisableRequest(iError, data) {
|
||||
if (iError) {
|
||||
if (Notification.UnsupportedPluginPackage === iError && data && data.ErrorMessage) {
|
||||
PluginAdminStore.error(data.ErrorMessage);
|
||||
} else {
|
||||
PluginAdminStore.error(getNotification(iError));
|
||||
}
|
||||
}
|
||||
|
||||
PluginAdminStore.fetch();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,8 +72,6 @@ export class SecurityAdminSettings {
|
|||
})
|
||||
});
|
||||
|
||||
this.onNewAdminPasswordResponse = this.onNewAdminPasswordResponse.bind(this);
|
||||
|
||||
decorateKoCommands(this, {
|
||||
saveNewAdminPasswordCommand: self => self.adminLogin().trim() && self.adminPassword()
|
||||
});
|
||||
|
|
@ -93,7 +91,19 @@ export class SecurityAdminSettings {
|
|||
this.adminPasswordUpdateError(false);
|
||||
this.adminPasswordUpdateSuccess(false);
|
||||
|
||||
Remote.saveNewAdminPassword(this.onNewAdminPasswordResponse, {
|
||||
Remote.saveNewAdminPassword((iError, data) => {
|
||||
if (iError) {
|
||||
this.adminPasswordUpdateError(true);
|
||||
} else {
|
||||
this.adminPassword('');
|
||||
this.adminPasswordNew('');
|
||||
this.adminPasswordNew2('');
|
||||
|
||||
this.adminPasswordUpdateSuccess(true);
|
||||
|
||||
this.weakPassword(!!data.Result.Weak);
|
||||
}
|
||||
}, {
|
||||
'Login': this.adminLogin(),
|
||||
'Password': this.adminPassword(),
|
||||
'NewPassword': this.adminPasswordNew()
|
||||
|
|
@ -102,20 +112,6 @@ export class SecurityAdminSettings {
|
|||
return true;
|
||||
}
|
||||
|
||||
onNewAdminPasswordResponse(iError, data) {
|
||||
if (iError) {
|
||||
this.adminPasswordUpdateError(true);
|
||||
} else {
|
||||
this.adminPassword('');
|
||||
this.adminPasswordNew('');
|
||||
this.adminPasswordNew2('');
|
||||
|
||||
this.adminPasswordUpdateSuccess(true);
|
||||
|
||||
this.weakPassword(!!data.Result.Weak);
|
||||
}
|
||||
}
|
||||
|
||||
onHide() {
|
||||
this.adminPassword('');
|
||||
this.adminPasswordNew('');
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
const storage = localStorage,
|
||||
const
|
||||
CLIENT_SIDE_STORAGE_INDEX_NAME = 'rlcsc',
|
||||
getStorage = () => {
|
||||
try {
|
||||
const value = storage.getItem(CLIENT_SIDE_STORAGE_INDEX_NAME) || null;
|
||||
return null == value ? null : JSON.parse(value);
|
||||
const value = localStorage.getItem(CLIENT_SIDE_STORAGE_INDEX_NAME);
|
||||
return value ? JSON.parse(value) : null;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ export function set(key, data) {
|
|||
storageResult['p' + key] = data;
|
||||
|
||||
try {
|
||||
storage.setItem(CLIENT_SIDE_STORAGE_INDEX_NAME, JSON.stringify(storageResult));
|
||||
localStorage.setItem(CLIENT_SIDE_STORAGE_INDEX_NAME, JSON.stringify(storageResult));
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
|
|
@ -32,10 +32,7 @@ export function set(key, data) {
|
|||
*/
|
||||
export function get(key) {
|
||||
try {
|
||||
key = 'p' + key;
|
||||
const storageResult = getStorage();
|
||||
|
||||
return storageResult && null != storageResult[key] ? storageResult[key] : null;
|
||||
return (getStorage() || {})['p' + key];
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -220,8 +220,6 @@ export const MessageUserStore = new class {
|
|||
}
|
||||
});
|
||||
|
||||
this.onMessageResponse = this.onMessageResponse.bind(this);
|
||||
|
||||
this.purgeMessageBodyCacheThrottle = this.purgeMessageBodyCache.throttle(30000);
|
||||
}
|
||||
|
||||
|
|
@ -437,7 +435,6 @@ export const MessageUserStore = new class {
|
|||
id = '',
|
||||
plain = '',
|
||||
resultHtml = '',
|
||||
pgpSigned = false,
|
||||
messagesDom = this.messagesBodiesDom(),
|
||||
selectedMessage = this.selectorMessageSelected(),
|
||||
message = this.message();
|
||||
|
|
@ -497,27 +494,17 @@ export const MessageUserStore = new class {
|
|||
|
||||
if ((message.isPgpSigned() || message.isPgpEncrypted()) && PgpUserStore.capaOpenPGP()) {
|
||||
plain = pString(json.Plain);
|
||||
|
||||
const isPgpEncrypted = /---BEGIN PGP MESSAGE---/.test(plain);
|
||||
if (!isPgpEncrypted) {
|
||||
pgpSigned =
|
||||
/-----BEGIN PGP SIGNED MESSAGE-----/.test(plain) && /-----BEGIN PGP SIGNATURE-----/.test(plain);
|
||||
}
|
||||
|
||||
const pre = createElement('pre');
|
||||
if (pgpSigned && message.isPgpSigned()) {
|
||||
if (message.isPgpSigned()) {
|
||||
pre.className = 'b-plain-openpgp signed';
|
||||
pre.textContent = plain;
|
||||
} else if (isPgpEncrypted && message.isPgpEncrypted()) {
|
||||
} else if (message.isPgpEncrypted()) {
|
||||
pre.className = 'b-plain-openpgp encrypted';
|
||||
pre.textContent = plain;
|
||||
} else {
|
||||
pre.innerHTML = resultHtml;
|
||||
}
|
||||
resultHtml = pre.outerHTML;
|
||||
|
||||
message.isPgpSigned(pgpSigned);
|
||||
message.isPgpEncrypted(isPgpEncrypted);
|
||||
} else {
|
||||
resultHtml = '<pre>' + resultHtml + '</pre>';
|
||||
}
|
||||
|
|
@ -630,27 +617,20 @@ export const MessageUserStore = new class {
|
|||
if (oMessage) {
|
||||
this.hideMessageBodies();
|
||||
this.messageLoading(true);
|
||||
Remote.message(this.onMessageResponse, oMessage.folder, oMessage.uid);
|
||||
Remote.message((iError, oData, bCached) => {
|
||||
if (iError) {
|
||||
if (Notification.RequestAborted !== iError) {
|
||||
this.message(null);
|
||||
this.messageError(getNotification(iError));
|
||||
}
|
||||
} else {
|
||||
this.setMessage(oData, bCached);
|
||||
}
|
||||
this.messageLoading(false);
|
||||
}, oMessage.folder, oMessage.uid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sResult
|
||||
* @param {FetchJsonDefaultResponse} oData
|
||||
* @param {boolean} bCached
|
||||
*/
|
||||
onMessageResponse(iError, oData, bCached) {
|
||||
if (iError) {
|
||||
if (Notification.RequestAborted !== iError) {
|
||||
this.message(null);
|
||||
this.messageError(getNotification(iError));
|
||||
}
|
||||
} else {
|
||||
this.setMessage(oData, bCached);
|
||||
}
|
||||
this.messageLoading(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array} list
|
||||
* @returns {string}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import * as Links from 'Common/Links';
|
|||
/**
|
||||
* Might not work due to the new ServiceWorkerRegistration.showNotification
|
||||
*/
|
||||
const HTML5Notification = window.Notification ? Notification : null,
|
||||
const HTML5Notification = window.Notification,
|
||||
HTML5NotificationStatus = () => (HTML5Notification && HTML5Notification.permission) || 'denied',
|
||||
NotificationsDenied = () => 'denied' === HTML5NotificationStatus(),
|
||||
NotificationsGranted = () => 'granted' === HTML5NotificationStatus(),
|
||||
|
|
|
|||
|
|
@ -340,11 +340,11 @@ export const PgpUserStore = new class {
|
|||
*/
|
||||
initMessageBodyControls(dom, rainLoopMessage) {
|
||||
const cl = dom && dom.classList;
|
||||
if (!cl.has('inited')) {
|
||||
if (!cl.contains('inited')) {
|
||||
cl.add('inited');
|
||||
|
||||
const encrypted = cl.has('encrypted'),
|
||||
signed = cl.has('signed'),
|
||||
const encrypted = cl.contains('encrypted'),
|
||||
signed = cl.contains('signed'),
|
||||
recipients = rainLoopMessage ? rainLoopMessage.getEmails(['from', 'to', 'cc']) : [];
|
||||
|
||||
let verControl = null;
|
||||
|
|
@ -355,10 +355,10 @@ export const PgpUserStore = new class {
|
|||
verControl = Element.fromHTML('<div class="b-openpgp-control"><i class="fontastic">🔒</i></div>');
|
||||
if (encrypted) {
|
||||
verControl.title = i18n('MESSAGE/PGP_ENCRYPTED_MESSAGE_DESC');
|
||||
verControl.addEventHandler('click', domControlEncryptedClickHelper(this, dom, domText, recipients));
|
||||
verControl.addEventListener('click', domControlEncryptedClickHelper(this, dom, domText, recipients));
|
||||
} else {
|
||||
verControl.title = i18n('MESSAGE/PGP_SIGNED_MESSAGE_DESC');
|
||||
verControl.addEventHandler('click', domControlSignedClickHelper(this, dom, domText));
|
||||
verControl.addEventListener('click', domControlSignedClickHelper(this, dom, domText));
|
||||
}
|
||||
|
||||
dom.before(verControl, createElement('div'));
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ body {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.e-spinner .e-bounce {
|
||||
.e-spinner div {
|
||||
animation: bouncedelay 1.4s infinite ease-in-out;
|
||||
background-color: var(--loading-color, #000);
|
||||
border-radius: 100%;
|
||||
|
|
@ -46,12 +46,12 @@ body {
|
|||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.e-spinner .bounce1 {
|
||||
animation-delay: -0.32s;
|
||||
.e-spinner div + div {
|
||||
animation-delay: 0.16s;
|
||||
}
|
||||
|
||||
.e-spinner .bounce2 {
|
||||
animation-delay: -0.16s;
|
||||
.e-spinner div + div + div {
|
||||
animation-delay: 0.32s;
|
||||
}
|
||||
|
||||
@keyframes bouncedelay {
|
||||
|
|
|
|||
|
|
@ -1,67 +1,25 @@
|
|||
|
||||
.b-admin-left {
|
||||
#rl-left {
|
||||
overflow: auto;
|
||||
padding-top: 50px + @rlLowMargin + 10px;
|
||||
|
||||
.b-toolbar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 34px;
|
||||
padding: 8px 0 0 @rlLowMargin;
|
||||
}
|
||||
|
||||
.b-content {
|
||||
position: absolute;
|
||||
top: 50px + @rlLowMargin + 10px;
|
||||
bottom: @rlLowMargin;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow: hidden;
|
||||
|
||||
.content {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
nav {
|
||||
a {
|
||||
color: var(--settings-menu-color, #333);
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
line-height: 30px;
|
||||
padding: 4px 10px;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.b-admin-menu {
|
||||
|
||||
.e-item {
|
||||
overflow: hidden;
|
||||
text-decoration: none;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.e-link {
|
||||
position: relative;
|
||||
display: block;
|
||||
height: 30px;
|
||||
line-height: 29px;
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
z-index: 1;
|
||||
cursor: default;
|
||||
|
||||
background-color: transparent;
|
||||
color: var(--settings-menu-disabled-color, #666);
|
||||
|
||||
padding: 4px 10px;
|
||||
|
||||
outline: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.e-item.selectable .e-link {
|
||||
cursor: pointer;
|
||||
color: var(--settings-menu-color, #333);
|
||||
}
|
||||
|
||||
.e-item.selectable {
|
||||
&:hover .e-link{
|
||||
a:focus, a:hover {
|
||||
background-color: var(--settings-menu-hover-bg-color, #333);
|
||||
color: var(--settings-menu-hover-color, #eee);
|
||||
}
|
||||
&.selected .e-link {
|
||||
|
||||
a.selected {
|
||||
background-color: var(--settings-menu-selected-bg-color, #333);
|
||||
color: var(--settings-menu-selected-color, #eee);
|
||||
}
|
||||
|
|
@ -97,14 +55,10 @@
|
|||
z-index: 2;
|
||||
|
||||
background-color: #fff;
|
||||
border: @rlMainBorderSize solid @rlMainDarkColor;
|
||||
border: 1px solid @rlMainDarkColor;
|
||||
|
||||
box-shadow: @rlMainShadow;
|
||||
border-radius: @rlMainBorderRadius;
|
||||
|
||||
.content {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,54 +3,49 @@
|
|||
|
||||
width: 600px;
|
||||
|
||||
.e-item {
|
||||
.domain-name {
|
||||
display: inline-block;
|
||||
word-break: break-all;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.domain-name {
|
||||
display: inline-block;
|
||||
word-break: break-all;
|
||||
box-sizing: border-box;
|
||||
.domain-alias {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
color: #bbb;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.button-delete {
|
||||
position: relative;
|
||||
right: 0;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
white-space: nowrap;
|
||||
|
||||
&.delete-access {
|
||||
visibility: visible;
|
||||
right: -15px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.domain-alias {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
.delete-domain, .disabled-domain {
|
||||
cursor: pointer;
|
||||
opacity: 0.5;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
.domain-name, .domain-alias {
|
||||
color: #bbb;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
.domain-name, .domain-alias {
|
||||
color: #bbb;
|
||||
}
|
||||
}
|
||||
|
||||
.button-delete {
|
||||
margin-right: 15px;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.delete-access {
|
||||
&.button-delete {
|
||||
visibility: visible;
|
||||
margin-right: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.delete-domain, .disabled-domain {
|
||||
cursor: pointer;
|
||||
.disabled-domain {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.disabled .disabled-domain {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.delete-domain, .disabled-domain {
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,26 +11,23 @@
|
|||
|
||||
width: 700px;
|
||||
|
||||
.e-item {
|
||||
.package-img {
|
||||
font-size: 12px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.package-img {
|
||||
font-size: 12px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.package-name.core {
|
||||
font-weight: bold;
|
||||
}
|
||||
.package-desc {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.package-name.core {
|
||||
font-weight: bold;
|
||||
}
|
||||
.package-desc {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.package-release, .package-actions {
|
||||
text-align: center;
|
||||
}
|
||||
.package-actions {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.package-release, .package-actions {
|
||||
text-align: center;
|
||||
}
|
||||
.package-actions {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,13 @@
|
|||
|
||||
.b-admin-plugins-list-table {
|
||||
max-width: 620px; /* span8 */
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.e-item {
|
||||
.plugin-img {
|
||||
font-size: 12px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
.plugin-img, .plugin-name {
|
||||
color: #bbb;
|
||||
}
|
||||
.disabled-plugin {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ html.rl-started-delay {
|
|||
|
||||
@media screen and (min-width: 1000px) {
|
||||
|
||||
html.rl-started-trigger .b-login-content .loginFormWrapper {
|
||||
html.rl-started-trigger .b-login-content {
|
||||
/*transform: scale(1.1);*/
|
||||
transform: translateY(-20px);
|
||||
opacity: 0.5;
|
||||
|
|
@ -40,11 +40,7 @@ html.rl-started-delay {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.b-login-content .afterLoginHide {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.b-login-content .loginFormWrapper {
|
||||
.b-login-content {
|
||||
transition: all 0.3s ease-out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
transition: margin 0.3s linear;
|
||||
}
|
||||
|
||||
.b-folders .b-content.opacity-on-panel-disabled {
|
||||
#rl-left .b-content {
|
||||
transition: opacity 0.3s linear;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
}
|
||||
|
||||
&.error {
|
||||
.attachmentIcon, .attachmentSize, .attachmentName {
|
||||
.iconMain, .iconPreview, .attachmentSize, .attachmentName {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
|
|
@ -91,11 +91,10 @@
|
|||
border-left: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.attachmentIcon {
|
||||
margin: 6px 0 0;
|
||||
.iconMain, .iconPreview {
|
||||
box-sizing: border-box;
|
||||
padding: 6px 0 0;
|
||||
font-size: 36px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
color: #aaa;
|
||||
|
||||
&.icon-none {
|
||||
|
|
@ -125,7 +124,7 @@
|
|||
}
|
||||
|
||||
.attachmentIconParent.hasPreview .showPreview,
|
||||
.attachmentIconParent.hasPreplay .showPreview {
|
||||
.attachmentIconParent.hasPreplay .showPreplay {
|
||||
display: inline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@
|
|||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@
|
|||
.attachmentAreaParent {
|
||||
border-top: 1px solid #ccc;
|
||||
overflow-y: auto;
|
||||
padding: 10px 10px 6px 10px;
|
||||
padding: 10px;
|
||||
|
||||
.no-attachments-desc {
|
||||
padding: 50px 10px;
|
||||
padding-top: 50px;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
color: #666;
|
||||
|
|
@ -38,7 +38,6 @@
|
|||
|
||||
.b-header-toolbar {
|
||||
|
||||
color: #fff;
|
||||
background-color: rgba(0,0,0,0.8);
|
||||
|
||||
.close, .minimize-custom {
|
||||
|
|
@ -72,23 +71,17 @@
|
|||
.b-header {
|
||||
|
||||
padding: 10px;
|
||||
background-color: #eee;
|
||||
color: #333;
|
||||
background-color: rgba(128,128,128,0.2);;
|
||||
|
||||
.e-identity {
|
||||
|
||||
color: #333;
|
||||
color: var(--main-color);
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.multiply {
|
||||
cursor: pointer;
|
||||
border-bottom: 1px dashed #555;
|
||||
border-bottom: 1px dashed var(--main-color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,16 +8,11 @@
|
|||
padding-top: 0;
|
||||
width: 50px;
|
||||
}
|
||||
.controls {
|
||||
margin-left: 70px;
|
||||
}
|
||||
}
|
||||
|
||||
&.modal {
|
||||
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: auto;
|
||||
|
|
@ -28,9 +23,9 @@
|
|||
}
|
||||
|
||||
.modal-body {
|
||||
overflow: auto;
|
||||
height: calc(100% - 49px);
|
||||
padding: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.b-list-toolbar {
|
||||
|
|
@ -71,10 +66,6 @@
|
|||
overflow-y: auto;
|
||||
scroll-behavior: smooth;
|
||||
|
||||
.content {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.listClear {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
|
|
@ -184,27 +175,13 @@
|
|||
overflow: auto;
|
||||
border-left: 1px solid rgba(128,128,128,0.25);
|
||||
|
||||
.content {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.contactValueStatic, .contactValueLargeStatic, .contactValueTextAreaStatic {
|
||||
span {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
font-size: 18px;
|
||||
display: inline-block;
|
||||
padding: 5px 7px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.read-only {
|
||||
.contactValueStatic, .contactValueLargeStatic, .contactValueTextAreaStatic {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.contactValueInput, .contactValueInputLarge, .contactValueTextArea {
|
||||
display: none;
|
||||
}
|
||||
padding: 5px 7px;
|
||||
font-size: 18px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.b-contact-view-desc {
|
||||
|
|
@ -235,16 +212,12 @@
|
|||
color: #aaa;
|
||||
}
|
||||
|
||||
.contactValueStatic, .contactValueLargeStatic, .contactValueTextAreaStatic {
|
||||
font-size: 18px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.contactValueInput, .contactValueInputLarge, .contactValueTextArea {
|
||||
input, textarea {
|
||||
box-shadow: none;
|
||||
border-color: #fff;
|
||||
font-size: 18px;
|
||||
width: 300px;
|
||||
width: 70vw;
|
||||
max-width: 400px;
|
||||
|
||||
&:hover {
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
|
|
@ -257,16 +230,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
.contactValueTextArea {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.contactValueInputLarge {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.hasError {
|
||||
.contactValueInput {
|
||||
input {
|
||||
color: #ee5f5b;
|
||||
border-color: #ee5f5b;
|
||||
}
|
||||
|
|
@ -293,11 +258,11 @@
|
|||
}
|
||||
|
||||
&.read-only {
|
||||
.e-read-only-sign {
|
||||
span, .e-read-only-sign {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.e-share-sign {
|
||||
input, textarea, .e-share-sign {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
.emailaddresses.emailaddresses-focused {
|
||||
background-color: #fff;
|
||||
border: @rlInputBorderSize solid darken(@inputBorder, 20%);
|
||||
border: 1px solid darken(@inputBorder, 20%);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
|
@ -49,7 +49,6 @@
|
|||
.emailaddresses li a {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
outline: 0;
|
||||
padding: 1px;
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
|
|
@ -73,7 +72,6 @@
|
|||
height: auto;
|
||||
line-height: inherit;
|
||||
margin: 0;
|
||||
outline: 0;
|
||||
padding: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
}
|
||||
|
||||
.b-folders-user {
|
||||
.e-link.print-count.system .badge {
|
||||
a.print-count.system .badge {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
|
@ -58,10 +58,6 @@
|
|||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
min-width: 100px;
|
||||
|
||||
.content {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
|
|
@ -75,7 +71,7 @@
|
|||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
.e-link {
|
||||
a {
|
||||
display: block;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
|
@ -108,11 +104,8 @@
|
|||
display: inline;
|
||||
}
|
||||
|
||||
padding: 0;
|
||||
padding-left: @folderItemPadding;
|
||||
padding-right: @folderItemPadding;
|
||||
padding: 0 @folderItemPadding;
|
||||
|
||||
outline: 0;
|
||||
text-decoration: none;
|
||||
|
||||
&.selectable {
|
||||
|
|
@ -204,21 +197,21 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.b-sub-folders .e-item .e-link {
|
||||
.b-sub-folders .e-item a {
|
||||
padding-left: @subPadding * 1 + @folderItemPadding;
|
||||
}
|
||||
.b-sub-folders .b-sub-folders .e-item .e-link {
|
||||
.b-sub-folders .b-sub-folders .e-item a {
|
||||
padding-left: @subPadding * 2 + @folderItemPadding;
|
||||
}
|
||||
.b-sub-folders .b-sub-folders .b-sub-folders .e-item .e-link {
|
||||
.b-sub-folders .b-sub-folders .b-sub-folders .e-item a {
|
||||
padding-left: @subPadding * 3 + @folderItemPadding;
|
||||
}
|
||||
.b-sub-folders .b-sub-folders .b-sub-folders .b-sub-folders .e-item .e-link {
|
||||
.b-sub-folders .b-sub-folders .b-sub-folders .b-sub-folders .e-item a {
|
||||
padding-left: @subPadding * 4 + @folderItemPadding;
|
||||
}
|
||||
|
||||
/**/
|
||||
&.single-root-inbox .i-am-inbox.e-link {
|
||||
&.single-root-inbox a.i-am-inbox {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
|
@ -229,16 +222,16 @@
|
|||
}
|
||||
|
||||
&.single-root-inbox .i-am-inbox-wrapper {
|
||||
.b-sub-folders .e-item .e-link {
|
||||
.b-sub-folders .e-item a {
|
||||
padding-left: @folderItemPadding;
|
||||
}
|
||||
.b-sub-folders .b-sub-folders .e-item .e-link {
|
||||
.b-sub-folders .b-sub-folders .e-item a {
|
||||
padding-left: @subPadding * 1 + @folderItemPadding;
|
||||
}
|
||||
.b-sub-folders .b-sub-folders .b-sub-folders .e-item .e-link {
|
||||
.b-sub-folders .b-sub-folders .b-sub-folders .e-item a {
|
||||
padding-left: @subPadding * 2 + @folderItemPadding;
|
||||
}
|
||||
.b-sub-folders .b-sub-folders .b-sub-folders .b-sub-folders .e-item .e-link {
|
||||
.b-sub-folders .b-sub-folders .b-sub-folders .b-sub-folders .e-item a {
|
||||
padding-left: @subPadding * 3 + @folderItemPadding;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
background-position: center;
|
||||
}
|
||||
|
||||
#rl-center, #rl-top, #rl-left, #rl-right {
|
||||
#rl-left, #rl-right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
|
@ -17,23 +17,8 @@
|
|||
z-index: 0;
|
||||
}
|
||||
|
||||
#rl-content {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#rl-center {
|
||||
min-width: 600px;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
html.rl-mobile {
|
||||
|
||||
#rl-center {
|
||||
min-width: 250px;
|
||||
min-height: 250px;
|
||||
}
|
||||
|
||||
&:not(.rl-left-panel-disabled) #rl-right {
|
||||
right: -150px;
|
||||
}
|
||||
|
|
@ -43,11 +28,6 @@ html.rl-mobile {
|
|||
}
|
||||
}
|
||||
|
||||
#rl-top {
|
||||
bottom: auto;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#rl-left {
|
||||
width: @rlLeftWidth;
|
||||
}
|
||||
|
|
@ -223,11 +203,10 @@ html:not(.rl-left-panel-disabled) #rl-left.resizable > .resizer,
|
|||
z-index: 1100;
|
||||
overflow: auto;
|
||||
background-color: rgba(0,0,0,0.3);
|
||||
// -webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.b-settings-content {
|
||||
padding:20px 20px 20px 30px;
|
||||
#rl-settings-subscreen {
|
||||
padding:20px;
|
||||
}
|
||||
|
||||
.dropdown-menu * + .dividerbar {
|
||||
|
|
@ -264,7 +243,7 @@ html:not(.rl-left-panel-disabled) #rl-left.resizable > .resizer,
|
|||
}
|
||||
|
||||
.btn-group > .btn.single {
|
||||
border-radius: @btnBorderRadius !important;
|
||||
border-radius: 3px !important;
|
||||
}
|
||||
|
||||
/* desktop */
|
||||
|
|
@ -300,8 +279,8 @@ html:not(.rl-left-panel-disabled) #rl-left.resizable > .resizer,
|
|||
left: 155px;
|
||||
}
|
||||
|
||||
.b-settings-content {
|
||||
padding: 10px 10px 10px 20px;
|
||||
#rl-settings-subscreen {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.dropdown-menu a {
|
||||
|
|
@ -324,7 +303,7 @@ html.rl-left-panel-disabled {
|
|||
display: block;
|
||||
}
|
||||
|
||||
.opacity-on-panel-disabled {
|
||||
.b-content {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
background-position: center;
|
||||
}
|
||||
|
||||
#rl-center, #rl-top, #rl-left, #rl-right {
|
||||
#rl-left, #rl-right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
|
@ -17,21 +17,6 @@
|
|||
z-index: 0;
|
||||
}
|
||||
|
||||
#rl-content {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#rl-center {
|
||||
min-width: 600px;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
#rl-top {
|
||||
bottom: auto;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#rl-left {
|
||||
width: @rlLeftWidth;
|
||||
}
|
||||
|
|
@ -50,11 +35,10 @@
|
|||
z-index: 1100;
|
||||
overflow: auto;
|
||||
background-color: rgba(0,0,0,0.3);
|
||||
// -webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.b-settings-content {
|
||||
padding:20px 20px 20px 30px;
|
||||
#rl-settings-subscreen {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* desktop */
|
||||
|
|
@ -77,13 +61,8 @@
|
|||
|
||||
/* mobile and tablet */
|
||||
@media screen and (max-width: 999px) {
|
||||
.b-settings-content {
|
||||
padding: 10px 10px 10px 20px;
|
||||
}
|
||||
|
||||
#rl-center {
|
||||
min-width: 250px;
|
||||
min-height: 250px;
|
||||
#rl-settings-subscreen {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
html:not(.rl-left-panel-disabled) #rl-right {
|
||||
|
|
@ -92,11 +71,7 @@
|
|||
|
||||
html.rl-left-panel-disabled {
|
||||
#rl-left {
|
||||
width: 0px !important;
|
||||
|
||||
.opacity-on-panel-disabled {
|
||||
opacity: 0.3;
|
||||
}
|
||||
width: 0 !important;
|
||||
}
|
||||
#rl-right {
|
||||
left: 5px !important;
|
||||
|
|
|
|||
|
|
@ -1,139 +1,145 @@
|
|||
|
||||
.rl-view-model {
|
||||
&.RL-Login, &.RL-AdminLogin {
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100%;
|
||||
max-width: 450px;
|
||||
z-index: 5;
|
||||
}
|
||||
.RL-Login, .RL-AdminLogin {
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
max-width: 600px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
@glass-color: #fff !important;
|
||||
@glass-error-color: #f76260 !important;
|
||||
@glass-m-color: rgba(255, 255, 255, .8) !important;
|
||||
@glass-color: #fff;
|
||||
@glass-error-color: #f76260;
|
||||
@glass-m-color: rgba(255, 255, 255, .8);
|
||||
|
||||
.b-login-content {
|
||||
|
||||
.loginFormWrapper {
|
||||
position: relative;
|
||||
|
||||
.descWrapper {
|
||||
color: var(--loading-color, #000);
|
||||
font-size: 30px;
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
text-shadow: var(--loading-text-shadow);
|
||||
}
|
||||
|
||||
.controls, .control-group {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
form {
|
||||
background-color: var(--login-bg-color, rgba(0, 0, 0, .5));
|
||||
border: var(--login-border, 1px solid rgba(255, 255, 255, .2));
|
||||
border-radius: var(--login-border-radius, 7px);
|
||||
box-shadow: var(--login-box-shadow);
|
||||
color: var(--login-color, @glass-m-color);
|
||||
margin: 0;
|
||||
padding: 40px 40px 20px 40px;
|
||||
position: relative;
|
||||
|
||||
.descWrapper {
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
|
||||
.desc {
|
||||
font-size: 30px;
|
||||
color: var(--loading-color, #000);
|
||||
text-shadow: var(--loading-text-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
.loginForm {
|
||||
background-color: var(--login-bg-color, rgba(0, 0, 0, .5));
|
||||
border: var(--login-border, 1px solid rgba(255, 255, 255, .2));
|
||||
border-radius: var(--login-border-radius, 7px);
|
||||
box-shadow: var(--login-box-shadow);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.input-append .add-on *,
|
||||
.loginForm, .legend, .e-checkbox-icon, .g-ui-link, .language-button {
|
||||
* {
|
||||
color: var(--login-color, @glass-m-color);
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
.controls, .control-group {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
padding: 40px 40px 20px 40px;
|
||||
}
|
||||
|
||||
.controls {
|
||||
.inputLoginForm, .inputEmail, .inputLogin, .inputPassword {
|
||||
font-size: 18px;
|
||||
height: 40px;
|
||||
line-height: 20px;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
.inputEmail, .inputLogin, .inputPassword {
|
||||
padding-right: 35px;
|
||||
}
|
||||
|
||||
input, .btn {
|
||||
border: 1px solid none !important;
|
||||
background: none !important;
|
||||
outline: none !important;
|
||||
text-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
|
||||
color: @glass-color;
|
||||
border-color: @glass-m-color;
|
||||
.controls.error {
|
||||
.input-append .add-on,
|
||||
.input-append .add-on * {
|
||||
color: @glass-error-color;
|
||||
}
|
||||
|
||||
input {
|
||||
|
||||
&:placeholder {
|
||||
color: @glass-color;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
&:focus, &:hover {
|
||||
border-color: @glass-color;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
||||
text-transform: uppercase;
|
||||
font-size: 13px;
|
||||
|
||||
&:hover, &:active {
|
||||
border-color: @glass-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.error {
|
||||
.input-append .add-on * {
|
||||
color: @glass-error-color;
|
||||
}
|
||||
|
||||
input {
|
||||
color: @glass-error-color;
|
||||
border-color: @glass-error-color;
|
||||
}
|
||||
color: @glass-error-color;
|
||||
border-color: @glass-error-color;
|
||||
}
|
||||
}
|
||||
|
||||
.signMeLabel .e-checkbox {
|
||||
margin-top: 5px;
|
||||
&.submitting > * {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.input-append .add-on {
|
||||
position: relative;
|
||||
height: 30px;
|
||||
background: none;
|
||||
margin-left: -35px;
|
||||
z-index: 1000;
|
||||
border: 0;
|
||||
&.submitting::after{
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -30px;
|
||||
margin-left: -30px;
|
||||
|
||||
border: 8px solid transparent;
|
||||
border-top-color: var(--spinner-color, #fff);
|
||||
animation: loginRotation 1s infinite ease-in-out;
|
||||
|
||||
border-radius: 50%;
|
||||
z-index: 1052;
|
||||
}
|
||||
}
|
||||
|
||||
.controls {
|
||||
.inputLoginForm, .inputLogin, .inputPassword {
|
||||
font-size: 18px;
|
||||
height: 40px;
|
||||
line-height: 20px;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
.inputLogin, .inputPassword {
|
||||
padding-right: 35px;
|
||||
}
|
||||
|
||||
.input-append .add-on * {
|
||||
font-size: 17px;
|
||||
line-height: 29px;
|
||||
outline: none !important;
|
||||
box-shadow: none !important;
|
||||
input, .btn {
|
||||
border: 1px solid none;
|
||||
background: none !important;
|
||||
text-shadow: none;
|
||||
box-shadow: none;
|
||||
|
||||
color: @glass-color;
|
||||
border-color: @glass-m-color;
|
||||
}
|
||||
|
||||
.controls.error .add-on *,
|
||||
.control-group.error .add-on * {
|
||||
color: #b94a48;
|
||||
input {
|
||||
|
||||
&:placeholder {
|
||||
color: @glass-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
&:focus, &:hover {
|
||||
border-color: @glass-color;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
||||
text-transform: uppercase;
|
||||
font-size: 13px;
|
||||
|
||||
&:hover, &:active {
|
||||
border-color: @glass-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.signMeLabel .e-checkbox {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.input-append .add-on {
|
||||
margin-left: -1.5em;
|
||||
position: absolute;
|
||||
font-size: 17px;
|
||||
line-height: 29px;
|
||||
right: 6px;
|
||||
top: 6px;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.input-append .add-on * {
|
||||
font-size: 17px;
|
||||
line-height: 29px;
|
||||
}
|
||||
|
||||
.buttonLogin {
|
||||
|
|
@ -163,14 +169,13 @@
|
|||
|
||||
.language-button {
|
||||
padding: 5px;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.b-login-content .loginFormWrapper {
|
||||
.wrapper {
|
||||
.b-login-content {
|
||||
form {
|
||||
padding: 30px 4vw 10px;
|
||||
}
|
||||
}
|
||||
|
|
@ -180,36 +185,11 @@
|
|||
to {transform: rotate(1turn);}
|
||||
}
|
||||
|
||||
.submitting-pane {
|
||||
position: relative;
|
||||
&.submitting > * {
|
||||
opacity: 0.3;
|
||||
}
|
||||
html &.submitting::after{
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -30px;
|
||||
margin-left: -30px;
|
||||
|
||||
border: 8px solid transparent;
|
||||
border-top-color: var(--spinner-color, #fff);
|
||||
animation: loginRotation 1s infinite ease-in-out;
|
||||
|
||||
border-radius: 50%;
|
||||
z-index: 1052;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-submit-icon-wrp {
|
||||
border: none;
|
||||
background: none;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ html.rl-no-preview-pane {
|
|||
right: 0;
|
||||
left: 0;
|
||||
height: 30px;
|
||||
padding: 10px @rlMainBorderSize;
|
||||
padding: 10px 1px;
|
||||
z-index: 102;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ html.rl-no-preview-pane {
|
|||
left: 0;
|
||||
bottom: @rlBottomMargin;
|
||||
|
||||
border: @rlMainBorderSize solid @rlMainDarkColor;
|
||||
border: 1px solid @rlMainDarkColor;
|
||||
|
||||
box-shadow: @rlMainShadow;
|
||||
border-radius: @rlMainBorderRadius;
|
||||
|
|
@ -90,7 +90,7 @@ html.rl-no-preview-pane {
|
|||
|
||||
.checkboxCheckAll {
|
||||
cursor: pointer;
|
||||
line-height: 30px;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.input-append {
|
||||
|
|
@ -134,10 +134,6 @@ html.rl-no-preview-pane {
|
|||
|
||||
background-color: #fff;
|
||||
|
||||
.content {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.listClear {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
.g-ui-min-height-300 {
|
||||
min-height: 300px;
|
||||
}
|
||||
|
|
@ -24,9 +23,9 @@
|
|||
right: @rlLowMargin;
|
||||
left: -2px;
|
||||
/*overflow: hidden;*/
|
||||
border: @rlLowBorderSize solid @rlMainDarkColor;
|
||||
border: 1px solid @rlMainDarkColor;
|
||||
|
||||
border-radius: @rlLowBorderRadius;
|
||||
border-radius: @rlMainBorderRadius;
|
||||
|
||||
background-color: #fff;
|
||||
|
||||
|
|
@ -57,10 +56,6 @@
|
|||
color: #DA4F49;
|
||||
}
|
||||
|
||||
.content {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.message-fixed-button-toolbar {
|
||||
z-index: 100;
|
||||
position: absolute;
|
||||
|
|
@ -96,11 +91,8 @@
|
|||
|
||||
padding: 10px;
|
||||
background-color: #f8f8f8;
|
||||
border-top: 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-top-right-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
z-index: 1;
|
||||
border-radius: @rlMainBorderRadius @rlMainBorderRadius 0 0;
|
||||
|
||||
.subjectParent {
|
||||
font-size: 18px;
|
||||
|
|
@ -109,9 +101,6 @@
|
|||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
margin-bottom: 8px;
|
||||
line-height: 100%;
|
||||
height: 22px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.messageButtons {
|
||||
|
|
@ -190,8 +179,6 @@
|
|||
left: 0;
|
||||
right: 0;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
border-radius: @rlLowBorderRadius;
|
||||
scroll-behavior: smooth;
|
||||
|
||||
.buttonFull {
|
||||
|
|
@ -294,13 +281,10 @@
|
|||
}
|
||||
|
||||
.rlBlockquoteSwitcher {
|
||||
|
||||
background-color: #eee;
|
||||
border: 1px solid #999;
|
||||
display: block;
|
||||
width: 30px;
|
||||
height: 14px;
|
||||
line-height: 14px;
|
||||
width: 3em;
|
||||
line-height: 1em;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin: 2em 0 10px;
|
||||
|
|
@ -311,10 +295,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.bodySubHeader {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.b-text-part {
|
||||
|
||||
height: 100%;
|
||||
|
|
@ -458,19 +438,21 @@
|
|||
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
color: #777;
|
||||
opacity: 0.5;
|
||||
|
||||
&:hover {
|
||||
color: #111;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.success {
|
||||
color: green;
|
||||
cursor: help;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.error {
|
||||
color: red;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -479,7 +461,6 @@
|
|||
&.message-focused .b-content {
|
||||
z-index: 101;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||
border-radius: @rlLowBorderRadius;
|
||||
border-color: darken(@rlMainDarkColor, 5%);
|
||||
}
|
||||
|
||||
|
|
@ -528,7 +509,7 @@ html.rl-no-preview-pane .messageView {
|
|||
}
|
||||
|
||||
.toolbar {
|
||||
padding-left: @rlMainBorderSize;
|
||||
padding-left: 1px;
|
||||
}
|
||||
|
||||
.b-content {
|
||||
|
|
@ -536,9 +517,8 @@ html.rl-no-preview-pane .messageView {
|
|||
left: 0;
|
||||
bottom: @rlBottomMargin;
|
||||
right: @rlBottomMargin;
|
||||
border: @rlMainBorderSize solid @rlMainDarkColor;
|
||||
border: 1px solid @rlMainDarkColor;
|
||||
box-shadow: @rlMainShadow;
|
||||
border-radius: @rlMainBorderRadius;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -577,8 +557,7 @@ html.rl-message-fullscreen {
|
|||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
z-index: 10000 !important;
|
||||
border: @rlLowBorderSize solid @rlMainDarkColor !important;
|
||||
border-radius: @rlLowBorderRadius !important;
|
||||
border: 1px solid @rlMainDarkColor !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,11 @@
|
|||
|
||||
.b-settins-left {
|
||||
|
||||
.b-toolbar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 34px;
|
||||
padding: 8px 0 0 @rlLowMargin;
|
||||
}
|
||||
|
||||
.b-footer {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
bottom: 10px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 20px;
|
||||
padding: 0 10px 0 5px;
|
||||
z-index: 101;
|
||||
}
|
||||
|
|
@ -27,50 +17,29 @@
|
|||
left: 0;
|
||||
right: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
nav {
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
color: var(--settings-menu-color, #333);
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
height: 30px;
|
||||
line-height: 29px;
|
||||
overflow: hidden;
|
||||
padding: 4px 10px;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.b-settings-menu {
|
||||
|
||||
.e-item {
|
||||
overflow: hidden;
|
||||
text-decoration: none;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.e-link {
|
||||
position: relative;
|
||||
display: block;
|
||||
height: 30px;
|
||||
line-height: 29px;
|
||||
font-size: 18px;
|
||||
z-index: 1;
|
||||
cursor: default;
|
||||
|
||||
background-color: transparent;
|
||||
color: var(--settings-menu-disabled-color, #666);
|
||||
|
||||
padding: 4px 10px;
|
||||
|
||||
outline: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.e-item.selectable .e-link {
|
||||
cursor: pointer;
|
||||
color: var(--settings-menu-color, #333);
|
||||
}
|
||||
|
||||
.e-item.selectable {
|
||||
&:hover .e-link{
|
||||
a:focus, a:hover {
|
||||
background-color: var(--settings-menu-hover-bg-color, #333);
|
||||
color: var(--settings-menu-hover-color, #eee);
|
||||
}
|
||||
&.selected .e-link {
|
||||
|
||||
a.selected {
|
||||
background-color: var(--settings-menu-selected-bg-color, #333);
|
||||
color: var(--settings-menu-selected-color, #eee);
|
||||
}
|
||||
|
|
@ -85,7 +54,7 @@
|
|||
right: 0;
|
||||
left: 0;
|
||||
height: 34px;
|
||||
padding: 8px 5px;
|
||||
padding: 8px 0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
|
@ -100,13 +69,9 @@
|
|||
scroll-behavior: smooth;
|
||||
|
||||
background-color: #fff;
|
||||
border: @rlMainBorderSize solid @rlMainDarkColor;
|
||||
border: 1px solid @rlMainDarkColor;
|
||||
box-shadow: @rlMainShadow;
|
||||
border-radius: @rlMainBorderRadius;
|
||||
|
||||
.content {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
.squire-toolbar {
|
||||
padding: 2px;
|
||||
border-bottom: 1px solid #b6b6b6;
|
||||
background: #EEE;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
white-space: nowrap;
|
||||
|
|
@ -143,7 +142,6 @@ Secondly, we can't rely on MUA's what to do with :empty
|
|||
border-radius: 0;
|
||||
display: none;
|
||||
font-family: var(--fontMono);
|
||||
outline: none;
|
||||
margin: 0;
|
||||
resize: none;
|
||||
white-space: pre-wrap;
|
||||
|
|
@ -162,6 +160,7 @@ Secondly, we can't rely on MUA's what to do with :empty
|
|||
display: none;
|
||||
}
|
||||
.rl-mobile .squire-toolbar {
|
||||
background: #EEE;
|
||||
padding: 1px;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
.email-title {
|
||||
display: inline-block;
|
||||
max-width: 200px;
|
||||
max-width: 50vw;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
|
|
@ -61,41 +61,27 @@
|
|||
}
|
||||
|
||||
.accountPlace {
|
||||
background-color: #000;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 0 #000;
|
||||
|
||||
display: inline-block;
|
||||
height: 29px;
|
||||
max-width: 250px;
|
||||
border-radius: 4px;
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
padding: 1px 8px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-radius: 4px;
|
||||
font-weight: bold;
|
||||
|
||||
font-size: 16px;
|
||||
height: 29px;
|
||||
line-height: 30px;
|
||||
max-width: 25vw;
|
||||
overflow: hidden;
|
||||
padding: 1px 8px;
|
||||
text-overflow: ellipsis;
|
||||
text-shadow: 0 1px 0 #000;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.account-item {
|
||||
|
||||
.icon-ok {
|
||||
&:not(.current) i:first-child,
|
||||
&.current i + i {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.current {
|
||||
.icon-ok {
|
||||
display: inline-block;
|
||||
}
|
||||
.icon-user {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.counter {
|
||||
|
|
@ -107,13 +93,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* mobile */
|
||||
@media screen and (max-width: 767px) {
|
||||
.accountPlace {
|
||||
max-width: 150px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes firstBar {
|
||||
0% { height: 30%; }
|
||||
50% { height: 100%; }
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
top: 100%;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
white-space: nowrap;
|
||||
z-index: 2001 !important;
|
||||
z-index: 2001;
|
||||
}
|
||||
@media only screen and (max-width: 600px) {
|
||||
[data-rainloopErrorTip]::before {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
|
||||
@rlLeftWidth: 200px;
|
||||
@rlInputBorderSize: 1px;
|
||||
@rlMainBorderSize: 1px;
|
||||
@rlLowBorderSize: 1px;
|
||||
|
||||
@rlMainBorderRadius: 5px;
|
||||
@rlLowBorderRadius: 3px;
|
||||
|
||||
@rlMainShadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||
|
||||
|
|
@ -13,6 +9,3 @@
|
|||
@rlBottomMargin: 5px;
|
||||
|
||||
@rlMainDarkColor: #aaa;
|
||||
|
||||
// bootstart
|
||||
@btnBorderRadius: 3px;
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
#progressjs {
|
||||
left: 0;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.progressjs-inner {
|
||||
background-color: #939595;
|
||||
height: 3px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
transition: width .5s;
|
||||
width: 0;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.progressjs-percent {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: -32px;
|
||||
bottom: 0;
|
||||
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
|
||||
background-size: 32px 32px;
|
||||
animation: simple-pace-stripe-animation 500ms linear infinite;
|
||||
}
|
||||
|
||||
@keyframes simple-pace-stripe-animation {
|
||||
0% { transform: none; }
|
||||
100% { transform: translate(-32px, 0); }
|
||||
}
|
||||
|
|
@ -21,8 +21,6 @@ class LoginAdminView extends AbstractViewCenter {
|
|||
loginError: false,
|
||||
passwordError: false,
|
||||
|
||||
formHidden: false,
|
||||
|
||||
submitRequest: false,
|
||||
submitError: ''
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
import { Scope } from 'Common/Enums';
|
||||
|
||||
import { settingsMenuKeysHandler } from 'Knoin/Knoin';
|
||||
import { AbstractViewLeft } from 'Knoin/AbstractViews';
|
||||
|
||||
class MenuSettingsAdminView extends AbstractViewLeft {
|
||||
|
|
@ -16,11 +13,6 @@ class MenuSettingsAdminView extends AbstractViewLeft {
|
|||
link(route) {
|
||||
return '#/' + route;
|
||||
}
|
||||
|
||||
onBuild(dom) {
|
||||
shortcuts.add('arrowup,arrowdown', '', Scope.Settings,
|
||||
settingsMenuKeysHandler(dom.querySelectorAll('.b-admin-menu .e-item')));
|
||||
}
|
||||
}
|
||||
|
||||
export { MenuSettingsAdminView };
|
||||
|
|
|
|||
|
|
@ -419,7 +419,24 @@ class ComposePopupView extends AbstractViewPopup {
|
|||
setFolderHash(sSentFolder, '');
|
||||
|
||||
Remote.sendMessage(
|
||||
this.sendMessageResponse.bind(this),
|
||||
(iError, data) => {
|
||||
this.sending(false);
|
||||
if (this.modalVisibility()) {
|
||||
if (iError) {
|
||||
if (Notification.CantSaveMessage === iError) {
|
||||
this.sendSuccessButSaveError(true);
|
||||
this.savedErrorDesc(i18n('COMPOSE/SAVED_ERROR_ON_SEND').trim());
|
||||
} else {
|
||||
this.sendError(true);
|
||||
this.sendErrorDesc(getNotification(iError, data && data.ErrorMessage)
|
||||
|| getNotification(Notification.CantSendMessage));
|
||||
}
|
||||
} else {
|
||||
this.closeCommand && this.closeCommand();
|
||||
}
|
||||
}
|
||||
this.reloadDraftFolder();
|
||||
},
|
||||
this.getMessageRequestParams(sSentFolder)
|
||||
);
|
||||
}
|
||||
|
|
@ -438,7 +455,40 @@ class ComposePopupView extends AbstractViewPopup {
|
|||
setFolderHash(FolderUserStore.draftFolder(), '');
|
||||
|
||||
Remote.saveMessage(
|
||||
this.saveMessageResponse.bind(this),
|
||||
(iError, oData) => {
|
||||
let result = false;
|
||||
|
||||
this.saving(false);
|
||||
|
||||
if (!iError) {
|
||||
if (oData.Result.NewFolder && oData.Result.NewUid) {
|
||||
result = true;
|
||||
|
||||
if (this.bFromDraft) {
|
||||
const message = MessageUserStore.message();
|
||||
if (message && this.draftFolder() === message.folder && this.draftUid() === message.uid) {
|
||||
MessageUserStore.message(null);
|
||||
}
|
||||
}
|
||||
|
||||
this.draftFolder(oData.Result.NewFolder);
|
||||
this.draftUid(oData.Result.NewUid);
|
||||
|
||||
this.savedTime(new Date);
|
||||
|
||||
if (this.bFromDraft) {
|
||||
setFolderHash(this.draftFolder(), '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
this.savedError(true);
|
||||
this.savedErrorDesc(getNotification(Notification.CantSaveMessage));
|
||||
}
|
||||
|
||||
this.reloadDraftFolder();
|
||||
},
|
||||
this.getMessageRequestParams(FolderUserStore.draftFolder())
|
||||
);
|
||||
}
|
||||
|
|
@ -578,63 +628,6 @@ class ComposePopupView extends AbstractViewPopup {
|
|||
}
|
||||
}
|
||||
|
||||
sendMessageResponse(iError, data) {
|
||||
|
||||
this.sending(false);
|
||||
|
||||
if (this.modalVisibility()) {
|
||||
if (iError) {
|
||||
if (Notification.CantSaveMessage === iError) {
|
||||
this.sendSuccessButSaveError(true);
|
||||
this.savedErrorDesc(i18n('COMPOSE/SAVED_ERROR_ON_SEND').trim());
|
||||
} else {
|
||||
this.sendError(true);
|
||||
this.sendErrorDesc(getNotification(iError, data && data.ErrorMessage)
|
||||
|| getNotification(Notification.CantSendMessage));
|
||||
}
|
||||
} else {
|
||||
this.closeCommand && this.closeCommand();
|
||||
}
|
||||
}
|
||||
|
||||
this.reloadDraftFolder();
|
||||
}
|
||||
|
||||
saveMessageResponse(iError, oData) {
|
||||
let result = false;
|
||||
|
||||
this.saving(false);
|
||||
|
||||
if (!iError) {
|
||||
if (oData.Result.NewFolder && oData.Result.NewUid) {
|
||||
result = true;
|
||||
|
||||
if (this.bFromDraft) {
|
||||
const message = MessageUserStore.message();
|
||||
if (message && this.draftFolder() === message.folder && this.draftUid() === message.uid) {
|
||||
MessageUserStore.message(null);
|
||||
}
|
||||
}
|
||||
|
||||
this.draftFolder(oData.Result.NewFolder);
|
||||
this.draftUid(oData.Result.NewUid);
|
||||
|
||||
this.savedTime(new Date);
|
||||
|
||||
if (this.bFromDraft) {
|
||||
setFolderHash(this.draftFolder(), '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
this.savedError(true);
|
||||
this.savedErrorDesc(getNotification(Notification.CantSaveMessage));
|
||||
}
|
||||
|
||||
this.reloadDraftFolder();
|
||||
}
|
||||
|
||||
onHide() {
|
||||
// Stop autosave
|
||||
clearTimeout(this.iTimer);
|
||||
|
|
@ -748,12 +741,6 @@ class ComposePopupView extends AbstractViewPopup {
|
|||
}
|
||||
}
|
||||
|
||||
onWarmUp() {
|
||||
if (this.modalVisibility && !this.modalVisibility()) {
|
||||
this.editor(editor => editor.modeWysiwyg());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Function} fKoValue
|
||||
* @param {Array} emails
|
||||
|
|
@ -1146,6 +1133,8 @@ class ComposePopupView extends AbstractViewPopup {
|
|||
ro.header = dom.querySelector('.b-header');
|
||||
ro.toolbar = dom.querySelector('.b-header-toolbar');
|
||||
ro.els = [dom.querySelector('.textAreaParent'), dom.querySelector('.attachmentAreaParent')];
|
||||
|
||||
this.editor(editor => editor.modeWysiwyg());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ class ContactsPopupView extends AbstractViewPopup {
|
|||
|
||||
this.bDropPageAfterDelete = false;
|
||||
|
||||
// this.saveCommandDebounce = _.debounce(this.saveCommand.bind(this), 1000);
|
||||
// this.saveCommandDebounce = this.saveCommand.bind(this).debounce(1000);
|
||||
|
||||
const
|
||||
// propertyFocused = property => !property.isValid() && !property.focused(),
|
||||
|
|
@ -382,26 +382,18 @@ class ContactsPopupView extends AbstractViewPopup {
|
|||
|
||||
deleteSelectedContacts() {
|
||||
if (this.contactsCheckedOrSelected().length) {
|
||||
Remote.contactsDelete(this.deleteResponse.bind(this), this.contactsCheckedOrSelectedUids());
|
||||
Remote.contactsDelete((iError, oData) => {
|
||||
if (500 < (!iError && oData && oData.Time ? pInt(oData.Time) : 0)) {
|
||||
this.reloadContactList(this.bDropPageAfterDelete);
|
||||
} else {
|
||||
setTimeout(() => this.reloadContactList(this.bDropPageAfterDelete), 500);
|
||||
}
|
||||
}, this.contactsCheckedOrSelectedUids());
|
||||
|
||||
this.removeCheckedOrSelectedContactsFromList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {int} iError
|
||||
* @param {FetchJsonDefaultResponse} oData
|
||||
*/
|
||||
deleteResponse(iError, oData) {
|
||||
if (500 < (!iError && oData && oData.Time ? pInt(oData.Time) : 0)) {
|
||||
this.reloadContactList(this.bDropPageAfterDelete);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.reloadContactList(this.bDropPageAfterDelete);
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
removeProperty(oProp) {
|
||||
this.viewProperties.remove(oProp);
|
||||
delegateRunOnDestroy(oProp);
|
||||
|
|
|
|||
|
|
@ -187,7 +187,48 @@ class DomainPopupView extends AbstractViewPopup {
|
|||
this.testing(true);
|
||||
|
||||
Remote.testConnectionForDomain(
|
||||
this.onTestConnectionResponse.bind(this),
|
||||
(iError, oData) => {
|
||||
this.testing(false);
|
||||
if (iError) {
|
||||
this.testingImapError(true);
|
||||
this.testingSieveError(true);
|
||||
this.testingSmtpError(true);
|
||||
this.sieveSettings(false);
|
||||
} else {
|
||||
let bImap = false,
|
||||
bSieve = false;
|
||||
|
||||
this.testingDone(true);
|
||||
this.testingImapError(true !== oData.Result.Imap);
|
||||
this.testingSieveError(true !== oData.Result.Sieve);
|
||||
this.testingSmtpError(true !== oData.Result.Smtp);
|
||||
|
||||
if (this.testingImapError() && oData.Result.Imap) {
|
||||
bImap = true;
|
||||
this.testingImapErrorDesc('');
|
||||
this.testingImapErrorDesc(oData.Result.Imap);
|
||||
}
|
||||
|
||||
if (this.testingSieveError() && oData.Result.Sieve) {
|
||||
bSieve = true;
|
||||
this.testingSieveErrorDesc('');
|
||||
this.testingSieveErrorDesc(oData.Result.Sieve);
|
||||
}
|
||||
|
||||
if (this.testingSmtpError() && oData.Result.Smtp) {
|
||||
this.testingSmtpErrorDesc('');
|
||||
this.testingSmtpErrorDesc(oData.Result.Smtp);
|
||||
}
|
||||
|
||||
if (this.sieveSettings()) {
|
||||
if (!bSieve && bImap) {
|
||||
this.sieveSettings(false);
|
||||
}
|
||||
} else if (bSieve && !bImap) {
|
||||
this.sieveSettings(true);
|
||||
}
|
||||
}
|
||||
},
|
||||
this
|
||||
);
|
||||
}
|
||||
|
|
@ -205,49 +246,6 @@ class DomainPopupView extends AbstractViewPopup {
|
|||
this.clearTesting();
|
||||
}
|
||||
|
||||
onTestConnectionResponse(iError, oData) {
|
||||
this.testing(false);
|
||||
if (iError) {
|
||||
this.testingImapError(true);
|
||||
this.testingSieveError(true);
|
||||
this.testingSmtpError(true);
|
||||
this.sieveSettings(false);
|
||||
} else {
|
||||
let bImap = false,
|
||||
bSieve = false;
|
||||
|
||||
this.testingDone(true);
|
||||
this.testingImapError(true !== oData.Result.Imap);
|
||||
this.testingSieveError(true !== oData.Result.Sieve);
|
||||
this.testingSmtpError(true !== oData.Result.Smtp);
|
||||
|
||||
if (this.testingImapError() && oData.Result.Imap) {
|
||||
bImap = true;
|
||||
this.testingImapErrorDesc('');
|
||||
this.testingImapErrorDesc(oData.Result.Imap);
|
||||
}
|
||||
|
||||
if (this.testingSieveError() && oData.Result.Sieve) {
|
||||
bSieve = true;
|
||||
this.testingSieveErrorDesc('');
|
||||
this.testingSieveErrorDesc(oData.Result.Sieve);
|
||||
}
|
||||
|
||||
if (this.testingSmtpError() && oData.Result.Smtp) {
|
||||
this.testingSmtpErrorDesc('');
|
||||
this.testingSmtpErrorDesc(oData.Result.Smtp);
|
||||
}
|
||||
|
||||
if (this.sieveSettings()) {
|
||||
if (!bSieve && bImap) {
|
||||
this.sieveSettings(false);
|
||||
}
|
||||
} else if (bSieve && !bImap) {
|
||||
this.sieveSettings(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onDomainCreateOrSaveResponse(iError) {
|
||||
this.saving(false);
|
||||
if (iError) {
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ class LanguagesPopupView extends AbstractViewPopup {
|
|||
}
|
||||
|
||||
languageTooltipName(language) {
|
||||
const result = convertLangName(language, true);
|
||||
return convertLangName(language, false) === result ? '' : result;
|
||||
return convertLangName(language, true);
|
||||
}
|
||||
|
||||
setLanguageSelection() {
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ class PluginPopupView extends AbstractViewPopup {
|
|||
constructor() {
|
||||
super('Plugin');
|
||||
|
||||
this.onPluginSettingsUpdateResponse = this.onPluginSettingsUpdateResponse.bind(this);
|
||||
|
||||
this.addObservables({
|
||||
saveError: '',
|
||||
name: '',
|
||||
|
|
@ -50,15 +48,11 @@ class PluginPopupView extends AbstractViewPopup {
|
|||
});
|
||||
|
||||
this.saveError('');
|
||||
Remote.pluginSettingsUpdate(this.onPluginSettingsUpdateResponse, list);
|
||||
}
|
||||
|
||||
onPluginSettingsUpdateResponse(iError) {
|
||||
if (iError) {
|
||||
this.saveError(getNotification(iError));
|
||||
} else {
|
||||
this.cancelCommand();
|
||||
}
|
||||
Remote.pluginSettingsUpdate(iError =>
|
||||
iError
|
||||
? this.saveError(getNotification(iError))
|
||||
: this.cancelCommand()
|
||||
, list);
|
||||
}
|
||||
|
||||
onShow(oPlugin) {
|
||||
|
|
|
|||
|
|
@ -46,8 +46,6 @@ class LoginUserView extends AbstractViewCenter {
|
|||
emailError: false,
|
||||
passwordError: false,
|
||||
|
||||
formHidden: false,
|
||||
|
||||
submitRequest: false,
|
||||
submitError: '',
|
||||
submitErrorAddidional: '',
|
||||
|
|
@ -57,9 +55,6 @@ class LoginUserView extends AbstractViewCenter {
|
|||
signMeType: LoginSignMeType.Unused
|
||||
});
|
||||
|
||||
this.forgotPasswordLinkUrl = Settings.app('forgotPasswordLinkUrl');
|
||||
this.registrationLinkUrl = Settings.app('registrationLinkUrl');
|
||||
|
||||
this.formError = ko.observable(false).extend({ falseTimeout: 500 });
|
||||
|
||||
this.allowLanguagesOnLogin = !!SettingsGet('AllowLanguagesOnLogin');
|
||||
|
|
@ -127,7 +122,8 @@ class LoginUserView extends AbstractViewCenter {
|
|||
if (Notification.InvalidInputArgument == iError) {
|
||||
iError = Notification.AuthError;
|
||||
}
|
||||
this.submitError(getNotification(iError, oData.ErrorMessage, Notification.UnknownNotification));
|
||||
this.submitError(getNotification(iError, (oData ? oData.ErrorMessage : ''),
|
||||
Notification.UnknownNotification));
|
||||
this.submitErrorAddidional((oData && oData.ErrorMessageAdditional) || '');
|
||||
} else {
|
||||
rl.route.reload();
|
||||
|
|
|
|||
|
|
@ -108,16 +108,16 @@ export class FolderListMailBoxUserView extends AbstractViewLeft {
|
|||
}
|
||||
}
|
||||
|
||||
el = eqs(event, '.b-folders .e-item .e-link.selectable .inbox-star-icon');
|
||||
el = eqs(event, '.b-folders .e-item a.selectable .inbox-star-icon');
|
||||
el && fSelectFolder(el, event, !this.isInboxStarred());
|
||||
|
||||
el = eqs(event, '.b-folders .e-item .e-link.selectable');
|
||||
el = eqs(event, '.b-folders .e-item a.selectable');
|
||||
el && fSelectFolder(el, event, false);
|
||||
});
|
||||
|
||||
shortcuts.add('arrowup,arrowdown', '', Scope.FolderList, event => {
|
||||
let items = [], index = 0;
|
||||
dom.querySelectorAll('.b-folders .e-item .e-link:not(.hidden)').forEach(node => {
|
||||
dom.querySelectorAll('.b-folders .e-item a:not(.hidden)').forEach(node => {
|
||||
if (node.offsetHeight || node.getClientRects().length) {
|
||||
items.push(node);
|
||||
if (node.matches('.focused')) {
|
||||
|
|
@ -140,7 +140,7 @@ export class FolderListMailBoxUserView extends AbstractViewLeft {
|
|||
});
|
||||
|
||||
shortcuts.add('enter,open', '', Scope.FolderList, () => {
|
||||
const item = qs('.b-folders .e-item .e-link:not(.hidden).focused');
|
||||
const item = qs('.b-folders .e-item a:not(.hidden).focused');
|
||||
if (item) {
|
||||
AppUserStore.focusedState(Scope.MessageList);
|
||||
item.click();
|
||||
|
|
@ -150,7 +150,7 @@ export class FolderListMailBoxUserView extends AbstractViewLeft {
|
|||
});
|
||||
|
||||
shortcuts.add('space', '', Scope.FolderList, () => {
|
||||
const item = qs('.b-folders .e-item .e-link:not(.hidden).focused'),
|
||||
const item = qs('.b-folders .e-item a:not(.hidden).focused'),
|
||||
folder = item && ko.dataFor(item);
|
||||
if (folder) {
|
||||
const collapsed = folder.collapsed();
|
||||
|
|
@ -169,11 +169,11 @@ export class FolderListMailBoxUserView extends AbstractViewLeft {
|
|||
});
|
||||
|
||||
AppUserStore.focusedState.subscribe(value => {
|
||||
let el = qs('.b-folders .e-item .e-link.focused');
|
||||
el && qs('.b-folders .e-item .e-link.focused').classList.remove('focused');
|
||||
let el = qs('.b-folders .e-item a.focused');
|
||||
el && qs('.b-folders .e-item a.focused').classList.remove('focused');
|
||||
if (Scope.FolderList === value) {
|
||||
el = qs('.b-folders .e-item .e-link.selected');
|
||||
el && qs('.b-folders .e-item .e-link.selected').classList.add('focused');
|
||||
el = qs('.b-folders .e-item a.selected');
|
||||
el && qs('.b-folders .e-item a.selected').classList.add('focused');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -181,7 +181,7 @@ export class FolderListMailBoxUserView extends AbstractViewLeft {
|
|||
scrollToFocused() {
|
||||
const scrollable = this.oContentScrollable;
|
||||
if (scrollable) {
|
||||
let block, focused = scrollable.querySelector('.e-item .e-link.focused');
|
||||
let block, focused = scrollable.querySelector('.e-item a.focused');
|
||||
if (focused) {
|
||||
const fRect = focused.getBoundingClientRect(),
|
||||
sRect = scrollable.getBoundingClientRect();
|
||||
|
|
|
|||
|
|
@ -263,8 +263,6 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
|||
|
||||
addEventListener('mailbox.message-view.toggle-full-screen', () => this.toggleFullScreen());
|
||||
|
||||
this.attachmentPreview = this.attachmentPreview.bind(this);
|
||||
|
||||
decorateKoCommands(this, {
|
||||
closeMessageCommand: 1,
|
||||
messageEditCommand: self => self.messageVisibility(),
|
||||
|
|
@ -313,57 +311,6 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
|||
this.oHeaderDom && this.viewBodyTopValue(this.message() ? this.oHeaderDom.offsetHeight : 0);
|
||||
}
|
||||
|
||||
// displayMailToPopup(sMailToUrl) {
|
||||
// sMailToUrl = sMailToUrl.replace(/\?.+$/, '');
|
||||
//
|
||||
// var
|
||||
// sResult = '',
|
||||
// aTo = [],
|
||||
// EmailModel = require('Model/Email').default,
|
||||
// fParseEmailLine = function(sLine) {
|
||||
// return sLine ? [decodeURIComponent(sLine)].map(sItem => {
|
||||
// var oEmailModel = new EmailModel();
|
||||
// oEmailModel.parse(sItem);
|
||||
// return oEmailModel.email ? oEmailModel : null;
|
||||
// }).filter(v => v) : null;
|
||||
// }
|
||||
// ;
|
||||
//
|
||||
// aTo = fParseEmailLine(sMailToUrl);
|
||||
// sResult = aTo && aTo[0] ? aTo[0].email : '';
|
||||
//
|
||||
// return sResult;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @param {Object} oAttachment
|
||||
* @returns {boolean}
|
||||
*/
|
||||
attachmentPreview(/*attachment*/) {
|
||||
/*
|
||||
if (attachment && attachment.isImage() && !attachment.isLinked && this.message() && this.message().attachments()) {
|
||||
const items = this.message().attachments.map(item => {
|
||||
if (item && !item.isLinked && item.isImage()) {
|
||||
if (item === attachment) {
|
||||
index = listIndex;
|
||||
}
|
||||
++listIndex;
|
||||
return {
|
||||
src: item.linkPreview(),
|
||||
msrc: item.linkThumbnail(),
|
||||
title: item.fileName
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}).filter(v => v);
|
||||
|
||||
if (items.length) {
|
||||
}
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
onBuild(dom) {
|
||||
this.fullScreenMode.subscribe(value => value && this.message() && AppUserStore.focusedState(Scope.MessageView));
|
||||
|
||||
|
|
@ -476,33 +423,28 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
|||
this.initShortcuts();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
escShortcuts() {
|
||||
if (this.viewModelVisible && this.message()) {
|
||||
const preview = SettingsUserStore.usePreviewPane();
|
||||
if (this.fullScreenMode()) {
|
||||
this.fullScreenMode(false);
|
||||
|
||||
if (preview) {
|
||||
AppUserStore.focusedState(Scope.MessageList);
|
||||
}
|
||||
} else if (!preview) {
|
||||
this.message(null);
|
||||
} else {
|
||||
AppUserStore.focusedState(Scope.MessageList);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
initShortcuts() {
|
||||
// exit fullscreen, back
|
||||
shortcuts.add('escape,backspace', '', Scope.MessageView, this.escShortcuts.bind(this));
|
||||
shortcuts.add('escape,backspace', '', Scope.MessageView, () => {
|
||||
if (this.viewModelVisible && this.message()) {
|
||||
const preview = SettingsUserStore.usePreviewPane();
|
||||
if (this.fullScreenMode()) {
|
||||
this.fullScreenMode(false);
|
||||
|
||||
if (preview) {
|
||||
AppUserStore.focusedState(Scope.MessageList);
|
||||
}
|
||||
} else if (!preview) {
|
||||
this.message(null);
|
||||
} else {
|
||||
AppUserStore.focusedState(Scope.MessageList);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// fullscreen
|
||||
shortcuts.add('enter,open', '', Scope.MessageView, () => {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import { Scope } from 'Common/Enums';
|
||||
import { leftPanelDisabled } from 'Common/Globals';
|
||||
import { settings, mailbox } from 'Common/Links';
|
||||
import { getFolderInboxName } from 'Common/Cache';
|
||||
|
||||
import { settingsMenuKeysHandler } from 'Knoin/Knoin';
|
||||
import { AbstractViewLeft } from 'Knoin/AbstractViews';
|
||||
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
|
@ -23,12 +21,9 @@ export class MenuSettingsUserView extends AbstractViewLeft {
|
|||
onBuild(dom) {
|
||||
dom.addEventListener('click', event =>
|
||||
ThemeStore.isMobile()
|
||||
&& event.target.closestWithin('.b-settings-menu .e-item.selectable', dom)
|
||||
&& event.target.closestWithin('.b-settins-left nav a', dom)
|
||||
&& leftPanelDisabled(true)
|
||||
);
|
||||
|
||||
shortcuts.add('arrowup,arrowdown', '', Scope.Settings,
|
||||
settingsMenuKeysHandler(dom.querySelectorAll('.b-settings-menu .e-item')));
|
||||
}
|
||||
|
||||
link(route) {
|
||||
|
|
|
|||
76
dev/boot.js
76
dev/boot.js
|
|
@ -38,17 +38,10 @@ const
|
|||
}
|
||||
return win[name];
|
||||
},
|
||||
STORAGE_KEY = '__rlA',
|
||||
TIME_KEY = '__rlT',
|
||||
AUTH_KEY = 'AuthAccountHash',
|
||||
storage = Storage('session'),
|
||||
timestamp = () => Math.round(Date.now() / 1000),
|
||||
setTimestamp = () => storage.setItem(TIME_KEY, timestamp()),
|
||||
|
||||
showError = () => {
|
||||
eId('rl-loading').hidden = true;
|
||||
eId('rl-loading-error').hidden = false;
|
||||
p.end();
|
||||
},
|
||||
|
||||
loadScript = src => {
|
||||
|
|
@ -57,29 +50,12 @@ const
|
|||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = doc.createElement('script');
|
||||
script.onload = () => {
|
||||
p.set(pStep += step);
|
||||
resolve();
|
||||
};
|
||||
script.onload = () => resolve();
|
||||
script.onerror = () => reject(new Error(src));
|
||||
script.src = src;
|
||||
// script.async = true;
|
||||
doc.head.append(script);
|
||||
});
|
||||
},
|
||||
|
||||
step = 100 / 7,
|
||||
p = win.progressJs = {
|
||||
set: percent => progress.style.width = Math.min(percent, 100) + '%',
|
||||
end: () => {
|
||||
if (container) {
|
||||
p.set(100);
|
||||
setTimeout(() => {
|
||||
container.remove();
|
||||
container = progress = null;
|
||||
}, 600);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!navigator || !navigator.cookieEnabled) {
|
||||
|
|
@ -89,37 +65,15 @@ if (!navigator || !navigator.cookieEnabled) {
|
|||
const layout = getCookie('rllayout');
|
||||
doc.documentElement.classList.toggle('rl-mobile', 'mobile' === layout || (!layout && 1000 > innerWidth));
|
||||
|
||||
let pStep = 0,
|
||||
container = eId('progressjs'),
|
||||
progress = container.querySelector('.progressjs-inner'),
|
||||
|
||||
let progress = eId('progressjs'),
|
||||
RL_APP_DATA = {};
|
||||
|
||||
if (progress) {
|
||||
progress.remove();
|
||||
progress = null;
|
||||
}
|
||||
|
||||
win.rl = {
|
||||
hash: {
|
||||
// getHash
|
||||
get: () => storage.getItem(STORAGE_KEY) || null,
|
||||
// setHash
|
||||
set: () => {
|
||||
storage.setItem(STORAGE_KEY, RL_APP_DATA && RL_APP_DATA[AUTH_KEY]
|
||||
? RL_APP_DATA[AUTH_KEY] : '');
|
||||
setTimestamp();
|
||||
},
|
||||
// clearHash
|
||||
clear: () => {
|
||||
storage.setItem(STORAGE_KEY, '');
|
||||
setTimestamp();
|
||||
},
|
||||
// checkTimestamp
|
||||
check: () => {
|
||||
if (timestamp() > (parseInt(storage.getItem(TIME_KEY) || 0, 10) || 0) + 3600000) {
|
||||
// 60m
|
||||
rl.hash.clear();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
data: () => RL_APP_DATA,
|
||||
adminArea: () => admin,
|
||||
settings: {
|
||||
|
|
@ -142,15 +96,8 @@ win.rl = {
|
|||
initData: appData => {
|
||||
RL_APP_DATA = appData;
|
||||
|
||||
rl.hash.set();
|
||||
|
||||
if (appData) {
|
||||
if (appData.NewThemeLink) {
|
||||
eId('app-theme-link').href = appData.NewThemeLink;
|
||||
}
|
||||
|
||||
loadScript(appData.StaticLibJsLink)
|
||||
.then(() => Promise.all([loadScript(appData.TemplatesLink), loadScript(appData.LangLink)]))
|
||||
.then(() => loadScript(appData.StaticAppJsLink))
|
||||
.then(() => appData.PluginsLink ? loadScript(appData.PluginsLink) : Promise.resolve())
|
||||
.then(() => win.__APP_BOOT ? win.__APP_BOOT(showError) : showError())
|
||||
|
|
@ -164,16 +111,11 @@ win.rl = {
|
|||
}
|
||||
};
|
||||
|
||||
p.set(1);
|
||||
|
||||
Storage('local');
|
||||
|
||||
// init section
|
||||
setInterval(setTimestamp, 60000); // 1m
|
||||
eId('app-css').href = eId('app-css').dataset.href;
|
||||
|
||||
[eId('app-css'),eId('app-theme-link')].forEach(css => css.href = css.dataset.href);
|
||||
|
||||
loadScript(`./?/${admin ? 'Admin' : ''}AppData/${rl.hash.get() || '0'}/${Math.random().toString().substr(2)}/`)
|
||||
loadScript(`./?/${admin ? 'Admin' : ''}AppData/0/${Math.random().toString().substr(2)}/`)
|
||||
.then(() => {});
|
||||
|
||||
})(this);
|
||||
|
|
|
|||
20
dev/bootstrap.js
vendored
20
dev/bootstrap.js
vendored
|
|
@ -1,9 +1,9 @@
|
|||
import { doc, elementById, dropdownVisibility, Settings } from 'Common/Globals';
|
||||
import { doc, dropdownVisibility, Settings } from 'Common/Globals';
|
||||
import { i18n } from 'Common/Translator';
|
||||
|
||||
import { root } from 'Common/Links';
|
||||
|
||||
export default (App) => {
|
||||
export default App => {
|
||||
|
||||
addEventListener('keydown', event => {
|
||||
event = event || window.event;
|
||||
|
|
@ -135,17 +135,11 @@ export default (App) => {
|
|||
});
|
||||
};
|
||||
|
||||
window.__APP_BOOT = fErrorCallback => {
|
||||
const cb = () => setTimeout(() => {
|
||||
if (rl.TEMPLATES) {
|
||||
elementById('rl-templates').innerHTML = rl.TEMPLATES;
|
||||
setTimeout(() => App.bootstart(), 10);
|
||||
} else {
|
||||
fErrorCallback();
|
||||
}
|
||||
|
||||
window.__APP_BOOT = null;
|
||||
}, 10);
|
||||
window.__APP_BOOT = () => {
|
||||
const cb = () => {
|
||||
window.__APP_BOOT = null;
|
||||
App.bootstart();
|
||||
};
|
||||
('loading' !== doc.readyState) ? cb() : doc.addEventListener('DOMContentLoaded', cb);
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue