mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-09-20 07:35:55 +08:00
Some tiny changes
This commit is contained in:
parent
219589b8ea
commit
c76823dc5f
26
README.md
26
README.md
|
@ -63,6 +63,7 @@ This fork of RainLoop has the following changes:
|
||||||
* Ongoing removal of old JavaScript code (things are native these days)
|
* Ongoing removal of old JavaScript code (things are native these days)
|
||||||
* Added modified [Squire](https://github.com/neilj/Squire) HTML editor as replacement for CKEditor
|
* Added modified [Squire](https://github.com/neilj/Squire) HTML editor as replacement for CKEditor
|
||||||
* Split Admin specific JavaScript code from User code
|
* Split Admin specific JavaScript code from User code
|
||||||
|
* Split Sieve specific JavaScript code from User code
|
||||||
* JSON reviver
|
* JSON reviver
|
||||||
* Better memory garbage collection management
|
* Better memory garbage collection management
|
||||||
* Added serviceworker for Notifications
|
* Added serviceworker for Notifications
|
||||||
|
@ -140,26 +141,27 @@ RainLoop 1.15 vs SnappyMail
|
||||||
|js/* |RainLoop |Snappy |
|
|js/* |RainLoop |Snappy |
|
||||||
|--------------- |--------: |--------: |
|
|--------------- |--------: |--------: |
|
||||||
|admin.js |2.158.025 | 79.018 |
|
|admin.js |2.158.025 | 79.018 |
|
||||||
|app.js |4.215.733 | 407.680 |
|
|app.js |4.215.733 | 407.697 |
|
||||||
|boot.js | 672.433 | 1.996 |
|
|boot.js | 672.433 | 2.025 |
|
||||||
|libs.js | 647.679 | 200.131 |
|
|libs.js | 647.679 | 200.131 |
|
||||||
|sieve.js | 0 | 30.809 |
|
|sieve.js | 0 | 75.642 |
|
||||||
|polyfills.js | 325.908 | 0 |
|
|polyfills.js | 325.908 | 0 |
|
||||||
|serviceworker.js | 0 | 285 |
|
|serviceworker.js | 0 | 285 |
|
||||||
|TOTAL |8.019.778 | 719.919 |
|
|TOTAL |8.019.778 | 764.798 |
|
||||||
|
|
||||||
|js/min/* |RainLoop |Snappy |RL gzip |SM gzip |RL brotli |SM brotli |
|
|js/min/* |RainLoop |Snappy |RL gzip |SM gzip |RL brotli |SM brotli |
|
||||||
|--------------- |--------: |--------: |------: |------: |--------: |--------: |
|
|--------------- |--------: |--------: |------: |------: |--------: |--------: |
|
||||||
|admin.min.js | 255.514 | 39.256 | 73.899 | 13.076 | 60.674 | 11.702 |
|
|admin.min.js | 255.514 | 39.256 | 73.899 | 13.076 | 60.674 | 11.702 |
|
||||||
|app.min.js | 516.000 | 194.277 |140.430 | 62.348 |110.657 | 53.485 |
|
|app.min.js | 516.000 | 194.148 |140.430 | 62.297 |110.657 | 53.432 |
|
||||||
|boot.min.js | 66.456 | 1.230 | 22.553 | 768 | 20.043 | 619 |
|
|boot.min.js | 66.456 | 1.252 | 22.553 | 782 | 20.043 | 631 |
|
||||||
|libs.min.js | 574.626 | 96.201 |177.280 | 35.522 |151.855 | 31.746 |
|
|libs.min.js | 574.626 | 96.201 |177.280 | 35.522 |151.855 | 31.746 |
|
||||||
|sieve.min.js | 0 | 15.009 | 0 | 5.228 | 0 | 4.702 |
|
|sieve.min.js | 0 | 36.632 | 0 | 9.689 | 0 | 8.770 |
|
||||||
|polyfills.min.js | 32.608 | 0 | 11.315 | 0 | 10.072 | 0 |
|
|polyfills.min.js | 32.608 | 0 | 11.315 | 0 | 10.072 | 0 |
|
||||||
|TOTAL |1.445.204 | 345.973 |425.477 |116.942 |353.301 |102.254 |
|
|TOTAL user |1.189.690 | 291.601 |351.061 | 98.601 |292.627 | 85.809 |
|
||||||
|TOTAL (no admin) |1.189.690 | 306.717 |351.061 |103.866 |292.627 | 90.552 |
|
|TOTAL user sieve |1.189.690 | 328.233 |351.061 |108.290 |292.627 | 94.579 |
|
||||||
|
|TOTAL admin |1.189.690 | 136.709 |351.061 | 49.380 |292.627 | 44.079 |
|
||||||
|
|
||||||
For a user its around 69% smaller and faster than traditional RainLoop.
|
For a user its around 70% smaller and faster than traditional RainLoop.
|
||||||
|
|
||||||
### CSS changes
|
### CSS changes
|
||||||
|
|
||||||
|
@ -185,8 +187,8 @@ For a user its around 69% smaller and faster than traditional RainLoop.
|
||||||
|
|
||||||
|css/* |RainLoop |Snappy |RL gzip |SM gzip |SM brotli |
|
|css/* |RainLoop |Snappy |RL gzip |SM gzip |SM brotli |
|
||||||
|------------ |-------: |------: |------: |------: |--------: |
|
|------------ |-------: |------: |------: |------: |--------: |
|
||||||
|app.css | 340.334 | 80.943 | 46.959 | 16.768 | 14.427 |
|
|app.css | 340.334 | 80.865 | 46.959 | 16.751 | 14.420 |
|
||||||
|app.min.css | 274.791 | 65.152 | 39.618 | 14.864 | 13.097 |
|
|app.min.css | 274.791 | 65.086 | 39.618 | 14.855 | 13.088 |
|
||||||
|boot.css | | 1.326 | | 664 | 545 |
|
|boot.css | | 1.326 | | 664 | 545 |
|
||||||
|boot.min.css | | 1.071 | | 590 | 474 |
|
|boot.min.css | | 1.071 | | 590 | 474 |
|
||||||
|admin.css | | 29.977 | | 6.795 | 5.900 |
|
|admin.css | | 29.977 | | 6.795 | 5.900 |
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { mailToHelper, setLayoutResizer, dropdownsDetectVisibility } from 'Commo
|
||||||
import {
|
import {
|
||||||
FolderType,
|
FolderType,
|
||||||
SetSystemFoldersNotification,
|
SetSystemFoldersNotification,
|
||||||
ClientSideKeyName
|
ClientSideKeyNameFolderListSize
|
||||||
} from 'Common/EnumsUser';
|
} from 'Common/EnumsUser';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -335,7 +335,7 @@ class AppUser extends AbstractApp {
|
||||||
const left = elementById('rl-left'),
|
const left = elementById('rl-left'),
|
||||||
right = elementById('rl-right'),
|
right = elementById('rl-right'),
|
||||||
fToggle = () =>
|
fToggle = () =>
|
||||||
setLayoutResizer(left, right, ClientSideKeyName.FolderListSize,
|
setLayoutResizer(left, right, ClientSideKeyNameFolderListSize,
|
||||||
(ThemeStore.isMobile() || leftPanelDisabled()) ? 0 : 'Width');
|
(ThemeStore.isMobile() || leftPanelDisabled()) ? 0 : 'Width');
|
||||||
if (left && right) {
|
if (left && right) {
|
||||||
fToggle();
|
fToggle();
|
||||||
|
|
|
@ -72,15 +72,14 @@ export const SetSystemFoldersNotification = {
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
export const ClientSideKeyName = {
|
export const
|
||||||
ExpandedFolders: 3,
|
ClientSideKeyNameExpandedFolders = 3,
|
||||||
FolderListSize: 4,
|
ClientSideKeyNameFolderListSize = 4,
|
||||||
MessageListSize: 5,
|
ClientSideKeyNameMessageListSize = 5,
|
||||||
LastReplyAction: 6,
|
ClientSideKeyNameLastReplyAction = 6,
|
||||||
LastSignMe: 7,
|
ClientSideKeyNameLastSignMe = 7,
|
||||||
MessageHeaderFullInfo: 9,
|
ClientSideKeyNameMessageHeaderFullInfo = 9,
|
||||||
MessageAttachmentControls: 10
|
ClientSideKeyNameMessageAttachmentControls = 10;
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { AbstractCollectionModel } from 'Model/AbstractCollection';
|
||||||
|
|
||||||
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
||||||
import { isArray, getKeyByValue, forEachObjectEntry, b64EncodeJSONSafe } from 'Common/Utils';
|
import { isArray, getKeyByValue, forEachObjectEntry, b64EncodeJSONSafe } from 'Common/Utils';
|
||||||
import { ClientSideKeyName, FolderType, FolderMetadataKeys } from 'Common/EnumsUser';
|
import { ClientSideKeyNameExpandedFolders, FolderType, FolderMetadataKeys } from 'Common/EnumsUser';
|
||||||
import { getFolderFromCacheList, setFolder, setFolderInboxName, setFolderHash } from 'Common/Cache';
|
import { getFolderFromCacheList, setFolder, setFolderInboxName, setFolderHash } from 'Common/Cache';
|
||||||
import { Settings, SettingsGet, fireEvent } from 'Common/Globals';
|
import { Settings, SettingsGet, fireEvent } from 'Common/Globals';
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ export const
|
||||||
* @param {boolean} bExpanded
|
* @param {boolean} bExpanded
|
||||||
*/
|
*/
|
||||||
setExpandedFolder = (sFullName, bExpanded) => {
|
setExpandedFolder = (sFullName, bExpanded) => {
|
||||||
let aExpandedList = Local.get(ClientSideKeyName.ExpandedFolders);
|
let aExpandedList = Local.get(ClientSideKeyNameExpandedFolders);
|
||||||
if (!isArray(aExpandedList)) {
|
if (!isArray(aExpandedList)) {
|
||||||
aExpandedList = [];
|
aExpandedList = [];
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ export const
|
||||||
aExpandedList = aExpandedList.filter(value => value !== sFullName);
|
aExpandedList = aExpandedList.filter(value => value !== sFullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Local.set(ClientSideKeyName.ExpandedFolders, aExpandedList);
|
Local.set(ClientSideKeyNameExpandedFolders, aExpandedList);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -127,7 +127,7 @@ export class FolderCollectionModel extends AbstractCollectionModel
|
||||||
* @returns {FolderCollectionModel}
|
* @returns {FolderCollectionModel}
|
||||||
*/
|
*/
|
||||||
static reviveFromJson(object) {
|
static reviveFromJson(object) {
|
||||||
const expandedFolders = Local.get(ClientSideKeyName.ExpandedFolders);
|
const expandedFolders = Local.get(ClientSideKeyNameExpandedFolders);
|
||||||
if (object && object.SystemFolders) {
|
if (object && object.SystemFolders) {
|
||||||
forEachObjectEntry(SystemFolders, key =>
|
forEachObjectEntry(SystemFolders, key =>
|
||||||
SystemFolders[key] = SettingsGet(key+'Folder') || object.SystemFolders[FolderType[key]]
|
SystemFolders[key] = SettingsGet(key+'Folder') || object.SystemFolders[FolderType[key]]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Scope } from 'Common/Enums';
|
import { Scope } from 'Common/Enums';
|
||||||
import { Layout, ClientSideKeyName } from 'Common/EnumsUser';
|
import { Layout, ClientSideKeyNameMessageListSize } from 'Common/EnumsUser';
|
||||||
import { doc, leftPanelDisabled, moveAction, Settings, elementById } from 'Common/Globals';
|
import { doc, leftPanelDisabled, moveAction, Settings, elementById } from 'Common/Globals';
|
||||||
import { pString, pInt } from 'Common/Utils';
|
import { pString, pInt } from 'Common/Utils';
|
||||||
import { setLayoutResizer } from 'Common/UtilsUser';
|
import { setLayoutResizer } from 'Common/UtilsUser';
|
||||||
|
@ -106,7 +106,7 @@ export class MailBoxUserScreen extends AbstractScreen {
|
||||||
bottom = elementById('V-MailMessageView'),
|
bottom = elementById('V-MailMessageView'),
|
||||||
fToggle = () => {
|
fToggle = () => {
|
||||||
let layout = SettingsUserStore.layout();
|
let layout = SettingsUserStore.layout();
|
||||||
setLayoutResizer(top, bottom, ClientSideKeyName.MessageListSize,
|
setLayoutResizer(top, bottom, ClientSideKeyNameMessageListSize,
|
||||||
(ThemeStore.isMobile() || Layout.NoPreview === layout)
|
(ThemeStore.isMobile() || Layout.NoPreview === layout)
|
||||||
? 0
|
? 0
|
||||||
: (Layout.SidePreview === layout ? 'Width' : 'Height')
|
: (Layout.SidePreview === layout ? 'Width' : 'Height')
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Notification } from 'Common/Enums';
|
import { Notification } from 'Common/Enums';
|
||||||
import { ClientSideKeyName } from 'Common/EnumsUser';
|
import { ClientSideKeyNameLastSignMe } from 'Common/EnumsUser';
|
||||||
import { SettingsGet, fireEvent } from 'Common/Globals';
|
import { SettingsGet, fireEvent } from 'Common/Globals';
|
||||||
import { getNotification, translatorReload, convertLangName } from 'Common/Translator';
|
import { getNotification, translatorReload, convertLangName } from 'Common/Translator';
|
||||||
|
|
||||||
|
@ -14,7 +14,8 @@ import { AbstractViewLogin } from 'Knoin/AbstractViews';
|
||||||
|
|
||||||
import { LanguagesPopupView } from 'View/Popup/Languages';
|
import { LanguagesPopupView } from 'View/Popup/Languages';
|
||||||
|
|
||||||
const SignMeOff = 0,
|
const
|
||||||
|
SignMeOff = 0,
|
||||||
SignMeOn = 1,
|
SignMeOn = 1,
|
||||||
SignMeUnused = 2;
|
SignMeUnused = 2;
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ export class LoginUserView extends AbstractViewLogin {
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
|
|
||||||
Local.set(ClientSideKeyName.LastSignMe, this.signMe() ? '-1-' : '-0-');
|
Local.set(ClientSideKeyNameLastSignMe, this.signMe() ? '-1-' : '-0-');
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
|
@ -129,8 +130,7 @@ export class LoginUserView extends AbstractViewLogin {
|
||||||
onBuild(dom) {
|
onBuild(dom) {
|
||||||
super.onBuild(dom);
|
super.onBuild(dom);
|
||||||
|
|
||||||
const signMeLocal = Local.get(ClientSideKeyName.LastSignMe),
|
const signMe = (SettingsGet('SignMe') || '').toLowerCase();
|
||||||
signMe = (SettingsGet('SignMe') || '').toLowerCase();
|
|
||||||
|
|
||||||
switch (signMe) {
|
switch (signMe) {
|
||||||
case 'defaultoff':
|
case 'defaultoff':
|
||||||
|
@ -139,7 +139,7 @@ export class LoginUserView extends AbstractViewLogin {
|
||||||
'defaulton' === signMe ? SignMeOn : SignMeOff
|
'defaulton' === signMe ? SignMeOn : SignMeOff
|
||||||
);
|
);
|
||||||
|
|
||||||
switch (signMeLocal) {
|
switch (Local.get(ClientSideKeyNameLastSignMe)) {
|
||||||
case '-1-':
|
case '-1-':
|
||||||
this.signMeType(SignMeOn);
|
this.signMeType(SignMeOn);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -7,7 +7,9 @@ import { Scope } from 'Common/Enums';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ComposeType,
|
ComposeType,
|
||||||
ClientSideKeyName,
|
ClientSideKeyNameLastReplyAction,
|
||||||
|
ClientSideKeyNameMessageHeaderFullInfo,
|
||||||
|
ClientSideKeyNameMessageAttachmentControls,
|
||||||
FolderType,
|
FolderType,
|
||||||
MessageSetAction
|
MessageSetAction
|
||||||
} from 'Common/EnumsUser';
|
} from 'Common/EnumsUser';
|
||||||
|
@ -96,7 +98,7 @@ export class MailMessageView extends AbstractViewRight {
|
||||||
showAttachmentControls: false,
|
showAttachmentControls: false,
|
||||||
downloadAsZipLoading: false,
|
downloadAsZipLoading: false,
|
||||||
lastReplyAction_: '',
|
lastReplyAction_: '',
|
||||||
showFullInfo: '1' === Local.get(ClientSideKeyName.MessageHeaderFullInfo),
|
showFullInfo: '1' === Local.get(ClientSideKeyNameMessageHeaderFullInfo),
|
||||||
moreDropdownTrigger: false,
|
moreDropdownTrigger: false,
|
||||||
|
|
||||||
// viewer
|
// viewer
|
||||||
|
@ -124,7 +126,7 @@ export class MailMessageView extends AbstractViewRight {
|
||||||
this.messageListOfThreadsLoading = ko.observable(false).extend({ rateLimit: 1 });
|
this.messageListOfThreadsLoading = ko.observable(false).extend({ rateLimit: 1 });
|
||||||
this.highlightUnselectedAttachments = ko.observable(false).extend({ falseTimeout: 2000 });
|
this.highlightUnselectedAttachments = ko.observable(false).extend({ falseTimeout: 2000 });
|
||||||
|
|
||||||
this.showAttachmentControlsState = v => Local.set(ClientSideKeyName.MessageAttachmentControls, !!v);
|
this.showAttachmentControlsState = v => Local.set(ClientSideKeyNameMessageAttachmentControls, !!v);
|
||||||
|
|
||||||
this.downloadAsZipError = ko.observable(false).extend({ falseTimeout: 7000 });
|
this.downloadAsZipError = ko.observable(false).extend({ falseTimeout: 7000 });
|
||||||
|
|
||||||
|
@ -183,14 +185,14 @@ export class MailMessageView extends AbstractViewRight {
|
||||||
showAttachmentControls: v => currentMessage()
|
showAttachmentControls: v => currentMessage()
|
||||||
&& currentMessage().attachments.forEach(item => item && item.checked(!!v)),
|
&& currentMessage().attachments.forEach(item => item && item.checked(!!v)),
|
||||||
|
|
||||||
lastReplyAction_: value => Local.set(ClientSideKeyName.LastReplyAction, value),
|
lastReplyAction_: value => Local.set(ClientSideKeyNameLastReplyAction, value),
|
||||||
|
|
||||||
message: message => {
|
message: message => {
|
||||||
MessageUserStore.activeDom(null);
|
MessageUserStore.activeDom(null);
|
||||||
|
|
||||||
if (message) {
|
if (message) {
|
||||||
this.showAttachmentControls(false);
|
this.showAttachmentControls(false);
|
||||||
if (Local.get(ClientSideKeyName.MessageAttachmentControls)) {
|
if (Local.get(ClientSideKeyNameMessageAttachmentControls)) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showAttachmentControls(true);
|
this.showAttachmentControls(true);
|
||||||
}, 50);
|
}, 50);
|
||||||
|
@ -222,10 +224,10 @@ export class MailMessageView extends AbstractViewRight {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
showFullInfo: value => Local.set(ClientSideKeyName.MessageHeaderFullInfo, value ? '1' : '0')
|
showFullInfo: value => Local.set(ClientSideKeyNameMessageHeaderFullInfo, value ? '1' : '0')
|
||||||
});
|
});
|
||||||
|
|
||||||
this.lastReplyAction(Local.get(ClientSideKeyName.LastReplyAction) || ComposeType.Reply);
|
this.lastReplyAction(Local.get(ClientSideKeyNameLastReplyAction) || ComposeType.Reply);
|
||||||
|
|
||||||
// commands
|
// commands
|
||||||
this.replyCommand = createCommandReplyHelper(ComposeType.Reply);
|
this.replyCommand = createCommandReplyHelper(ComposeType.Reply);
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
display: none;
|
display: none;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
.cke, .cke_inner {
|
||||||
|
min-height: 99%;
|
||||||
|
}
|
||||||
|
|
||||||
.cke_chrome {
|
.cke_chrome {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
|
@ -105,12 +109,9 @@ a.cke_button.cke_button_disabled:hover:last-child::after {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cke_inner,
|
||||||
.cke_wysiwyg_div {
|
.cke_wysiwyg_div {
|
||||||
padding: 10px;
|
background: transparent !important;
|
||||||
font-family: var(--fontSans);
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 16px;
|
|
||||||
color: #333;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cke_wysiwyg_div ul {
|
.cke_wysiwyg_div ul {
|
||||||
|
@ -173,19 +174,8 @@ a.cke_button.cke_button_disabled:hover:last-child::after {
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cke_wysiwyg_div a {
|
.cke_dialog {
|
||||||
color: blue;
|
z-index: 99999;
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.cke_wysiwyg_div a:visited {
|
|
||||||
color: #609;
|
|
||||||
}
|
|
||||||
.cke_wysiwyg_div a:active {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cke_dialog a:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cke_dialog_ui_labeled_content {
|
.cke_dialog_ui_labeled_content {
|
||||||
|
|
Loading…
Reference in a new issue