Merge branch 'master' into plugin-2fa

This commit is contained in:
djmaze 2021-07-14 12:51:54 +02:00
commit 7985eaa23a
303 changed files with 51374 additions and 11952 deletions

View file

@ -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) {

View file

@ -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();
}
}

View file

@ -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);

View file

@ -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/';
}
/**

View file

@ -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();
};

View file

@ -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);
}
})

View file

@ -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);
}
}
}

View file

@ -412,6 +412,7 @@ class SquireUI
input.title = ctrlKey + cfg.key;
}
input.dataset.action = action;
input.tabIndex = -1;
cfg.input = input;
toolgroup.append(input);
}

View file

@ -92,7 +92,7 @@ export class AbstractViewCenter extends AbstractView
{
constructor(name, templateID)
{
super(name, templateID, ViewType.Center);
super(name, templateID, ViewType.Content);
}
}

View file

@ -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}

View file

@ -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);

View file

@ -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) {

View file

@ -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)
});
}
});

View file

@ -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);

View file

@ -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);

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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('');

View file

@ -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;
}

View file

@ -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}

View file

@ -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(),

View file

@ -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'));

View file

@ -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 {

View file

@ -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;
}
}
}

View file

@ -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;
}
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -57,7 +57,6 @@
&.disabled {
cursor: not-allowed;
opacity: 0.5;
outline: 0;
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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 {

View file

@ -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;

View file

@ -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%; }

View file

@ -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 {

View file

@ -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;

View file

@ -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); }
}

View file

@ -21,8 +21,6 @@ class LoginAdminView extends AbstractViewCenter {
loginError: false,
passwordError: false,
formHidden: false,
submitRequest: false,
submitError: ''
});

View file

@ -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 };

View file

@ -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());
}
/**

View file

@ -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);

View file

@ -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) {

View file

@ -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() {

View file

@ -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) {

View file

@ -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();

View file

@ -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();

View file

@ -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, () => {

View file

@ -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) {

View file

@ -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
View file

@ -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);
};
};