mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-04 15:07:02 +03:00
Restructure JavaScript
Split list code from MessageUserStore into MessagelistUserStore Move functions out of AppUser
This commit is contained in:
parent
60b7f61e42
commit
661cd2aaf9
26 changed files with 1144 additions and 1186 deletions
435
dev/Stores/User/Messagelist.js
Normal file
435
dev/Stores/User/Messagelist.js
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
import { koComputable } from 'External/ko';
|
||||
|
||||
import { MessageSetAction } from 'Common/EnumsUser';
|
||||
import { $htmlCL } from 'Common/Globals';
|
||||
import { arrayLength, pInt, pString } from 'Common/Utils';
|
||||
import { addObservablesTo, addComputablesTo } from 'External/ko';
|
||||
|
||||
import {
|
||||
getFolderInboxName,
|
||||
addNewMessageCache,
|
||||
setFolderUidNext,
|
||||
getFolderFromCacheList,
|
||||
setFolderHash,
|
||||
MessageFlagsCache,
|
||||
clearNewMessageCache
|
||||
} from 'Common/Cache';
|
||||
|
||||
import { mailBox } from 'Common/Links';
|
||||
import { i18n, getNotification } from 'Common/Translator';
|
||||
|
||||
import { EmailCollectionModel } from 'Model/EmailCollection';
|
||||
import { MessageCollectionModel } from 'Model/MessageCollection';
|
||||
|
||||
import { AccountUserStore } from 'Stores/User/Account';
|
||||
import { FolderUserStore } from 'Stores/User/Folder';
|
||||
import { MessageUserStore } from 'Stores/User/Message';
|
||||
import { NotificationUserStore } from 'Stores/User/Notification';
|
||||
import { SettingsUserStore } from 'Stores/User/Settings';
|
||||
|
||||
//import Remote from 'Remote/User/Fetch'; // Circular dependency
|
||||
|
||||
const
|
||||
isChecked = item => item.checked();
|
||||
|
||||
export const MessagelistUserStore = ko.observableArray().extend({ debounce: 0 });
|
||||
|
||||
addObservablesTo(MessagelistUserStore, {
|
||||
count: 0,
|
||||
listSearch: '',
|
||||
threadUid: 0,
|
||||
page: 1,
|
||||
pageBeforeThread: 1,
|
||||
error: '',
|
||||
|
||||
endHash: '',
|
||||
endThreadUid: 0,
|
||||
|
||||
loading: false,
|
||||
// Happens when message(s) removed from list
|
||||
isIncomplete: false,
|
||||
|
||||
selectedMessage: null,
|
||||
focusedMessage: null
|
||||
});
|
||||
|
||||
MessagelistUserStore.disableAutoSelect = ko.observable(false).extend({ falseTimeout: 500 });
|
||||
|
||||
// Computed Observables
|
||||
|
||||
addComputablesTo(MessagelistUserStore, {
|
||||
isLoading: () => {
|
||||
const value = MessagelistUserStore.loading() | MessagelistUserStore.isIncomplete();
|
||||
$htmlCL.toggle('list-loading', value);
|
||||
return value;
|
||||
},
|
||||
|
||||
pageCount: () => Math.max(1, Math.ceil(MessagelistUserStore.count() / SettingsUserStore.messagesPerPage())),
|
||||
|
||||
mainSearch: {
|
||||
read: MessagelistUserStore.listSearch,
|
||||
write: value => rl.route.setHash(
|
||||
mailBox(FolderUserStore.currentFolderFullNameHash(), 1,
|
||||
value.toString().trim(), MessagelistUserStore.threadUid())
|
||||
)
|
||||
},
|
||||
|
||||
listCheckedOrSelected: () => {
|
||||
const
|
||||
selectedMessage = MessagelistUserStore.selectedMessage(),
|
||||
focusedMessage = MessagelistUserStore.focusedMessage(),
|
||||
checked = MessagelistUserStore.filter(item => isChecked(item) || item === selectedMessage);
|
||||
return checked.length ? checked : (focusedMessage ? [focusedMessage] : []);
|
||||
},
|
||||
|
||||
listCheckedOrSelectedUidsWithSubMails: () => {
|
||||
let result = [];
|
||||
MessagelistUserStore.listCheckedOrSelected().forEach(message => {
|
||||
result.push(message.uid);
|
||||
if (1 < message.threadsLen()) {
|
||||
result = result.concat(message.threads()).unique();
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
MessagelistUserStore.listChecked = koComputable(
|
||||
() => MessagelistUserStore.filter(isChecked)).extend({ rateLimit: 0 }
|
||||
);
|
||||
|
||||
MessagelistUserStore.hasCheckedMessages = koComputable(
|
||||
() => !!MessagelistUserStore.find(isChecked)
|
||||
).extend({ rateLimit: 0 });
|
||||
|
||||
MessagelistUserStore.hasCheckedOrSelected = koComputable(() =>
|
||||
!!(MessagelistUserStore.selectedMessage()
|
||||
|| MessagelistUserStore.focusedMessage()
|
||||
|| MessagelistUserStore.find(item => item.checked()))
|
||||
).extend({ rateLimit: 50 });
|
||||
|
||||
MessagelistUserStore.initUidNextAndNewMessages = (folder, uidNext, newMessages) => {
|
||||
if (getFolderInboxName() === folder && uidNext) {
|
||||
if (arrayLength(newMessages)) {
|
||||
newMessages.forEach(item => addNewMessageCache(folder, item.Uid));
|
||||
|
||||
NotificationUserStore.playSoundNotification();
|
||||
|
||||
const len = newMessages.length;
|
||||
if (3 < len) {
|
||||
NotificationUserStore.displayDesktopNotification(
|
||||
AccountUserStore.email(),
|
||||
i18n('MESSAGE_LIST/NEW_MESSAGE_NOTIFICATION', {
|
||||
COUNT: len
|
||||
}),
|
||||
{ Url: mailBox(newMessages[0].Folder) }
|
||||
);
|
||||
} else {
|
||||
newMessages.forEach(item => {
|
||||
NotificationUserStore.displayDesktopNotification(
|
||||
EmailCollectionModel.reviveFromJson(item.From).toString(),
|
||||
item.Subject,
|
||||
{ Folder: item.Folder, Uid: item.Uid }
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setFolderUidNext(folder, uidNext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean=} bDropPagePosition = false
|
||||
* @param {boolean=} bDropCurrenFolderCache = false
|
||||
*/
|
||||
MessagelistUserStore.reload = (bDropPagePosition = false, bDropCurrenFolderCache = false) => {
|
||||
let iOffset = (MessagelistUserStore.page() - 1) * SettingsUserStore.messagesPerPage();
|
||||
|
||||
if (bDropCurrenFolderCache) {
|
||||
setFolderHash(FolderUserStore.currentFolderFullName(), '');
|
||||
}
|
||||
|
||||
if (bDropPagePosition) {
|
||||
MessagelistUserStore.page(1);
|
||||
MessagelistUserStore.pageBeforeThread(1);
|
||||
iOffset = 0;
|
||||
|
||||
rl.route.setHash(
|
||||
mailBox(
|
||||
FolderUserStore.currentFolderFullNameHash(),
|
||||
MessagelistUserStore.page(),
|
||||
MessagelistUserStore.listSearch(),
|
||||
MessagelistUserStore.threadUid()
|
||||
),
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
MessagelistUserStore.loading(true);
|
||||
MessagelistUserStore.error('');
|
||||
rl.app.Remote.messageList(
|
||||
(iError, oData, bCached) => {
|
||||
if (iError) {
|
||||
if (Notification.RequestAborted !== iError) {
|
||||
MessagelistUserStore([]);
|
||||
MessagelistUserStore.error(getNotification(iError));
|
||||
}
|
||||
} else {
|
||||
const collection = MessageCollectionModel.reviveFromJson(oData.Result, bCached);
|
||||
if (collection) {
|
||||
let unreadCountChange = false;
|
||||
|
||||
const
|
||||
folder = getFolderFromCacheList(collection.Folder);
|
||||
|
||||
if (folder && !bCached) {
|
||||
folder.expires = Date.now();
|
||||
|
||||
setFolderHash(collection.Folder, collection.FolderHash);
|
||||
|
||||
if (null != collection.MessageCount) {
|
||||
folder.messageCountAll(collection.MessageCount);
|
||||
}
|
||||
|
||||
if (null != collection.MessageUnseenCount) {
|
||||
if (pInt(folder.messageCountUnread()) !== pInt(collection.MessageUnseenCount)) {
|
||||
unreadCountChange = true;
|
||||
MessageFlagsCache.clearFolder(folder.fullName);
|
||||
}
|
||||
|
||||
folder.messageCountUnread(collection.MessageUnseenCount);
|
||||
}
|
||||
|
||||
MessagelistUserStore.initUidNextAndNewMessages(folder.fullName, collection.UidNext, collection.NewMessages);
|
||||
}
|
||||
|
||||
MessagelistUserStore.count(collection.MessageResultCount);
|
||||
MessagelistUserStore.listSearch(pString(collection.Search));
|
||||
MessagelistUserStore.page(Math.ceil(collection.Offset / SettingsUserStore.messagesPerPage() + 1));
|
||||
MessagelistUserStore.threadUid(collection.ThreadUid);
|
||||
|
||||
MessagelistUserStore.endHash(
|
||||
collection.Folder +
|
||||
'|' + collection.Search +
|
||||
'|' + MessagelistUserStore.threadUid() +
|
||||
'|' + MessagelistUserStore.page()
|
||||
);
|
||||
MessagelistUserStore.endThreadUid(collection.ThreadUid);
|
||||
const message = MessageUserStore.message();
|
||||
if (message && collection.Folder !== message.folder) {
|
||||
MessageUserStore.message(null);
|
||||
}
|
||||
|
||||
MessagelistUserStore.disableAutoSelect(true);
|
||||
|
||||
MessagelistUserStore(collection);
|
||||
MessagelistUserStore.isIncomplete(false);
|
||||
|
||||
clearNewMessageCache();
|
||||
|
||||
if (folder && (bCached || unreadCountChange || SettingsUserStore.useThreads())) {
|
||||
rl.app.folderInformation(folder.fullName, collection);
|
||||
}
|
||||
} else {
|
||||
MessagelistUserStore.count(0);
|
||||
MessagelistUserStore([]);
|
||||
MessagelistUserStore.error(getNotification(Notification.CantGetMessageList));
|
||||
}
|
||||
}
|
||||
MessagelistUserStore.loading(false);
|
||||
},
|
||||
{
|
||||
Folder: FolderUserStore.currentFolderFullName(),
|
||||
Offset: iOffset,
|
||||
Limit: SettingsUserStore.messagesPerPage(),
|
||||
Search: MessagelistUserStore.listSearch(),
|
||||
ThreadUid: MessagelistUserStore.threadUid()
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullName
|
||||
* @param {number} iSetAction
|
||||
* @param {Array=} messages = null
|
||||
*/
|
||||
MessagelistUserStore.setAction = (sFolderFullName, iSetAction, messages) => {
|
||||
messages = messages || MessagelistUserStore.listChecked();
|
||||
|
||||
let folder = null,
|
||||
alreadyUnread = 0,
|
||||
rootUids = messages.map(oMessage => oMessage && oMessage.uid ? oMessage.uid : null)
|
||||
.validUnique(),
|
||||
length = rootUids.length;
|
||||
|
||||
if (sFolderFullName && length) {
|
||||
switch (iSetAction) {
|
||||
case MessageSetAction.SetSeen:
|
||||
length = 0;
|
||||
// fallthrough is intentionally
|
||||
case MessageSetAction.UnsetSeen:
|
||||
rootUids.forEach(sSubUid =>
|
||||
alreadyUnread += MessageFlagsCache.storeBySetAction(sFolderFullName, sSubUid, iSetAction)
|
||||
);
|
||||
|
||||
folder = getFolderFromCacheList(sFolderFullName);
|
||||
if (folder) {
|
||||
folder.messageCountUnread(folder.messageCountUnread() - alreadyUnread + length);
|
||||
}
|
||||
|
||||
rl.app.Remote.request('MessageSetSeen', null, {
|
||||
Folder: sFolderFullName,
|
||||
Uids: rootUids.join(','),
|
||||
SetAction: iSetAction == MessageSetAction.SetSeen ? 1 : 0
|
||||
});
|
||||
break;
|
||||
|
||||
case MessageSetAction.SetFlag:
|
||||
case MessageSetAction.UnsetFlag:
|
||||
rootUids.forEach(sSubUid =>
|
||||
MessageFlagsCache.storeBySetAction(sFolderFullName, sSubUid, iSetAction)
|
||||
);
|
||||
rl.app.Remote.request('MessageSetFlagged', null, {
|
||||
Folder: sFolderFullName,
|
||||
Uids: rootUids.join(','),
|
||||
SetAction: iSetAction == MessageSetAction.SetFlag ? 1 : 0
|
||||
});
|
||||
break;
|
||||
// no default
|
||||
}
|
||||
|
||||
MessagelistUserStore.reloadFlagsAndCachedMessage();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} fromFolderFullName
|
||||
* @param {Array} uidForRemove
|
||||
* @param {string=} toFolderFullName = ''
|
||||
* @param {boolean=} copy = false
|
||||
*/
|
||||
MessagelistUserStore.removeMessagesFromList = (
|
||||
fromFolderFullName, uidForRemove, toFolderFullName = '', copy = false
|
||||
) => {
|
||||
uidForRemove = uidForRemove.map(mValue => pInt(mValue));
|
||||
|
||||
let unseenCount = 0,
|
||||
messageList = MessagelistUserStore,
|
||||
currentMessage = MessageUserStore.message();
|
||||
|
||||
const trashFolder = FolderUserStore.trashFolder(),
|
||||
spamFolder = FolderUserStore.spamFolder(),
|
||||
fromFolder = getFolderFromCacheList(fromFolderFullName),
|
||||
toFolder = toFolderFullName ? getFolderFromCacheList(toFolderFullName) : null,
|
||||
messages =
|
||||
FolderUserStore.currentFolderFullName() === fromFolderFullName
|
||||
? messageList.filter(item => item && uidForRemove.includes(pInt(item.uid)))
|
||||
: [];
|
||||
|
||||
messages.forEach(item => {
|
||||
if (item && item.isUnseen()) {
|
||||
++unseenCount;
|
||||
}
|
||||
});
|
||||
|
||||
if (fromFolder && !copy) {
|
||||
fromFolder.messageCountAll(
|
||||
0 <= fromFolder.messageCountAll() - uidForRemove.length ? fromFolder.messageCountAll() - uidForRemove.length : 0
|
||||
);
|
||||
|
||||
if (0 < unseenCount) {
|
||||
fromFolder.messageCountUnread(
|
||||
0 <= fromFolder.messageCountUnread() - unseenCount ? fromFolder.messageCountUnread() - unseenCount : 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (toFolder) {
|
||||
if (trashFolder === toFolder.fullName || spamFolder === toFolder.fullName) {
|
||||
unseenCount = 0;
|
||||
}
|
||||
|
||||
toFolder.messageCountAll(toFolder.messageCountAll() + uidForRemove.length);
|
||||
if (0 < unseenCount) {
|
||||
toFolder.messageCountUnread(toFolder.messageCountUnread() + unseenCount);
|
||||
}
|
||||
|
||||
toFolder.actionBlink(true);
|
||||
}
|
||||
|
||||
if (messages.length) {
|
||||
if (copy) {
|
||||
messages.forEach(item => item.checked(false));
|
||||
} else {
|
||||
MessagelistUserStore.isIncomplete(true);
|
||||
|
||||
messages.forEach(item => {
|
||||
if (currentMessage && currentMessage.hash === item.hash) {
|
||||
currentMessage = null;
|
||||
MessageUserStore.message(null);
|
||||
}
|
||||
|
||||
item.deleted(true);
|
||||
});
|
||||
|
||||
setTimeout(() => messages.forEach(item => messageList.remove(item)), 350);
|
||||
}
|
||||
}
|
||||
|
||||
if (fromFolderFullName) {
|
||||
setFolderHash(fromFolderFullName, '');
|
||||
}
|
||||
|
||||
if (toFolderFullName) {
|
||||
setFolderHash(toFolderFullName, '');
|
||||
}
|
||||
|
||||
if (MessagelistUserStore.threadUid()) {
|
||||
if (
|
||||
messageList.length &&
|
||||
!!messageList.find(item => !!(item && item.deleted() && item.uid == MessagelistUserStore.threadUid()))
|
||||
) {
|
||||
const message = messageList.find(item => item && !item.deleted());
|
||||
let setHash;
|
||||
if (!message) {
|
||||
if (1 < MessagelistUserStore.page()) {
|
||||
MessagelistUserStore.page(MessagelistUserStore.page() - 1);
|
||||
setHash = 1;
|
||||
} else {
|
||||
MessagelistUserStore.threadUid(0);
|
||||
rl.route.setHash(
|
||||
mailBox(
|
||||
FolderUserStore.currentFolderFullNameHash(),
|
||||
MessagelistUserStore.pageBeforeThread(),
|
||||
MessagelistUserStore.listSearch()
|
||||
),
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
} else if (MessagelistUserStore.threadUid() != message.uid) {
|
||||
MessagelistUserStore.threadUid(message.uid);
|
||||
setHash = 1;
|
||||
}
|
||||
if (setHash) {
|
||||
rl.route.setHash(
|
||||
mailBox(
|
||||
FolderUserStore.currentFolderFullNameHash(),
|
||||
MessagelistUserStore.page(),
|
||||
MessagelistUserStore.listSearch(),
|
||||
MessagelistUserStore.threadUid()
|
||||
),
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
MessagelistUserStore.reloadFlagsAndCachedMessage = () => {
|
||||
MessagelistUserStore.forEach(message => MessageFlagsCache.initMessage(message));
|
||||
MessageFlagsCache.initMessage(MessageUserStore.message());
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue