mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-01-01 04:22:15 +08:00
Resolve Issue #100
This commit is contained in:
parent
1996c79240
commit
bb15cd1ec3
5 changed files with 81 additions and 68 deletions
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -220,7 +220,7 @@ export const MessageUserStore = new class {
|
|||
}
|
||||
});
|
||||
|
||||
this.purgeMessageBodyCacheThrottle = this.purgeMessageBodyCache.throttle(30000);
|
||||
this.purgeMessageBodyCache = this.purgeMessageBodyCache.throttle(30000);
|
||||
}
|
||||
|
||||
purgeMessageBodyCache() {
|
||||
|
@ -428,16 +428,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 +443,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 +456,7 @@ export const MessageUserStore = new class {
|
|||
}
|
||||
|
||||
if (message && message.uid === json.Uid) {
|
||||
this.messageError('');
|
||||
oMessage || this.messageError('');
|
||||
|
||||
if (cached) {
|
||||
delete json.IsSeen;
|
||||
|
@ -475,7 +471,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 +480,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 +507,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 +514,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 +541,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 +554,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 +564,6 @@ export const MessageUserStore = new class {
|
|||
}
|
||||
|
||||
if (isNew) {
|
||||
message = this.message();
|
||||
|
||||
if (
|
||||
selectedMessage &&
|
||||
message &&
|
||||
|
@ -613,20 +612,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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
this.bPrefetch = false;
|
||||
this.emptySubjectValue = '';
|
||||
|
||||
this.iGoToUpUpOrDownDownTimeout = 0;
|
||||
this.iGoToUpOrDownTimeout = 0;
|
||||
|
||||
this.newMoveToFolder = !!SettingsGet('NewMoveToFolder');
|
||||
|
||||
|
@ -191,13 +191,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 +353,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 => {
|
||||
|
|
Loading…
Reference in a new issue