Cleanup and improve HTML/CSS and it's JavaScript handling

This commit is contained in:
djmaze 2021-11-06 12:27:37 +01:00
parent 6273869b32
commit 2e34f98c80
26 changed files with 516 additions and 598 deletions

View file

@ -683,7 +683,7 @@ class AppUser extends AbstractApp {
right = elementById('rl-right'), right = elementById('rl-right'),
fToggle = () => fToggle = () =>
setLayoutResizer(left, right, ClientSideKeyName.FolderListSize, setLayoutResizer(left, right, ClientSideKeyName.FolderListSize,
(ThemeStore.isMobile() || leftPanelDisabled()) ? null : 'width'); (ThemeStore.isMobile() || leftPanelDisabled()) ? 0 : 'Width');
if (left && right) { if (left && right) {
fToggle(); fToggle();
leftPanelDisabled.subscribe(fToggle); leftPanelDisabled.subscribe(fToggle);

View file

@ -53,6 +53,7 @@ dropdownVisibility.subscribe(value => {
} }
}); });
leftPanelDisabled.toggle = () => leftPanelDisabled(!leftPanelDisabled());
leftPanelDisabled.subscribe(value => { leftPanelDisabled.subscribe(value => {
value && moveAction() && moveAction(false); value && moveAction() && moveAction(false);
$htmlCL.toggle('rl-left-panel-disabled', value); $htmlCL.toggle('rl-left-panel-disabled', value);

View file

@ -407,15 +407,25 @@ setLayoutResizer = (source, target, sClientSideKeyName, mode) =>
target.removeAttribute('style'); target.removeAttribute('style');
source.removeAttribute('style'); source.removeAttribute('style');
} }
// source.classList.toggle('resizable', mode);
if (mode) { if (mode) {
source.classList.add('resizable'); const length = Local.get(sClientSideKeyName+mode);
if (!source.layoutResizer) { if (!source.layoutResizer) {
const resizer = createElement('div', {'class':'resizer'}), const resizer = createElement('div', {'class':'resizer'}),
size = {}, size = {},
store = () => {
if ('Width' == resizer.mode) {
target.style.left = source.offsetWidth + 'px';
Local.set(resizer.key+resizer.mode, source.offsetWidth);
} else {
target.style.top = (4 + source.offsetTop + source.offsetHeight) + 'px';
Local.set(resizer.key+resizer.mode, source.offsetHeight);
}
},
cssint = s => { cssint = s => {
let value = getComputedStyle(source, null)[s].replace('px', ''); let value = getComputedStyle(source, null)[s].replace('px', '');
if (value.includes('%')) { if (value.includes('%')) {
value = source.parentElement['width'==resizer.mode ? 'offsetWidth' : 'offsetHeight'] value = source.parentElement['offset'+resizer.mode]
* value.replace('%', '') / 100; * value.replace('%', '') / 100;
} }
return parseFloat(value); return parseFloat(value);
@ -425,17 +435,20 @@ setLayoutResizer = (source, target, sClientSideKeyName, mode) =>
resizer.addEventListener('mousedown', { resizer.addEventListener('mousedown', {
handleEvent: function(e) { handleEvent: function(e) {
if ('mousedown' == e.type) { if ('mousedown' == e.type) {
const lmode = resizer.mode.toLowerCase();
e.preventDefault(); e.preventDefault();
size.pos = ('width' == resizer.mode) ? e.pageX : e.pageY; size.pos = ('width' == lmode) ? e.pageX : e.pageY;
size.min = cssint('min-'+resizer.mode); size.min = cssint('min-'+lmode);
size.max = cssint('max-'+resizer.mode); size.max = cssint('max-'+lmode);
size.org = cssint(resizer.mode); size.org = cssint(lmode);
addEventListener('mousemove', this); addEventListener('mousemove', this);
addEventListener('mouseup', this); addEventListener('mouseup', this);
} else if ('mousemove' == e.type) { } else if ('mousemove' == e.type) {
const length = size.org + (('width' == resizer.mode ? e.pageX : e.pageY) - size.pos); const lmode = resizer.mode.toLowerCase(),
length = size.org + (('width' == lmode ? e.pageX : e.pageY) - size.pos);
if (length >= size.min && length <= size.max ) { if (length >= size.min && length <= size.max ) {
source.style[resizer.mode] = length + 'px'; source.style[lmode] = length + 'px';
source.observer || store();
} }
} else if ('mouseup' == e.type) { } else if ('mouseup' == e.type) {
removeEventListener('mousemove', this); removeEventListener('mousemove', this);
@ -443,25 +456,16 @@ setLayoutResizer = (source, target, sClientSideKeyName, mode) =>
} }
} }
}); });
source.observer = new ResizeObserver(() => { source.observer = window.ResizeObserver ? new ResizeObserver(store) : null;
if ('width' == resizer.mode) {
target.style.left = source.offsetWidth + 'px';
Local.set(sClientSideKeyName, source.offsetWidth);
} else {
target.style.top = (4 + source.offsetTop + source.offsetHeight) + 'px';
Local.set(sClientSideKeyName, source.offsetHeight);
}
});
} }
source.layoutResizer.mode = mode; source.layoutResizer.mode = mode;
source.observer.observe(source, { box: 'border-box' }); source.layoutResizer.key = sClientSideKeyName;
const length = Local.get(sClientSideKeyName); source.observer && source.observer.observe(source, { box: 'border-box' });
if (length) { if (length) {
source.style[mode] = length + 'px'; source.style[mode] = length + 'px';
} }
} else { } else {
source.observer && source.observer.disconnect(); source.observer && source.observer.disconnect();
source.classList.remove('resizable');
} }
}; };

View file

@ -110,8 +110,8 @@ export class MailBoxUserScreen extends AbstractScreen {
let layout = SettingsUserStore.layout(); let layout = SettingsUserStore.layout();
setLayoutResizer(top, bottom, ClientSideKeyName.MessageListSize, setLayoutResizer(top, bottom, ClientSideKeyName.MessageListSize,
(ThemeStore.isMobile() || Layout.NoPreview === layout) (ThemeStore.isMobile() || Layout.NoPreview === layout)
? null ? 0
: (Layout.SidePreview === layout ? 'width' : 'height') : (Layout.SidePreview === layout ? 'Width' : 'Height')
); );
}; };
if (top && bottom) { if (top && bottom) {

View file

@ -1,5 +1,5 @@
import { Scope } from 'Common/Enums'; import { Scope } from 'Common/Enums';
import { keyScope, leftPanelDisabled, SettingsGet } from 'Common/Globals'; import { doc, keyScope, leftPanelDisabled, SettingsGet } from 'Common/Globals';
import { addObservablesTo } from 'Common/Utils'; import { addObservablesTo } from 'Common/Utils';
import { ThemeStore } from 'Stores/Theme'; import { ThemeStore } from 'Stores/Theme';
@ -24,4 +24,8 @@ AppUserStore.focusedState.subscribe(value => {
ThemeStore.isMobile() && leftPanelDisabled(Scope.FolderList !== value); ThemeStore.isMobile() && leftPanelDisabled(Scope.FolderList !== value);
break; break;
} }
['FolderList','MessageList','MessageView'].forEach(name => {
let dom = doc.querySelector('.RL-Mail'+name);
dom && dom.classList.toggle('focused', name === value);
});
}); });

View file

@ -212,7 +212,9 @@ export const MessageUserStore = new class {
if (message && folder && folder !== message.folder) { if (message && folder && folder !== message.folder) {
this.message(null); this.message(null);
} }
} },
isMessageSelected: value => elementById('rl-right').classList.toggle('message-selected', value)
}); });
this.purgeMessageBodyCache = this.purgeMessageBodyCache.throttle(30000); this.purgeMessageBodyCache = this.purgeMessageBodyCache.throttle(30000);

View file

@ -17,6 +17,15 @@
z-index: 0; z-index: 0;
} }
#rl-left {
width: @rlLeftWidth;
}
#rl-right {
z-index: 1;
left: @rlLeftWidth;
}
html.rl-mobile { html.rl-mobile {
&:not(.rl-left-panel-disabled) #rl-right { &:not(.rl-left-panel-disabled) #rl-right {
@ -28,10 +37,6 @@ html.rl-mobile {
} }
} }
#rl-left {
width: @rlLeftWidth;
}
/* /*
.resizable::after { .resizable::after {
background-color: #aaa; background-color: #aaa;
@ -50,7 +55,7 @@ html.rl-mobile {
} }
*/ */
.resizable > .resizer { .resizer {
background: #aaa; background: #aaa;
background: rgba(255,255,255,0.5); background: rgba(255,255,255,0.5);
display: none; display: none;
@ -58,11 +63,11 @@ html.rl-mobile {
position: absolute; position: absolute;
z-index: 102; z-index: 102;
} }
.resizable > .resizer:hover { .resizer:hover {
opacity: 1; opacity: 1;
} }
html:not(.rl-left-panel-disabled) #rl-left.resizable { html:not(.rl-left-panel-disabled) #rl-left {
resize: horizontal; resize: horizontal;
overflow: hidden; overflow: hidden;
min-width: 155px; min-width: 155px;
@ -78,6 +83,99 @@ html:not(.rl-left-panel-disabled) #rl-left.resizable {
width: 5px; width: 5px;
} }
.rl-side-preview-pane .RL-MailMessageList {
resize: horizontal;
min-width: 320px;
max-width: 60%;
}
.rl-bottom-preview-pane .RL-MailMessageList {
resize: vertical;
min-height: 200px;
max-height: 60%;
}
.rl-bottom-preview-pane .RL-MailMessageList > .resizer {
cursor: ns-resize;
height: 5px;
left: 0;
bottom: 0;
width: 100%;
}
html:not(.rl-left-panel-disabled) #rl-left > .resizer,
.RL-MailMessageList > .resizer {
display: block;
}
.RL-MailMessageList {
position: absolute;
top: 0;
bottom: @rlBottomMargin;
left: 0;
width: 50%;
}
.RL-MailMessageView {
position: absolute;
top: 50px + @rlLowMargin;
bottom: 13px;
right: 0;
left: 0;
.b-message-view-backdrop {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, .4);
z-index: 10;
text-align: center;
.backdrop-message {
position: relative;
display: inline-block;
color: white;
font-size: 20px;
line-height: 30px;
background: rgba(0, 0, 0, .6);
padding: 15px;
border-radius: 5px;
text-shadow: 0 1px 1px #000;
transform: translateY(-50%);
top: 50%;
}
}
}
html.rl-side-preview-pane {
.RL-MailMessageView {
left: 50%;
}
}
/*
#rl-popups > dialog {
top: 0;
margin: 10px auto;
padding: 0;
border: 0;
}
*/
#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;
}
.dropdown-menu { .dropdown-menu {
max-height: 60vh; max-height: 60vh;
max-width: 90vw; max-width: 90vw;
@ -107,98 +205,6 @@ html:not(.rl-left-panel-disabled) #rl-left.resizable {
} }
} }
.rl-side-preview-pane .RL-MailMessageList.resizable {
resize: horizontal;
min-width: 320px;
max-width: 60%;
}
.rl-bottom-preview-pane .RL-MailMessageList.resizable {
resize: vertical;
min-height: 200px;
max-height: 60%;
}
.rl-bottom-preview-pane .RL-MailMessageList > .resizer {
cursor: ns-resize;
height: 5px;
left: 0;
bottom: 0;
width: 100%;
}
html:not(.rl-left-panel-disabled) #rl-left.resizable > .resizer,
.RL-MailMessageList > .resizer {
display: block;
}
#rl-right {
z-index: 1;
left: @rlLeftWidth;
}
.RL-MailMessageList {
position: absolute;
top: 50px;
bottom: @rlBottomMargin;
left: 0;
width: 50%;
}
.RL-MailMessageView {
position: absolute;
top: 50px + @rlLowMargin;
bottom: 13px;
right: 0;
left: 50%;
.b-message-view-backdrop {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, .4);
z-index: 10;
text-align: center;
.backdrop-message {
position: relative;
display: inline-block;
color: white;
font-size: 20px;
line-height: 30px;
background: rgba(0, 0, 0, .6);
padding: 15px;
border-radius: 5px;
text-shadow: 0 1px 1px #000;
transform: translateY(-50%);
top: 50%;
}
}
}
/*
#rl-popups > dialog {
top: 0;
margin: 10px auto;
padding: 0;
border: 0;
}
*/
#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;
}
.dropdown-menu * + .dividerbar { .dropdown-menu * + .dividerbar {
margin-top: 9px; margin-top: 9px;
padding-top: 9px; padding-top: 9px;
@ -254,9 +260,11 @@ html:not(.rl-left-panel-disabled) #rl-left.resizable > .resizer,
width: 40%; width: 40%;
} }
html.rl-side-preview-pane {
.RL-MailMessageView { .RL-MailMessageView {
left: 40%; left: 40%;
} }
}
} }
/* mobile and tablet */ /* mobile and tablet */
@ -307,7 +315,6 @@ html.rl-left-panel-disabled {
} }
} }
html.rl-mobile,
html.rl-no-preview-pane { html.rl-no-preview-pane {
.RL-MailMessageList { .RL-MailMessageList {
@ -315,28 +322,24 @@ html.rl-no-preview-pane {
width: inherit; width: inherit;
} }
.RL-MailMessageView {
left: 0 !important;
}
} }
html.rl-mobile #rl-left > .resizer, html.rl-mobile #rl-left > .resizer,
html.rl-no-preview-pane #rl-right .resizer, html.rl-no-preview-pane #rl-right .resizer {
html.rl-mobile #rl-right .resizer {
display: none !important; display: none !important;
} }
html.rl-bottom-preview-pane:not(.rl-mobile) { html.rl-bottom-preview-pane {
.RL-MailMessageList { .RL-MailMessageList {
right: @rlBottomMargin !important;
bottom: inherit; bottom: inherit;
width: inherit; width: inherit;
height: 300px; height: 300px;
right: 0;
} }
.RL-MailMessageView { .RL-MailMessageView {
left: 0 !important; left: 0;
top: 356px; top: 356px;
} }
} }

View file

@ -1,40 +1,34 @@
html.rl-mobile, html.rl-mobile,
html.rl-no-preview-pane { html.rl-no-preview-pane {
.messageList.message-selected { .message-selected .RL-MailMessageList {
display: none; display: none;
} }
} }
.RL-MailMessageList.focused .messageList {
border-color: #9d9d9d;
}
#sort-list-dropdown-id { #sort-list-dropdown-id {
padding-left: 6px; padding-left: 6px;
padding-right: 6px; padding-right: 6px;
} }
.RL-MailMessageList .btn-toolbar {
height: 30px;
padding: 10px 1px;
white-space: nowrap;
}
.messageList { .messageList {
height: 100%; height: calc(100% - 50px);
background-color: #fff; background-color: #fff;
border: 1px solid @rlMainDarkColor; border: 1px solid @rlMainDarkColor;
border-radius: @rlMainBorderRadius; border-radius: @rlMainBorderRadius;
box-shadow: @rlMainShadow; box-shadow: @rlMainShadow;
z-index: 101;
.toolbar {
position: absolute;
top: -50px;
right: 0;
left: 0;
height: 30px;
padding: 10px 1px;
z-index: 102;
white-space: nowrap;
}
.b-message-list-wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%;
}
.b-footer { .b-footer {
flex-shrink: 0; flex-shrink: 0;
@ -163,10 +157,6 @@ html.rl-no-preview-pane {
text-align: center; text-align: center;
} }
} }
&.focused {
border-color: #9d9d9d;
}
} }
.hideMessageListCheckbox { .hideMessageListCheckbox {
@ -414,7 +404,7 @@ html.rl-ctrl-key-pressed .messageListItem {
} }
} }
.b-message-list-wrapper:not(.hideMessageListCheckbox) .subjectParent { .messageList:not(.hideMessageListCheckbox) .subjectParent {
margin-left: 30px; margin-left: 30px;
} }
} }

View file

@ -1,5 +1,13 @@
.g-ui-min-height-300 {
min-height: 300px; html.rl-no-preview-pane {
#rl-right:not(.message-selected) .RL-MailMessageView {
display: none;
}
}
.RL-MailMessageView.focused .messageView {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
border-color: darken(@rlMainDarkColor, 5%);
} }
.messageView { .messageView {
@ -204,7 +212,7 @@
text-align: center; text-align: center;
font-size: 24px; font-size: 24px;
color: grey; color: grey;
padding-top: 50px; padding: 50px 0;
} }
.showImages, .readReceipt, .pgpSigned, .pgpEncrypted { .showImages, .readReceipt, .pgpSigned, .pgpEncrypted {
@ -446,11 +454,6 @@
} }
} }
&.focused {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
border-color: darken(@rlMainDarkColor, 5%);
}
.thread-controls { .thread-controls {
.dropdown-toggle { .dropdown-toggle {
padding-left: 10px; padding-left: 10px;
@ -463,13 +466,8 @@
} }
} }
html.rl-mobile .messageView,
html.rl-no-preview-pane .messageView { html.rl-no-preview-pane .messageView {
&:not(.message-selected) {
display: none;
}
.toolbar { .toolbar {
padding-left: 1px; padding-left: 1px;
} }
@ -490,7 +488,7 @@ html:not(.rl-mobile):not(.rl-no-preview-pane) .messageView {
} }
} }
html.rl-bottom-preview-pane:not(.rl-mobile) .messageView { html.rl-bottom-preview-pane .messageView {
.b-content { .b-content {
bottom: @rlBottomMargin; bottom: @rlBottomMargin;
} }

View file

@ -10,16 +10,14 @@
top: 40px; top: 40px;
} }
.b-system-drop-down { .RL-SystemDropDown {
.b-toolbar {
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
height: 30px; height: 30px;
padding: 10px @rlLowMargin; padding: 10px @rlLowMargin;
z-index: 103; z-index: 103;
}
.email-title { .email-title {
display: inline-block; display: inline-block;

View file

@ -20,12 +20,6 @@ class PaneSettingsAdminView extends AbstractViewRight {
.computed(() => PackageAdminStore.loading() ? 'visible' : 'hidden'); .computed(() => PackageAdminStore.loading() ? 'visible' : 'hidden');
} }
toggleLeft(item, event) {
event.preventDefault();
event.stopPropagation();
leftPanelDisabled(!leftPanelDisabled());
}
logoutClick() { logoutClick() {
Remote.adminLogout(() => rl.logoutReload()); Remote.adminLogout(() => rl.logoutReload());
} }

View file

@ -10,7 +10,6 @@ import { AppUserStore } from 'Stores/User/App';
import { SettingsUserStore } from 'Stores/User/Settings'; import { SettingsUserStore } from 'Stores/User/Settings';
import { FolderUserStore } from 'Stores/User/Folder'; import { FolderUserStore } from 'Stores/User/Folder';
import { MessageUserStore } from 'Stores/User/Message'; import { MessageUserStore } from 'Stores/User/Message';
import { ThemeStore } from 'Stores/Theme';
import { showScreenPopup } from 'Knoin/Knoin'; import { showScreenPopup } from 'Knoin/Knoin';
import { AbstractViewLeft } from 'Knoin/AbstractViews'; import { AbstractViewLeft } from 'Knoin/AbstractViews';
@ -40,8 +39,6 @@ export class MailFolderList extends AbstractViewLeft {
this.allowContacts = AppUserStore.allowContacts(); this.allowContacts = AppUserStore.allowContacts();
addComputablesTo(this, { addComputablesTo(this, {
folderListFocused: () => Scope.FolderList === AppUserStore.focusedState(),
folderListVisible: () => { folderListVisible: () => {
let multiple = false, let multiple = false,
inbox, visible, inbox, visible,
@ -85,7 +82,6 @@ export class MailFolderList extends AbstractViewLeft {
el = eqs(event, 'a'); el = eqs(event, 'a');
if (el && el.matches('.selectable')) { if (el && el.matches('.selectable')) {
ThemeStore.isMobile() && leftPanelDisabled(true);
event.preventDefault(); event.preventDefault();
const folder = ko.dataFor(el); const folder = ko.dataFor(el);
if (folder) { if (folder) {
@ -120,7 +116,7 @@ export class MailFolderList extends AbstractViewLeft {
shortcuts.add('arrowup,arrowdown', '', Scope.FolderList, event => { shortcuts.add('arrowup,arrowdown', '', Scope.FolderList, event => {
let items = [], index = 0; let items = [], index = 0;
dom.querySelectorAll('.b-folders li a:not(.hidden)').forEach(node => { dom.querySelectorAll('li a:not(.hidden)').forEach(node => {
if (node.offsetHeight || node.getClientRects().length) { if (node.offsetHeight || node.getClientRects().length) {
items.push(node); items.push(node);
if (node.matches('.focused')) { if (node.matches('.focused')) {
@ -143,7 +139,7 @@ export class MailFolderList extends AbstractViewLeft {
}); });
shortcuts.add('enter,open', '', Scope.FolderList, () => { shortcuts.add('enter,open', '', Scope.FolderList, () => {
const item = qs('.b-folders li a:not(.hidden).focused'); const item = qs('li a:not(.hidden).focused');
if (item) { if (item) {
AppUserStore.focusedState(Scope.MessageList); AppUserStore.focusedState(Scope.MessageList);
item.click(); item.click();
@ -153,7 +149,7 @@ export class MailFolderList extends AbstractViewLeft {
}); });
shortcuts.add('space', '', Scope.FolderList, () => { shortcuts.add('space', '', Scope.FolderList, () => {
const item = qs('.b-folders li a:not(.hidden).focused'), const item = qs('li a:not(.hidden).focused'),
folder = item && ko.dataFor(item); folder = item && ko.dataFor(item);
if (folder) { if (folder) {
const collapsed = folder.collapsed(); const collapsed = folder.collapsed();
@ -172,10 +168,10 @@ export class MailFolderList extends AbstractViewLeft {
}); });
AppUserStore.focusedState.subscribe(value => { AppUserStore.focusedState.subscribe(value => {
let el = qs('.b-folders li a.focused'); let el = qs('li a.focused');
el && el.classList.remove('focused'); el && el.classList.remove('focused');
if (Scope.FolderList === value) { if (Scope.FolderList === value) {
el = qs('.b-folders li a.selected'); el = qs('li a.selected');
el && el.classList.add('focused'); el && el.classList.add('focused');
} }
}); });

View file

@ -69,9 +69,10 @@ export class MailMessageList extends AbstractViewRight {
); );
this.composeInEdit = AppUserStore.composeInEdit; this.composeInEdit = AppUserStore.composeInEdit;
this.isMobile = ThemeStore.isMobile;
this.leftPanelDisabled = leftPanelDisabled; this.leftPanelDisabled = leftPanelDisabled;
this.isMessageSelected = MessageUserStore.isMessageSelected;
this.messageListSearch = MessageUserStore.listSearch; this.messageListSearch = MessageUserStore.listSearch;
this.messageListError = MessageUserStore.listError; this.messageListError = MessageUserStore.listError;
@ -167,8 +168,6 @@ export class MailMessageList extends AbstractViewRight {
mobileCheckedStateHide: () => ThemeStore.isMobile() ? !MessageUserStore.listChecked().length : true, mobileCheckedStateHide: () => ThemeStore.isMobile() ? !MessageUserStore.listChecked().length : true,
messageListFocused: () => Scope.MessageList === AppUserStore.focusedState(),
sortText: () => { sortText: () => {
let mode = FolderUserStore.sortMode(), let mode = FolderUserStore.sortMode(),
desc = '' === mode || mode.includes('REVERSE'); desc = '' === mode || mode.includes('REVERSE');
@ -338,20 +337,6 @@ export class MailMessageList extends AbstractViewRight {
} }
} }
hideLeft(item, event) {
event.preventDefault();
event.stopPropagation();
leftPanelDisabled(true);
}
showLeft(item, event) {
event.preventDefault();
event.stopPropagation();
leftPanelDisabled(false);
}
composeClick() { composeClick() {
showMessageComposer(); showMessageComposer();
} }
@ -683,14 +668,14 @@ export class MailMessageList extends AbstractViewRight {
} }
onBuild(dom) { onBuild(dom) {
const eqs = (ev, s) => ev.target.closestWithin('.messageList '+s, dom); const eqs = (ev, s) => ev.target.closestWithin(s, dom);
this.selector.init(dom.querySelector('.b-content'), Scope.MessageList); this.selector.init(dom.querySelector('.b-content'), Scope.MessageList);
dom.addEventListener('click', event => { dom.addEventListener('click', event => {
ThemeStore.isMobile() && leftPanelDisabled(true); ThemeStore.isMobile() && !eqs(event, '.toggleLeft') && leftPanelDisabled(true);
if (eqs(event, '.b-message-list-wrapper') && Scope.MessageView === AppUserStore.focusedState()) { if (eqs(event, '.messageList') && Scope.MessageView === AppUserStore.focusedState()) {
AppUserStore.focusedState(Scope.MessageList); AppUserStore.focusedState(Scope.MessageList);
} }

View file

@ -81,7 +81,6 @@ export class MailMessageView extends AbstractViewRight {
this.hasCheckedMessages = MessageUserStore.hasCheckedMessages; this.hasCheckedMessages = MessageUserStore.hasCheckedMessages;
this.messageLoadingThrottle = MessageUserStore.messageLoading; this.messageLoadingThrottle = MessageUserStore.messageLoading;
this.messagesBodiesDom = MessageUserStore.messagesBodiesDom; this.messagesBodiesDom = MessageUserStore.messagesBodiesDom;
this.isMessageSelected = MessageUserStore.isMessageSelected;
this.messageActiveDom = MessageUserStore.messageActiveDom; this.messageActiveDom = MessageUserStore.messageActiveDom;
this.messageError = MessageUserStore.messageError; this.messageError = MessageUserStore.messageError;
@ -177,8 +176,6 @@ export class MailMessageView extends AbstractViewRight {
return ''; return '';
}, },
messageFocused: () => Scope.MessageView === AppUserStore.focusedState(),
messageListAndMessageViewLoading: messageListAndMessageViewLoading:
() => MessageUserStore.listCompleteLoading() || MessageUserStore.messageLoading() () => MessageUserStore.listCompleteLoading() || MessageUserStore.messageLoading()
}); });

View file

@ -4,8 +4,6 @@ import { getFolderInboxName } from 'Common/Cache';
import { AbstractViewLeft } from 'Knoin/AbstractViews'; import { AbstractViewLeft } from 'Knoin/AbstractViews';
import { ThemeStore } from 'Stores/Theme';
export class MenuSettingsUserView extends AbstractViewLeft { export class MenuSettingsUserView extends AbstractViewLeft {
/** /**
* @param {Object} screen * @param {Object} screen
@ -18,14 +16,6 @@ export class MenuSettingsUserView extends AbstractViewLeft {
this.menu = screen.menu; this.menu = screen.menu;
} }
onBuild(dom) {
dom.addEventListener('click', event =>
ThemeStore.isMobile()
&& event.target.closestWithin('.b-settins-left nav a', dom)
&& leftPanelDisabled(true)
);
}
link(route) { link(route) {
return settings(route); return settings(route);
} }

View file

@ -11,6 +11,7 @@ export class PaneSettingsUserView extends AbstractViewRight {
constructor() { constructor() {
super('SettingsPane'); super('SettingsPane');
this.isMobile = ThemeStore.isMobile;
this.leftPanelDisabled = leftPanelDisabled; this.leftPanelDisabled = leftPanelDisabled;
} }
@ -18,22 +19,10 @@ export class PaneSettingsUserView extends AbstractViewRight {
MessageUserStore.message(null); MessageUserStore.message(null);
} }
hideLeft(item, event) {
event.preventDefault();
event.stopPropagation();
leftPanelDisabled(true);
}
showLeft(item, event) {
event.preventDefault();
event.stopPropagation();
leftPanelDisabled(false);
}
onBuild(dom) { onBuild(dom) {
dom.addEventListener('click', () => ThemeStore.isMobile() && leftPanelDisabled(true)); dom.addEventListener('click', () =>
ThemeStore.isMobile() && !event.target.closestWithin('.toggleLeft', dom) && leftPanelDisabled(true)
);
} }
backToMailBoxClick() { backToMailBoxClick() {

View file

@ -1,20 +0,0 @@
'use strict';
(w=>{
// Edge Legacy (pre chromium/webkit), Firefox < 69, Safari < 13.4
w.ResizeObserver || (w.ResizeObserver = class {
constructor(callback) {
this.observer = new MutationObserver(callback.debounce(250));
}
disconnect() {
this.observer.disconnect();
}
observe(target) {
this.observer.observe(target, { attributes: true, subtree: true, attributeFilter: ['style'] });
}
});
})(this);

View file

@ -19,8 +19,7 @@
{{BaseAppFaviconTouchLinkTag}} {{BaseAppFaviconTouchLinkTag}}
</head> </head>
<body> <body id="rl-app" data-admin='{{BaseAppAdmin}}'>
<div id="rl-app" data-admin='{{BaseAppAdmin}}'>
<div id="rl-loading"> <div id="rl-loading">
<div id="rl-loading-desc">{{LoadingDescriptionEsc}}</div> <div id="rl-loading-desc">{{LoadingDescriptionEsc}}</div>
<div class="e-spinner"> <div class="e-spinner">
@ -31,11 +30,10 @@
</div> </div>
<div id="rl-loading-error" hidden="">An error occurred.<br>Please refresh the page and try again.</div> <div id="rl-loading-error" hidden="">An error occurred.<br>Please refresh the page and try again.</div>
<div id="rl-content" hidden=""> <div id="rl-content" hidden="">
<div id="rl-popups"></div>
<div id="rl-left"></div> <div id="rl-left"></div>
<div id="rl-right"></div> <div id="rl-right"></div>
</div> </div>
</div> <div id="rl-popups"></div>
{{BaseTemplates}} {{BaseTemplates}}
<script nonce="" type="text/javascript">{{BaseAppBootScript}}{{BaseLanguage}}</script> <script nonce="" type="text/javascript">{{BaseAppBootScript}}{{BaseLanguage}}</script>
</body> </body>

View file

@ -1,6 +1,6 @@
<div class="b-settings b-admin-right"> <div class="b-settings b-admin-right">
<div class="b-toolbar g-ui-user-select-none"> <div class="b-toolbar g-ui-user-select-none">
<a class="btn btn-thin-2 fontastic toggleLeft" data-bind="click: toggleLeft, text: leftPanelDisabled() ? '' : ''"></a> <a class="btn btn-thin-2 fontastic toggleLeft" data-bind="click: leftPanelDisabled.toggle, text: leftPanelDisabled() ? '' : ''"></a>
<i class="icon-spinner" style="margin: 10px" data-bind="style: {'visibility': adminManLoadingVisibility }"></i> <i class="icon-spinner" style="margin: 10px" data-bind="style: {'visibility': adminManLoadingVisibility }"></i>
<h4>SnappyMail - <span data-i18n="TOP_PANEL/LABEL_ADMIN_PANEL"></span></h4> <h4>SnappyMail - <span data-i18n="TOP_PANEL/LABEL_ADMIN_PANEL"></span></h4>
<a class="btn btn-logout fontastic" data-bind="click: logoutClick"></a> <a class="btn btn-logout fontastic" data-bind="click: logoutClick"></a>

View file

@ -1,4 +1,4 @@
<div class="b-folders g-ui-user-select-none" data-bind="css: {'focused': folderListFocused, 'single-root-inbox': foldersListWithSingleInboxRootFolder}"> <div class="b-folders g-ui-user-select-none" data-bind="css: {'single-root-inbox': foldersListWithSingleInboxRootFolder}">
<div class="b-toolbar btn-toolbar hide-mobile"> <div class="b-toolbar btn-toolbar hide-mobile">
<a class="btn buttonCompose" data-bind="click: composeClick, css: {'btn-warning': composeInEdit, 'btn-success': !composeInEdit()}" data-i18n="[title]FOLDER_LIST/BUTTON_NEW_MESSAGE"> <a class="btn buttonCompose" data-bind="click: composeClick, css: {'btn-warning': composeInEdit, 'btn-success': !composeInEdit()}" data-i18n="[title]FOLDER_LIST/BUTTON_NEW_MESSAGE">
<i class="icon-paper-plane"></i> <i class="icon-paper-plane"></i>
@ -12,10 +12,10 @@
<ul class="b-folders-user" data-bind="template: { name: 'MailFolderListItem', foreach: folderListVisible }"></ul> <ul class="b-folders-user" data-bind="template: { name: 'MailFolderListItem', foreach: folderListVisible }"></ul>
<div class="move-action-content-wrapper" data-bind="visible: moveAction"></div> <div class="move-action-content-wrapper" data-bind="visible: moveAction"></div>
</div> </div>
<div class="b-content show-on-panel-disabled" data-bind="click: function () { leftPanelDisabled(false); }"></div> <div class="b-content show-on-panel-disabled" data-bind="click: leftPanelDisabled.toggle()"></div>
<div class="b-footer btn-toolbar hide-mobile"> <div class="b-footer btn-toolbar hide-mobile">
<div class="btn-group"> <div class="btn-group">
<a class="btn buttonResize" data-bind="click: function () { leftPanelDisabled(!leftPanelDisabled()); }"> <a class="btn buttonResize" data-bind="click: leftPanelDisabled.toggle()">
<i data-bind="css: {'icon-resize-out': leftPanelDisabled(), 'icon-resize-in': !leftPanelDisabled()}"></i> <i data-bind="css: {'icon-resize-out': leftPanelDisabled(), 'icon-resize-in': !leftPanelDisabled()}"></i>
</a> </a>
</div> </div>

View file

@ -1,12 +1,10 @@
<div class="messageList g-ui-user-select-none" <div class="btn-toolbar">
data-bind="css: {'message-selected': isMessageSelected, 'focused': messageListFocused() }"> <!-- ko if: isMobile() -->
<div class="toolbar"> <a class="btn btn-thin-2 fontastic toggleLeft" data-bind="click: leftPanelDisabled.toggle, text: leftPanelDisabled() ? '' : ''"></a>
<div class="btn-toolbar"> <a class="btn buttonCompose" data-bind="click: composeClick, css: {'btn-warning': composeInEdit, 'btn-success': !composeInEdit()}, visible: mobileCheckedStateHide()" data-i18n="[title]FOLDER_LIST/BUTTON_NEW_MESSAGE">
<a class="btn btn-thin-2 fontastic show-mobile" data-bind="click: hideLeft, visible: !leftPanelDisabled()"></a>
<a class="btn btn-thin-2 fontastic show-mobile" data-bind="click: showLeft, visible: leftPanelDisabled()"></a>
<a class="btn buttonCompose show-mobile" data-bind="click: composeClick, css: {'btn-warning': composeInEdit, 'btn-success': !composeInEdit()}, visible: mobileCheckedStateHide()" data-i18n="[title]FOLDER_LIST/BUTTON_NEW_MESSAGE">
<i class="icon-paper-plane"></i> <i class="icon-paper-plane"></i>
</a> </a>
<!-- /ko -->
<a class="btn" data-bind="command: reloadCommand, visible: mobileCheckedStateHide()" data-i18n="[title]MESSAGE_LIST/BUTTON_RELOAD"> <a class="btn" data-bind="command: reloadCommand, visible: mobileCheckedStateHide()" data-i18n="[title]MESSAGE_LIST/BUTTON_RELOAD">
<i class="icon-spinner not-animated"></i> <i class="icon-spinner not-animated"></i>
</a> </a>
@ -151,9 +149,9 @@
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</div>
<div class="b-message-list-wrapper" data-bind="css: {'hideMessageListCheckbox': !useCheckboxesInList() }"> <div class="messageList g-ui-user-select-none" data-bind="css: {'hideMessageListCheckbox': !useCheckboxesInList() }">
<div class="second-toolbar thm-message-list-top-toolbar"> <div class="second-toolbar thm-message-list-top-toolbar">
<div class="form-inline"> <div class="form-inline">
<i class="checkboxCheckAll fontastic" data-bind="text: checkAll() ? (isIncompleteChecked() ? '▣' : '☑') : '☐'"></i> <i class="checkboxCheckAll fontastic" data-bind="text: checkAll() ? (isIncompleteChecked() ? '▣' : '☑') : '☐'"></i>
@ -233,5 +231,4 @@
<!-- ko template: { name: 'Paginator', data: messageListPaginator } --><!-- /ko --> <!-- ko template: { name: 'Paginator', data: messageListPaginator } --><!-- /ko -->
</div> </div>
</div> </div>
</div>
</div> </div>

View file

@ -1,4 +1,4 @@
<div class="messageView" data-bind="css: {'message-selected': isMessageSelected, 'focused': messageFocused}"> <div class="messageView">
<div class="toolbar top-toolbar g-ui-user-select-none"> <div class="toolbar top-toolbar g-ui-user-select-none">
<div class="messageButtons btn-toolbar"> <div class="messageButtons btn-toolbar">
<div class="btn-group" data-i18n="[title]GLOBAL/CLOSE"> <div class="btn-group" data-i18n="[title]GLOBAL/CLOSE">
@ -243,17 +243,15 @@
<div class="messageItem" data-bind="css: viewLineAsCss()"> <div class="messageItem" data-bind="css: viewLineAsCss()">
<div tabindex="0" data-bind="hasfocus: messageDomFocused"> <div tabindex="0" data-bind="hasfocus: messageDomFocused">
<div>
<span class="buttonFull" data-bind="click: toggleFullScreen"> <span class="buttonFull" data-bind="click: toggleFullScreen">
<i data-bind="css: { 'icon-arrows-out': !fullScreenMode(), 'icon-arrows-in': fullScreenMode }"></i> <i data-bind="css: { 'icon-arrows-out': !fullScreenMode(), 'icon-arrows-in': fullScreenMode }"></i>
</span> </span>
<div class="loading g-ui-min-height-300" data-bind="visible: messageLoadingThrottle()"> <div class="loading" data-bind="visible: messageLoadingThrottle()">
<i class="icon-spinner"></i> <i class="icon-spinner"></i>
<span data-i18n="GLOBAL/LOADING"></span> <span data-i18n="GLOBAL/LOADING"></span>
</div> </div>
</div>
<div class="g-ui-min-height-300" data-bind="visible: !messageLoadingThrottle()"> <div data-bind="visible: !messageLoadingThrottle()">
<div class="bodySubHeader"> <div class="bodySubHeader">
<div class="showImages" data-bind="visible: message() && message().hasImages(), click: showImages"> <div class="showImages" data-bind="visible: message() && message().hasImages(), click: showImages">
<i class="fontastic">🖼</i> <i class="fontastic">🖼</i>
@ -310,7 +308,7 @@
</div> </div>
</div> </div>
<div class="bodyText g-ui-min-height-300" <div class="bodyText"
data-bind="initDom: messagesBodiesDom"></div> data-bind="initDom: messagesBodiesDom"></div>
</div> </div>
</div> </div>

View file

@ -4,9 +4,9 @@
<a data-bind="css: {'selected': selected }, attr: { 'href': $root.link(route), 'data-i18n': label }"></a> <a data-bind="css: {'selected': selected }, attr: { 'href': $root.link(route), 'data-i18n': label }"></a>
</nav> </nav>
</div> </div>
<div class="b-content show-on-panel-disabled" data-bind="click: function () { leftPanelDisabled(false); }"></div> <div class="b-content show-on-panel-disabled" data-bind="click: leftPanelDisabled.toggle()"></div>
<div class="b-footer"> <div class="b-footer">
<a class="btn buttonResize" data-bind="click: function () { leftPanelDisabled(!leftPanelDisabled()); }"> <a class="btn buttonResize" data-bind="click: leftPanelDisabled.toggle()">
<i data-bind="css: {'icon-resize-out': leftPanelDisabled(), 'icon-resize-in': !leftPanelDisabled()}"></i> <i data-bind="css: {'icon-resize-out': leftPanelDisabled(), 'icon-resize-in': !leftPanelDisabled()}"></i>
</a> </a>
</div> </div>

View file

@ -1,11 +1,10 @@
<div class="b-settings b-settins-right"> <div class="b-settings b-settins-right">
<div class="b-toolbar btn-toolbar" style="margin-top: 2px;"> <div class="b-toolbar btn-toolbar" style="margin-top: 2px;">
<div class="btn-group show-mobile" data-bind="visible: !leftPanelDisabled()" style="margin-left: -1px"> <!-- ko if: isMobile() -->
<a class="btn btn-thin-2 fontastic" data-bind="click: hideLeft"></a> <div class="btn-group" style="margin-left: -1px">
</div> <a class="btn btn-thin-2 fontastic toggleLeft" data-bind="click: leftPanelDisabled.toggle, text: leftPanelDisabled() ? '' : ''"></a>
<div class="btn-group show-mobile" data-bind="visible: leftPanelDisabled()">
<a class="btn btn-thin-2 fontastic" data-bind="click: showLeft"></a>
</div> </div>
<!-- /ko -->
<a class="btn button-back" data-bind="click: backToMailBoxClick"> <a class="btn button-back" data-bind="click: backToMailBoxClick">
<i class="fontastic"></i> <i class="fontastic"></i>
<span data-i18n="GLOBAL/BACK"></span> <span data-i18n="GLOBAL/BACK"></span>

View file

@ -1,6 +1,4 @@
<div class="b-system-drop-down g-ui-user-select-none"> <div class="btn-toolbar g-ui-user-select-none">
<div class="b-toolbar">
<div class="btn-toolbar">
<div class="audioPlace" <div class="audioPlace"
data-bind="visible: '' !== currentAudio(), attr: { title: currentAudio }, click: stopPlay"> data-bind="visible: '' !== currentAudio(), attr: { title: currentAudio }, click: stopPlay">
<div class="playIcon"><div></div></div> <div class="playIcon"><div></div></div>
@ -76,6 +74,4 @@
</li> </li>
</ul> </ul>
</div> </div>
</div>
</div>
</div> </div>

View file

@ -59,7 +59,6 @@ config.paths.js = {
libs: { libs: {
name: 'libs.js', name: 'libs.js',
src: [ src: [
'dev/polyfill.js',
'dev/prototype.js', 'dev/prototype.js',
'dev/External/ifvisible.js', 'dev/External/ifvisible.js',
'dev/dragdropgecko.js', 'dev/dragdropgecko.js',