mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-29 20:19:22 +03:00
Merge branch 'master' into plugin-2fa
This commit is contained in:
commit
0aab26383c
156 changed files with 3155 additions and 1686 deletions
|
|
@ -38,7 +38,6 @@ import {
|
|||
} from 'Common/Cache';
|
||||
|
||||
import {
|
||||
userBackground,
|
||||
mailBox,
|
||||
root,
|
||||
openPgpWorkerJs,
|
||||
|
|
@ -81,6 +80,8 @@ import { ComposePopupView } from 'View/Popup/Compose';
|
|||
import { FolderSystemPopupView } from 'View/Popup/FolderSystem';
|
||||
import { AskPopupView } from 'View/Popup/Ask';
|
||||
|
||||
import { timeToNode } from 'Common/Momentor';
|
||||
|
||||
// Every 5 minutes
|
||||
const refreshFolders = 300000;
|
||||
|
||||
|
|
@ -110,16 +111,6 @@ class AppUser extends AbstractApp {
|
|||
lastTime = currentTime;
|
||||
}, interval);
|
||||
|
||||
if (SettingsGet('UserBackgroundHash')) {
|
||||
setTimeout(() => {
|
||||
const img = userBackground(SettingsGet('UserBackgroundHash'));
|
||||
if (img) {
|
||||
$htmlCL.add('UserBackground');
|
||||
doc.body.style.backgroundImage = "url("+img+")";
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
const fn = (ev=>$htmlCL.toggle('rl-ctrl-key-pressed', ev.ctrlKey)).debounce(500);
|
||||
['keydown','keyup'].forEach(t => doc.addEventListener(t, fn));
|
||||
|
||||
|
|
@ -1020,7 +1011,14 @@ class AppUser extends AbstractApp {
|
|||
this.hideLoading();
|
||||
}
|
||||
|
||||
setInterval(() => dispatchEvent(new CustomEvent('reload-time')), 60000);
|
||||
setInterval(this.reloadTime(), 60000);
|
||||
}
|
||||
|
||||
reloadTime()
|
||||
{
|
||||
setTimeout(() =>
|
||||
doc.querySelectorAll('[data-bind*="moment:"]').forEach(element => timeToNode(element))
|
||||
, 1)
|
||||
}
|
||||
|
||||
showMessageComposer(params = [])
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import * as Links from 'Common/Links';
|
||||
import { doc } from 'Common/Globals';
|
||||
import { doc, SettingsGet } from 'Common/Globals';
|
||||
|
||||
let notificator = null,
|
||||
player = null,
|
||||
|
|
@ -106,11 +106,11 @@ export const SMAudio = new class {
|
|||
|
||||
playNotification(silent) {
|
||||
if ('running' == audioCtx.state && (this.supportedMp3 || this.supportedOgg)) {
|
||||
if (!notificator) {
|
||||
notificator = createNewObject();
|
||||
notificator.src = Links.staticLink('sounds/new-mail.'+ (this.supportedMp3 ? 'mp3' : 'ogg'));
|
||||
}
|
||||
notificator = notificator || createNewObject();
|
||||
if (notificator) {
|
||||
notificator.src = Links.staticLink('sounds/'
|
||||
+ SettingsGet('NotificationSound')
|
||||
+ (this.supportedMp3 ? '.mp3' : '.ogg'));
|
||||
notificator.volume = silent ? 0.01 : 1;
|
||||
notificator.play();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,14 +70,6 @@ export function change(email) {
|
|||
return serverRequest('Change') + encodeURIComponent(email) + '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} hash
|
||||
* @returns {string}
|
||||
*/
|
||||
export function userBackground(hash) {
|
||||
return serverRequestRaw('UserBackground', hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} lang
|
||||
* @param {boolean} isAdmin
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { doc } from 'Common/Globals';
|
||||
import { i18n } from 'Common/Translator';
|
||||
|
||||
export function timestampToString(timeStampInUTC, formatStr) {
|
||||
|
|
@ -53,8 +52,3 @@ export function timeToNode(element, time) {
|
|||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
addEventListener('reload-time', () => setTimeout(() =>
|
||||
doc.querySelectorAll('[data-bind*="moment:"]').forEach(element => timeToNode(element))
|
||||
, 1)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,15 @@
|
|||
import ko from 'ko';
|
||||
import { isArray } from 'Common/Utils';
|
||||
|
||||
/*
|
||||
oCallbacks:
|
||||
ItemSelect
|
||||
MiddleClick
|
||||
AutoSelect
|
||||
ItemGetUid
|
||||
UpOrDown
|
||||
*/
|
||||
|
||||
export class Selector {
|
||||
/**
|
||||
* @param {koProperty} koList
|
||||
|
|
@ -209,11 +218,9 @@ export class Selector {
|
|||
|
||||
itemSelected(item) {
|
||||
if (this.isListChecked()) {
|
||||
if (!item) {
|
||||
(this.oCallbacks.onItemSelect || (()=>{}))(item || null);
|
||||
}
|
||||
item || (this.oCallbacks.ItemSelect || (()=>{}))(null);
|
||||
} else if (item) {
|
||||
(this.oCallbacks.onItemSelect || (()=>{}))(item);
|
||||
(this.oCallbacks.ItemSelect || (()=>{}))(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -226,20 +233,32 @@ export class Selector {
|
|||
this.oContentScrollable = contentScrollable;
|
||||
|
||||
if (contentScrollable) {
|
||||
let getItem = selector => {
|
||||
let el = event.target.closestWithin(selector, contentScrollable);
|
||||
return el ? ko.dataFor(el) : null;
|
||||
};
|
||||
|
||||
contentScrollable.addEventListener('click', event => {
|
||||
let el = event.target.closestWithin(this.sItemSelector, contentScrollable);
|
||||
el && this.actionClick(ko.dataFor(el), event);
|
||||
|
||||
el = event.target.closestWithin(this.sItemCheckedSelector, contentScrollable);
|
||||
if (el) {
|
||||
const item = ko.dataFor(el);
|
||||
const item = getItem(this.sItemCheckedSelector);
|
||||
if (item) {
|
||||
if (event.shiftKey) {
|
||||
this.actionClick(item, event);
|
||||
} else {
|
||||
this.focusedItem(item);
|
||||
item.checked(!item.checked());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
contentScrollable.addEventListener('auxclick', event => {
|
||||
if (1 == event.button) {
|
||||
const item = getItem(this.sItemSelector);
|
||||
if (item) {
|
||||
if (event.shiftKey) {
|
||||
this.actionClick(item, event);
|
||||
} else {
|
||||
this.focusedItem(item);
|
||||
item.checked(!item.checked());
|
||||
}
|
||||
this.focusedItem(item);
|
||||
(this.oCallbacks.MiddleClick || (()=>{}))(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -271,7 +290,7 @@ export class Selector {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
autoSelect() {
|
||||
return !!(this.oCallbacks.onAutoSelect || (()=>true))();
|
||||
return !!(this.oCallbacks.AutoSelect || (()=>true))();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -281,7 +300,7 @@ export class Selector {
|
|||
getItemUid(item) {
|
||||
let uid = '';
|
||||
|
||||
const getItemUidCallback = this.oCallbacks.onItemGetUid || null;
|
||||
const getItemUidCallback = this.oCallbacks.ItemGetUid || null;
|
||||
if (getItemUidCallback && item) {
|
||||
uid = getItemUidCallback(item);
|
||||
}
|
||||
|
|
@ -312,7 +331,7 @@ export class Selector {
|
|||
} else if (++i < listLen) {
|
||||
result = list[i];
|
||||
}
|
||||
result || (this.oCallbacks.onUpUpOrDownDown || (()=>true))('ArrowUp' === sEventKey);
|
||||
result || (this.oCallbacks.UpOrDown || (()=>true))('ArrowUp' === sEventKey);
|
||||
} else if ('Home' === sEventKey) {
|
||||
result = list[0];
|
||||
} else if ('End' === sEventKey) {
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ export function reload(admin, language) {
|
|||
// reload the data
|
||||
if (init()) {
|
||||
i18nToNodes(doc);
|
||||
dispatchEvent(new CustomEvent('reload-time'));
|
||||
admin || rl.app.reloadTime();
|
||||
trigger(!trigger());
|
||||
}
|
||||
script.remove();
|
||||
|
|
|
|||
|
|
@ -38,9 +38,6 @@ class AbstractView {
|
|||
keyScope(this.sCurrentScope);
|
||||
}
|
||||
|
||||
cancelCommand() {}
|
||||
closeCommand() {}
|
||||
|
||||
querySelector(selectors) {
|
||||
return this.viewModelDom.querySelector(selectors);
|
||||
}
|
||||
|
|
@ -68,7 +65,10 @@ export class AbstractViewPopup extends AbstractView
|
|||
this.sDefaultScope = Scope[name];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
cancelCommand() {}
|
||||
closeCommand() {}
|
||||
*/
|
||||
/**
|
||||
* @returns {void}
|
||||
*/
|
||||
|
|
@ -76,7 +76,7 @@ export class AbstractViewPopup extends AbstractView
|
|||
addEventListener('keydown', event => {
|
||||
if (event && this.modalVisibility && this.modalVisibility()) {
|
||||
if (!this.bDisabeCloseOnEsc && 'Escape' == event.key) {
|
||||
this.cancelCommand && this.cancelCommand();
|
||||
this.cancelCommand();
|
||||
return false;
|
||||
} else if ('Backspace' == event.key && !inFocus()) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -524,13 +524,6 @@ export class MessageModel extends AbstractModel {
|
|||
}
|
||||
}
|
||||
|
||||
storeDataInDom() {
|
||||
if (this.body) {
|
||||
this.body.rlIsHtml = !!this.isHtml();
|
||||
this.body.rlHasImages = !!this.hasImages();
|
||||
}
|
||||
}
|
||||
|
||||
fetchDataFromDom() {
|
||||
if (this.body) {
|
||||
this.isHtml(!!this.body.rlIsHtml);
|
||||
|
|
|
|||
|
|
@ -38,13 +38,6 @@ class RemoteAdminFetch extends AbstractFetchRemote {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
pluginList(fCallback) {
|
||||
this.defaultRequest(fCallback, 'AdminPluginList');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import { DomainsAdminSettings } from 'Settings/Admin/Domains';
|
|||
import { LoginAdminSettings } from 'Settings/Admin/Login';
|
||||
import { ContactsAdminSettings } from 'Settings/Admin/Contacts';
|
||||
import { SecurityAdminSettings } from 'Settings/Admin/Security';
|
||||
import { PluginsAdminSettings } from 'Settings/Admin/Plugins';
|
||||
import { PackagesAdminSettings } from 'Settings/Admin/Packages';
|
||||
import { AboutAdminSettings } from 'Settings/Admin/About';
|
||||
import { BrandingAdminSettings } from 'Settings/Admin/Branding';
|
||||
|
|
@ -38,7 +37,6 @@ export class SettingsAdminScreen extends AbstractSettingsScreen {
|
|||
[BrandingAdminSettings, 'Branding'],
|
||||
[ContactsAdminSettings, 'Contacts'],
|
||||
[SecurityAdminSettings, 'Security'],
|
||||
[PluginsAdminSettings, 'Plugins'],
|
||||
[PackagesAdminSettings, 'Packages'],
|
||||
[AboutAdminSettings, 'About'],
|
||||
].forEach(item =>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ import { getNotification } from 'Common/Translator';
|
|||
import { PackageAdminStore } from 'Stores/Admin/Package';
|
||||
import Remote from 'Remote/Admin/Fetch';
|
||||
|
||||
import { showScreenPopup } from 'Knoin/Knoin';
|
||||
import { PluginPopupView } from 'View/Popup/Plugin';
|
||||
import { SettingsGet } from 'Common/Globals';
|
||||
|
||||
export class PackagesAdminSettings {
|
||||
constructor() {
|
||||
this.packagesError = ko.observable('');
|
||||
|
|
@ -13,24 +17,42 @@ export class PackagesAdminSettings {
|
|||
this.packages = PackageAdminStore;
|
||||
|
||||
this.packagesCurrent = ko.computed(() =>
|
||||
PackageAdminStore.filter(item => item && item.installed && !item.compare)
|
||||
PackageAdminStore.filter(item => item && item.installed && !item.canBeUpdated)
|
||||
);
|
||||
this.packagesAvailableForUpdate = ko.computed(() =>
|
||||
PackageAdminStore.filter(item => item && item.installed && !!item.compare)
|
||||
PackageAdminStore.filter(item => item && item.installed && !!item.canBeUpdated)
|
||||
);
|
||||
this.packagesAvailableForInstallation = ko.computed(() =>
|
||||
PackageAdminStore.filter(item => item && !item.installed)
|
||||
);
|
||||
|
||||
this.visibility = ko.computed(() => (PackageAdminStore.loading() ? 'visible' : 'hidden'));
|
||||
|
||||
this.enabledPlugins = ko.observable(!!SettingsGet('EnabledPlugins'));
|
||||
this.enabledPlugins.subscribe(value =>
|
||||
Remote.saveAdminConfig(null, {
|
||||
EnabledPlugins: value ? 1 : 0
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
onShow() {
|
||||
this.packagesError('');
|
||||
}
|
||||
|
||||
onBuild() {
|
||||
onBuild(oDom) {
|
||||
PackageAdminStore.fetch();
|
||||
|
||||
oDom.addEventListener('click', event => {
|
||||
// configurePlugin
|
||||
let el = event.target.closestWithin('.package-configure', oDom),
|
||||
data = el ? ko.dataFor(el) : 0;
|
||||
data && Remote.plugin((iError, data) => iError || showScreenPopup(PluginPopupView, [data.Result]), data.name)
|
||||
// disablePlugin
|
||||
el = event.target.closestWithin('.package-active', oDom);
|
||||
data = el ? ko.dataFor(el) : 0;
|
||||
data && this.disablePlugin(data);
|
||||
});
|
||||
}
|
||||
|
||||
requestHelper(packageToRequest, install) {
|
||||
|
|
@ -70,4 +92,20 @@ export class PackagesAdminSettings {
|
|||
Remote.packageInstall(this.requestHelper(packageToInstall, true), packageToInstall);
|
||||
}
|
||||
}
|
||||
|
||||
disablePlugin(plugin) {
|
||||
let b = !plugin.enabled();
|
||||
plugin.enabled(b);
|
||||
Remote.pluginDisable((iError, data) => {
|
||||
if (iError) {
|
||||
this.packagesError(
|
||||
(Notification.UnsupportedPluginPackage === iError && data && data.ErrorMessage)
|
||||
? data.ErrorMessage
|
||||
: getNotification(iError)
|
||||
);
|
||||
}
|
||||
// PackageAdminStore.fetch();
|
||||
}, plugin.name, !b);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
import ko from 'ko';
|
||||
|
||||
import { Notification } from 'Common/Enums';
|
||||
import { SettingsGet } from 'Common/Globals';
|
||||
import { getNotification } from 'Common/Translator';
|
||||
|
||||
import { showScreenPopup } from 'Knoin/Knoin';
|
||||
|
||||
import { PluginAdminStore } from 'Stores/Admin/Plugin';
|
||||
|
||||
import Remote from 'Remote/Admin/Fetch';
|
||||
|
||||
import { PluginPopupView } from 'View/Popup/Plugin';
|
||||
|
||||
export class PluginsAdminSettings
|
||||
{
|
||||
constructor() {
|
||||
this.enabledPlugins = ko.observable(!!SettingsGet('EnabledPlugins'));
|
||||
|
||||
this.plugins = PluginAdminStore;
|
||||
this.pluginsError = PluginAdminStore.error;
|
||||
|
||||
this.enabledPlugins.subscribe(value =>
|
||||
Remote.saveAdminConfig(null, {
|
||||
EnabledPlugins: value ? 1 : 0
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
disablePlugin(plugin) {
|
||||
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((iError, data) => iError || showScreenPopup(PluginPopupView, [data.Result]), plugin.name);
|
||||
}
|
||||
|
||||
onBuild(oDom) {
|
||||
oDom.addEventListener('click', event => {
|
||||
let el = event.target.closestWithin('.configure-plugin-action', oDom);
|
||||
el && ko.dataFor(el) && this.configurePlugin(ko.dataFor(el));
|
||||
|
||||
el = event.target.closestWithin('.disabled-plugin', oDom);
|
||||
el && ko.dataFor(el) && this.disablePlugin(ko.dataFor(el));
|
||||
});
|
||||
}
|
||||
|
||||
onShow() {
|
||||
PluginAdminStore.error('');
|
||||
PluginAdminStore.fetch();
|
||||
}
|
||||
}
|
||||
|
|
@ -32,6 +32,8 @@ export class GeneralUserSettings {
|
|||
this.layout = SettingsUserStore.layout;
|
||||
|
||||
this.enableSoundNotification = NotificationUserStore.enableSoundNotification;
|
||||
this.notificationSound = ko.observable(SettingsGet('NotificationSound'));
|
||||
this.notificationSounds = ko.observableArray(SettingsGet('NewMailSounds'));
|
||||
|
||||
this.enableDesktopNotification = NotificationUserStore.enableDesktopNotification;
|
||||
this.isDesktopNotificationDenied = NotificationUserStore.isDesktopNotificationDenied;
|
||||
|
|
@ -115,6 +117,10 @@ export class GeneralUserSettings {
|
|||
enableDesktopNotification: value => Remote.saveSetting('DesktopNotifications', value ? 1 : 0),
|
||||
|
||||
enableSoundNotification: value => Remote.saveSetting('SoundNotification', value ? 1 : 0),
|
||||
notificationSound: value => {
|
||||
Remote.saveSetting('NotificationSound', value);
|
||||
rl.settings.set('NotificationSound', value);
|
||||
},
|
||||
|
||||
replySameFolder: value => Remote.saveSetting('ReplySameFolder', value ? 1 : 0),
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import ko from 'ko';
|
|||
|
||||
import { SaveSettingsStep, UploadErrorCode, Capa } from 'Common/Enums';
|
||||
import { changeTheme, convertThemeName } from 'Common/Utils';
|
||||
import { userBackground, themePreviewLink, serverRequest } from 'Common/Links';
|
||||
import { themePreviewLink, serverRequest } from 'Common/Links';
|
||||
import { i18n } from 'Common/Translator';
|
||||
import { doc, $htmlCL, Settings } from 'Common/Globals';
|
||||
import { Settings } from 'Common/Globals';
|
||||
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
|
|
@ -38,16 +38,6 @@ export class ThemesUserSettings {
|
|||
Theme: value
|
||||
});
|
||||
});
|
||||
|
||||
this.background.hash.subscribe((value) => {
|
||||
if (!value) {
|
||||
$htmlCL.remove('UserBackground');
|
||||
doc.body.removeAttribute('style');
|
||||
} else {
|
||||
$htmlCL.add('UserBackground');
|
||||
doc.body.style.backgroundImage = "url("+userBackground(value)+")";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onBuild() {
|
||||
|
|
|
|||
|
|
@ -8,35 +8,34 @@ PackageAdminStore.real = ko.observable(true);
|
|||
|
||||
PackageAdminStore.loading = ko.observable(false);
|
||||
|
||||
//PackageAdminStore.error = ko.observable('');
|
||||
|
||||
PackageAdminStore.fetch = () => {
|
||||
PackageAdminStore.loading(true);
|
||||
Remote.packagesList((iError, data) => {
|
||||
PackageAdminStore.loading(false);
|
||||
if (!iError) {
|
||||
if (iError) {
|
||||
PackageAdminStore.real(false);
|
||||
} else {
|
||||
PackageAdminStore.real(!!data.Result.Real);
|
||||
|
||||
let list = [];
|
||||
const loading = {};
|
||||
|
||||
PackageAdminStore.forEach(item => {
|
||||
if (item && item.loading()) {
|
||||
loading[item.file] = item;
|
||||
}
|
||||
});
|
||||
|
||||
let list = [];
|
||||
if (isArray(data.Result.List)) {
|
||||
list = data.Result.List.map(item => {
|
||||
if (item) {
|
||||
item.loading = ko.observable(loading[item.file] !== undefined);
|
||||
return 'core' === item.type && !item.canBeInstalled ? null : item;
|
||||
}
|
||||
return null;
|
||||
}).filter(v => v);
|
||||
list = data.Result.List.filter(v => v).map(item => {
|
||||
item.loading = ko.observable(loading[item.file] !== undefined);
|
||||
item.enabled = ko.observable(item.enabled);
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
PackageAdminStore(list);
|
||||
} else {
|
||||
PackageAdminStore.real(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
import ko from 'ko';
|
||||
import Remote from 'Remote/Admin/Fetch';
|
||||
|
||||
export const PluginAdminStore = ko.observableArray();
|
||||
|
||||
PluginAdminStore.loading = ko.observable(false);
|
||||
|
||||
PluginAdminStore.error = ko.observable('');
|
||||
|
||||
PluginAdminStore.fetch = () => {
|
||||
PluginAdminStore.loading(true);
|
||||
Remote.pluginList((iError, data) => {
|
||||
PluginAdminStore.loading(false);
|
||||
if (!iError) {
|
||||
PluginAdminStore(
|
||||
data.Result.map(item => ({
|
||||
name: item.Name,
|
||||
disabled: ko.observable(!item.Enabled),
|
||||
configured: ko.observable(!!item.Configured)
|
||||
}))
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import ko from 'ko';
|
||||
import { $htmlCL, leftPanelDisabled, Settings, SettingsGet } from 'Common/Globals';
|
||||
import { doc, $htmlCL, leftPanelDisabled, Settings, SettingsGet } from 'Common/Globals';
|
||||
import { isArray } from 'Common/Utils';
|
||||
import { serverRequestRaw } from 'Common/Links';
|
||||
|
||||
export const ThemeStore = {
|
||||
themes: ko.observableArray(),
|
||||
|
|
@ -25,3 +26,13 @@ export const ThemeStore = {
|
|||
ThemeStore.theme = ko.observable('').extend({ limitedList: ThemeStore.themes });
|
||||
|
||||
ThemeStore.isMobile.subscribe(value => $htmlCL.toggle('rl-mobile', value));
|
||||
|
||||
ThemeStore.userBackgroundHash.subscribe(value => {
|
||||
if (value) {
|
||||
$htmlCL.add('UserBackground');
|
||||
doc.body.style.backgroundImage = "url("+serverRequestRaw('UserBackground', value)+")";
|
||||
} else {
|
||||
$htmlCL.remove('UserBackground');
|
||||
doc.body.removeAttribute('style');
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import ko from 'ko';
|
|||
|
||||
import { Scope, Notification } from 'Common/Enums';
|
||||
import { MessageSetAction } from 'Common/EnumsUser';
|
||||
import { doc, createElement, elementById } from 'Common/Globals';
|
||||
import { doc, $htmlCL, createElement, elementById } from 'Common/Globals';
|
||||
import { isNonEmptyArray, pInt, pString, addObservablesTo, addSubscribablesTo } from 'Common/Utils';
|
||||
import { plainToHtml } from 'Common/UtilsUser';
|
||||
|
||||
|
|
@ -186,6 +186,8 @@ export const MessageUserStore = new class {
|
|||
}
|
||||
},
|
||||
|
||||
listLoadingAnimation: value => $htmlCL.toggle('list-loading', value),
|
||||
|
||||
listLoading: value =>
|
||||
this.listCompleteLoading(value || this.listIsNotCompleted()),
|
||||
|
||||
|
|
@ -220,7 +222,7 @@ export const MessageUserStore = new class {
|
|||
}
|
||||
});
|
||||
|
||||
this.purgeMessageBodyCacheThrottle = this.purgeMessageBodyCache.throttle(30000);
|
||||
this.purgeMessageBodyCache = this.purgeMessageBodyCache.throttle(30000);
|
||||
}
|
||||
|
||||
purgeMessageBodyCache() {
|
||||
|
|
@ -428,16 +430,12 @@ export const MessageUserStore = new class {
|
|||
);
|
||||
}
|
||||
|
||||
setMessage(data, cached) {
|
||||
setMessage(data, cached, oMessage) {
|
||||
let isNew = false,
|
||||
body = null,
|
||||
json = data && data.Result,
|
||||
id = '',
|
||||
plain = '',
|
||||
resultHtml = '',
|
||||
messagesDom = this.messagesBodiesDom(),
|
||||
selectedMessage = this.selectorMessageSelected(),
|
||||
message = this.message();
|
||||
message = oMessage || this.message();
|
||||
|
||||
if (
|
||||
json &&
|
||||
|
|
@ -447,7 +445,7 @@ export const MessageUserStore = new class {
|
|||
) {
|
||||
const threads = message.threads();
|
||||
if (message.uid !== json.Uid && 1 < threads.length && threads.includes(json.Uid)) {
|
||||
message = MessageModel.reviveFromJson(json);
|
||||
message = oMessage ? null : MessageModel.reviveFromJson(json);
|
||||
if (message) {
|
||||
message.threads(threads);
|
||||
MessageFlagsCache.initMessage(message);
|
||||
|
|
@ -460,7 +458,7 @@ export const MessageUserStore = new class {
|
|||
}
|
||||
|
||||
if (message && message.uid === json.Uid) {
|
||||
this.messageError('');
|
||||
oMessage || this.messageError('');
|
||||
|
||||
if (cached) {
|
||||
delete json.IsSeen;
|
||||
|
|
@ -475,7 +473,8 @@ export const MessageUserStore = new class {
|
|||
addRequestedMessage(message.folder, message.uid);
|
||||
|
||||
if (messagesDom) {
|
||||
id = 'rl-mgs-' + message.hash.replace(/[^a-zA-Z0-9]/g, '');
|
||||
let body = null,
|
||||
id = 'rl-mgs-' + message.hash.replace(/[^a-zA-Z0-9]/g, '');
|
||||
|
||||
const textBody = elementById(id);
|
||||
if (textBody) {
|
||||
|
|
@ -483,7 +482,9 @@ export const MessageUserStore = new class {
|
|||
message.fetchDataFromDom();
|
||||
messagesDom.append(textBody);
|
||||
} else {
|
||||
let isHtml = !!json.Html;
|
||||
let isHtml = !!json.Html,
|
||||
plain = '',
|
||||
resultHtml = '<pre></pre>';
|
||||
if (isHtml) {
|
||||
resultHtml = json.Html.toString();
|
||||
if (SettingsUserStore.removeColors()) {
|
||||
|
|
@ -508,8 +509,6 @@ export const MessageUserStore = new class {
|
|||
} else {
|
||||
resultHtml = '<pre>' + resultHtml + '</pre>';
|
||||
}
|
||||
} else {
|
||||
resultHtml = '<pre>' + resultHtml + '</pre>';
|
||||
}
|
||||
|
||||
body = Element.fromHTML('<div id="' + id + '" hidden="" class="b-text-part '
|
||||
|
|
@ -517,22 +516,25 @@ export const MessageUserStore = new class {
|
|||
+ findEmailAndLinks(resultHtml)
|
||||
+ '</div>');
|
||||
|
||||
// Drop Microsoft Office style properties
|
||||
const rgbRE = /rgb\((\d+),\s*(\d+),\s*(\d+)\)/g,
|
||||
hex = n => ('0' + parseInt(n).toString(16)).slice(-2);
|
||||
body.querySelectorAll('[style*=mso]').forEach(el =>
|
||||
el.setAttribute('style', el.style.cssText.replace(rgbRE, (m,r,g,b) => '#' + hex(r) + hex(g) + hex(b)))
|
||||
);
|
||||
if (isHtml) {
|
||||
// Drop Microsoft Office style properties
|
||||
const rgbRE = /rgb\((\d+),\s*(\d+),\s*(\d+)\)/g,
|
||||
hex = n => ('0' + parseInt(n).toString(16)).slice(-2);
|
||||
body.querySelectorAll('[style*=mso]').forEach(el =>
|
||||
el.setAttribute('style', el.style.cssText.replace(rgbRE, (m,r,g,b) => '#' + hex(r) + hex(g) + hex(b)))
|
||||
);
|
||||
}
|
||||
|
||||
body.rlIsHtml = isHtml;
|
||||
body.rlHasImages = !!json.HasExternals;
|
||||
|
||||
message.body = body;
|
||||
|
||||
message.isHtml(isHtml);
|
||||
message.hasImages(!!json.HasExternals);
|
||||
message.hasImages(body.rlHasImages);
|
||||
|
||||
messagesDom.append(body);
|
||||
|
||||
message.storeDataInDom();
|
||||
|
||||
if (json.HasInternals) {
|
||||
message.showInternalImages();
|
||||
}
|
||||
|
|
@ -541,12 +543,12 @@ export const MessageUserStore = new class {
|
|||
message.showExternalImages();
|
||||
}
|
||||
|
||||
this.purgeMessageBodyCacheThrottle();
|
||||
this.purgeMessageBodyCache();
|
||||
}
|
||||
|
||||
this.messageActiveDom(message.body);
|
||||
oMessage || this.messageActiveDom(message.body);
|
||||
|
||||
this.hideMessageBodies();
|
||||
oMessage || this.hideMessageBodies();
|
||||
|
||||
if (body) {
|
||||
this.initOpenPgpControls(body, message);
|
||||
|
|
@ -554,7 +556,8 @@ export const MessageUserStore = new class {
|
|||
this.initBlockquoteSwitcher(body);
|
||||
}
|
||||
|
||||
message.body.hidden = false;
|
||||
oMessage || (message.body.hidden = false);
|
||||
oMessage && message.viewPopupMessage();
|
||||
}
|
||||
|
||||
MessageFlagsCache.initMessage(message);
|
||||
|
|
@ -563,8 +566,6 @@ export const MessageUserStore = new class {
|
|||
}
|
||||
|
||||
if (isNew) {
|
||||
message = this.message();
|
||||
|
||||
if (
|
||||
selectedMessage &&
|
||||
message &&
|
||||
|
|
@ -613,20 +614,20 @@ export const MessageUserStore = new class {
|
|||
}
|
||||
}
|
||||
|
||||
populateMessageBody(oMessage) {
|
||||
populateMessageBody(oMessage, preload) {
|
||||
if (oMessage) {
|
||||
this.hideMessageBodies();
|
||||
this.messageLoading(true);
|
||||
preload || this.hideMessageBodies();
|
||||
preload || this.messageLoading(true);
|
||||
Remote.message((iError, oData, bCached) => {
|
||||
if (iError) {
|
||||
if (Notification.RequestAborted !== iError) {
|
||||
if (Notification.RequestAborted !== iError && !preload) {
|
||||
this.message(null);
|
||||
this.messageError(getNotification(iError));
|
||||
}
|
||||
} else {
|
||||
this.setMessage(oData, bCached);
|
||||
this.setMessage(oData, bCached, preload ? oMessage : null);
|
||||
}
|
||||
this.messageLoading(false);
|
||||
preload || this.messageLoading(false);
|
||||
}, oMessage.folder, oMessage.uid);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,21 +23,19 @@
|
|||
|
||||
@import "Ui.less";
|
||||
@import "Main.less";
|
||||
@import "LayoutAdmin.less";
|
||||
@import "Components.less";
|
||||
@import "Login.less";
|
||||
@import "Ask.less";
|
||||
@import "Languages.less";
|
||||
|
||||
@import "Admin.less";
|
||||
@import "AdminGeneral.less";
|
||||
@import "AdminBranding.less";
|
||||
@import "AdminDomains.less";
|
||||
@import "AdminDomain.less";
|
||||
@import "AdminPackages.less";
|
||||
@import "AdminPlugins.less";
|
||||
@import "AdminPlugin.less";
|
||||
@import "AdminAbout.less";
|
||||
@import "Admin/Layout.less";
|
||||
@import "Admin/General.less";
|
||||
@import "Admin/Branding.less";
|
||||
@import "Admin/Domains.less";
|
||||
@import "Admin/Domain.less";
|
||||
@import "Admin/Packages.less";
|
||||
@import "Admin/Plugin.less";
|
||||
@import "Admin/About.less";
|
||||
|
||||
@import "Animations.less";
|
||||
|
||||
|
|
|
|||
|
|
@ -24,45 +24,39 @@
|
|||
|
||||
@import "Ui.less";
|
||||
@import "Main.less";
|
||||
@import "Layout.less";
|
||||
@import "Components.less";
|
||||
@import "Login.less";
|
||||
@import "Ask.less";
|
||||
@import "Languages.less";
|
||||
|
||||
@import "SystemDropDown.less";
|
||||
@import "Shortcuts.less";
|
||||
@import "FolderList.less";
|
||||
/*
|
||||
@import "FolderClear.less";
|
||||
@import "FolderCreate.less";
|
||||
@import "FolderSystem.less";
|
||||
@import "Account.less";
|
||||
*/
|
||||
@import "Filter.less";
|
||||
@import "Template.less";
|
||||
@import "OpenPgpKey.less";
|
||||
@import "Identity.less";
|
||||
@import "AdvancedSearch.less";
|
||||
@import "Attachmnets.less";
|
||||
@import "MessageList.less";
|
||||
@import "MessageView.less";
|
||||
@import "Contacts.less";
|
||||
@import "Compose.less";
|
||||
@import "EmailAddresses.less";
|
||||
@import "User/Layout.less";
|
||||
@import "User/SystemDropDown.less";
|
||||
@import "User/Shortcuts.less";
|
||||
@import "User/FolderList.less";
|
||||
@import "User/Filter.less";
|
||||
@import "User/Template.less";
|
||||
@import "User/OpenPgpKey.less";
|
||||
@import "User/Identity.less";
|
||||
@import "User/AdvancedSearch.less";
|
||||
@import "User/Attachmnets.less";
|
||||
@import "User/MessageList.less";
|
||||
@import "User/MessageView.less";
|
||||
@import "User/Contacts.less";
|
||||
@import "User/Compose.less";
|
||||
@import "User/EmailAddresses.less";
|
||||
|
||||
@import "Settings.less";
|
||||
@import "SettingsGeneral.less";
|
||||
@import "SettingsAccounts.less";
|
||||
@import "SettingsTemplates.less";
|
||||
@import "SettingsOpenPGP.less";
|
||||
@import "SettingsFolders.less";
|
||||
@import "SettingsThemes.less";
|
||||
@import "SettingsFilters.less";
|
||||
@import "User/Settings.less";
|
||||
@import "User/SettingsGeneral.less";
|
||||
@import "User/SettingsAccounts.less";
|
||||
@import "User/SettingsTemplates.less";
|
||||
@import "User/SettingsOpenPGP.less";
|
||||
@import "User/SettingsFolders.less";
|
||||
@import "User/SettingsThemes.less";
|
||||
@import "User/SettingsFilters.less";
|
||||
|
||||
@import "SquireUI.less";
|
||||
@import "User/SquireUI.less";
|
||||
|
||||
@import "AnimationsUser.less";
|
||||
@import "User/Animations.less";
|
||||
@import "Animations.less";
|
||||
|
||||
@import "_End.less";
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
.b-account-add-content {
|
||||
.modal-header {
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
.b-domain-alias-content {
|
||||
&.modal {
|
||||
width: 330px;
|
||||
max-width: 330px;
|
||||
}
|
||||
|
||||
.error-desc {
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
.b-domain-content {
|
||||
|
||||
&.modal {
|
||||
width: 810px;
|
||||
max-width: 810px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
|
|
@ -1,7 +1,25 @@
|
|||
.UserBackground body {
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
#rl-left, #rl-right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#rl-left {
|
||||
overflow: auto;
|
||||
padding-top: 50px + @rlLowMargin + 10px;
|
||||
width: @rlLeftWidth;
|
||||
|
||||
nav {
|
||||
a {
|
||||
|
|
@ -26,6 +44,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
#rl-right {
|
||||
z-index: 1;
|
||||
left: @rlLeftWidth;
|
||||
}
|
||||
|
||||
.b-admin-right {
|
||||
|
||||
.b-toolbar {
|
||||
|
|
@ -67,3 +90,56 @@
|
|||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
#rl-popups > .rl-view-model {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1100;
|
||||
overflow: auto;
|
||||
background-color: rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
#rl-settings-subscreen {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* desktop */
|
||||
@media screen and (min-width: 1000px) {
|
||||
.toggleLeft {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* desktop-large */
|
||||
@media screen and (min-width: 1401px) {
|
||||
#rl-left {
|
||||
width: @rlLeftWidth + 20;
|
||||
}
|
||||
|
||||
#rl-right {
|
||||
left: @rlLeftWidth + 20;
|
||||
}
|
||||
}
|
||||
|
||||
/* mobile and tablet */
|
||||
@media screen and (max-width: 999px) {
|
||||
#rl-settings-subscreen {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
html:not(.rl-left-panel-disabled) #rl-right {
|
||||
right: 5-@rlLeftWidth;
|
||||
}
|
||||
|
||||
html.rl-left-panel-disabled {
|
||||
#rl-left {
|
||||
width: 0 !important;
|
||||
}
|
||||
#rl-right {
|
||||
left: 5px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,11 @@
|
|||
width: 650px;
|
||||
}
|
||||
|
||||
.disabled table,
|
||||
table .disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.b-admin-packages-list-table {
|
||||
|
|
@ -30,4 +35,9 @@
|
|||
.package-actions {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.package-configure, .package-active {
|
||||
cursor: pointer;
|
||||
margin-right: 1em;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
.b-plugin-content {
|
||||
|
||||
&.modal {
|
||||
width: 660px;
|
||||
max-width: 660px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
|
||||
.b-admin-plugins-list-table {
|
||||
max-width: 620px; /* span8 */
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.b-admin-plugin-property {
|
||||
.help-block {
|
||||
display: block; // account for any element using help-block
|
||||
font-style: italic;
|
||||
opacity: 0.5;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.controls {
|
||||
width: 470px;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
.b-folder-clear-content {
|
||||
.modal-header {
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
.b-folder-create-content {
|
||||
.modal-header {
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
.b-folder-system-content {
|
||||
.modal-header {
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,15 @@
|
|||
.b-languages-content {
|
||||
|
||||
&.modal {
|
||||
width: 700px;
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
.lang-item {
|
||||
label {
|
||||
display: inline-block;
|
||||
padding: 5px 15px;
|
||||
margin: 2px 5px;
|
||||
width: 180px;
|
||||
background-color: rgba(128, 128, 128, 0.1);
|
||||
text-align: left;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
|
|
@ -26,7 +25,6 @@
|
|||
}
|
||||
&.selected::after {
|
||||
content: "✔";
|
||||
color: #080;
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
font-family: snappymail;
|
||||
|
|
@ -39,7 +37,7 @@
|
|||
}
|
||||
|
||||
@media screen and (max-width: 999px) {
|
||||
.b-languages-content .lang-item {
|
||||
width: calc(~'100% - 40px');
|
||||
.b-languages-content label {
|
||||
width: calc(100% - 40px);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
|
||||
.UserBackground body {
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
#rl-left, #rl-right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#rl-left {
|
||||
width: @rlLeftWidth;
|
||||
}
|
||||
|
||||
#rl-right {
|
||||
z-index: 1;
|
||||
left: @rlLeftWidth;
|
||||
}
|
||||
|
||||
#rl-popups > .rl-view-model {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1100;
|
||||
overflow: auto;
|
||||
background-color: rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
#rl-settings-subscreen {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* desktop */
|
||||
@media screen and (min-width: 1000px) {
|
||||
.toggleLeft {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* desktop-large */
|
||||
@media screen and (min-width: 1401px) {
|
||||
#rl-left {
|
||||
width: @rlLeftWidth + 20;
|
||||
}
|
||||
|
||||
#rl-right {
|
||||
left: @rlLeftWidth + 20;
|
||||
}
|
||||
}
|
||||
|
||||
/* mobile and tablet */
|
||||
@media screen and (max-width: 999px) {
|
||||
#rl-settings-subscreen {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
html:not(.rl-left-panel-disabled) #rl-right {
|
||||
right: 5-@rlLeftWidth;
|
||||
}
|
||||
|
||||
html.rl-left-panel-disabled {
|
||||
#rl-left {
|
||||
width: 0 !important;
|
||||
}
|
||||
#rl-right {
|
||||
left: 5px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,11 @@ body {
|
|||
right: 0;
|
||||
}
|
||||
|
||||
html.list-loading body {
|
||||
/* cursor: wait;*/
|
||||
cursor: progress;
|
||||
}
|
||||
|
||||
html:not(.rl-mobile) {
|
||||
min-width: 700px;
|
||||
}
|
||||
|
|
@ -32,10 +37,6 @@ html:not(.rl-mobile) {
|
|||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: none;
|
||||
}
|
||||
|
||||
option:disabled {
|
||||
color: #aaa;
|
||||
cursor: not-allowed;
|
||||
|
|
|
|||
|
|
@ -16,32 +16,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.e-paginator {
|
||||
|
||||
.e-page {
|
||||
|
||||
display: inline-block;
|
||||
opacity: 0.5;
|
||||
text-decoration: none;
|
||||
font-size: 22px;
|
||||
padding: 3px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&.current {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.current .e-page-number {
|
||||
font-size: 115%;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.settings-save-trigger {
|
||||
|
||||
display: inline-block;
|
||||
|
|
@ -93,25 +67,6 @@ textarea + .settings-save-trigger {
|
|||
}
|
||||
}
|
||||
|
||||
.e-languages {
|
||||
|
||||
margin-top: 8px;
|
||||
color: #333;
|
||||
|
||||
.flag-name {
|
||||
|
||||
color: #333;
|
||||
border-bottom: 1px dashed #333;
|
||||
cursor: pointer;
|
||||
padding: 2px 0;
|
||||
|
||||
&:focus {
|
||||
outline: 1px;
|
||||
outline-style: dotted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.e-action {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.b-advanced-search-content {
|
||||
&.modal {
|
||||
width: 780px;
|
||||
max-width: 780px;
|
||||
}
|
||||
.control-label {
|
||||
width: 110px;
|
||||
|
|
@ -43,15 +43,6 @@
|
|||
transition: opacity 0.3s linear;
|
||||
}
|
||||
|
||||
.messageList {
|
||||
.messageListItem {
|
||||
transition: max-height 400ms ease;
|
||||
}
|
||||
.listDragOver {
|
||||
transition: all 400ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
.b-list-content {
|
||||
.e-contact-item {
|
||||
transition: max-height 400ms ease;
|
||||
|
|
@ -144,6 +144,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 999px) {
|
||||
.b-compose.modal {
|
||||
border: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.minimize-custom {
|
||||
border: 0 solid #333;
|
||||
border-bottom-width: 3px;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
@contacts-popup-left-width: 220px;
|
||||
@contacts-popup-left-width: 25%;
|
||||
|
||||
.b-contacts-content {
|
||||
.RL-PopupsContacts {
|
||||
|
||||
.control-group {
|
||||
.control-label {
|
||||
|
|
@ -10,11 +10,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.modal {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
.modal {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: auto;
|
||||
min-width: 550px;
|
||||
max-width: 900px;
|
||||
|
|
@ -36,8 +33,8 @@
|
|||
border-bottom: 1px solid rgba(128,128,128,0.4);
|
||||
|
||||
.e-search {
|
||||
margin-top: 7px;
|
||||
width: @contacts-popup-left-width - 20;
|
||||
margin: 7px 0 0;
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -268,18 +265,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
.b-contacts-content {
|
||||
.b-list-content, .b-list-toolbar, .b-list-footer-toolbar {
|
||||
width: 170px;
|
||||
}
|
||||
.b-list-toolbar .e-search {
|
||||
width: 150px;
|
||||
}
|
||||
.b-view-content-toolbar, .b-view-content {
|
||||
left: 170px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -240,7 +240,7 @@
|
|||
|
||||
.btn {
|
||||
&.buttonCompose {
|
||||
width: calc(~'100% - 85px');
|
||||
width: calc(100% - 85px);
|
||||
max-width: -moz-fit-content;
|
||||
max-width: -webkit-fit-content;
|
||||
max-width: fit-content;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
.b-identity-content {
|
||||
|
||||
&.modal {
|
||||
width: 770px;
|
||||
max-width: 770px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
|
|
@ -371,3 +371,24 @@ html:not(.rl-mobile) .show-mobile {
|
|||
html.rl-mobile .width100-on-mobile {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.e-paginator {
|
||||
|
||||
.e-page {
|
||||
opacity: 0.5;
|
||||
text-decoration: none;
|
||||
font-size: 22px;
|
||||
padding: 3px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&.current {
|
||||
opacity: 1;
|
||||
font-size: 25px;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -198,215 +198,6 @@ html.rl-no-preview-pane {
|
|||
}
|
||||
}
|
||||
|
||||
.messageListItem {
|
||||
|
||||
position: relative;
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
|
||||
margin: 0;
|
||||
padding: 5px 0;
|
||||
border: 0;
|
||||
border-bottom: 1px solid rgba(153, 153, 153, 0.2);
|
||||
border-left: 6px solid #eee;
|
||||
|
||||
z-index: 100;
|
||||
|
||||
&.focused {
|
||||
background-color: rgba(128, 128, 128, 0.1);
|
||||
border-left-color: #ccc;
|
||||
}
|
||||
|
||||
.importantMark {
|
||||
display: none;
|
||||
|
||||
color:red;
|
||||
margin-right:5px
|
||||
}
|
||||
|
||||
&.deleted-mark {
|
||||
opacity: .7;
|
||||
.subjectParent {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
|
||||
&.important .importantMark {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
&.new {
|
||||
max-height: 0;
|
||||
}
|
||||
|
||||
&.deleted {
|
||||
max-height: 0;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
.checkboxMessage {
|
||||
line-height: 12px;
|
||||
padding: 0 8px 0 6px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.flagParent {
|
||||
padding: 0 10px 0 5px;
|
||||
}
|
||||
|
||||
time, .sizeParent {
|
||||
margin: 0 5px;
|
||||
opacity: 0.6;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.threadsParent {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.attachmentParent {
|
||||
position: relative;
|
||||
margin: 2px 10px 0 5px;
|
||||
color: #666;
|
||||
text-shadow: 0 1px 0 #eee;
|
||||
}
|
||||
|
||||
.senderParent, .subjectParent {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.threadsCountParent {
|
||||
display: inline;
|
||||
overflow: hidden;
|
||||
background-color: #eee;
|
||||
padding: 1px 5px;
|
||||
margin-right: 5px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.threadsCountParent.lastSelected {
|
||||
background-color: #999;
|
||||
border-color: #999;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.threadsCountParent:hover {
|
||||
border-color: #666;
|
||||
}
|
||||
|
||||
.subjectParent .emptySubjectText {
|
||||
display: none;
|
||||
font-style: italic;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.emptySubject .subjectParent {
|
||||
.subject {
|
||||
display: none;
|
||||
}
|
||||
.emptySubjectText {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.sender, .subject {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.threads-len {
|
||||
.threads-len-data {
|
||||
|
||||
border-radius: 6px;
|
||||
padding: 2px 0 1px 4px;
|
||||
border: 1px solid #ccc;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(127,127,127,0.3);
|
||||
border-color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flagOff {
|
||||
opacity: 0.5;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.flagOn, .flagOnHalf {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.replyFlag, .forwardFlag {
|
||||
display: none;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
&.answered .replyFlag {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&.forwarded .forwardFlag {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&:not(.withAttachments) .attachmentParent {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.hasUnseenSubMessage {
|
||||
background-color: rgba(255, 255, 64, 0.15);
|
||||
border-left-color: lighten(orange, 30%);
|
||||
&.focused {
|
||||
border-left-color: darken(orange, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
&.unseen {
|
||||
background-color: rgba(255, 255, 64, 0.15);
|
||||
border-left-color: orange;
|
||||
.sender, .subjectParent {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&.focused {
|
||||
border-left-color: darken(orange, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
&.checked {
|
||||
border-left-color: lighten(#398CF2, 10%);
|
||||
|
||||
&.focused {
|
||||
border-left-color: darken(#398CF2, 5%);
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: rgba(140, 200, 255, 0.3);
|
||||
border-bottom-color: rgba(57, 140, 242, 0.2);
|
||||
border-left-color: #398CF2;
|
||||
z-index: 101;
|
||||
|
||||
+ .messageListItem {
|
||||
border-bottom-color: rgba(57, 140, 242, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.flagged) .flagOn,
|
||||
&:not(.hasFlaggedSubMessage) .flagOnHalf,
|
||||
&.flagged .flagOff, &.hasFlaggedSubMessage .flagOff {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.message-focused {
|
||||
.b-message-list-wrapper {
|
||||
background-color: #000;
|
||||
|
|
@ -415,17 +206,250 @@ html.rl-no-preview-pane {
|
|||
opacity: 0.97;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.hideMessageListCheckbox {
|
||||
.checkboxMessage, .checkboxCheckAll {
|
||||
visibility: hidden;
|
||||
.hideMessageListCheckbox {
|
||||
.checkboxCheckAll {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.checkboxMessage {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.messageListItem {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
position: relative;
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
|
||||
margin: 0;
|
||||
padding: 5px 0;
|
||||
border: 0;
|
||||
border-bottom: 1px solid rgba(153, 153, 153, 0.2);
|
||||
border-left: 6px solid #eee;
|
||||
|
||||
z-index: 100;
|
||||
|
||||
> * {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
order: 0;
|
||||
}
|
||||
|
||||
&.focused {
|
||||
background-color: rgba(128, 128, 128, 0.1);
|
||||
border-left-color: #ccc;
|
||||
}
|
||||
|
||||
.importantMark {
|
||||
display: none;
|
||||
|
||||
color:red;
|
||||
margin-right:5px
|
||||
}
|
||||
|
||||
&.deleted-mark {
|
||||
opacity: .7;
|
||||
.subjectParent {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
|
||||
&.important .importantMark {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
&.new {
|
||||
max-height: 0;
|
||||
}
|
||||
|
||||
&.deleted {
|
||||
max-height: 0;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
.checkboxMessage {
|
||||
line-height: 12px;
|
||||
padding: 0 8px 0 6px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.flagParent {
|
||||
padding: 0 10px 0 5px;
|
||||
}
|
||||
|
||||
time, .sizeParent {
|
||||
margin: 0 5px;
|
||||
opacity: 0.6;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.threadsParent {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.attachmentParent {
|
||||
position: relative;
|
||||
margin: 2px 10px 0 5px;
|
||||
color: #666;
|
||||
text-shadow: 0 1px 0 #eee;
|
||||
}
|
||||
|
||||
.senderParent, .subjectParent {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.threadsCountParent {
|
||||
display: inline;
|
||||
overflow: hidden;
|
||||
background-color: #eee;
|
||||
padding: 1px 5px;
|
||||
margin-right: 5px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.threadsCountParent.lastSelected {
|
||||
background-color: #999;
|
||||
border-color: #999;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.threadsCountParent:hover {
|
||||
border-color: #666;
|
||||
}
|
||||
|
||||
.subjectParent .emptySubjectText {
|
||||
display: none;
|
||||
font-style: italic;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.emptySubject .subjectParent {
|
||||
.subject {
|
||||
display: none;
|
||||
}
|
||||
.emptySubjectText {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.sender, .subject {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.threads-len {
|
||||
.threads-len-data {
|
||||
|
||||
border-radius: 6px;
|
||||
padding: 2px 0 1px 4px;
|
||||
border: 1px solid #ccc;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(127,127,127,0.3);
|
||||
border-color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flagOff {
|
||||
opacity: 0.5;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.flagOn, .flagOnHalf {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.replyFlag, .forwardFlag {
|
||||
display: none;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
&.answered .replyFlag {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&.forwarded .forwardFlag {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&:not(.withAttachments) .attachmentParent {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.hasUnseenSubMessage {
|
||||
background-color: rgba(255, 255, 64, 0.15);
|
||||
border-left-color: lighten(orange, 30%);
|
||||
&.focused {
|
||||
border-left-color: darken(orange, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
&.unseen {
|
||||
background-color: rgba(255, 255, 64, 0.15);
|
||||
border-left-color: orange;
|
||||
.sender, .subjectParent {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&.focused {
|
||||
border-left-color: darken(orange, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
&.checked {
|
||||
border-left-color: lighten(#398CF2, 10%);
|
||||
|
||||
&.focused {
|
||||
border-left-color: darken(#398CF2, 5%);
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: rgba(140, 200, 255, 0.3);
|
||||
border-bottom-color: rgba(57, 140, 242, 0.2);
|
||||
border-left-color: #398CF2;
|
||||
z-index: 101;
|
||||
|
||||
+ .messageListItem {
|
||||
border-bottom-color: rgba(57, 140, 242, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.flagged) .flagOn,
|
||||
&:not(.hasFlaggedSubMessage) .flagOnHalf,
|
||||
&.flagged .flagOff, &.hasFlaggedSubMessage .flagOff {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
html.rl-ctrl-key-pressed .messageListItem {
|
||||
cursor: copy;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1000px) {
|
||||
.messageList {
|
||||
.listDragOver {
|
||||
transition: all 400ms ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* desktop-large */
|
||||
@media screen and (min-width: 1401px) {
|
||||
.messageList .messageListItem {
|
||||
.messageListItem {
|
||||
font-size: 13px;
|
||||
time {
|
||||
font-size: 13px;
|
||||
|
|
@ -448,18 +472,6 @@ html .messageList .line-loading {
|
|||
top: 0;
|
||||
}
|
||||
|
||||
.messageListItem {
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
> * {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
order: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.rl-side-preview-pane, .rl-mobile {
|
||||
|
||||
.messageListItem {
|
||||
|
|
@ -471,7 +483,6 @@ html .messageList .line-loading {
|
|||
.subjectParent {
|
||||
flex: 1 0 auto;
|
||||
line-height: 16px;
|
||||
margin-left: 30px;
|
||||
order: 1;
|
||||
width: calc(100% - 120px);
|
||||
}
|
||||
|
|
@ -492,9 +503,13 @@ html .messageList .line-loading {
|
|||
order: 3;
|
||||
}
|
||||
}
|
||||
|
||||
.b-message-list-wrapper:not(.hideMessageListCheckbox) .subjectParent {
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
html:not(.rl-mobile):not(.rl-side-preview-pane) .messageList {
|
||||
html:not(.rl-mobile):not(.rl-side-preview-pane) {
|
||||
|
||||
.messageListItem {
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
.b-open-pgp-key-view-content, .b-open-pgp-key-generate-content {
|
||||
&.modal {
|
||||
width: 570px;
|
||||
max-width: 570px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
.b-compose-open-pgp-content {
|
||||
&.modal {
|
||||
width: 800px;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.key-list {
|
||||
|
|
@ -97,7 +97,7 @@
|
|||
|
||||
.b-message-open-pgp-content {
|
||||
&.modal {
|
||||
width: 700px;
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
.key-list {
|
||||
|
|
@ -134,7 +134,7 @@
|
|||
|
||||
.b-open-pgp-key-add-content {
|
||||
&.modal {
|
||||
width: 645px;
|
||||
max-width: 645px;
|
||||
}
|
||||
.inputKey {
|
||||
font-family: var(--fontMono);
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
.rl-view-model {
|
||||
.b-shortcuts-content {
|
||||
&.modal {
|
||||
width: 700px;
|
||||
max-width: 700px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
.b-template-add-content {
|
||||
|
||||
&.modal {
|
||||
width: 750px;
|
||||
max-width: 750px;
|
||||
}
|
||||
|
||||
.e-template-place {
|
||||
|
|
@ -12,12 +12,7 @@ label.inline, span.inline {
|
|||
line-height: @baseLineHeight * 2;
|
||||
color: @grayDark;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
|
||||
small {
|
||||
font-size: @baseLineHeight * .75;
|
||||
color: @grayLight;
|
||||
}
|
||||
border-bottom: 1px solid @dropdownDividerTop;
|
||||
}
|
||||
|
||||
.legend + .control-group {
|
||||
|
|
@ -40,30 +35,19 @@ label.inline, span.inline {
|
|||
|
||||
.alert a {
|
||||
text-decoration: underline;
|
||||
color: #c09853;
|
||||
color: @warningText;
|
||||
}
|
||||
|
||||
.alert.alert-info a {
|
||||
color: #3a87ad;
|
||||
color: @infoText;
|
||||
}
|
||||
|
||||
.alert.alert-error a {
|
||||
color: #b94a48;
|
||||
}
|
||||
|
||||
.form-horizontal.long-label .control-group {
|
||||
.control-label {
|
||||
width: 160px;
|
||||
}
|
||||
color: @errorText;
|
||||
}
|
||||
|
||||
/* mobile and tablet */
|
||||
@media screen and (max-width: 999px) {
|
||||
|
||||
.modal {
|
||||
width: calc(~'100% - 20px') !important;
|
||||
}
|
||||
|
||||
.form-horizontal {
|
||||
.control-group {
|
||||
.control-label {
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@
|
|||
margin: -1px -2px;
|
||||
}
|
||||
|
||||
.icon-spinner:not(.not-animated) {
|
||||
.icon-spinner:not(.not-animated),
|
||||
.list-loading .icon-spinner.not-animated {
|
||||
border-color: transparent;
|
||||
border-top-color: #999;
|
||||
animation: rotation .8s infinite ease-in-out;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class AddOpenPgpKeyPopupView extends AbstractViewPopup {
|
|||
return false;
|
||||
}
|
||||
|
||||
this.cancelCommand && this.cancelCommand();
|
||||
this.cancelCommand();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import { serverRequest } from 'Common/Links';
|
|||
import { i18n, getNotification, getUploadErrorDescByCode } from 'Common/Translator';
|
||||
import { timestampToString } from 'Common/Momentor';
|
||||
import { MessageFlagsCache, setFolderHash } from 'Common/Cache';
|
||||
import { Settings, SettingsGet } from 'Common/Globals';
|
||||
import { doc, Settings, SettingsGet } from 'Common/Globals';
|
||||
|
||||
import { AppUserStore } from 'Stores/User/App';
|
||||
import { SettingsUserStore } from 'Stores/User/Settings';
|
||||
|
|
@ -43,6 +43,8 @@ import { AskPopupView } from 'View/Popup/Ask';
|
|||
import { ContactsPopupView } from 'View/Popup/Contacts';
|
||||
import { ComposeOpenPgpPopupView } from 'View/Popup/ComposeOpenPgp';
|
||||
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
const
|
||||
/**
|
||||
* @param {string} prefix
|
||||
|
|
@ -432,7 +434,7 @@ class ComposePopupView extends AbstractViewPopup {
|
|||
|| getNotification(Notification.CantSendMessage));
|
||||
}
|
||||
} else {
|
||||
this.closeCommand && this.closeCommand();
|
||||
this.closeCommand();
|
||||
}
|
||||
}
|
||||
this.reloadDraftFolder();
|
||||
|
|
@ -643,6 +645,8 @@ class ComposePopupView extends AbstractViewPopup {
|
|||
rl.route.on();
|
||||
|
||||
this.resizeObserver.disconnect();
|
||||
|
||||
(doc.fullscreenElement || doc.webkitFullscreenElement) === this.oContent && doc.exitFullscreen();
|
||||
}
|
||||
|
||||
editor(fOnInit) {
|
||||
|
|
@ -739,6 +743,9 @@ class ComposePopupView extends AbstractViewPopup {
|
|||
} else {
|
||||
this.initOnShow(type, oMessageOrArray, aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText);
|
||||
}
|
||||
|
||||
// (navigator.standalone || matchMedia('(display-mode: standalone)').matches || matchMedia('(display-mode: fullscreen)').matches) &&
|
||||
ThemeStore.isMobile() && this.oContent.requestFullscreen && this.oContent.requestFullscreen();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1062,14 +1069,12 @@ class ComposePopupView extends AbstractViewPopup {
|
|||
tryToClosePopup() {
|
||||
if (!isPopupVisible(AskPopupView) && this.modalVisibility()) {
|
||||
if (this.bSkipNextHide || (this.isEmptyForm() && !this.draftUid())) {
|
||||
this.closeCommand && this.closeCommand();
|
||||
this.closeCommand();
|
||||
} else {
|
||||
showScreenPopup(AskPopupView, [
|
||||
i18n('POPUPS_ASK/DESC_WANT_CLOSE_THIS_WINDOW'),
|
||||
() => {
|
||||
if (this.modalVisibility()) {
|
||||
this.closeCommand && this.closeCommand();
|
||||
}
|
||||
this.modalVisibility() && this.closeCommand();
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
|
@ -1135,6 +1140,26 @@ class ComposePopupView extends AbstractViewPopup {
|
|||
ro.els = [dom.querySelector('.textAreaParent'), dom.querySelector('.attachmentAreaParent')];
|
||||
|
||||
this.editor(editor => editor.modeWysiwyg());
|
||||
|
||||
// Fullscreen must be on app, else other popups fail
|
||||
const el = doc.getElementById('rl-app');
|
||||
let event = 'fullscreenchange';
|
||||
if (!el.requestFullscreen && el.webkitRequestFullscreen) {
|
||||
el.requestFullscreen = el.webkitRequestFullscreen;
|
||||
event = 'webkit' + event;
|
||||
}
|
||||
if (el.requestFullscreen) {
|
||||
if (!doc.exitFullscreen && doc.webkitExitFullscreen) {
|
||||
doc.exitFullscreen = doc.webkitExitFullscreen;
|
||||
}
|
||||
this.oContent = el;
|
||||
el.addEventListener(event, () =>
|
||||
ThemeStore.isMobile()
|
||||
&& this.modalVisibility()
|
||||
&& (doc.fullscreenElement || doc.webkitFullscreenElement) !== el
|
||||
&& this.skipCommand()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -79,14 +79,14 @@ class ContactsPopupView extends AbstractViewPopup {
|
|||
'.e-contact-item.focused'
|
||||
);
|
||||
|
||||
this.selector.on('onItemSelect', contact => {
|
||||
this.populateViewContact(contact || null);
|
||||
this.selector.on('ItemSelect', contact => {
|
||||
this.populateViewContact(contact);
|
||||
if (!contact) {
|
||||
this.emptySelection(true);
|
||||
}
|
||||
});
|
||||
|
||||
this.selector.on('onItemGetUid', contact => contact ? contact.generateUid() : '');
|
||||
this.selector.on('ItemGetUid', contact => contact ? contact.generateUid() : '');
|
||||
|
||||
this.bDropPageAfterDelete = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class FilterPopupView extends AbstractViewPopup {
|
|||
|
||||
this.fTrueCallback && this.fTrueCallback(this.filter());
|
||||
|
||||
this.modalVisibility() && this.closeCommand && this.closeCommand();
|
||||
this.modalVisibility() && this.closeCommand();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class NewOpenPgpKeyPopupView extends AbstractViewPopup {
|
|||
openpgpKeyring.store();
|
||||
|
||||
rl.app.reloadOpenPgpKeys();
|
||||
this.cancelCommand && this.cancelCommand();
|
||||
this.cancelCommand();
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class PluginPopupView extends AbstractViewPopup {
|
|||
if (!isPopupVisible(AskPopupView)) {
|
||||
showScreenPopup(AskPopupView, [
|
||||
i18n('POPUPS_ASK/DESC_WANT_CLOSE_THIS_WINDOW'),
|
||||
() => this.modalVisibility() && this.cancelCommand && this.cancelCommand()
|
||||
() => this.modalVisibility() && this.cancelCommand()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
this.bPrefetch = false;
|
||||
this.emptySubjectValue = '';
|
||||
|
||||
this.iGoToUpUpOrDownDownTimeout = 0;
|
||||
this.iGoToUpOrDownTimeout = 0;
|
||||
|
||||
this.newMoveToFolder = !!SettingsGet('NewMoveToFolder');
|
||||
|
||||
|
|
@ -86,7 +86,6 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
|
||||
this.messageListCheckedOrSelected = MessageUserStore.listCheckedOrSelected;
|
||||
this.messageListCompleteLoadingThrottle = MessageUserStore.listCompleteLoading;
|
||||
this.messageListCompleteLoadingThrottleForAnimation = MessageUserStore.listLoadingAnimation;
|
||||
|
||||
initOnStartOrLangChange(() => this.emptySubjectValue = i18n('MESSAGE_LIST/EMPTY_SUBJECT_TEXT'));
|
||||
|
||||
|
|
@ -191,13 +190,15 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
'.messageListItem.focused'
|
||||
);
|
||||
|
||||
this.selector.on('onItemSelect', message => MessageUserStore.selectMessage(message));
|
||||
this.selector.on('ItemSelect', message => MessageUserStore.selectMessage(message));
|
||||
|
||||
this.selector.on('onItemGetUid', message => (message ? message.generateUid() : ''));
|
||||
this.selector.on('MiddleClick', message => MessageUserStore.populateMessageBody(message, true));
|
||||
|
||||
this.selector.on('onAutoSelect', () => this.useAutoSelect());
|
||||
this.selector.on('ItemGetUid', message => (message ? message.generateUid() : ''));
|
||||
|
||||
this.selector.on('onUpUpOrDownDown', v => this.goToUpUpOrDownDown(v));
|
||||
this.selector.on('AutoSelect', () => this.useAutoSelect());
|
||||
|
||||
this.selector.on('UpOrDown', v => this.goToUpOrDown(v));
|
||||
|
||||
addEventListener('mailbox.message-list.selector.go-down',
|
||||
e => this.selector.newSelectPosition('ArrowDown', false, e.detail)
|
||||
|
|
@ -351,13 +352,13 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
showMessageComposer();
|
||||
}
|
||||
|
||||
goToUpUpOrDownDown(up) {
|
||||
goToUpOrDown(up) {
|
||||
if (MessageUserStore.listChecked().length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
clearTimeout(this.iGoToUpUpOrDownDownTimeout);
|
||||
this.iGoToUpUpOrDownDownTimeout = setTimeout(() => {
|
||||
clearTimeout(this.iGoToUpOrDownTimeout);
|
||||
this.iGoToUpOrDownTimeout = setTimeout(() => {
|
||||
let prev, next, temp, current;
|
||||
|
||||
this.messageListPaginator().find(item => {
|
||||
|
|
@ -668,31 +669,31 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
}
|
||||
|
||||
onBuild(dom) {
|
||||
const eqs = (ev, s) => ev.target.closestWithin(s, dom);
|
||||
const eqs = (ev, s) => ev.target.closestWithin('.messageList '+s, dom);
|
||||
|
||||
this.selector.init(dom.querySelector('.b-content'), Scope.MessageList);
|
||||
|
||||
dom.addEventListener('click', event => {
|
||||
ThemeStore.isMobile() && leftPanelDisabled(true);
|
||||
|
||||
if (eqs(event, '.messageList .b-message-list-wrapper') && Scope.MessageView === AppUserStore.focusedState()) {
|
||||
if (eqs(event, '.b-message-list-wrapper') && Scope.MessageView === AppUserStore.focusedState()) {
|
||||
AppUserStore.focusedState(Scope.MessageList);
|
||||
}
|
||||
|
||||
let el = eqs(event, '.e-paginator .e-page');
|
||||
el && this.gotoPage(ko.dataFor(el));
|
||||
|
||||
eqs(event, '.messageList .checkboxCheckAll') && this.checkAll(!this.checkAll());
|
||||
eqs(event, '.checkboxCheckAll') && this.checkAll(!this.checkAll());
|
||||
|
||||
el = eqs(event, '.messageList .messageListItem .flagParent');
|
||||
el = eqs(event, '.messageListItem .flagParent');
|
||||
el && this.flagMessages(ko.dataFor(el));
|
||||
|
||||
el = eqs(event, '.messageList .messageListItem .threads-len');
|
||||
el = eqs(event, '.messageListItem .threads-len');
|
||||
el && this.gotoThread(ko.dataFor(el));
|
||||
});
|
||||
|
||||
dom.addEventListener('dblclick', event => {
|
||||
let el = eqs(event, '.messageList .messageListItem .actionHandle');
|
||||
let el = eqs(event, '.messageListItem .actionHandle');
|
||||
el && this.gotoThread(ko.dataFor(el));
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue