mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Code refactoring
This commit is contained in:
parent
bf56821c2d
commit
31860420cb
32 changed files with 1342 additions and 1282 deletions
212
dev/App/User.js
212
dev/App/User.js
|
|
@ -29,16 +29,16 @@
|
||||||
TemplateStore = require('Stores/User/Template'),
|
TemplateStore = require('Stores/User/Template'),
|
||||||
FolderStore = require('Stores/User/Folder'),
|
FolderStore = require('Stores/User/Folder'),
|
||||||
PgpStore = require('Stores/User/Pgp'),
|
PgpStore = require('Stores/User/Pgp'),
|
||||||
|
MessageStore = require('Stores/User/Message'),
|
||||||
|
ContactStore = require('Stores/User/Contact'),
|
||||||
|
|
||||||
Local = require('Storage/Client'),
|
Local = require('Storage/Client'),
|
||||||
Settings = require('Storage/Settings'),
|
Settings = require('Storage/Settings'),
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
Cache = require('Storage/User/Cache'),
|
Cache = require('Storage/User/Cache'),
|
||||||
Remote = require('Storage/User/Remote'),
|
Remote = require('Storage/User/Remote'),
|
||||||
|
|
||||||
EmailModel = require('Model/Email'),
|
EmailModel = require('Model/Email'),
|
||||||
FolderModel = require('Model/Folder'),
|
FolderModel = require('Model/Folder'),
|
||||||
MessageModel = require('Model/Message'),
|
|
||||||
AccountModel = require('Model/Account'),
|
AccountModel = require('Model/Account'),
|
||||||
IdentityModel = require('Model/Identity'),
|
IdentityModel = require('Model/Identity'),
|
||||||
TemplateModel = require('Model/Template'),
|
TemplateModel = require('Model/Template'),
|
||||||
|
|
@ -146,11 +146,11 @@
|
||||||
|
|
||||||
AppUser.prototype.reloadFlagsCurrentMessageListAndMessageFromCache = function ()
|
AppUser.prototype.reloadFlagsCurrentMessageListAndMessageFromCache = function ()
|
||||||
{
|
{
|
||||||
_.each(Data.messageList(), function (oMessage) {
|
_.each(MessageStore.messageList(), function (oMessage) {
|
||||||
Cache.initMessageFlagsFromCache(oMessage);
|
Cache.initMessageFlagsFromCache(oMessage);
|
||||||
});
|
});
|
||||||
|
|
||||||
Cache.initMessageFlagsFromCache(Data.message());
|
Cache.initMessageFlagsFromCache(MessageStore.message());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -160,45 +160,45 @@
|
||||||
AppUser.prototype.reloadMessageList = function (bDropPagePosition, bDropCurrenFolderCache)
|
AppUser.prototype.reloadMessageList = function (bDropPagePosition, bDropCurrenFolderCache)
|
||||||
{
|
{
|
||||||
var
|
var
|
||||||
self = this,
|
iOffset = (MessageStore.messageListPage() - 1) * SettingsStore.messagesPerPage()
|
||||||
iOffset = (Data.messageListPage() - 1) * SettingsStore.messagesPerPage()
|
|
||||||
;
|
;
|
||||||
|
|
||||||
if (Utils.isUnd(bDropCurrenFolderCache) ? false : !!bDropCurrenFolderCache)
|
if (Utils.isUnd(bDropCurrenFolderCache) ? false : !!bDropCurrenFolderCache)
|
||||||
{
|
{
|
||||||
Cache.setFolderHash(Data.currentFolderFullNameRaw(), '');
|
Cache.setFolderHash(FolderStore.currentFolderFullNameRaw(), '');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.isUnd(bDropPagePosition) ? false : !!bDropPagePosition)
|
if (Utils.isUnd(bDropPagePosition) ? false : !!bDropPagePosition)
|
||||||
{
|
{
|
||||||
Data.messageListPage(1);
|
MessageStore.messageListPage(1);
|
||||||
iOffset = 0;
|
iOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data.messageListLoading(true);
|
MessageStore.messageListLoading(true);
|
||||||
Remote.messageList(function (sResult, oData, bCached) {
|
Remote.messageList(function (sResult, oData, bCached) {
|
||||||
|
|
||||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
||||||
{
|
{
|
||||||
Data.messageListError('');
|
MessageStore.messageListError('');
|
||||||
Data.messageListLoading(false);
|
MessageStore.messageListLoading(false);
|
||||||
self.setMessageList(oData, bCached);
|
|
||||||
|
MessageStore.setMessageList(oData, bCached);
|
||||||
}
|
}
|
||||||
else if (Enums.StorageResultType.Unload === sResult)
|
else if (Enums.StorageResultType.Unload === sResult)
|
||||||
{
|
{
|
||||||
Data.messageListError('');
|
MessageStore.messageListError('');
|
||||||
Data.messageListLoading(false);
|
MessageStore.messageListLoading(false);
|
||||||
}
|
}
|
||||||
else if (Enums.StorageResultType.Abort !== sResult)
|
else if (Enums.StorageResultType.Abort !== sResult)
|
||||||
{
|
{
|
||||||
Data.messageList([]);
|
MessageStore.messageList([]);
|
||||||
Data.messageListLoading(false);
|
MessageStore.messageListLoading(false);
|
||||||
Data.messageListError(oData && oData.ErrorCode ?
|
MessageStore.messageListError(oData && oData.ErrorCode ?
|
||||||
Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST')
|
Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}, Data.currentFolderFullNameRaw(), iOffset, SettingsStore.messagesPerPage(), Data.messageListSearch());
|
}, FolderStore.currentFolderFullNameRaw(), iOffset, SettingsStore.messagesPerPage(), MessageStore.messageListSearch());
|
||||||
};
|
};
|
||||||
|
|
||||||
AppUser.prototype.recacheInboxMessageList = function ()
|
AppUser.prototype.recacheInboxMessageList = function ()
|
||||||
|
|
@ -217,8 +217,8 @@
|
||||||
*/
|
*/
|
||||||
AppUser.prototype.contactsSync = function (fResultFunc)
|
AppUser.prototype.contactsSync = function (fResultFunc)
|
||||||
{
|
{
|
||||||
var oContacts = Data.contacts;
|
var oContacts = ContactStore.contacts;
|
||||||
if (oContacts.importing() || oContacts.syncing() || !Data.enableContactsSync() || !Data.allowContactsSync())
|
if (oContacts.importing() || oContacts.syncing() || !ContactStore.enableContactsSync() || !ContactStore.allowContactsSync())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -296,7 +296,7 @@
|
||||||
|
|
||||||
AppUser.prototype.moveOrDeleteResponseHelper = function (sResult, oData)
|
AppUser.prototype.moveOrDeleteResponseHelper = function (sResult, oData)
|
||||||
{
|
{
|
||||||
if (Enums.StorageResultType.Success === sResult && Data.currentFolder())
|
if (Enums.StorageResultType.Success === sResult && FolderStore.currentFolder())
|
||||||
{
|
{
|
||||||
if (oData && Utils.isArray(oData.Result) && 2 === oData.Result.length)
|
if (oData && Utils.isArray(oData.Result) && 2 === oData.Result.length)
|
||||||
{
|
{
|
||||||
|
|
@ -304,7 +304,7 @@
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Cache.setFolderHash(Data.currentFolderFullNameRaw(), '');
|
Cache.setFolderHash(FolderStore.currentFolderFullNameRaw(), '');
|
||||||
|
|
||||||
if (oData && -1 < Utils.inArray(oData.ErrorCode,
|
if (oData && -1 < Utils.inArray(oData.ErrorCode,
|
||||||
[Enums.Notification.CantMoveMessage, Enums.Notification.CantCopyMessage]))
|
[Enums.Notification.CantMoveMessage, Enums.Notification.CantCopyMessage]))
|
||||||
|
|
@ -313,7 +313,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.reloadMessageListHelper(0 === Data.messageList().length);
|
this.reloadMessageListHelper(0 === MessageStore.messageList().length);
|
||||||
this.quotaDebounce();
|
this.quotaDebounce();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -325,7 +325,7 @@
|
||||||
AppUser.prototype.deleteMessagesFromFolderWithoutCheck = function (sFromFolderFullNameRaw, aUidForRemove)
|
AppUser.prototype.deleteMessagesFromFolderWithoutCheck = function (sFromFolderFullNameRaw, aUidForRemove)
|
||||||
{
|
{
|
||||||
this.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove);
|
this.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove);
|
||||||
Data.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove);
|
MessageStore.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -382,14 +382,14 @@
|
||||||
kn.showScreenPopup(require('View/Popup/Ask'), [Translator.i18n('POPUPS_ASK/DESC_WANT_DELETE_MESSAGES'), function () {
|
kn.showScreenPopup(require('View/Popup/Ask'), [Translator.i18n('POPUPS_ASK/DESC_WANT_DELETE_MESSAGES'), function () {
|
||||||
|
|
||||||
self.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove);
|
self.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove);
|
||||||
Data.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove);
|
MessageStore.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove);
|
||||||
|
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
else if (oMoveFolder)
|
else if (oMoveFolder)
|
||||||
{
|
{
|
||||||
this.messagesMoveHelper(sFromFolderFullNameRaw, oMoveFolder.fullNameRaw, aUidForRemove);
|
this.messagesMoveHelper(sFromFolderFullNameRaw, oMoveFolder.fullNameRaw, aUidForRemove);
|
||||||
Data.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove, oMoveFolder.fullNameRaw);
|
MessageStore.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove, oMoveFolder.fullNameRaw);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -419,7 +419,7 @@
|
||||||
this.messagesMoveHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove);
|
this.messagesMoveHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove);
|
||||||
}
|
}
|
||||||
|
|
||||||
Data.removeMessagesFromList(oFromFolder.fullNameRaw, aUidForMove, oToFolder.fullNameRaw, bCopy);
|
MessageStore.removeMessagesFromList(oFromFolder.fullNameRaw, aUidForMove, oToFolder.fullNameRaw, bCopy);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -432,12 +432,12 @@
|
||||||
*/
|
*/
|
||||||
AppUser.prototype.folders = function (fCallback)
|
AppUser.prototype.folders = function (fCallback)
|
||||||
{
|
{
|
||||||
Data.foldersLoading(true);
|
FolderStore.foldersLoading(true);
|
||||||
|
|
||||||
Remote.folders(_.bind(function (sResult, oData) {
|
Remote.folders(_.bind(function (sResult, oData) {
|
||||||
|
|
||||||
var bResult = false;
|
var bResult = false;
|
||||||
Data.foldersLoading(false);
|
FolderStore.foldersLoading(false);
|
||||||
|
|
||||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
||||||
{
|
{
|
||||||
|
|
@ -707,11 +707,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Data.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages);
|
MessageStore.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages);
|
||||||
|
|
||||||
if (oData.Result.Hash !== sHash || '' === sHash)
|
if (oData.Result.Hash !== sHash || '' === sHash)
|
||||||
{
|
{
|
||||||
if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw())
|
if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw())
|
||||||
{
|
{
|
||||||
self.reloadMessageList();
|
self.reloadMessageList();
|
||||||
}
|
}
|
||||||
|
|
@ -722,9 +722,9 @@
|
||||||
}
|
}
|
||||||
else if (bUnreadCountChange)
|
else if (bUnreadCountChange)
|
||||||
{
|
{
|
||||||
if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw())
|
if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw())
|
||||||
{
|
{
|
||||||
aList = Data.messageList();
|
aList = MessageStore.messageList();
|
||||||
if (Utils.isNonEmptyArray(aList))
|
if (Utils.isNonEmptyArray(aList))
|
||||||
{
|
{
|
||||||
self.folderInformation(oFolder.fullNameRaw, aList);
|
self.folderInformation(oFolder.fullNameRaw, aList);
|
||||||
|
|
@ -748,7 +748,7 @@
|
||||||
var
|
var
|
||||||
self = this,
|
self = this,
|
||||||
iUtc = moment().unix(),
|
iUtc = moment().unix(),
|
||||||
aFolders = Data.getNextFolderNames(bBoot)
|
aFolders = FolderStore.getNextFolderNames(bBoot)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (Utils.isNonEmptyArray(aFolders))
|
if (Utils.isNonEmptyArray(aFolders))
|
||||||
|
|
@ -798,16 +798,16 @@
|
||||||
|
|
||||||
if (oItem.Hash !== sHash || '' === sHash)
|
if (oItem.Hash !== sHash || '' === sHash)
|
||||||
{
|
{
|
||||||
if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw())
|
if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw())
|
||||||
{
|
{
|
||||||
self.reloadMessageList();
|
self.reloadMessageList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bUnreadCountChange)
|
else if (bUnreadCountChange)
|
||||||
{
|
{
|
||||||
if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw())
|
if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw())
|
||||||
{
|
{
|
||||||
aList = Data.messageList();
|
aList = MessageStore.messageList();
|
||||||
if (Utils.isNonEmptyArray(aList))
|
if (Utils.isNonEmptyArray(aList))
|
||||||
{
|
{
|
||||||
self.folderInformation(oFolder.fullNameRaw, aList);
|
self.folderInformation(oFolder.fullNameRaw, aList);
|
||||||
|
|
@ -941,136 +941,6 @@
|
||||||
}, sQuery);
|
}, sQuery);
|
||||||
};
|
};
|
||||||
|
|
||||||
AppUser.prototype.setMessageList = function (oData, bCached)
|
|
||||||
{
|
|
||||||
if (oData && oData.Result && 'Collection/MessageCollection' === oData.Result['@Object'] &&
|
|
||||||
oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection']))
|
|
||||||
{
|
|
||||||
var
|
|
||||||
mLastCollapsedThreadUids = null,
|
|
||||||
iIndex = 0,
|
|
||||||
iLen = 0,
|
|
||||||
iCount = 0,
|
|
||||||
iOffset = 0,
|
|
||||||
aList = [],
|
|
||||||
iUtc = moment().unix(),
|
|
||||||
aStaticList = Data.staticMessageList,
|
|
||||||
oJsonMessage = null,
|
|
||||||
oMessage = null,
|
|
||||||
oFolder = null,
|
|
||||||
iNewCount = 0,
|
|
||||||
bUnreadCountChange = false
|
|
||||||
;
|
|
||||||
|
|
||||||
iCount = Utils.pInt(oData.Result.MessageResultCount);
|
|
||||||
iOffset = Utils.pInt(oData.Result.Offset);
|
|
||||||
|
|
||||||
if (Utils.isNonEmptyArray(oData.Result.LastCollapsedThreadUids))
|
|
||||||
{
|
|
||||||
mLastCollapsedThreadUids = oData.Result.LastCollapsedThreadUids;
|
|
||||||
}
|
|
||||||
|
|
||||||
oFolder = Cache.getFolderFromCacheList(
|
|
||||||
Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
|
|
||||||
|
|
||||||
if (oFolder && !bCached)
|
|
||||||
{
|
|
||||||
oFolder.interval = iUtc;
|
|
||||||
|
|
||||||
Cache.setFolderHash(oData.Result.Folder, oData.Result.FolderHash);
|
|
||||||
|
|
||||||
if (Utils.isNormal(oData.Result.MessageCount))
|
|
||||||
{
|
|
||||||
oFolder.messageCountAll(oData.Result.MessageCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Utils.isNormal(oData.Result.MessageUnseenCount))
|
|
||||||
{
|
|
||||||
if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount))
|
|
||||||
{
|
|
||||||
bUnreadCountChange = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
oFolder.messageCountUnread(oData.Result.MessageUnseenCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
Data.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bUnreadCountChange && oFolder)
|
|
||||||
{
|
|
||||||
Cache.clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (iIndex = 0, iLen = oData.Result['@Collection'].length; iIndex < iLen; iIndex++)
|
|
||||||
{
|
|
||||||
oJsonMessage = oData.Result['@Collection'][iIndex];
|
|
||||||
if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
|
|
||||||
{
|
|
||||||
oMessage = aStaticList[iIndex];
|
|
||||||
if (!oMessage || !oMessage.initByJson(oJsonMessage))
|
|
||||||
{
|
|
||||||
oMessage = MessageModel.newInstanceFromJson(oJsonMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oMessage)
|
|
||||||
{
|
|
||||||
if (Cache.hasNewMessageAndRemoveFromCache(oMessage.folderFullNameRaw, oMessage.uid) && 5 >= iNewCount)
|
|
||||||
{
|
|
||||||
iNewCount++;
|
|
||||||
oMessage.newForAnimation(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
oMessage.deleted(false);
|
|
||||||
|
|
||||||
if (bCached)
|
|
||||||
{
|
|
||||||
Cache.initMessageFlagsFromCache(oMessage);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Cache.storeMessageFlagsToCache(oMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
oMessage.lastInCollapsedThread(mLastCollapsedThreadUids && -1 < Utils.inArray(Utils.pInt(oMessage.uid), mLastCollapsedThreadUids) ? true : false);
|
|
||||||
|
|
||||||
aList.push(oMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Data.messageListCount(iCount);
|
|
||||||
Data.messageListSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
|
|
||||||
Data.messageListPage(window.Math.ceil((iOffset / SettingsStore.messagesPerPage()) + 1));
|
|
||||||
Data.messageListEndFolder(Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
|
|
||||||
Data.messageListEndSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
|
|
||||||
Data.messageListEndPage(Data.messageListPage());
|
|
||||||
|
|
||||||
Data.messageList(aList);
|
|
||||||
Data.messageListIsNotCompleted(false);
|
|
||||||
|
|
||||||
if (aStaticList.length < aList.length)
|
|
||||||
{
|
|
||||||
Data.staticMessageList = aList;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cache.clearNewMessageCache();
|
|
||||||
|
|
||||||
if (oFolder && (bCached || bUnreadCountChange || SettingsStore.useThreads()))
|
|
||||||
{
|
|
||||||
this.folderInformation(oFolder.fullNameRaw, aList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Data.messageListCount(0);
|
|
||||||
Data.messageList([]);
|
|
||||||
Data.messageListError(Translator.getNotification(
|
|
||||||
oData && oData.ErrorCode ? oData.ErrorCode : Enums.Notification.CantGetMessageList
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} sNamespace
|
* @param {string} sNamespace
|
||||||
* @param {Array} aFolders
|
* @param {Array} aFolders
|
||||||
|
|
@ -1163,13 +1033,13 @@
|
||||||
{
|
{
|
||||||
if (!Utils.isUnd(oData.Result.Namespace))
|
if (!Utils.isUnd(oData.Result.Namespace))
|
||||||
{
|
{
|
||||||
Data.namespace = oData.Result.Namespace;
|
FolderStore.namespace = oData.Result.Namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppStore.threadsAllowed(!!Settings.settingsGet('UseImapThread') &&
|
AppStore.threadsAllowed(!!Settings.settingsGet('UseImapThread') &&
|
||||||
oData.Result.IsThreadsSupported && true);
|
oData.Result.IsThreadsSupported && true);
|
||||||
|
|
||||||
Data.folderList(this.folderResponseParseRec(Data.namespace, oData.Result['@Collection']));
|
FolderStore.folderList(this.folderResponseParseRec(FolderStore.namespace, oData.Result['@Collection']));
|
||||||
|
|
||||||
if (oData.Result['SystemFolders'] && '' === '' +
|
if (oData.Result['SystemFolders'] && '' === '' +
|
||||||
Settings.settingsGet('SentFolder') +
|
Settings.settingsGet('SentFolder') +
|
||||||
|
|
@ -1525,7 +1395,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.sub('interval.3m', function () {
|
Events.sub('interval.3m', function () {
|
||||||
var sF = Data.currentFolderFullNameRaw();
|
var sF = FolderStore.currentFolderFullNameRaw();
|
||||||
if (Cache.getFolderInboxName() !== sF)
|
if (Cache.getFolderInboxName() !== sF)
|
||||||
{
|
{
|
||||||
self.folderInformation(sF);
|
self.folderInformation(sF);
|
||||||
|
|
@ -1562,7 +1432,7 @@
|
||||||
self.accountsAndIdentities(true);
|
self.accountsAndIdentities(true);
|
||||||
|
|
||||||
_.delay(function () {
|
_.delay(function () {
|
||||||
var sF = Data.currentFolderFullNameRaw();
|
var sF = FolderStore.currentFolderFullNameRaw();
|
||||||
if (Cache.getFolderInboxName() !== sF)
|
if (Cache.getFolderInboxName() !== sF)
|
||||||
{
|
{
|
||||||
self.folderInformation(sF);
|
self.folderInformation(sF);
|
||||||
|
|
|
||||||
|
|
@ -1205,9 +1205,8 @@
|
||||||
var
|
var
|
||||||
aRes = [],
|
aRes = [],
|
||||||
mPgpMessage = null,
|
mPgpMessage = null,
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '',
|
sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '',
|
||||||
aPublicKeys = Data.findPublicKeysByEmail(sFrom),
|
aPublicKeys = PgpStore.findPublicKeysByEmail(sFrom),
|
||||||
oValidKey = null,
|
oValidKey = null,
|
||||||
oValidSysKey = null,
|
oValidSysKey = null,
|
||||||
sPlain = ''
|
sPlain = ''
|
||||||
|
|
@ -1233,7 +1232,7 @@
|
||||||
|
|
||||||
if (oValidKey)
|
if (oValidKey)
|
||||||
{
|
{
|
||||||
oValidSysKey = Data.findPublicKeyByHex(oValidKey.keyid.toHex());
|
oValidSysKey = PgpStore.findPublicKeyByHex(oValidKey.keyid.toHex());
|
||||||
if (oValidSysKey)
|
if (oValidSysKey)
|
||||||
{
|
{
|
||||||
sPlain = mPgpMessage.getText();
|
sPlain = mPgpMessage.getText();
|
||||||
|
|
@ -1269,10 +1268,9 @@
|
||||||
aRes = [],
|
aRes = [],
|
||||||
mPgpMessage = null,
|
mPgpMessage = null,
|
||||||
mPgpMessageDecrypted = null,
|
mPgpMessageDecrypted = null,
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '',
|
sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '',
|
||||||
aPublicKey = Data.findPublicKeysByEmail(sFrom),
|
aPublicKey = PgpStore.findPublicKeysByEmail(sFrom),
|
||||||
oPrivateKey = Data.findSelfPrivateKey(sPassword),
|
oPrivateKey = PgpStore.findSelfPrivateKey(sPassword),
|
||||||
oValidKey = null,
|
oValidKey = null,
|
||||||
oValidSysKey = null,
|
oValidSysKey = null,
|
||||||
sPlain = ''
|
sPlain = ''
|
||||||
|
|
@ -1305,7 +1303,7 @@
|
||||||
|
|
||||||
if (oValidKey)
|
if (oValidKey)
|
||||||
{
|
{
|
||||||
oValidSysKey = Data.findPublicKeyByHex(oValidKey.keyid.toHex());
|
oValidSysKey = PgpStore.findPublicKeyByHex(oValidKey.keyid.toHex());
|
||||||
if (oValidSysKey)
|
if (oValidSysKey)
|
||||||
{
|
{
|
||||||
this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Success);
|
this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Success);
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,9 @@
|
||||||
|
|
||||||
AccountStore = require('Stores/User/Account'),
|
AccountStore = require('Stores/User/Account'),
|
||||||
SettingsStore = require('Stores/User/Settings'),
|
SettingsStore = require('Stores/User/Settings'),
|
||||||
|
FolderStore = require('Stores/User/Folder'),
|
||||||
|
MessageStore = require('Stores/User/Message'),
|
||||||
|
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
Cache = require('Storage/User/Cache'),
|
Cache = require('Storage/User/Cache'),
|
||||||
|
|
||||||
AbstractScreen = require('Knoin/AbstractScreen')
|
AbstractScreen = require('Knoin/AbstractScreen')
|
||||||
|
|
@ -48,7 +49,7 @@
|
||||||
{
|
{
|
||||||
var
|
var
|
||||||
sEmail = AccountStore.email(),
|
sEmail = AccountStore.email(),
|
||||||
nFoldersInboxUnreadCount = Data.foldersInboxUnreadCount()
|
nFoldersInboxUnreadCount = FolderStore.foldersInboxUnreadCount()
|
||||||
;
|
;
|
||||||
|
|
||||||
require('App/User').setTitle(('' === sEmail ? '' :
|
require('App/User').setTitle(('' === sEmail ? '' :
|
||||||
|
|
@ -72,7 +73,7 @@
|
||||||
{
|
{
|
||||||
if (Utils.isUnd(bPreview) ? false : !!bPreview)
|
if (Utils.isUnd(bPreview) ? false : !!bPreview)
|
||||||
{
|
{
|
||||||
if (Enums.Layout.NoPreview === SettingsStore.layout() && !Data.message())
|
if (Enums.Layout.NoPreview === SettingsStore.layout() && !MessageStore.message())
|
||||||
{
|
{
|
||||||
require('App/User').historyBack();
|
require('App/User').historyBack();
|
||||||
}
|
}
|
||||||
|
|
@ -86,15 +87,13 @@
|
||||||
|
|
||||||
if (oFolder)
|
if (oFolder)
|
||||||
{
|
{
|
||||||
Data
|
FolderStore.currentFolder(oFolder);
|
||||||
.currentFolder(oFolder)
|
MessageStore.messageListPage(iPage);
|
||||||
.messageListPage(iPage)
|
MessageStore.messageListSearch(sSearch);
|
||||||
.messageListSearch(sSearch)
|
|
||||||
;
|
|
||||||
|
|
||||||
if (Enums.Layout.NoPreview === SettingsStore.layout() && Data.message())
|
if (Enums.Layout.NoPreview === SettingsStore.layout() && MessageStore.message())
|
||||||
{
|
{
|
||||||
Data.message(null);
|
MessageStore.message(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
require('App/User').reloadMessageList();
|
require('App/User').reloadMessageList();
|
||||||
|
|
@ -104,9 +103,10 @@
|
||||||
|
|
||||||
MailBoxUserScreen.prototype.onStart = function ()
|
MailBoxUserScreen.prototype.onStart = function ()
|
||||||
{
|
{
|
||||||
Data.folderList.subscribe(Utils.windowResizeCallback);
|
FolderStore.folderList.subscribe(Utils.windowResizeCallback);
|
||||||
Data.messageList.subscribe(Utils.windowResizeCallback);
|
|
||||||
Data.message.subscribe(Utils.windowResizeCallback);
|
MessageStore.messageList.subscribe(Utils.windowResizeCallback);
|
||||||
|
MessageStore.message.subscribe(Utils.windowResizeCallback);
|
||||||
|
|
||||||
_.delay(function () {
|
_.delay(function () {
|
||||||
SettingsStore.layout.valueHasMutated();
|
SettingsStore.layout.valueHasMutated();
|
||||||
|
|
@ -114,7 +114,7 @@
|
||||||
|
|
||||||
Events.sub('mailbox.inbox-unread-count', function (iCount) {
|
Events.sub('mailbox.inbox-unread-count', function (iCount) {
|
||||||
|
|
||||||
Data.foldersInboxUnreadCount(iCount);
|
FolderStore.foldersInboxUnreadCount(iCount);
|
||||||
|
|
||||||
var sEmail = AccountStore.email();
|
var sEmail = AccountStore.email();
|
||||||
|
|
||||||
|
|
@ -126,7 +126,7 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Data.foldersInboxUnreadCount.subscribe(function () {
|
FolderStore.foldersInboxUnreadCount.subscribe(function () {
|
||||||
this.setNewTitle();
|
this.setNewTitle();
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@
|
||||||
ko = require('ko'),
|
ko = require('ko'),
|
||||||
|
|
||||||
AppStore = require('Stores/User/App'),
|
AppStore = require('Stores/User/App'),
|
||||||
|
ContactStore = require('Stores/User/Contact'),
|
||||||
|
|
||||||
Remote = require('Storage/User/Remote'),
|
Remote = require('Storage/User/Remote')
|
||||||
Data = require('Storage/User/Data')
|
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -19,11 +19,11 @@
|
||||||
{
|
{
|
||||||
this.contactsAutosave = AppStore.contactsAutosave;
|
this.contactsAutosave = AppStore.contactsAutosave;
|
||||||
|
|
||||||
this.allowContactsSync = Data.allowContactsSync;
|
this.allowContactsSync = ContactStore.allowContactsSync;
|
||||||
this.enableContactsSync = Data.enableContactsSync;
|
this.enableContactsSync = ContactStore.enableContactsSync;
|
||||||
this.contactsSyncUrl = Data.contactsSyncUrl;
|
this.contactsSyncUrl = ContactStore.contactsSyncUrl;
|
||||||
this.contactsSyncUser = Data.contactsSyncUser;
|
this.contactsSyncUser = ContactStore.contactsSyncUser;
|
||||||
this.contactsSyncPass = Data.contactsSyncPass;
|
this.contactsSyncPass = ContactStore.contactsSyncPass;
|
||||||
|
|
||||||
this.saveTrigger = ko.computed(function () {
|
this.saveTrigger = ko.computed(function () {
|
||||||
return [
|
return [
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,9 @@
|
||||||
Utils = require('Common/Utils'),
|
Utils = require('Common/Utils'),
|
||||||
Translator = require('Common/Translator'),
|
Translator = require('Common/Translator'),
|
||||||
|
|
||||||
|
FolderStore = require('Stores/User/Folder'),
|
||||||
|
|
||||||
Settings = require('Storage/Settings'),
|
Settings = require('Storage/Settings'),
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
Cache = require('Storage/User/Cache'),
|
Cache = require('Storage/User/Cache'),
|
||||||
Remote = require('Storage/User/Remote'),
|
Remote = require('Storage/User/Remote'),
|
||||||
Local = require('Storage/Client')
|
Local = require('Storage/Client')
|
||||||
|
|
@ -22,15 +23,15 @@
|
||||||
*/
|
*/
|
||||||
function FoldersUserSettings()
|
function FoldersUserSettings()
|
||||||
{
|
{
|
||||||
this.folderList = Data.folderList;
|
this.folderList = FolderStore.folderList;
|
||||||
|
|
||||||
this.loading = ko.computed(function () {
|
this.loading = ko.computed(function () {
|
||||||
|
|
||||||
var
|
var
|
||||||
bLoading = Data.foldersLoading(),
|
bLoading = FolderStore.foldersLoading(),
|
||||||
bCreating = Data.foldersCreating(),
|
bCreating = FolderStore.foldersCreating(),
|
||||||
bDeleting = Data.foldersDeleting(),
|
bDeleting = FolderStore.foldersDeleting(),
|
||||||
bRenaming = Data.foldersRenaming()
|
bRenaming = FolderStore.foldersRenaming()
|
||||||
;
|
;
|
||||||
|
|
||||||
return bLoading || bCreating || bDeleting || bRenaming;
|
return bLoading || bCreating || bDeleting || bRenaming;
|
||||||
|
|
@ -66,13 +67,13 @@
|
||||||
{
|
{
|
||||||
Local.set(Enums.ClientSideKeyName.FoldersLashHash, '');
|
Local.set(Enums.ClientSideKeyName.FoldersLashHash, '');
|
||||||
|
|
||||||
Data.foldersRenaming(true);
|
FolderStore.foldersRenaming(true);
|
||||||
Remote.folderRename(function (sResult, oData) {
|
Remote.folderRename(function (sResult, oData) {
|
||||||
|
|
||||||
Data.foldersRenaming(false);
|
FolderStore.foldersRenaming(false);
|
||||||
if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result)
|
if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result)
|
||||||
{
|
{
|
||||||
Data.folderList.error(
|
FolderStore.folderList.error(
|
||||||
oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_RENAME_FOLDER'));
|
oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_RENAME_FOLDER'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,7 +99,7 @@
|
||||||
|
|
||||||
FoldersUserSettings.prototype.onShow = function ()
|
FoldersUserSettings.prototype.onShow = function ()
|
||||||
{
|
{
|
||||||
Data.folderList.error('');
|
FolderStore.folderList.error('');
|
||||||
};
|
};
|
||||||
|
|
||||||
FoldersUserSettings.prototype.createFolder = function ()
|
FoldersUserSettings.prototype.createFolder = function ()
|
||||||
|
|
@ -135,15 +136,15 @@
|
||||||
{
|
{
|
||||||
Local.set(Enums.ClientSideKeyName.FoldersLashHash, '');
|
Local.set(Enums.ClientSideKeyName.FoldersLashHash, '');
|
||||||
|
|
||||||
Data.folderList.remove(fRemoveFolder);
|
FolderStore.folderList.remove(fRemoveFolder);
|
||||||
|
|
||||||
Data.foldersDeleting(true);
|
FolderStore.foldersDeleting(true);
|
||||||
Remote.folderDelete(function (sResult, oData) {
|
Remote.folderDelete(function (sResult, oData) {
|
||||||
|
|
||||||
Data.foldersDeleting(false);
|
FolderStore.foldersDeleting(false);
|
||||||
if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result)
|
if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result)
|
||||||
{
|
{
|
||||||
Data.folderList.error(
|
FolderStore.folderList.error(
|
||||||
oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_DELETE_FOLDER'));
|
oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_DELETE_FOLDER'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,7 +157,7 @@
|
||||||
}
|
}
|
||||||
else if (0 < oFolderToRemove.privateMessageCountAll())
|
else if (0 < oFolderToRemove.privateMessageCountAll())
|
||||||
{
|
{
|
||||||
Data.folderList.error(Translator.getNotification(Enums.Notification.CantDeleteNonEmptyFolder));
|
FolderStore.folderList.error(Translator.getNotification(Enums.Notification.CantDeleteNonEmptyFolder));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
LanguageStore = require('Stores/Language'),
|
LanguageStore = require('Stores/Language'),
|
||||||
SettingsStore = require('Stores/User/Settings'),
|
SettingsStore = require('Stores/User/Settings'),
|
||||||
NotificationStore = require('Stores/User/Notification'),
|
NotificationStore = require('Stores/User/Notification'),
|
||||||
|
MessageStore = require('Stores/User/Message'),
|
||||||
|
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
Remote = require('Storage/User/Remote')
|
Remote = require('Storage/User/Remote')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -163,7 +163,7 @@
|
||||||
|
|
||||||
self.useThreads.subscribe(function (bValue) {
|
self.useThreads.subscribe(function (bValue) {
|
||||||
|
|
||||||
Data.messageList([]);
|
MessageStore.messageList([]);
|
||||||
|
|
||||||
Remote.saveSettings(null, {
|
Remote.saveSettings(null, {
|
||||||
'UseThreads': bValue ? '1' : '0'
|
'UseThreads': bValue ? '1' : '0'
|
||||||
|
|
@ -172,7 +172,7 @@
|
||||||
|
|
||||||
self.layout.subscribe(function (nValue) {
|
self.layout.subscribe(function (nValue) {
|
||||||
|
|
||||||
Data.messageList([]);
|
MessageStore.messageList([]);
|
||||||
|
|
||||||
Remote.saveSettings(f2, {
|
Remote.saveSettings(f2, {
|
||||||
'Layout': nValue
|
'Layout': nValue
|
||||||
|
|
|
||||||
|
|
@ -3,894 +3,14 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var
|
|
||||||
window = require('window'),
|
|
||||||
_ = require('_'),
|
|
||||||
$ = require('$'),
|
|
||||||
ko = require('ko'),
|
|
||||||
moment = require('moment'),
|
|
||||||
|
|
||||||
Consts = require('Common/Consts'),
|
|
||||||
Enums = require('Common/Enums'),
|
|
||||||
Globals = require('Common/Globals'),
|
|
||||||
Utils = require('Common/Utils'),
|
|
||||||
Links = require('Common/Links'),
|
|
||||||
Translator = require('Common/Translator'),
|
|
||||||
|
|
||||||
SettingsStore = require('Stores/User/Settings'),
|
|
||||||
|
|
||||||
Settings = require('Storage/Settings'),
|
|
||||||
Cache = require('Storage/User/Cache'),
|
|
||||||
|
|
||||||
kn = require('Knoin/Knoin'),
|
|
||||||
|
|
||||||
MessageModel = require('Model/Message')
|
|
||||||
;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function DataUserStorage()
|
function DataUserStorage()
|
||||||
{
|
{
|
||||||
// contacts
|
|
||||||
this.contacts = ko.observableArray([]);
|
|
||||||
this.contacts.loading = ko.observable(false).extend({'throttle': 200});
|
|
||||||
this.contacts.importing = ko.observable(false).extend({'throttle': 200});
|
|
||||||
this.contacts.syncing = ko.observable(false).extend({'throttle': 200});
|
|
||||||
this.contacts.exportingVcf = ko.observable(false).extend({'throttle': 200});
|
|
||||||
this.contacts.exportingCsv = ko.observable(false).extend({'throttle': 200});
|
|
||||||
|
|
||||||
this.allowContactsSync = ko.observable(false);
|
|
||||||
this.enableContactsSync = ko.observable(false);
|
|
||||||
this.contactsSyncUrl = ko.observable('');
|
|
||||||
this.contactsSyncUser = ko.observable('');
|
|
||||||
this.contactsSyncPass = ko.observable('');
|
|
||||||
|
|
||||||
this.allowContactsSync = ko.observable(!!Settings.settingsGet('ContactsSyncIsAllowed'));
|
|
||||||
this.enableContactsSync = ko.observable(!!Settings.settingsGet('EnableContactsSync'));
|
|
||||||
this.contactsSyncUrl = ko.observable(Settings.settingsGet('ContactsSyncUrl'));
|
|
||||||
this.contactsSyncUser = ko.observable(Settings.settingsGet('ContactsSyncUser'));
|
|
||||||
this.contactsSyncPass = ko.observable(Settings.settingsGet('ContactsSyncPassword'));
|
|
||||||
|
|
||||||
// folders
|
|
||||||
this.namespace = '';
|
|
||||||
this.folderList = ko.observableArray([]);
|
|
||||||
this.folderList.focused = ko.observable(false);
|
|
||||||
this.folderList.optimized = ko.observable(false);
|
|
||||||
this.folderList.error = ko.observable('');
|
|
||||||
|
|
||||||
this.foldersLoading = ko.observable(false);
|
|
||||||
this.foldersCreating = ko.observable(false);
|
|
||||||
this.foldersDeleting = ko.observable(false);
|
|
||||||
this.foldersRenaming = ko.observable(false);
|
|
||||||
|
|
||||||
this.foldersListWithSingleInboxRootFolder = ko.computed(function () {
|
|
||||||
var aList = this.folderList();
|
|
||||||
return !_.find(aList, function (oFolder) {
|
|
||||||
return oFolder && !oFolder.isSystemFolder() && oFolder.visible();
|
|
||||||
});
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.foldersChanging = ko.computed(function () {
|
|
||||||
var
|
|
||||||
bLoading = this.foldersLoading(),
|
|
||||||
bCreating = this.foldersCreating(),
|
|
||||||
bDeleting = this.foldersDeleting(),
|
|
||||||
bRenaming = this.foldersRenaming()
|
|
||||||
;
|
|
||||||
return bLoading || bCreating || bDeleting || bRenaming;
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.foldersInboxUnreadCount = ko.observable(0);
|
|
||||||
|
|
||||||
this.currentFolder = ko.observable(null).extend({'toggleSubscribe': [null,
|
|
||||||
function (oPrev) {
|
|
||||||
if (oPrev)
|
|
||||||
{
|
|
||||||
oPrev.selected(false);
|
|
||||||
}
|
|
||||||
}, function (oNext) {
|
|
||||||
if (oNext)
|
|
||||||
{
|
|
||||||
oNext.selected(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]});
|
|
||||||
|
|
||||||
this.currentFolderFullNameRaw = ko.computed(function () {
|
|
||||||
return this.currentFolder() ? this.currentFolder().fullNameRaw : '';
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.currentFolderFullName = ko.computed(function () {
|
|
||||||
return this.currentFolder() ? this.currentFolder().fullName : '';
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.currentFolderFullNameHash = ko.computed(function () {
|
|
||||||
return this.currentFolder() ? this.currentFolder().fullNameHash : '';
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.currentFolderName = ko.computed(function () {
|
|
||||||
return this.currentFolder() ? this.currentFolder().name() : '';
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.folderListSystemNames = ko.computed(function () {
|
|
||||||
|
|
||||||
var
|
|
||||||
FolderStore = require('Stores/User/Folder'),
|
|
||||||
|
|
||||||
aList = [Cache.getFolderInboxName()],
|
|
||||||
aFolders = this.folderList(),
|
|
||||||
sSentFolder = FolderStore.sentFolder(),
|
|
||||||
sDraftFolder = FolderStore.draftFolder(),
|
|
||||||
sSpamFolder = FolderStore.spamFolder(),
|
|
||||||
sTrashFolder = FolderStore.trashFolder(),
|
|
||||||
sArchiveFolder = FolderStore.archiveFolder()
|
|
||||||
;
|
|
||||||
|
|
||||||
if (Utils.isArray(aFolders) && 0 < aFolders.length)
|
|
||||||
{
|
|
||||||
if ('' !== sSentFolder && Consts.Values.UnuseOptionValue !== sSentFolder)
|
|
||||||
{
|
|
||||||
aList.push(sSentFolder);
|
|
||||||
}
|
|
||||||
if ('' !== sDraftFolder && Consts.Values.UnuseOptionValue !== sDraftFolder)
|
|
||||||
{
|
|
||||||
aList.push(sDraftFolder);
|
|
||||||
}
|
|
||||||
if ('' !== sSpamFolder && Consts.Values.UnuseOptionValue !== sSpamFolder)
|
|
||||||
{
|
|
||||||
aList.push(sSpamFolder);
|
|
||||||
}
|
|
||||||
if ('' !== sTrashFolder && Consts.Values.UnuseOptionValue !== sTrashFolder)
|
|
||||||
{
|
|
||||||
aList.push(sTrashFolder);
|
|
||||||
}
|
|
||||||
if ('' !== sArchiveFolder && Consts.Values.UnuseOptionValue !== sArchiveFolder)
|
|
||||||
{
|
|
||||||
aList.push(sArchiveFolder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return aList;
|
|
||||||
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.folderListSystem = ko.computed(function () {
|
|
||||||
return _.compact(_.map(this.folderListSystemNames(), function (sName) {
|
|
||||||
return Cache.getFolderFromCacheList(sName);
|
|
||||||
}));
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.folderMenuForMove = ko.computed(function () {
|
|
||||||
return Utils.folderListOptionsBuilder(this.folderListSystem(), this.folderList(), [
|
|
||||||
this.currentFolderFullNameRaw()
|
|
||||||
], null, null, null, null, function (oItem) {
|
|
||||||
return oItem ? oItem.localName() : '';
|
|
||||||
});
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.folderMenuForFilters = ko.computed(function () {
|
|
||||||
return Utils.folderListOptionsBuilder(this.folderListSystem(), this.folderList(),
|
|
||||||
['INBOX'], [['', '']], null, null, null, function (oItem) {
|
|
||||||
return oItem ? oItem.localName() : '';
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
// message list
|
|
||||||
this.staticMessageList = [];
|
|
||||||
|
|
||||||
this.messageList = ko.observableArray([]).extend({'rateLimit': 0});
|
|
||||||
|
|
||||||
this.messageListCount = ko.observable(0);
|
|
||||||
this.messageListSearch = ko.observable('');
|
|
||||||
this.messageListPage = ko.observable(1);
|
|
||||||
|
|
||||||
this.messageListThreadFolder = ko.observable('');
|
|
||||||
this.messageListThreadUids = ko.observableArray([]);
|
|
||||||
|
|
||||||
this.messageListThreadFolder.subscribe(function () {
|
|
||||||
this.messageListThreadUids([]);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.messageListEndFolder = ko.observable('');
|
|
||||||
this.messageListEndSearch = ko.observable('');
|
|
||||||
this.messageListEndPage = ko.observable(1);
|
|
||||||
|
|
||||||
this.messageListEndHash = ko.computed(function () {
|
|
||||||
return this.messageListEndFolder() + '|' + this.messageListEndSearch() + '|' + this.messageListEndPage();
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.messageListPageCount = ko.computed(function () {
|
|
||||||
var iPage = window.Math.ceil(this.messageListCount() /
|
|
||||||
SettingsStore.messagesPerPage());
|
|
||||||
return 0 >= iPage ? 1 : iPage;
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.mainMessageListSearch = ko.computed({
|
|
||||||
'read': this.messageListSearch,
|
|
||||||
'write': function (sValue) {
|
|
||||||
kn.setHash(Links.mailBox(
|
|
||||||
this.currentFolderFullNameHash(), 1, Utils.trim(sValue.toString())
|
|
||||||
));
|
|
||||||
},
|
|
||||||
'owner': this
|
|
||||||
});
|
|
||||||
|
|
||||||
this.messageListError = ko.observable('');
|
|
||||||
|
|
||||||
this.messageListLoading = ko.observable(false);
|
|
||||||
this.messageListIsNotCompleted = ko.observable(false);
|
|
||||||
this.messageListCompleteLoadingThrottle = ko.observable(false).extend({'throttle': 200});
|
|
||||||
|
|
||||||
this.messageListCompleteLoading = ko.computed(function () {
|
|
||||||
var
|
|
||||||
bOne = this.messageListLoading(),
|
|
||||||
bTwo = this.messageListIsNotCompleted()
|
|
||||||
;
|
|
||||||
return bOne || bTwo;
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.messageListCompleteLoading.subscribe(function (bValue) {
|
|
||||||
this.messageListCompleteLoadingThrottle(bValue);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.messageList.subscribe(_.debounce(function (aList) {
|
|
||||||
_.each(aList, function (oItem) {
|
|
||||||
if (oItem.newForAnimation())
|
|
||||||
{
|
|
||||||
oItem.newForAnimation(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 500));
|
|
||||||
|
|
||||||
// message preview
|
|
||||||
this.staticMessageList = new MessageModel();
|
|
||||||
this.message = ko.observable(null);
|
|
||||||
this.messageLoading = ko.observable(false);
|
|
||||||
this.messageLoadingThrottle = ko.observable(false).extend({'throttle': 50});
|
|
||||||
|
|
||||||
this.message.focused = ko.observable(false);
|
|
||||||
|
|
||||||
this.message.subscribe(function (oMessage) {
|
|
||||||
if (!oMessage)
|
|
||||||
{
|
|
||||||
this.message.focused(false);
|
|
||||||
this.messageFullScreenMode(false);
|
|
||||||
this.hideMessageBodies();
|
|
||||||
|
|
||||||
if (Enums.Layout.NoPreview === SettingsStore.layout() &&
|
|
||||||
-1 < window.location.hash.indexOf('message-preview'))
|
|
||||||
{
|
|
||||||
require('App/User').historyBack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Enums.Layout.NoPreview === SettingsStore.layout())
|
|
||||||
{
|
|
||||||
this.message.focused(true);
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.message.focused.subscribe(function (bValue) {
|
|
||||||
if (bValue)
|
|
||||||
{
|
|
||||||
this.folderList.focused(false);
|
|
||||||
Globals.keyScope(Enums.KeyState.MessageView);
|
|
||||||
}
|
|
||||||
else if (Enums.KeyState.MessageView === Globals.keyScope())
|
|
||||||
{
|
|
||||||
if (Enums.Layout.NoPreview === SettingsStore.layout() && this.message())
|
|
||||||
{
|
|
||||||
Globals.keyScope(Enums.KeyState.MessageView);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Globals.keyScope(Enums.KeyState.MessageList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.folderList.focused.subscribe(function (bValue) {
|
|
||||||
if (bValue)
|
|
||||||
{
|
|
||||||
Globals.keyScope(Enums.KeyState.FolderList);
|
|
||||||
}
|
|
||||||
else if (Enums.KeyState.FolderList === Globals.keyScope())
|
|
||||||
{
|
|
||||||
Globals.keyScope(Enums.KeyState.MessageList);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.messageLoading.subscribe(function (bValue) {
|
|
||||||
this.messageLoadingThrottle(bValue);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.messageFullScreenMode = ko.observable(false);
|
|
||||||
|
|
||||||
this.messageError = ko.observable('');
|
|
||||||
|
|
||||||
this.messagesBodiesDom = ko.observable(null);
|
|
||||||
|
|
||||||
this.messagesBodiesDom.subscribe(function (oDom) {
|
|
||||||
if (oDom && !(oDom instanceof $))
|
|
||||||
{
|
|
||||||
this.messagesBodiesDom($(oDom));
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.messageActiveDom = ko.observable(null);
|
|
||||||
|
|
||||||
this.isMessageSelected = ko.computed(function () {
|
|
||||||
return null !== this.message();
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.currentMessage = ko.observable(null);
|
|
||||||
|
|
||||||
this.messageListChecked = ko.computed(function () {
|
|
||||||
return _.filter(this.messageList(), function (oItem) {
|
|
||||||
return oItem.checked();
|
|
||||||
});
|
|
||||||
}, this).extend({'rateLimit': 0});
|
|
||||||
|
|
||||||
this.hasCheckedMessages = ko.computed(function () {
|
|
||||||
return 0 < this.messageListChecked().length;
|
|
||||||
}, this).extend({'rateLimit': 0});
|
|
||||||
|
|
||||||
this.messageListCheckedOrSelected = ko.computed(function () {
|
|
||||||
|
|
||||||
var
|
|
||||||
aChecked = this.messageListChecked(),
|
|
||||||
oSelectedMessage = this.currentMessage()
|
|
||||||
;
|
|
||||||
|
|
||||||
return _.union(aChecked, oSelectedMessage ? [oSelectedMessage] : []);
|
|
||||||
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.messageListCheckedOrSelectedUidsWithSubMails = ko.computed(function () {
|
|
||||||
var aList = [];
|
|
||||||
_.each(this.messageListCheckedOrSelected(), function (oMessage) {
|
|
||||||
if (oMessage)
|
|
||||||
{
|
|
||||||
aList.push(oMessage.uid);
|
|
||||||
if (0 < oMessage.threadsLen() && 0 === oMessage.parentUid() && oMessage.lastInCollapsedThread())
|
|
||||||
{
|
|
||||||
aList = _.union(aList, oMessage.threads());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return aList;
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
// other
|
|
||||||
this.composeInEdit = ko.observable(false);
|
|
||||||
|
|
||||||
this.purgeMessageBodyCacheThrottle = _.throttle(this.purgeMessageBodyCache, 1000 * 30);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataUserStorage.prototype.purgeMessageBodyCache = function()
|
|
||||||
{
|
|
||||||
var
|
|
||||||
iCount = 0,
|
|
||||||
oMessagesBodiesDom = null,
|
|
||||||
iEnd = Globals.iMessageBodyCacheCount - Consts.Values.MessageBodyCacheLimit
|
|
||||||
;
|
|
||||||
|
|
||||||
if (0 < iEnd)
|
|
||||||
{
|
|
||||||
oMessagesBodiesDom = this.messagesBodiesDom();
|
|
||||||
if (oMessagesBodiesDom)
|
|
||||||
{
|
|
||||||
oMessagesBodiesDom.find('.rl-cache-class').each(function () {
|
|
||||||
var oItem = $(this);
|
|
||||||
if (iEnd > oItem.data('rl-cache-count'))
|
|
||||||
{
|
|
||||||
oItem.addClass('rl-cache-purge');
|
|
||||||
iCount++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (0 < iCount)
|
|
||||||
{
|
|
||||||
_.delay(function () {
|
|
||||||
oMessagesBodiesDom.find('.rl-cache-purge').remove();
|
|
||||||
}, 300);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
DataUserStorage.prototype.initUidNextAndNewMessages = function (sFolder, sUidNext, aNewMessages)
|
|
||||||
{
|
|
||||||
if (Cache.getFolderInboxName() === sFolder && Utils.isNormal(sUidNext) && sUidNext !== '')
|
|
||||||
{
|
|
||||||
if (Utils.isArray(aNewMessages) && 0 < aNewMessages.length)
|
|
||||||
{
|
|
||||||
var
|
|
||||||
iIndex = 0,
|
|
||||||
iLen = aNewMessages.length,
|
|
||||||
NotificationStore = require('Stores/User/Notification')
|
|
||||||
;
|
|
||||||
|
|
||||||
_.each(aNewMessages, function (oItem) {
|
|
||||||
Cache.addNewMessageCache(sFolder, oItem.Uid);
|
|
||||||
});
|
|
||||||
|
|
||||||
NotificationStore.playSoundNotification();
|
|
||||||
|
|
||||||
if (3 < iLen)
|
|
||||||
{
|
|
||||||
NotificationStore.displayDesktopNotification(
|
|
||||||
Links.notificationMailIcon(),
|
|
||||||
require('Stores/User/Account').email(),
|
|
||||||
Translator.i18n('MESSAGE_LIST/NEW_MESSAGE_NOTIFICATION', {
|
|
||||||
'COUNT': iLen
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (; iIndex < iLen; iIndex++)
|
|
||||||
{
|
|
||||||
NotificationStore.displayDesktopNotification(
|
|
||||||
Links.notificationMailIcon(),
|
|
||||||
MessageModel.emailsToLine(MessageModel.initEmailsFromJson(aNewMessages[iIndex].From), false),
|
|
||||||
aNewMessages[iIndex].Subject
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Cache.setFolderUidNext(sFolder, sUidNext);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
DataUserStorage.prototype.hideMessageBodies = function ()
|
|
||||||
{
|
|
||||||
var oMessagesBodiesDom = this.messagesBodiesDom();
|
|
||||||
if (oMessagesBodiesDom)
|
|
||||||
{
|
|
||||||
oMessagesBodiesDom.find('.b-text-part').hide();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {boolean=} bBoot = false
|
|
||||||
* @returns {Array}
|
|
||||||
*/
|
|
||||||
DataUserStorage.prototype.getNextFolderNames = function (bBoot)
|
|
||||||
{
|
|
||||||
bBoot = Utils.isUnd(bBoot) ? false : !!bBoot;
|
|
||||||
|
|
||||||
var
|
|
||||||
aResult = [],
|
|
||||||
iLimit = 5,
|
|
||||||
iUtc = moment().unix(),
|
|
||||||
iTimeout = iUtc - 60 * 5,
|
|
||||||
aTimeouts = [],
|
|
||||||
sInboxFolderName = Cache.getFolderInboxName(),
|
|
||||||
fSearchFunction = function (aList) {
|
|
||||||
_.each(aList, function (oFolder) {
|
|
||||||
if (oFolder && sInboxFolderName !== oFolder.fullNameRaw &&
|
|
||||||
oFolder.selectable && oFolder.existen &&
|
|
||||||
iTimeout > oFolder.interval &&
|
|
||||||
(!bBoot || oFolder.subScribed()))
|
|
||||||
{
|
|
||||||
aTimeouts.push([oFolder.interval, oFolder.fullNameRaw]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oFolder && 0 < oFolder.subFolders().length)
|
|
||||||
{
|
|
||||||
fSearchFunction(oFolder.subFolders());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
fSearchFunction(this.folderList());
|
|
||||||
|
|
||||||
aTimeouts.sort(function(a, b) {
|
|
||||||
if (a[0] < b[0]) {
|
|
||||||
return -1;
|
|
||||||
} else if (a[0] > b[0]) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
_.find(aTimeouts, function (aItem) {
|
|
||||||
var oFolder = Cache.getFolderFromCacheList(aItem[1]);
|
|
||||||
if (oFolder)
|
|
||||||
{
|
|
||||||
oFolder.interval = iUtc;
|
|
||||||
aResult.push(aItem[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return iLimit <= aResult.length;
|
|
||||||
});
|
|
||||||
|
|
||||||
return _.uniq(aResult);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} sFromFolderFullNameRaw
|
|
||||||
* @param {Array} aUidForRemove
|
|
||||||
* @param {string=} sToFolderFullNameRaw = ''
|
|
||||||
* @param {bCopy=} bCopy = false
|
|
||||||
*/
|
|
||||||
DataUserStorage.prototype.removeMessagesFromList = function (
|
|
||||||
sFromFolderFullNameRaw, aUidForRemove, sToFolderFullNameRaw, bCopy)
|
|
||||||
{
|
|
||||||
sToFolderFullNameRaw = Utils.isNormal(sToFolderFullNameRaw) ? sToFolderFullNameRaw : '';
|
|
||||||
bCopy = Utils.isUnd(bCopy) ? false : !!bCopy;
|
|
||||||
|
|
||||||
aUidForRemove = _.map(aUidForRemove, function (mValue) {
|
|
||||||
return Utils.pInt(mValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
var
|
|
||||||
self = this,
|
|
||||||
iUnseenCount = 0,
|
|
||||||
aMessageList = this.messageList(),
|
|
||||||
oFromFolder = Cache.getFolderFromCacheList(sFromFolderFullNameRaw),
|
|
||||||
oToFolder = '' === sToFolderFullNameRaw ? null : Cache.getFolderFromCacheList(sToFolderFullNameRaw || ''),
|
|
||||||
sCurrentFolderFullNameRaw = this.currentFolderFullNameRaw(),
|
|
||||||
oCurrentMessage = this.message(),
|
|
||||||
aMessages = sCurrentFolderFullNameRaw === sFromFolderFullNameRaw ? _.filter(aMessageList, function (oMessage) {
|
|
||||||
return oMessage && -1 < Utils.inArray(Utils.pInt(oMessage.uid), aUidForRemove);
|
|
||||||
}) : []
|
|
||||||
;
|
|
||||||
|
|
||||||
_.each(aMessages, function (oMessage) {
|
|
||||||
if (oMessage && oMessage.unseen())
|
|
||||||
{
|
|
||||||
iUnseenCount++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (oFromFolder && !bCopy)
|
|
||||||
{
|
|
||||||
oFromFolder.messageCountAll(0 <= oFromFolder.messageCountAll() - aUidForRemove.length ?
|
|
||||||
oFromFolder.messageCountAll() - aUidForRemove.length : 0);
|
|
||||||
|
|
||||||
if (0 < iUnseenCount)
|
|
||||||
{
|
|
||||||
oFromFolder.messageCountUnread(0 <= oFromFolder.messageCountUnread() - iUnseenCount ?
|
|
||||||
oFromFolder.messageCountUnread() - iUnseenCount : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oToFolder)
|
|
||||||
{
|
|
||||||
oToFolder.messageCountAll(oToFolder.messageCountAll() + aUidForRemove.length);
|
|
||||||
if (0 < iUnseenCount)
|
|
||||||
{
|
|
||||||
oToFolder.messageCountUnread(oToFolder.messageCountUnread() + iUnseenCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
oToFolder.actionBlink(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 < aMessages.length)
|
|
||||||
{
|
|
||||||
if (bCopy)
|
|
||||||
{
|
|
||||||
_.each(aMessages, function (oMessage) {
|
|
||||||
oMessage.checked(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.messageListIsNotCompleted(true);
|
|
||||||
|
|
||||||
_.each(aMessages, function (oMessage) {
|
|
||||||
if (oCurrentMessage && oCurrentMessage.hash === oMessage.hash)
|
|
||||||
{
|
|
||||||
oCurrentMessage = null;
|
|
||||||
self.message(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
oMessage.deleted(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
_.delay(function () {
|
|
||||||
_.each(aMessages, function (oMessage) {
|
|
||||||
self.messageList.remove(oMessage);
|
|
||||||
});
|
|
||||||
}, 400);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('' !== sFromFolderFullNameRaw)
|
|
||||||
{
|
|
||||||
Cache.setFolderHash(sFromFolderFullNameRaw, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('' !== sToFolderFullNameRaw)
|
|
||||||
{
|
|
||||||
Cache.setFolderHash(sToFolderFullNameRaw, '');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Object} oMessageTextBody
|
|
||||||
*/
|
|
||||||
DataUserStorage.prototype.initBlockquoteSwitcher = function (oMessageTextBody)
|
|
||||||
{
|
|
||||||
if (oMessageTextBody)
|
|
||||||
{
|
|
||||||
var $oList = $('blockquote:not(.rl-bq-switcher)', oMessageTextBody).filter(function () {
|
|
||||||
return 0 === $(this).parent().closest('blockquote', oMessageTextBody).length;
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($oList && 0 < $oList.length)
|
|
||||||
{
|
|
||||||
_.delay(function () {
|
|
||||||
$oList.each(function () {
|
|
||||||
var $self = $(this), iH = $self.height();
|
|
||||||
if (0 === iH || 150 < iH)
|
|
||||||
{
|
|
||||||
$self.addClass('rl-bq-switcher hidden-bq');
|
|
||||||
$('<span class="rlBlockquoteSwitcher"><i class="icon-ellipsis" /></span>')
|
|
||||||
.insertBefore($self)
|
|
||||||
.click(function () {
|
|
||||||
$self.toggleClass('hidden-bq');
|
|
||||||
Utils.windowResize();
|
|
||||||
})
|
|
||||||
.after('<br />')
|
|
||||||
.before('<br />')
|
|
||||||
;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
DataUserStorage.prototype.setMessage = function (oData, bCached)
|
|
||||||
{
|
|
||||||
var
|
|
||||||
bIsHtml = false,
|
|
||||||
bHasExternals = false,
|
|
||||||
bHasInternals = false,
|
|
||||||
oBody = null,
|
|
||||||
oTextBody = null,
|
|
||||||
sId = '',
|
|
||||||
sResultHtml = '',
|
|
||||||
bPgpSigned = false,
|
|
||||||
bPgpEncrypted = false,
|
|
||||||
oMessagesBodiesDom = this.messagesBodiesDom(),
|
|
||||||
oMessage = this.message()
|
|
||||||
;
|
|
||||||
|
|
||||||
if (oData && oMessage && oData.Result && 'Object/Message' === oData.Result['@Object'] &&
|
|
||||||
oMessage.folderFullNameRaw === oData.Result.Folder && oMessage.uid === oData.Result.Uid)
|
|
||||||
{
|
|
||||||
this.messageError('');
|
|
||||||
|
|
||||||
oMessage.initUpdateByMessageJson(oData.Result);
|
|
||||||
Cache.addRequestedMessage(oMessage.folderFullNameRaw, oMessage.uid);
|
|
||||||
|
|
||||||
if (!bCached)
|
|
||||||
{
|
|
||||||
oMessage.initFlagsByJson(oData.Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
oMessagesBodiesDom = oMessagesBodiesDom && oMessagesBodiesDom[0] ? oMessagesBodiesDom : null;
|
|
||||||
if (oMessagesBodiesDom)
|
|
||||||
{
|
|
||||||
sId = 'rl-mgs-' + oMessage.hash.replace(/[^a-zA-Z0-9]/g, '');
|
|
||||||
oTextBody = oMessagesBodiesDom.find('#' + sId);
|
|
||||||
if (!oTextBody || !oTextBody[0])
|
|
||||||
{
|
|
||||||
bHasExternals = !!oData.Result.HasExternals;
|
|
||||||
bHasInternals = !!oData.Result.HasInternals;
|
|
||||||
|
|
||||||
oBody = $('<div id="' + sId + '" />').hide().addClass('rl-cache-class');
|
|
||||||
oBody.data('rl-cache-count', ++Globals.iMessageBodyCacheCount);
|
|
||||||
|
|
||||||
if (Utils.isNormal(oData.Result.Html) && '' !== oData.Result.Html)
|
|
||||||
{
|
|
||||||
bIsHtml = true;
|
|
||||||
sResultHtml = oData.Result.Html.toString();
|
|
||||||
}
|
|
||||||
else if (Utils.isNormal(oData.Result.Plain) && '' !== oData.Result.Plain)
|
|
||||||
{
|
|
||||||
bIsHtml = false;
|
|
||||||
sResultHtml = Utils.plainToHtml(oData.Result.Plain.toString(), false);
|
|
||||||
|
|
||||||
if ((oMessage.isPgpSigned() || oMessage.isPgpEncrypted()) && require('Stores/User/Pgp').capaOpenPGP())
|
|
||||||
{
|
|
||||||
oMessage.plainRaw = Utils.pString(oData.Result.Plain);
|
|
||||||
|
|
||||||
bPgpEncrypted = /---BEGIN PGP MESSAGE---/.test(oMessage.plainRaw);
|
|
||||||
if (!bPgpEncrypted)
|
|
||||||
{
|
|
||||||
bPgpSigned = /-----BEGIN PGP SIGNED MESSAGE-----/.test(oMessage.plainRaw) &&
|
|
||||||
/-----BEGIN PGP SIGNATURE-----/.test(oMessage.plainRaw);
|
|
||||||
}
|
|
||||||
|
|
||||||
Globals.$div.empty();
|
|
||||||
if (bPgpSigned && oMessage.isPgpSigned())
|
|
||||||
{
|
|
||||||
sResultHtml =
|
|
||||||
Globals.$div.append(
|
|
||||||
$('<pre class="b-plain-openpgp signed"></pre>').text(oMessage.plainRaw)
|
|
||||||
).html()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
else if (bPgpEncrypted && oMessage.isPgpEncrypted())
|
|
||||||
{
|
|
||||||
sResultHtml =
|
|
||||||
Globals.$div.append(
|
|
||||||
$('<pre class="b-plain-openpgp encrypted"></pre>').text(oMessage.plainRaw)
|
|
||||||
).html()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
Globals.$div.empty();
|
|
||||||
|
|
||||||
oMessage.isPgpSigned(bPgpSigned);
|
|
||||||
oMessage.isPgpEncrypted(bPgpEncrypted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bIsHtml = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
oBody
|
|
||||||
.html(Utils.findEmailAndLinks(sResultHtml))
|
|
||||||
.addClass('b-text-part ' + (bIsHtml ? 'html' : 'plain'))
|
|
||||||
;
|
|
||||||
|
|
||||||
oMessage.isHtml(!!bIsHtml);
|
|
||||||
oMessage.hasImages(!!bHasExternals);
|
|
||||||
oMessage.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.None);
|
|
||||||
oMessage.pgpSignedVerifyUser('');
|
|
||||||
|
|
||||||
oMessage.body = oBody;
|
|
||||||
if (oMessage.body)
|
|
||||||
{
|
|
||||||
oMessagesBodiesDom.append(oMessage.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
oMessage.storeDataToDom();
|
|
||||||
|
|
||||||
if (bHasInternals)
|
|
||||||
{
|
|
||||||
oMessage.showInternalImages(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oMessage.hasImages() && SettingsStore.showImages())
|
|
||||||
{
|
|
||||||
oMessage.showExternalImages(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.purgeMessageBodyCacheThrottle();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oMessage.body = oTextBody;
|
|
||||||
if (oMessage.body)
|
|
||||||
{
|
|
||||||
oMessage.body.data('rl-cache-count', ++Globals.iMessageBodyCacheCount);
|
|
||||||
oMessage.fetchDataToDom();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.messageActiveDom(oMessage.body);
|
|
||||||
|
|
||||||
this.hideMessageBodies();
|
|
||||||
oMessage.body.show();
|
|
||||||
|
|
||||||
if (oBody)
|
|
||||||
{
|
|
||||||
this.initBlockquoteSwitcher(oBody);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Cache.initMessageFlagsFromCache(oMessage);
|
|
||||||
if (oMessage.unseen())
|
|
||||||
{
|
|
||||||
require('App/User').setMessageSeen(oMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils.windowResize();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Array} aList
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
DataUserStorage.prototype.calculateMessageListHash = function (aList)
|
|
||||||
{
|
|
||||||
return _.map(aList, function (oMessage) {
|
|
||||||
return '' + oMessage.hash + '_' + oMessage.threadsLen() + '_' + oMessage.flagHash();
|
|
||||||
}).join('|');
|
|
||||||
};
|
|
||||||
|
|
||||||
DataUserStorage.prototype.findPublicKeyByHex = function (sHash)
|
|
||||||
{
|
|
||||||
return _.find(require('Stores/User/Pgp').openpgpkeysPublic(), function (oItem) {
|
|
||||||
return oItem && sHash === oItem.id;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
DataUserStorage.prototype.findPublicKeysByEmail = function (sEmail)
|
|
||||||
{
|
|
||||||
var PgpStore = require('Stores/User/Pgp');
|
|
||||||
return _.compact(_.map(PgpStore.openpgpkeysPublic(), function (oItem) {
|
|
||||||
|
|
||||||
var oKey = null;
|
|
||||||
if (oItem && sEmail === oItem.email)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
oKey = PgpStore.openpgp.key.readArmored(oItem.armor);
|
|
||||||
if (oKey && !oKey.err && oKey.keys && oKey.keys[0])
|
|
||||||
{
|
|
||||||
return oKey.keys[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} sEmail
|
|
||||||
* @param {string=} sPassword
|
|
||||||
* @returns {?}
|
|
||||||
*/
|
|
||||||
DataUserStorage.prototype.findPrivateKeyByEmail = function (sEmail, sPassword)
|
|
||||||
{
|
|
||||||
var
|
|
||||||
PgpStore = require('Stores/User/Pgp'),
|
|
||||||
oPrivateKey = null,
|
|
||||||
oKey = _.find(PgpStore.openpgpkeysPrivate(), function (oItem) {
|
|
||||||
return oItem && sEmail === oItem.email;
|
|
||||||
})
|
|
||||||
;
|
|
||||||
|
|
||||||
if (oKey)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
oPrivateKey = PgpStore.openpgp.key.readArmored(oKey.armor);
|
|
||||||
if (oPrivateKey && !oPrivateKey.err && oPrivateKey.keys && oPrivateKey.keys[0])
|
|
||||||
{
|
|
||||||
oPrivateKey = oPrivateKey.keys[0];
|
|
||||||
oPrivateKey.decrypt(Utils.pString(sPassword));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oPrivateKey = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
oPrivateKey = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return oPrivateKey;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string=} sPassword
|
|
||||||
* @returns {?}
|
|
||||||
*/
|
|
||||||
DataUserStorage.prototype.findSelfPrivateKey = function (sPassword)
|
|
||||||
{
|
|
||||||
return this.findPrivateKeyByEmail(require('Stores/User/Account').email(), sPassword);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = new DataUserStorage();
|
module.exports = new DataUserStorage();
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
|
|
||||||
AppStore = require('Stores/User/App'),
|
AppStore = require('Stores/User/App'),
|
||||||
SettingsStore = require('Stores/User/Settings'),
|
SettingsStore = require('Stores/User/Settings'),
|
||||||
|
MessageStore = require('Stores/User/Message'),
|
||||||
|
|
||||||
Settings = require('Storage/Settings'),
|
Settings = require('Storage/Settings'),
|
||||||
Cache = require('Storage/User/Cache'),
|
Cache = require('Storage/User/Cache'),
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
|
|
||||||
AbstractRemoteStorage = require('Storage/AbstractRemote')
|
AbstractRemoteStorage = require('Storage/AbstractRemote')
|
||||||
;
|
;
|
||||||
|
|
@ -348,7 +348,7 @@
|
||||||
sFolderHash,
|
sFolderHash,
|
||||||
Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
|
Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
|
||||||
AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0',
|
AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0',
|
||||||
AppStore.threadsAllowed() && sFolderFullNameRaw === Data.messageListThreadFolder() ? Data.messageListThreadUids().join(',') : ''
|
AppStore.threadsAllowed() && sFolderFullNameRaw === MessageStore.messageListThreadFolder() ? MessageStore.messageListThreadUids().join(',') : ''
|
||||||
].join(String.fromCharCode(0))), bSilent ? [] : ['MessageList']);
|
].join(String.fromCharCode(0))), bSilent ? [] : ['MessageList']);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -360,7 +360,7 @@
|
||||||
'Search': sSearch,
|
'Search': sSearch,
|
||||||
'UidNext': Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
|
'UidNext': Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
|
||||||
'UseThreads': AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0',
|
'UseThreads': AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0',
|
||||||
'ExpandedThreadUid': AppStore.threadsAllowed() && sFolderFullNameRaw === Data.messageListThreadFolder() ? Data.messageListThreadUids().join(',') : ''
|
'ExpandedThreadUid': AppStore.threadsAllowed() && sFolderFullNameRaw === MessageStore.messageListThreadFolder() ? MessageStore.messageListThreadUids().join(',') : ''
|
||||||
}, '' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout, '', bSilent ? [] : ['MessageList']);
|
}, '' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout, '', bSilent ? [] : ['MessageList']);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
this.projectHash = ko.observable('');
|
this.projectHash = ko.observable('');
|
||||||
this.threadsAllowed = ko.observable(false);
|
this.threadsAllowed = ko.observable(false);
|
||||||
|
|
||||||
|
this.composeInEdit = ko.observable(false);
|
||||||
|
|
||||||
this.contactsAutosave = ko.observable(false);
|
this.contactsAutosave = ko.observable(false);
|
||||||
this.useLocalProxyForExternalImages = ko.observable(false);
|
this.useLocalProxyForExternalImages = ko.observable(false);
|
||||||
|
|
||||||
|
|
|
||||||
43
dev/Stores/User/Contact.js
Normal file
43
dev/Stores/User/Contact.js
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var
|
||||||
|
ko = require('ko'),
|
||||||
|
|
||||||
|
Settings = require('Storage/Settings')
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function ContactUserStore()
|
||||||
|
{
|
||||||
|
this.contacts = ko.observableArray([]);
|
||||||
|
this.contacts.loading = ko.observable(false).extend({'throttle': 200});
|
||||||
|
this.contacts.importing = ko.observable(false).extend({'throttle': 200});
|
||||||
|
this.contacts.syncing = ko.observable(false).extend({'throttle': 200});
|
||||||
|
this.contacts.exportingVcf = ko.observable(false).extend({'throttle': 200});
|
||||||
|
this.contacts.exportingCsv = ko.observable(false).extend({'throttle': 200});
|
||||||
|
|
||||||
|
this.allowContactsSync = ko.observable(false);
|
||||||
|
this.enableContactsSync = ko.observable(false);
|
||||||
|
this.contactsSyncUrl = ko.observable('');
|
||||||
|
this.contactsSyncUser = ko.observable('');
|
||||||
|
this.contactsSyncPass = ko.observable('');
|
||||||
|
}
|
||||||
|
|
||||||
|
ContactUserStore.prototype.populate = function ()
|
||||||
|
{
|
||||||
|
this.allowContactsSync(!!Settings.settingsGet('ContactsSyncIsAllowed'));
|
||||||
|
this.enableContactsSync(!!Settings.settingsGet('EnableContactsSync'));
|
||||||
|
|
||||||
|
this.contactsSyncUrl(Settings.settingsGet('ContactsSyncUrl'));
|
||||||
|
this.contactsSyncUser(Settings.settingsGet('ContactsSyncUser'));
|
||||||
|
this.contactsSyncPass(Settings.settingsGet('ContactsSyncPassword'));
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = new ContactUserStore();
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
@ -4,10 +4,14 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var
|
var
|
||||||
|
_ = require('_'),
|
||||||
ko = require('ko'),
|
ko = require('ko'),
|
||||||
|
moment = require('moment'),
|
||||||
|
|
||||||
Enums = require('Common/Enums'),
|
Enums = require('Common/Enums'),
|
||||||
Consts = require('Common/Consts'),
|
Consts = require('Common/Consts'),
|
||||||
|
Globals = require('Common/Globals'),
|
||||||
|
Utils = require('Common/Utils'),
|
||||||
|
|
||||||
Cache = require('Storage/User/Cache')
|
Cache = require('Storage/User/Cache')
|
||||||
;
|
;
|
||||||
|
|
@ -23,6 +27,25 @@
|
||||||
this.trashFolder = ko.observable('');
|
this.trashFolder = ko.observable('');
|
||||||
this.archiveFolder = ko.observable('');
|
this.archiveFolder = ko.observable('');
|
||||||
|
|
||||||
|
this.namespace = '';
|
||||||
|
|
||||||
|
this.folderList = ko.observableArray([]);
|
||||||
|
this.folderList.focused = ko.observable(false);
|
||||||
|
this.folderList.optimized = ko.observable(false);
|
||||||
|
this.folderList.error = ko.observable('');
|
||||||
|
|
||||||
|
this.foldersLoading = ko.observable(false);
|
||||||
|
this.foldersCreating = ko.observable(false);
|
||||||
|
this.foldersDeleting = ko.observable(false);
|
||||||
|
this.foldersRenaming = ko.observable(false);
|
||||||
|
|
||||||
|
this.foldersInboxUnreadCount = ko.observable(0);
|
||||||
|
|
||||||
|
this.currentFolder = ko.observable(null).extend({'toggleSubscribe': [null,
|
||||||
|
function (oPrev) { if (oPrev) { oPrev.selected(false); }},
|
||||||
|
function (oNext) { if (oNext) { oNext.selected(true); }}
|
||||||
|
]});
|
||||||
|
|
||||||
this.computers();
|
this.computers();
|
||||||
this.subscribers();
|
this.subscribers();
|
||||||
}
|
}
|
||||||
|
|
@ -32,6 +55,96 @@
|
||||||
this.draftFolderNotEnabled = ko.computed(function () {
|
this.draftFolderNotEnabled = ko.computed(function () {
|
||||||
return '' === this.draftFolder() || Consts.Values.UnuseOptionValue === this.draftFolder();
|
return '' === this.draftFolder() || Consts.Values.UnuseOptionValue === this.draftFolder();
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
this.foldersListWithSingleInboxRootFolder = ko.computed(function () {
|
||||||
|
return !_.find(this.folderList(), function (oFolder) {
|
||||||
|
return oFolder && !oFolder.isSystemFolder() && oFolder.visible();
|
||||||
|
});
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.currentFolderFullNameRaw = ko.computed(function () {
|
||||||
|
return this.currentFolder() ? this.currentFolder().fullNameRaw : '';
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.currentFolderFullName = ko.computed(function () {
|
||||||
|
return this.currentFolder() ? this.currentFolder().fullName : '';
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.currentFolderFullNameHash = ko.computed(function () {
|
||||||
|
return this.currentFolder() ? this.currentFolder().fullNameHash : '';
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.foldersChanging = ko.computed(function () {
|
||||||
|
var
|
||||||
|
bLoading = this.foldersLoading(),
|
||||||
|
bCreating = this.foldersCreating(),
|
||||||
|
bDeleting = this.foldersDeleting(),
|
||||||
|
bRenaming = this.foldersRenaming()
|
||||||
|
;
|
||||||
|
return bLoading || bCreating || bDeleting || bRenaming;
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.folderListSystemNames = ko.computed(function () {
|
||||||
|
|
||||||
|
var
|
||||||
|
aList = [Cache.getFolderInboxName()],
|
||||||
|
aFolders = this.folderList(),
|
||||||
|
sSentFolder = this.sentFolder(),
|
||||||
|
sDraftFolder = this.draftFolder(),
|
||||||
|
sSpamFolder = this.spamFolder(),
|
||||||
|
sTrashFolder = this.trashFolder(),
|
||||||
|
sArchiveFolder = this.archiveFolder()
|
||||||
|
;
|
||||||
|
|
||||||
|
if (Utils.isArray(aFolders) && 0 < aFolders.length)
|
||||||
|
{
|
||||||
|
if ('' !== sSentFolder && Consts.Values.UnuseOptionValue !== sSentFolder)
|
||||||
|
{
|
||||||
|
aList.push(sSentFolder);
|
||||||
|
}
|
||||||
|
if ('' !== sDraftFolder && Consts.Values.UnuseOptionValue !== sDraftFolder)
|
||||||
|
{
|
||||||
|
aList.push(sDraftFolder);
|
||||||
|
}
|
||||||
|
if ('' !== sSpamFolder && Consts.Values.UnuseOptionValue !== sSpamFolder)
|
||||||
|
{
|
||||||
|
aList.push(sSpamFolder);
|
||||||
|
}
|
||||||
|
if ('' !== sTrashFolder && Consts.Values.UnuseOptionValue !== sTrashFolder)
|
||||||
|
{
|
||||||
|
aList.push(sTrashFolder);
|
||||||
|
}
|
||||||
|
if ('' !== sArchiveFolder && Consts.Values.UnuseOptionValue !== sArchiveFolder)
|
||||||
|
{
|
||||||
|
aList.push(sArchiveFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return aList;
|
||||||
|
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.folderListSystem = ko.computed(function () {
|
||||||
|
return _.compact(_.map(this.folderListSystemNames(), function (sName) {
|
||||||
|
return Cache.getFolderFromCacheList(sName);
|
||||||
|
}));
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.folderMenuForMove = ko.computed(function () {
|
||||||
|
return Utils.folderListOptionsBuilder(this.folderListSystem(), this.folderList(), [
|
||||||
|
this.currentFolderFullNameRaw()
|
||||||
|
], null, null, null, null, function (oItem) {
|
||||||
|
return oItem ? oItem.localName() : '';
|
||||||
|
});
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.folderMenuForFilters = ko.computed(function () {
|
||||||
|
return Utils.folderListOptionsBuilder(this.folderListSystem(), this.folderList(),
|
||||||
|
['INBOX'], [['', '']], null, null, null, function (oItem) {
|
||||||
|
return oItem ? oItem.localName() : '';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
FolderUserStore.prototype.subscribers = function ()
|
FolderUserStore.prototype.subscribers = function ()
|
||||||
|
|
@ -68,6 +181,76 @@
|
||||||
this.spamFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Spam), this);
|
this.spamFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Spam), this);
|
||||||
this.trashFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Trash), this);
|
this.trashFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Trash), this);
|
||||||
this.archiveFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Archive), this);
|
this.archiveFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Archive), this);
|
||||||
|
|
||||||
|
this.folderList.focused.subscribe(function (bValue) {
|
||||||
|
if (bValue)
|
||||||
|
{
|
||||||
|
Globals.keyScope(Enums.KeyState.FolderList);
|
||||||
|
}
|
||||||
|
else if (Enums.KeyState.FolderList === Globals.keyScope())
|
||||||
|
{
|
||||||
|
Globals.keyScope(Enums.KeyState.MessageList);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean=} bBoot = false
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
FolderUserStore.prototype.getNextFolderNames = function (bBoot)
|
||||||
|
{
|
||||||
|
bBoot = Utils.isUnd(bBoot) ? false : !!bBoot;
|
||||||
|
|
||||||
|
var
|
||||||
|
aResult = [],
|
||||||
|
iLimit = 5,
|
||||||
|
iUtc = moment().unix(),
|
||||||
|
iTimeout = iUtc - 60 * 5,
|
||||||
|
aTimeouts = [],
|
||||||
|
sInboxFolderName = Cache.getFolderInboxName(),
|
||||||
|
fSearchFunction = function (aList) {
|
||||||
|
_.each(aList, function (oFolder) {
|
||||||
|
if (oFolder && sInboxFolderName !== oFolder.fullNameRaw &&
|
||||||
|
oFolder.selectable && oFolder.existen &&
|
||||||
|
iTimeout > oFolder.interval &&
|
||||||
|
(!bBoot || oFolder.subScribed()))
|
||||||
|
{
|
||||||
|
aTimeouts.push([oFolder.interval, oFolder.fullNameRaw]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oFolder && 0 < oFolder.subFolders().length)
|
||||||
|
{
|
||||||
|
fSearchFunction(oFolder.subFolders());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
fSearchFunction(this.folderList());
|
||||||
|
|
||||||
|
aTimeouts.sort(function(a, b) {
|
||||||
|
if (a[0] < b[0]) {
|
||||||
|
return -1;
|
||||||
|
} else if (a[0] > b[0]) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
_.find(aTimeouts, function (aItem) {
|
||||||
|
var oFolder = Cache.getFolderFromCacheList(aItem[1]);
|
||||||
|
if (oFolder)
|
||||||
|
{
|
||||||
|
oFolder.interval = iUtc;
|
||||||
|
aResult.push(aItem[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return iLimit <= aResult.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
return _.uniq(aResult);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = new FolderUserStore();
|
module.exports = new FolderUserStore();
|
||||||
|
|
|
||||||
745
dev/Stores/User/Message.js
Normal file
745
dev/Stores/User/Message.js
Normal file
|
|
@ -0,0 +1,745 @@
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var
|
||||||
|
_ = require('_'),
|
||||||
|
ko = require('ko'),
|
||||||
|
window = require('window'),
|
||||||
|
moment = require('moment'),
|
||||||
|
$ = require('$'),
|
||||||
|
|
||||||
|
kn = require('Knoin/Knoin'),
|
||||||
|
|
||||||
|
Enums = require('Common/Enums'),
|
||||||
|
Consts = require('Common/Consts'),
|
||||||
|
Globals = require('Common/Globals'),
|
||||||
|
Utils = require('Common/Utils'),
|
||||||
|
Links = require('Common/Links'),
|
||||||
|
Translator = require('Common/Translator'),
|
||||||
|
|
||||||
|
FolderStore = require('Stores/User/Folder'),
|
||||||
|
SettingsStore = require('Stores/User/Settings'),
|
||||||
|
|
||||||
|
MessageModel = require('Model/Message'),
|
||||||
|
|
||||||
|
Cache = require('Storage/User/Cache')
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function MessageUserStore()
|
||||||
|
{
|
||||||
|
this.staticMessage = new MessageModel();
|
||||||
|
this.staticMessageList = [];
|
||||||
|
|
||||||
|
this.messageList = ko.observableArray([]).extend({'rateLimit': 0});
|
||||||
|
|
||||||
|
this.messageListCount = ko.observable(0);
|
||||||
|
this.messageListSearch = ko.observable('');
|
||||||
|
this.messageListPage = ko.observable(1);
|
||||||
|
this.messageListError = ko.observable('');
|
||||||
|
|
||||||
|
this.messageListThreadFolder = ko.observable('');
|
||||||
|
this.messageListThreadUids = ko.observableArray([]);
|
||||||
|
|
||||||
|
this.messageListEndFolder = ko.observable('');
|
||||||
|
this.messageListEndSearch = ko.observable('');
|
||||||
|
this.messageListEndPage = ko.observable(1);
|
||||||
|
|
||||||
|
this.messageListLoading = ko.observable(false);
|
||||||
|
this.messageListIsNotCompleted = ko.observable(false);
|
||||||
|
this.messageListCompleteLoadingThrottle = ko.observable(false).extend({'throttle': 200});
|
||||||
|
|
||||||
|
// message viewer
|
||||||
|
this.message = ko.observable(null);
|
||||||
|
this.currentMessage = ko.observable(null);
|
||||||
|
|
||||||
|
this.message.focused = ko.observable(false);
|
||||||
|
|
||||||
|
this.messageError = ko.observable('');
|
||||||
|
this.messageLoading = ko.observable(false);
|
||||||
|
this.messageLoadingThrottle = ko.observable(false).extend({'throttle': 50});
|
||||||
|
|
||||||
|
this.messageFullScreenMode = ko.observable(false);
|
||||||
|
|
||||||
|
this.messagesBodiesDom = ko.observable(null);
|
||||||
|
this.messageActiveDom = ko.observable(null);
|
||||||
|
|
||||||
|
this.messageListChecked = ko.computed(function () {
|
||||||
|
return _.filter(this.messageList(), function (oItem) {
|
||||||
|
return oItem.checked();
|
||||||
|
});
|
||||||
|
}, this).extend({'rateLimit': 0});
|
||||||
|
|
||||||
|
this.hasCheckedMessages = ko.computed(function () {
|
||||||
|
return 0 < this.messageListChecked().length;
|
||||||
|
}, this).extend({'rateLimit': 0});
|
||||||
|
|
||||||
|
this.messageListCheckedOrSelected = ko.computed(function () {
|
||||||
|
|
||||||
|
var
|
||||||
|
aChecked = this.messageListChecked(),
|
||||||
|
oSelectedMessage = this.currentMessage()
|
||||||
|
;
|
||||||
|
|
||||||
|
return _.union(aChecked, oSelectedMessage ? [oSelectedMessage] : []);
|
||||||
|
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.messageListCheckedOrSelectedUidsWithSubMails = ko.computed(function () {
|
||||||
|
var aList = [];
|
||||||
|
_.each(this.messageListCheckedOrSelected(), function (oMessage) {
|
||||||
|
if (oMessage)
|
||||||
|
{
|
||||||
|
aList.push(oMessage.uid);
|
||||||
|
if (0 < oMessage.threadsLen() && 0 === oMessage.parentUid() && oMessage.lastInCollapsedThread())
|
||||||
|
{
|
||||||
|
aList = _.union(aList, oMessage.threads());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return aList;
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
|
||||||
|
this.computers();
|
||||||
|
this.subscribers();
|
||||||
|
|
||||||
|
this.purgeMessageBodyCacheThrottle = _.throttle(this.purgeMessageBodyCache, 1000 * 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageUserStore.prototype.computers = function ()
|
||||||
|
{
|
||||||
|
this.messageListEndHash = ko.computed(function () {
|
||||||
|
return this.messageListEndFolder() + '|' + this.messageListEndSearch() + '|' + this.messageListEndPage();
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.messageListPageCount = ko.computed(function () {
|
||||||
|
var iPage = window.Math.ceil(this.messageListCount() /
|
||||||
|
SettingsStore.messagesPerPage());
|
||||||
|
return 0 >= iPage ? 1 : iPage;
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.mainMessageListSearch = ko.computed({
|
||||||
|
'read': this.messageListSearch,
|
||||||
|
'write': function (sValue) {
|
||||||
|
kn.setHash(Links.mailBox(
|
||||||
|
FolderStore.currentFolderFullNameHash(), 1, Utils.trim(sValue.toString())
|
||||||
|
));
|
||||||
|
},
|
||||||
|
'owner': this
|
||||||
|
});
|
||||||
|
|
||||||
|
this.messageListCompleteLoading = ko.computed(function () {
|
||||||
|
var
|
||||||
|
bOne = this.messageListLoading(),
|
||||||
|
bTwo = this.messageListIsNotCompleted()
|
||||||
|
;
|
||||||
|
return bOne || bTwo;
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.isMessageSelected = ko.computed(function () {
|
||||||
|
return null !== this.message();
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageUserStore.prototype.subscribers = function ()
|
||||||
|
{
|
||||||
|
this.messageListThreadFolder.subscribe(function () {
|
||||||
|
this.messageListThreadUids([]);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.messageListCompleteLoading.subscribe(function (bValue) {
|
||||||
|
this.messageListCompleteLoadingThrottle(bValue);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.messageList.subscribe(_.debounce(function (aList) {
|
||||||
|
_.each(aList, function (oItem) {
|
||||||
|
if (oItem && oItem.newForAnimation())
|
||||||
|
{
|
||||||
|
oItem.newForAnimation(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 500));
|
||||||
|
|
||||||
|
this.message.subscribe(function (oMessage) {
|
||||||
|
if (!oMessage)
|
||||||
|
{
|
||||||
|
this.message.focused(false);
|
||||||
|
this.messageFullScreenMode(false);
|
||||||
|
this.hideMessageBodies();
|
||||||
|
|
||||||
|
if (Enums.Layout.NoPreview === SettingsStore.layout() &&
|
||||||
|
-1 < window.location.hash.indexOf('message-preview'))
|
||||||
|
{
|
||||||
|
require('App/User').historyBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Enums.Layout.NoPreview === SettingsStore.layout())
|
||||||
|
{
|
||||||
|
this.message.focused(true);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.message.focused.subscribe(function (bValue) {
|
||||||
|
if (bValue)
|
||||||
|
{
|
||||||
|
FolderStore.folderList.focused(false);
|
||||||
|
Globals.keyScope(Enums.KeyState.MessageView);
|
||||||
|
}
|
||||||
|
else if (Enums.KeyState.MessageView === Globals.keyScope())
|
||||||
|
{
|
||||||
|
if (Enums.Layout.NoPreview === SettingsStore.layout() && this.message())
|
||||||
|
{
|
||||||
|
Globals.keyScope(Enums.KeyState.MessageView);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Globals.keyScope(Enums.KeyState.MessageList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.messageLoading.subscribe(function (bValue) {
|
||||||
|
this.messageLoadingThrottle(bValue);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.messagesBodiesDom.subscribe(function (oDom) {
|
||||||
|
if (oDom && !(oDom instanceof $))
|
||||||
|
{
|
||||||
|
this.messagesBodiesDom($(oDom));
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.messageListEndFolder.subscribe(function (sFolder) {
|
||||||
|
var oMessage = this.message();
|
||||||
|
if (oMessage && sFolder && sFolder !== oMessage.folderFullNameRaw)
|
||||||
|
{
|
||||||
|
this.message(null);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageUserStore.prototype.purgeMessageBodyCache = function()
|
||||||
|
{
|
||||||
|
var
|
||||||
|
iCount = 0,
|
||||||
|
oMessagesBodiesDom = null,
|
||||||
|
iEnd = Globals.iMessageBodyCacheCount - Consts.Values.MessageBodyCacheLimit
|
||||||
|
;
|
||||||
|
|
||||||
|
if (0 < iEnd)
|
||||||
|
{
|
||||||
|
oMessagesBodiesDom = this.messagesBodiesDom();
|
||||||
|
if (oMessagesBodiesDom)
|
||||||
|
{
|
||||||
|
oMessagesBodiesDom.find('.rl-cache-class').each(function () {
|
||||||
|
var oItem = $(this);
|
||||||
|
if (iEnd > oItem.data('rl-cache-count'))
|
||||||
|
{
|
||||||
|
oItem.addClass('rl-cache-purge');
|
||||||
|
iCount++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (0 < iCount)
|
||||||
|
{
|
||||||
|
_.delay(function () {
|
||||||
|
oMessagesBodiesDom.find('.rl-cache-purge').remove();
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageUserStore.prototype.initUidNextAndNewMessages = function (sFolder, sUidNext, aNewMessages)
|
||||||
|
{
|
||||||
|
if (Cache.getFolderInboxName() === sFolder && Utils.isNormal(sUidNext) && sUidNext !== '')
|
||||||
|
{
|
||||||
|
if (Utils.isArray(aNewMessages) && 0 < aNewMessages.length)
|
||||||
|
{
|
||||||
|
var
|
||||||
|
iIndex = 0,
|
||||||
|
iLen = aNewMessages.length,
|
||||||
|
NotificationStore = require('Stores/User/Notification')
|
||||||
|
;
|
||||||
|
|
||||||
|
_.each(aNewMessages, function (oItem) {
|
||||||
|
Cache.addNewMessageCache(sFolder, oItem.Uid);
|
||||||
|
});
|
||||||
|
|
||||||
|
NotificationStore.playSoundNotification();
|
||||||
|
|
||||||
|
if (3 < iLen)
|
||||||
|
{
|
||||||
|
NotificationStore.displayDesktopNotification(
|
||||||
|
Links.notificationMailIcon(),
|
||||||
|
require('Stores/User/Account').email(),
|
||||||
|
Translator.i18n('MESSAGE_LIST/NEW_MESSAGE_NOTIFICATION', {
|
||||||
|
'COUNT': iLen
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; iIndex < iLen; iIndex++)
|
||||||
|
{
|
||||||
|
NotificationStore.displayDesktopNotification(
|
||||||
|
Links.notificationMailIcon(),
|
||||||
|
MessageModel.emailsToLine(MessageModel.initEmailsFromJson(aNewMessages[iIndex].From), false),
|
||||||
|
aNewMessages[iIndex].Subject
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cache.setFolderUidNext(sFolder, sUidNext);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageUserStore.prototype.hideMessageBodies = function ()
|
||||||
|
{
|
||||||
|
var oMessagesBodiesDom = this.messagesBodiesDom();
|
||||||
|
if (oMessagesBodiesDom)
|
||||||
|
{
|
||||||
|
oMessagesBodiesDom.find('.b-text-part').hide();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} sFromFolderFullNameRaw
|
||||||
|
* @param {Array} aUidForRemove
|
||||||
|
* @param {string=} sToFolderFullNameRaw = ''
|
||||||
|
* @param {bCopy=} bCopy = false
|
||||||
|
*/
|
||||||
|
MessageUserStore.prototype.removeMessagesFromList = function (
|
||||||
|
sFromFolderFullNameRaw, aUidForRemove, sToFolderFullNameRaw, bCopy)
|
||||||
|
{
|
||||||
|
sToFolderFullNameRaw = Utils.isNormal(sToFolderFullNameRaw) ? sToFolderFullNameRaw : '';
|
||||||
|
bCopy = Utils.isUnd(bCopy) ? false : !!bCopy;
|
||||||
|
|
||||||
|
aUidForRemove = _.map(aUidForRemove, function (mValue) {
|
||||||
|
return Utils.pInt(mValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
var
|
||||||
|
self = this,
|
||||||
|
iUnseenCount = 0,
|
||||||
|
aMessageList = this.messageList(),
|
||||||
|
oFromFolder = Cache.getFolderFromCacheList(sFromFolderFullNameRaw),
|
||||||
|
oToFolder = '' === sToFolderFullNameRaw ? null : Cache.getFolderFromCacheList(sToFolderFullNameRaw || ''),
|
||||||
|
sCurrentFolderFullNameRaw = FolderStore.currentFolderFullNameRaw(),
|
||||||
|
oCurrentMessage = this.message(),
|
||||||
|
aMessages = sCurrentFolderFullNameRaw === sFromFolderFullNameRaw ? _.filter(aMessageList, function (oMessage) {
|
||||||
|
return oMessage && -1 < Utils.inArray(Utils.pInt(oMessage.uid), aUidForRemove);
|
||||||
|
}) : []
|
||||||
|
;
|
||||||
|
|
||||||
|
_.each(aMessages, function (oMessage) {
|
||||||
|
if (oMessage && oMessage.unseen())
|
||||||
|
{
|
||||||
|
iUnseenCount++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (oFromFolder && !bCopy)
|
||||||
|
{
|
||||||
|
oFromFolder.messageCountAll(0 <= oFromFolder.messageCountAll() - aUidForRemove.length ?
|
||||||
|
oFromFolder.messageCountAll() - aUidForRemove.length : 0);
|
||||||
|
|
||||||
|
if (0 < iUnseenCount)
|
||||||
|
{
|
||||||
|
oFromFolder.messageCountUnread(0 <= oFromFolder.messageCountUnread() - iUnseenCount ?
|
||||||
|
oFromFolder.messageCountUnread() - iUnseenCount : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oToFolder)
|
||||||
|
{
|
||||||
|
oToFolder.messageCountAll(oToFolder.messageCountAll() + aUidForRemove.length);
|
||||||
|
if (0 < iUnseenCount)
|
||||||
|
{
|
||||||
|
oToFolder.messageCountUnread(oToFolder.messageCountUnread() + iUnseenCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
oToFolder.actionBlink(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < aMessages.length)
|
||||||
|
{
|
||||||
|
if (bCopy)
|
||||||
|
{
|
||||||
|
_.each(aMessages, function (oMessage) {
|
||||||
|
oMessage.checked(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.messageListIsNotCompleted(true);
|
||||||
|
|
||||||
|
_.each(aMessages, function (oMessage) {
|
||||||
|
if (oCurrentMessage && oCurrentMessage.hash === oMessage.hash)
|
||||||
|
{
|
||||||
|
oCurrentMessage = null;
|
||||||
|
self.message(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
oMessage.deleted(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
_.delay(function () {
|
||||||
|
_.each(aMessages, function (oMessage) {
|
||||||
|
self.messageList.remove(oMessage);
|
||||||
|
});
|
||||||
|
}, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('' !== sFromFolderFullNameRaw)
|
||||||
|
{
|
||||||
|
Cache.setFolderHash(sFromFolderFullNameRaw, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('' !== sToFolderFullNameRaw)
|
||||||
|
{
|
||||||
|
Cache.setFolderHash(sToFolderFullNameRaw, '');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} oMessageTextBody
|
||||||
|
*/
|
||||||
|
MessageUserStore.prototype.initBlockquoteSwitcher = function (oMessageTextBody)
|
||||||
|
{
|
||||||
|
if (oMessageTextBody)
|
||||||
|
{
|
||||||
|
var $oList = $('blockquote:not(.rl-bq-switcher)', oMessageTextBody).filter(function () {
|
||||||
|
return 0 === $(this).parent().closest('blockquote', oMessageTextBody).length;
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($oList && 0 < $oList.length)
|
||||||
|
{
|
||||||
|
_.delay(function () {
|
||||||
|
$oList.each(function () {
|
||||||
|
var $self = $(this), iH = $self.height();
|
||||||
|
if (0 === iH || 150 < iH)
|
||||||
|
{
|
||||||
|
$self.addClass('rl-bq-switcher hidden-bq');
|
||||||
|
$('<span class="rlBlockquoteSwitcher"><i class="icon-ellipsis" /></span>')
|
||||||
|
.insertBefore($self)
|
||||||
|
.click(function () {
|
||||||
|
$self.toggleClass('hidden-bq');
|
||||||
|
Utils.windowResize();
|
||||||
|
})
|
||||||
|
.after('<br />')
|
||||||
|
.before('<br />')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageUserStore.prototype.setMessage = function (oData, bCached)
|
||||||
|
{
|
||||||
|
var
|
||||||
|
bIsHtml = false,
|
||||||
|
bHasExternals = false,
|
||||||
|
bHasInternals = false,
|
||||||
|
oBody = null,
|
||||||
|
oTextBody = null,
|
||||||
|
sId = '',
|
||||||
|
sResultHtml = '',
|
||||||
|
bPgpSigned = false,
|
||||||
|
bPgpEncrypted = false,
|
||||||
|
oMessagesBodiesDom = this.messagesBodiesDom(),
|
||||||
|
oMessage = this.message()
|
||||||
|
;
|
||||||
|
|
||||||
|
if (oData && oMessage && oData.Result && 'Object/Message' === oData.Result['@Object'] &&
|
||||||
|
oMessage.folderFullNameRaw === oData.Result.Folder && oMessage.uid === oData.Result.Uid)
|
||||||
|
{
|
||||||
|
this.messageError('');
|
||||||
|
|
||||||
|
oMessage.initUpdateByMessageJson(oData.Result);
|
||||||
|
Cache.addRequestedMessage(oMessage.folderFullNameRaw, oMessage.uid);
|
||||||
|
|
||||||
|
if (!bCached)
|
||||||
|
{
|
||||||
|
oMessage.initFlagsByJson(oData.Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
oMessagesBodiesDom = oMessagesBodiesDom && oMessagesBodiesDom[0] ? oMessagesBodiesDom : null;
|
||||||
|
if (oMessagesBodiesDom)
|
||||||
|
{
|
||||||
|
sId = 'rl-mgs-' + oMessage.hash.replace(/[^a-zA-Z0-9]/g, '');
|
||||||
|
oTextBody = oMessagesBodiesDom.find('#' + sId);
|
||||||
|
if (!oTextBody || !oTextBody[0])
|
||||||
|
{
|
||||||
|
bHasExternals = !!oData.Result.HasExternals;
|
||||||
|
bHasInternals = !!oData.Result.HasInternals;
|
||||||
|
|
||||||
|
oBody = $('<div id="' + sId + '" />').hide().addClass('rl-cache-class');
|
||||||
|
oBody.data('rl-cache-count', ++Globals.iMessageBodyCacheCount);
|
||||||
|
|
||||||
|
if (Utils.isNormal(oData.Result.Html) && '' !== oData.Result.Html)
|
||||||
|
{
|
||||||
|
bIsHtml = true;
|
||||||
|
sResultHtml = oData.Result.Html.toString();
|
||||||
|
}
|
||||||
|
else if (Utils.isNormal(oData.Result.Plain) && '' !== oData.Result.Plain)
|
||||||
|
{
|
||||||
|
bIsHtml = false;
|
||||||
|
sResultHtml = Utils.plainToHtml(oData.Result.Plain.toString(), false);
|
||||||
|
|
||||||
|
if ((oMessage.isPgpSigned() || oMessage.isPgpEncrypted()) && require('Stores/User/Pgp').capaOpenPGP())
|
||||||
|
{
|
||||||
|
oMessage.plainRaw = Utils.pString(oData.Result.Plain);
|
||||||
|
|
||||||
|
bPgpEncrypted = /---BEGIN PGP MESSAGE---/.test(oMessage.plainRaw);
|
||||||
|
if (!bPgpEncrypted)
|
||||||
|
{
|
||||||
|
bPgpSigned = /-----BEGIN PGP SIGNED MESSAGE-----/.test(oMessage.plainRaw) &&
|
||||||
|
/-----BEGIN PGP SIGNATURE-----/.test(oMessage.plainRaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
Globals.$div.empty();
|
||||||
|
if (bPgpSigned && oMessage.isPgpSigned())
|
||||||
|
{
|
||||||
|
sResultHtml =
|
||||||
|
Globals.$div.append(
|
||||||
|
$('<pre class="b-plain-openpgp signed"></pre>').text(oMessage.plainRaw)
|
||||||
|
).html()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if (bPgpEncrypted && oMessage.isPgpEncrypted())
|
||||||
|
{
|
||||||
|
sResultHtml =
|
||||||
|
Globals.$div.append(
|
||||||
|
$('<pre class="b-plain-openpgp encrypted"></pre>').text(oMessage.plainRaw)
|
||||||
|
).html()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
Globals.$div.empty();
|
||||||
|
|
||||||
|
oMessage.isPgpSigned(bPgpSigned);
|
||||||
|
oMessage.isPgpEncrypted(bPgpEncrypted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bIsHtml = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
oBody
|
||||||
|
.html(Utils.findEmailAndLinks(sResultHtml))
|
||||||
|
.addClass('b-text-part ' + (bIsHtml ? 'html' : 'plain'))
|
||||||
|
;
|
||||||
|
|
||||||
|
oMessage.isHtml(!!bIsHtml);
|
||||||
|
oMessage.hasImages(!!bHasExternals);
|
||||||
|
oMessage.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.None);
|
||||||
|
oMessage.pgpSignedVerifyUser('');
|
||||||
|
|
||||||
|
oMessage.body = oBody;
|
||||||
|
if (oMessage.body)
|
||||||
|
{
|
||||||
|
oMessagesBodiesDom.append(oMessage.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
oMessage.storeDataToDom();
|
||||||
|
|
||||||
|
if (bHasInternals)
|
||||||
|
{
|
||||||
|
oMessage.showInternalImages(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oMessage.hasImages() && SettingsStore.showImages())
|
||||||
|
{
|
||||||
|
oMessage.showExternalImages(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.purgeMessageBodyCacheThrottle();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oMessage.body = oTextBody;
|
||||||
|
if (oMessage.body)
|
||||||
|
{
|
||||||
|
oMessage.body.data('rl-cache-count', ++Globals.iMessageBodyCacheCount);
|
||||||
|
oMessage.fetchDataToDom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.messageActiveDom(oMessage.body);
|
||||||
|
|
||||||
|
this.hideMessageBodies();
|
||||||
|
oMessage.body.show();
|
||||||
|
|
||||||
|
if (oBody)
|
||||||
|
{
|
||||||
|
this.initBlockquoteSwitcher(oBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cache.initMessageFlagsFromCache(oMessage);
|
||||||
|
if (oMessage.unseen())
|
||||||
|
{
|
||||||
|
require('App/User').setMessageSeen(oMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils.windowResize();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array} aList
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
MessageUserStore.prototype.calculateMessageListHash = function (aList)
|
||||||
|
{
|
||||||
|
return _.map(aList, function (oMessage) {
|
||||||
|
return '' + oMessage.hash + '_' + oMessage.threadsLen() + '_' + oMessage.flagHash();
|
||||||
|
}).join('|');
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageUserStore.prototype.setMessageList = function (oData, bCached)
|
||||||
|
{
|
||||||
|
if (oData && oData.Result && 'Collection/MessageCollection' === oData.Result['@Object'] &&
|
||||||
|
oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection']))
|
||||||
|
{
|
||||||
|
var
|
||||||
|
mLastCollapsedThreadUids = null,
|
||||||
|
iIndex = 0,
|
||||||
|
iLen = 0,
|
||||||
|
iCount = 0,
|
||||||
|
iOffset = 0,
|
||||||
|
aList = [],
|
||||||
|
iUtc = moment().unix(),
|
||||||
|
aStaticList = this.staticMessageList,
|
||||||
|
oJsonMessage = null,
|
||||||
|
oMessage = null,
|
||||||
|
oFolder = null,
|
||||||
|
iNewCount = 0,
|
||||||
|
bUnreadCountChange = false
|
||||||
|
;
|
||||||
|
|
||||||
|
iCount = Utils.pInt(oData.Result.MessageResultCount);
|
||||||
|
iOffset = Utils.pInt(oData.Result.Offset);
|
||||||
|
|
||||||
|
if (Utils.isNonEmptyArray(oData.Result.LastCollapsedThreadUids))
|
||||||
|
{
|
||||||
|
mLastCollapsedThreadUids = oData.Result.LastCollapsedThreadUids;
|
||||||
|
}
|
||||||
|
|
||||||
|
oFolder = Cache.getFolderFromCacheList(
|
||||||
|
Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
|
||||||
|
|
||||||
|
if (oFolder && !bCached)
|
||||||
|
{
|
||||||
|
oFolder.interval = iUtc;
|
||||||
|
|
||||||
|
Cache.setFolderHash(oData.Result.Folder, oData.Result.FolderHash);
|
||||||
|
|
||||||
|
if (Utils.isNormal(oData.Result.MessageCount))
|
||||||
|
{
|
||||||
|
oFolder.messageCountAll(oData.Result.MessageCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Utils.isNormal(oData.Result.MessageUnseenCount))
|
||||||
|
{
|
||||||
|
if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount))
|
||||||
|
{
|
||||||
|
bUnreadCountChange = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
oFolder.messageCountUnread(oData.Result.MessageUnseenCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bUnreadCountChange && oFolder)
|
||||||
|
{
|
||||||
|
Cache.clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (iIndex = 0, iLen = oData.Result['@Collection'].length; iIndex < iLen; iIndex++)
|
||||||
|
{
|
||||||
|
oJsonMessage = oData.Result['@Collection'][iIndex];
|
||||||
|
if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
|
||||||
|
{
|
||||||
|
oMessage = aStaticList[iIndex];
|
||||||
|
if (!oMessage || !oMessage.initByJson(oJsonMessage))
|
||||||
|
{
|
||||||
|
oMessage = MessageModel.newInstanceFromJson(oJsonMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oMessage)
|
||||||
|
{
|
||||||
|
if (Cache.hasNewMessageAndRemoveFromCache(oMessage.folderFullNameRaw, oMessage.uid) && 5 >= iNewCount)
|
||||||
|
{
|
||||||
|
iNewCount++;
|
||||||
|
oMessage.newForAnimation(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
oMessage.deleted(false);
|
||||||
|
|
||||||
|
if (bCached)
|
||||||
|
{
|
||||||
|
Cache.initMessageFlagsFromCache(oMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Cache.storeMessageFlagsToCache(oMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
oMessage.lastInCollapsedThread(mLastCollapsedThreadUids && -1 < Utils.inArray(Utils.pInt(oMessage.uid), mLastCollapsedThreadUids) ? true : false);
|
||||||
|
|
||||||
|
aList.push(oMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.messageListCount(iCount);
|
||||||
|
this.messageListSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
|
||||||
|
this.messageListPage(window.Math.ceil((iOffset / SettingsStore.messagesPerPage()) + 1));
|
||||||
|
|
||||||
|
this.messageListEndFolder(Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
|
||||||
|
this.messageListEndSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
|
||||||
|
this.messageListEndPage(this.messageListPage());
|
||||||
|
|
||||||
|
this.messageList(aList);
|
||||||
|
this.messageListIsNotCompleted(false);
|
||||||
|
|
||||||
|
if (aStaticList.length < aList.length)
|
||||||
|
{
|
||||||
|
this.staticMessageList = aList;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cache.clearNewMessageCache();
|
||||||
|
|
||||||
|
if (oFolder && (bCached || bUnreadCountChange || SettingsStore.useThreads()))
|
||||||
|
{
|
||||||
|
require('App/User').folderInformation(oFolder.fullNameRaw, aList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.messageListCount(0);
|
||||||
|
this.messageList([]);
|
||||||
|
this.messageListError(Translator.getNotification(
|
||||||
|
oData && oData.ErrorCode ? oData.ErrorCode : Enums.Notification.CantGetMessageList
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = new MessageUserStore();
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
|
|
@ -3,7 +3,10 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var
|
var
|
||||||
ko = require('ko')
|
_ = require('_'),
|
||||||
|
ko = require('ko'),
|
||||||
|
|
||||||
|
Utils = require('Common/Utils')
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -35,6 +38,84 @@
|
||||||
return !!this.openpgp;
|
return !!this.openpgp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PgpUserStore.prototype.findPublicKeyByHex = function (sHash)
|
||||||
|
{
|
||||||
|
return _.find(this.openpgpkeysPublic(), function (oItem) {
|
||||||
|
return oItem && sHash === oItem.id;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
PgpUserStore.prototype.findPublicKeysByEmail = function (sEmail)
|
||||||
|
{
|
||||||
|
var self = this;
|
||||||
|
return _.compact(_.map(this.openpgpkeysPublic(), function (oItem) {
|
||||||
|
|
||||||
|
var oKey = null;
|
||||||
|
if (oItem && sEmail === oItem.email)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
oKey = self.openpgp.key.readArmored(oItem.armor);
|
||||||
|
if (oKey && !oKey.err && oKey.keys && oKey.keys[0])
|
||||||
|
{
|
||||||
|
return oKey.keys[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} sEmail
|
||||||
|
* @param {string=} sPassword
|
||||||
|
* @returns {?}
|
||||||
|
*/
|
||||||
|
PgpUserStore.prototype.findPrivateKeyByEmail = function (sEmail, sPassword)
|
||||||
|
{
|
||||||
|
var
|
||||||
|
oPrivateKey = null,
|
||||||
|
oKey = _.find(this.openpgpkeysPrivate(), function (oItem) {
|
||||||
|
return oItem && sEmail === oItem.email;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
|
||||||
|
if (oKey)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
oPrivateKey = this.openpgp.key.readArmored(oKey.armor);
|
||||||
|
if (oPrivateKey && !oPrivateKey.err && oPrivateKey.keys && oPrivateKey.keys[0])
|
||||||
|
{
|
||||||
|
oPrivateKey = oPrivateKey.keys[0];
|
||||||
|
oPrivateKey.decrypt(Utils.pString(sPassword));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oPrivateKey = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
oPrivateKey = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return oPrivateKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string=} sPassword
|
||||||
|
* @returns {?}
|
||||||
|
*/
|
||||||
|
PgpUserStore.prototype.findSelfPrivateKey = function (sPassword)
|
||||||
|
{
|
||||||
|
return this.findPrivateKeyByEmail(require('Stores/User/Account').email(), sPassword);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = new PgpUserStore();
|
module.exports = new PgpUserStore();
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,9 @@
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-color: #eee;
|
border-color: #eee;
|
||||||
|
|
||||||
|
font-size: 28px;
|
||||||
|
line-height: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn.disabled {
|
.btn.disabled {
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ html.ssm-state-tablet, html.ssm-state-mobile {
|
||||||
}
|
}
|
||||||
|
|
||||||
.b-compose.modal {
|
.b-compose.modal {
|
||||||
width: 700px;
|
width: 720px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.b-contacts-content.modal {
|
.b-contacts-content.modal {
|
||||||
|
|
@ -156,7 +156,7 @@ html.ssm-state-tablet, html.ssm-state-mobile {
|
||||||
html.ssm-state-tablet {
|
html.ssm-state-tablet {
|
||||||
|
|
||||||
.b-compose.modal {
|
.b-compose.modal {
|
||||||
width: 700px;
|
width: 720px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.b-contacts-content.modal {
|
.b-contacts-content.modal {
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,8 @@
|
||||||
|
|
||||||
blockquote p {
|
blockquote p {
|
||||||
margin: 0 0 10px;
|
margin: 0 0 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
Utils = require('Common/Utils'),
|
Utils = require('Common/Utils'),
|
||||||
|
|
||||||
Data = require('Storage/User/Data'),
|
MessageStore = require('Stores/User/Message'),
|
||||||
|
|
||||||
kn = require('Knoin/Knoin'),
|
kn = require('Knoin/Knoin'),
|
||||||
AbstractView = require('Knoin/AbstractView')
|
AbstractView = require('Knoin/AbstractView')
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
var sSearch = this.buildSearchString();
|
var sSearch = this.buildSearchString();
|
||||||
if ('' !== sSearch)
|
if ('' !== sSearch)
|
||||||
{
|
{
|
||||||
Data.mainMessageListSearch(sSearch);
|
MessageStore.mainMessageListSearch(sSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cancelCommand();
|
this.cancelCommand();
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,10 @@
|
||||||
AccountStore = require('Stores/User/Account'),
|
AccountStore = require('Stores/User/Account'),
|
||||||
FolderStore = require('Stores/User/Folder'),
|
FolderStore = require('Stores/User/Folder'),
|
||||||
PgpStore = require('Stores/User/Pgp'),
|
PgpStore = require('Stores/User/Pgp'),
|
||||||
|
MessageStore = require('Stores/User/Message'),
|
||||||
SocialStore = require('Stores/Social'),
|
SocialStore = require('Stores/Social'),
|
||||||
|
|
||||||
Settings = require('Storage/Settings'),
|
Settings = require('Storage/Settings'),
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
Cache = require('Storage/User/Cache'),
|
Cache = require('Storage/User/Cache'),
|
||||||
Remote = require('Storage/User/Remote'),
|
Remote = require('Storage/User/Remote'),
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@
|
||||||
this.allowContacts = !!AppStore.contactsIsAllowed();
|
this.allowContacts = !!AppStore.contactsIsAllowed();
|
||||||
|
|
||||||
this.bSkipNextHide = false;
|
this.bSkipNextHide = false;
|
||||||
this.composeInEdit = Data.composeInEdit;
|
this.composeInEdit = AppStore.composeInEdit;
|
||||||
this.editorDefaultType = SettingsStore.editorDefaultType;
|
this.editorDefaultType = SettingsStore.editorDefaultType;
|
||||||
|
|
||||||
this.capaOpenPGP = PgpStore.capaOpenPGP;
|
this.capaOpenPGP = PgpStore.capaOpenPGP;
|
||||||
|
|
@ -433,8 +433,6 @@
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
window.console.log(this.sLastFocusedField);
|
|
||||||
|
|
||||||
_.delay(function () {
|
_.delay(function () {
|
||||||
kn.showScreenPopup(require('View/Popup/Contacts'),
|
kn.showScreenPopup(require('View/Popup/Contacts'),
|
||||||
[true, self.sLastFocusedField]);
|
[true, self.sLastFocusedField]);
|
||||||
|
|
@ -578,7 +576,7 @@
|
||||||
if ('' !== sDraftFolder)
|
if ('' !== sDraftFolder)
|
||||||
{
|
{
|
||||||
Cache.setFolderHash(sDraftFolder, '');
|
Cache.setFolderHash(sDraftFolder, '');
|
||||||
if (Data.currentFolderFullNameRaw() === sDraftFolder)
|
if (FolderStore.currentFolderFullNameRaw() === sDraftFolder)
|
||||||
{
|
{
|
||||||
require('App/User').reloadMessageList(true);
|
require('App/User').reloadMessageList(true);
|
||||||
}
|
}
|
||||||
|
|
@ -701,10 +699,10 @@
|
||||||
|
|
||||||
if (this.bFromDraft)
|
if (this.bFromDraft)
|
||||||
{
|
{
|
||||||
oMessage = Data.message();
|
oMessage = MessageStore.message();
|
||||||
if (oMessage && this.draftFolder() === oMessage.folderFullNameRaw && this.draftUid() === oMessage.uid)
|
if (oMessage && this.draftFolder() === oMessage.folderFullNameRaw && this.draftUid() === oMessage.uid)
|
||||||
{
|
{
|
||||||
Data.message(null);
|
MessageStore.message(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -741,7 +739,7 @@
|
||||||
|
|
||||||
if (!this.bSkipNextHide)
|
if (!this.bSkipNextHide)
|
||||||
{
|
{
|
||||||
this.composeInEdit(false);
|
AppStore.composeInEdit(false);
|
||||||
this.reset();
|
this.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -883,7 +881,7 @@
|
||||||
|
|
||||||
this.autosaveStart();
|
this.autosaveStart();
|
||||||
|
|
||||||
if (this.composeInEdit())
|
if (AppStore.composeInEdit())
|
||||||
{
|
{
|
||||||
sType = sType || Enums.ComposeType.Empty;
|
sType = sType || Enums.ComposeType.Empty;
|
||||||
|
|
||||||
|
|
@ -969,7 +967,7 @@
|
||||||
ComposePopupView.prototype.initOnShow = function (sType, oMessageOrArray,
|
ComposePopupView.prototype.initOnShow = function (sType, oMessageOrArray,
|
||||||
aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText)
|
aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText)
|
||||||
{
|
{
|
||||||
this.composeInEdit(true);
|
AppStore.composeInEdit(true);
|
||||||
|
|
||||||
var
|
var
|
||||||
self = this,
|
self = this,
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
Enums = require('Common/Enums'),
|
Enums = require('Common/Enums'),
|
||||||
Translator = require('Common/Translator'),
|
Translator = require('Common/Translator'),
|
||||||
|
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
PgpStore = require('Stores/User/Pgp'),
|
PgpStore = require('Stores/User/Pgp'),
|
||||||
|
|
||||||
EmailModel = require('Model/Email'),
|
EmailModel = require('Model/Email'),
|
||||||
|
|
@ -66,7 +65,7 @@
|
||||||
|
|
||||||
if (bResult && this.sign())
|
if (bResult && this.sign())
|
||||||
{
|
{
|
||||||
oPrivateKey = Data.findPrivateKeyByEmail(this.from(), this.password());
|
oPrivateKey = PgpStore.findPrivateKeyByEmail(this.from(), this.password());
|
||||||
if (!oPrivateKey)
|
if (!oPrivateKey)
|
||||||
{
|
{
|
||||||
this.notification(Translator.i18n('PGP_NOTIFICATIONS/NO_PRIVATE_KEY_FOUND_FOR', {
|
this.notification(Translator.i18n('PGP_NOTIFICATIONS/NO_PRIVATE_KEY_FOUND_FOR', {
|
||||||
|
|
@ -87,7 +86,7 @@
|
||||||
{
|
{
|
||||||
aPublicKeys = [];
|
aPublicKeys = [];
|
||||||
_.each(this.to(), function (sEmail) {
|
_.each(this.to(), function (sEmail) {
|
||||||
var aKeys = Data.findPublicKeysByEmail(sEmail);
|
var aKeys = PgpStore.findPublicKeysByEmail(sEmail);
|
||||||
if (0 === aKeys.length && bResult)
|
if (0 === aKeys.length && bResult)
|
||||||
{
|
{
|
||||||
self.notification(Translator.i18n('PGP_NOTIFICATIONS/NO_PUBLIC_KEYS_FOUND_FOR', {
|
self.notification(Translator.i18n('PGP_NOTIFICATIONS/NO_PUBLIC_KEYS_FOUND_FOR', {
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@
|
||||||
Translator = require('Common/Translator'),
|
Translator = require('Common/Translator'),
|
||||||
|
|
||||||
SettingsStore = require('Stores/User/Settings'),
|
SettingsStore = require('Stores/User/Settings'),
|
||||||
|
ContactStore = require('Stores/User/Contact'),
|
||||||
|
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
Remote = require('Storage/User/Remote'),
|
Remote = require('Storage/User/Remote'),
|
||||||
|
|
||||||
EmailModel = require('Model/Email'),
|
EmailModel = require('Model/Email'),
|
||||||
|
|
@ -52,13 +52,13 @@
|
||||||
this.bBackToCompose = false;
|
this.bBackToCompose = false;
|
||||||
this.sLastComposeFocusedField = '';
|
this.sLastComposeFocusedField = '';
|
||||||
|
|
||||||
this.allowContactsSync = Data.allowContactsSync;
|
this.allowContactsSync = ContactStore.allowContactsSync;
|
||||||
this.enableContactsSync = Data.enableContactsSync;
|
this.enableContactsSync = ContactStore.enableContactsSync;
|
||||||
this.allowExport = !Globals.bMobileDevice;
|
this.allowExport = !Globals.bMobileDevice;
|
||||||
|
|
||||||
this.search = ko.observable('');
|
this.search = ko.observable('');
|
||||||
this.contactsCount = ko.observable(0);
|
this.contactsCount = ko.observable(0);
|
||||||
this.contacts = Data.contacts;
|
this.contacts = ContactStore.contacts;
|
||||||
|
|
||||||
this.currentContact = ko.observable(null);
|
this.currentContact = ko.observable(null);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,8 @@
|
||||||
Utils = require('Common/Utils'),
|
Utils = require('Common/Utils'),
|
||||||
Translator = require('Common/Translator'),
|
Translator = require('Common/Translator'),
|
||||||
|
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
|
|
||||||
FilterStore = require('Stores/User/Filter'),
|
FilterStore = require('Stores/User/Filter'),
|
||||||
|
FolderStore = require('Stores/User/Folder'),
|
||||||
|
|
||||||
kn = require('Knoin/Knoin'),
|
kn = require('Knoin/Knoin'),
|
||||||
AbstractView = require('Knoin/AbstractView')
|
AbstractView = require('Knoin/AbstractView')
|
||||||
|
|
@ -38,7 +37,7 @@
|
||||||
this.allowMarkAsRead = ko.observable(false);
|
this.allowMarkAsRead = ko.observable(false);
|
||||||
|
|
||||||
this.defautOptionsAfterRender = Utils.defautOptionsAfterRender;
|
this.defautOptionsAfterRender = Utils.defautOptionsAfterRender;
|
||||||
this.folderSelectList = Data.folderMenuForFilters;
|
this.folderSelectList = FolderStore.folderMenuForFilters;
|
||||||
this.selectedFolderValue = ko.observable('');
|
this.selectedFolderValue = ko.observable('');
|
||||||
|
|
||||||
this.selectedFolderValue.subscribe(function() {
|
this.selectedFolderValue.subscribe(function() {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@
|
||||||
Utils = require('Common/Utils'),
|
Utils = require('Common/Utils'),
|
||||||
Translator = require('Common/Translator'),
|
Translator = require('Common/Translator'),
|
||||||
|
|
||||||
Data = require('Storage/User/Data'),
|
MessageStore = require('Stores/User/Message'),
|
||||||
|
|
||||||
Cache = require('Storage/User/Cache'),
|
Cache = require('Storage/User/Cache'),
|
||||||
Remote = require('Storage/User/Remote'),
|
Remote = require('Storage/User/Remote'),
|
||||||
|
|
||||||
|
|
@ -56,8 +57,8 @@
|
||||||
|
|
||||||
if (oFolderToClear)
|
if (oFolderToClear)
|
||||||
{
|
{
|
||||||
Data.message(null);
|
MessageStore.message(null);
|
||||||
Data.messageList([]);
|
MessageStore.messageList([]);
|
||||||
|
|
||||||
this.clearingProcess(true);
|
this.clearingProcess(true);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@
|
||||||
Utils = require('Common/Utils'),
|
Utils = require('Common/Utils'),
|
||||||
Translator = require('Common/Translator'),
|
Translator = require('Common/Translator'),
|
||||||
|
|
||||||
Data = require('Storage/User/Data'),
|
FolderStore = require('Stores/User/Folder'),
|
||||||
|
|
||||||
Remote = require('Storage/User/Remote'),
|
Remote = require('Storage/User/Remote'),
|
||||||
|
|
||||||
kn = require('Knoin/Knoin'),
|
kn = require('Knoin/Knoin'),
|
||||||
|
|
@ -43,7 +44,7 @@
|
||||||
aTop = [],
|
aTop = [],
|
||||||
fDisableCallback = null,
|
fDisableCallback = null,
|
||||||
fVisibleCallback = null,
|
fVisibleCallback = null,
|
||||||
aList = Data.folderList(),
|
aList = FolderStore.folderList(),
|
||||||
fRenameCallback = function (oItem) {
|
fRenameCallback = function (oItem) {
|
||||||
return oItem ? (oItem.isSystemFolder() ? oItem.name() + ' ' + oItem.manageFolderSystemName() : oItem.name()) : '';
|
return oItem ? (oItem.isSystemFolder() ? oItem.name() + ' ' + oItem.manageFolderSystemName() : oItem.name()) : '';
|
||||||
}
|
}
|
||||||
|
|
@ -51,11 +52,11 @@
|
||||||
|
|
||||||
aTop.push(['', this.sNoParentText]);
|
aTop.push(['', this.sNoParentText]);
|
||||||
|
|
||||||
if ('' !== Data.namespace)
|
if ('' !== FolderStore.namespace)
|
||||||
{
|
{
|
||||||
fDisableCallback = function (oItem)
|
fDisableCallback = function (oItem)
|
||||||
{
|
{
|
||||||
return Data.namespace !== oItem.fullNameRaw.substr(0, Data.namespace.length);
|
return FolderStore.namespace !== oItem.fullNameRaw.substr(0, FolderStore.namespace.length);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,22 +71,22 @@
|
||||||
sParentFolderName = this.selectedParentValue()
|
sParentFolderName = this.selectedParentValue()
|
||||||
;
|
;
|
||||||
|
|
||||||
if ('' === sParentFolderName && 1 < Data.namespace.length)
|
if ('' === sParentFolderName && 1 < FolderStore.namespace.length)
|
||||||
{
|
{
|
||||||
sParentFolderName = Data.namespace.substr(0, Data.namespace.length - 1);
|
sParentFolderName = FolderStore.namespace.substr(0, FolderStore.namespace.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Data.foldersCreating(true);
|
FolderStore.foldersCreating(true);
|
||||||
Remote.folderCreate(function (sResult, oData) {
|
Remote.folderCreate(function (sResult, oData) {
|
||||||
|
|
||||||
Data.foldersCreating(false);
|
FolderStore.foldersCreating(false);
|
||||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
||||||
{
|
{
|
||||||
require('App/User').folders();
|
require('App/User').folders();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Data.folderList.error(
|
FolderStore.folderList.error(
|
||||||
oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_CREATE_FOLDER'));
|
oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_CREATE_FOLDER'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
FolderStore = require('Stores/User/Folder'),
|
FolderStore = require('Stores/User/Folder'),
|
||||||
|
|
||||||
Settings = require('Storage/Settings'),
|
Settings = require('Storage/Settings'),
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
Remote = require('Storage/User/Remote'),
|
Remote = require('Storage/User/Remote'),
|
||||||
|
|
||||||
kn = require('Knoin/Knoin'),
|
kn = require('Knoin/Knoin'),
|
||||||
|
|
@ -38,7 +37,7 @@
|
||||||
this.notification = ko.observable('');
|
this.notification = ko.observable('');
|
||||||
|
|
||||||
this.folderSelectList = ko.computed(function () {
|
this.folderSelectList = ko.computed(function () {
|
||||||
return Utils.folderListOptionsBuilder([], Data.folderList(), Data.folderListSystemNames(), [
|
return Utils.folderListOptionsBuilder([], FolderStore.folderList(), FolderStore.folderListSystemNames(), [
|
||||||
['', this.sChooseOnText],
|
['', this.sChooseOnText],
|
||||||
[Consts.Values.UnuseOptionValue, this.sUnuseText]
|
[Consts.Values.UnuseOptionValue, this.sUnuseText]
|
||||||
], null, null, null, null, null, true);
|
], null, null, null, null, null, true);
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,10 @@
|
||||||
|
|
||||||
AppStore = require('Stores/User/App'),
|
AppStore = require('Stores/User/App'),
|
||||||
SettingsStore = require('Stores/User/Settings'),
|
SettingsStore = require('Stores/User/Settings'),
|
||||||
|
FolderStore = require('Stores/User/Folder'),
|
||||||
|
MessageStore = require('Stores/User/Message'),
|
||||||
|
|
||||||
Cache = require('Storage/User/Cache'),
|
Cache = require('Storage/User/Cache'),
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
|
|
||||||
kn = require('Knoin/Knoin'),
|
kn = require('Knoin/Knoin'),
|
||||||
AbstractView = require('Knoin/AbstractView')
|
AbstractView = require('Knoin/AbstractView')
|
||||||
|
|
@ -36,14 +37,14 @@
|
||||||
this.oContentVisible = null;
|
this.oContentVisible = null;
|
||||||
this.oContentScrollable = null;
|
this.oContentScrollable = null;
|
||||||
|
|
||||||
this.composeInEdit = Data.composeInEdit;
|
this.composeInEdit = AppStore.composeInEdit;
|
||||||
|
|
||||||
this.messageList = Data.messageList;
|
this.messageList = MessageStore.messageList;
|
||||||
this.folderList = Data.folderList;
|
this.folderList = FolderStore.folderList;
|
||||||
this.folderListSystem = Data.folderListSystem;
|
this.folderListSystem = FolderStore.folderListSystem;
|
||||||
this.foldersChanging = Data.foldersChanging;
|
this.foldersChanging = FolderStore.foldersChanging;
|
||||||
|
|
||||||
this.foldersListWithSingleInboxRootFolder = Data.foldersListWithSingleInboxRootFolder;
|
this.foldersListWithSingleInboxRootFolder = FolderStore.foldersListWithSingleInboxRootFolder;
|
||||||
|
|
||||||
this.leftPanelDisabled = Globals.leftPanelDisabled;
|
this.leftPanelDisabled = Globals.leftPanelDisabled;
|
||||||
|
|
||||||
|
|
@ -94,10 +95,10 @@
|
||||||
{
|
{
|
||||||
if (Enums.Layout.NoPreview === SettingsStore.layout())
|
if (Enums.Layout.NoPreview === SettingsStore.layout())
|
||||||
{
|
{
|
||||||
Data.message(null);
|
MessageStore.message(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw())
|
if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw())
|
||||||
{
|
{
|
||||||
Cache.setFolderHash(oFolder.fullNameRaw, '');
|
Cache.setFolderHash(oFolder.fullNameRaw, '');
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +144,7 @@
|
||||||
var $items = $('.b-folders .e-item .e-link:not(.hidden).focused', oDom);
|
var $items = $('.b-folders .e-item .e-link:not(.hidden).focused', oDom);
|
||||||
if ($items.length && $items[0])
|
if ($items.length && $items[0])
|
||||||
{
|
{
|
||||||
self.folderList.focused(false);
|
FolderStore.folderList.focused(false);
|
||||||
$items.click();
|
$items.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,11 +168,11 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
key('esc, tab, shift+tab, right', Enums.KeyState.FolderList, function () {
|
key('esc, tab, shift+tab, right', Enums.KeyState.FolderList, function () {
|
||||||
self.folderList.focused(false);
|
FolderStore.folderList.focused(false);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
self.folderList.focused.subscribe(function (bValue) {
|
FolderStore.folderList.focused.subscribe(function (bValue) {
|
||||||
$('.b-folders .e-item .e-link.focused', oDom).removeClass('focused');
|
$('.b-folders .e-item .e-link.focused', oDom).removeClass('focused');
|
||||||
if (bValue)
|
if (bValue)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,10 @@
|
||||||
QuotaStore = require('Stores/User/Quota'),
|
QuotaStore = require('Stores/User/Quota'),
|
||||||
SettingsStore = require('Stores/User/Settings'),
|
SettingsStore = require('Stores/User/Settings'),
|
||||||
FolderStore = require('Stores/User/Folder'),
|
FolderStore = require('Stores/User/Folder'),
|
||||||
|
MessageStore = require('Stores/User/Message'),
|
||||||
|
|
||||||
Settings = require('Storage/Settings'),
|
Settings = require('Storage/Settings'),
|
||||||
Cache = require('Storage/User/Cache'),
|
Cache = require('Storage/User/Cache'),
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
Remote = require('Storage/User/Remote'),
|
Remote = require('Storage/User/Remote'),
|
||||||
|
|
||||||
kn = require('Knoin/Knoin'),
|
kn = require('Knoin/Knoin'),
|
||||||
|
|
@ -49,24 +49,24 @@
|
||||||
|
|
||||||
this.popupVisibility = Globals.popupVisibility;
|
this.popupVisibility = Globals.popupVisibility;
|
||||||
|
|
||||||
this.message = Data.message;
|
this.message = MessageStore.message;
|
||||||
this.messageList = Data.messageList;
|
this.messageList = MessageStore.messageList;
|
||||||
this.folderList = Data.folderList;
|
this.folderList = FolderStore.folderList;
|
||||||
this.currentMessage = Data.currentMessage;
|
this.currentMessage = MessageStore.currentMessage;
|
||||||
this.isMessageSelected = Data.isMessageSelected;
|
this.isMessageSelected = MessageStore.isMessageSelected;
|
||||||
this.messageListSearch = Data.messageListSearch;
|
this.messageListSearch = MessageStore.messageListSearch;
|
||||||
this.messageListError = Data.messageListError;
|
this.messageListError = MessageStore.messageListError;
|
||||||
this.folderMenuForMove = Data.folderMenuForMove;
|
this.folderMenuForMove = FolderStore.folderMenuForMove;
|
||||||
|
|
||||||
this.useCheckboxesInList = SettingsStore.useCheckboxesInList;
|
this.useCheckboxesInList = SettingsStore.useCheckboxesInList;
|
||||||
|
|
||||||
this.mainMessageListSearch = Data.mainMessageListSearch;
|
this.mainMessageListSearch = MessageStore.mainMessageListSearch;
|
||||||
this.messageListEndFolder = Data.messageListEndFolder;
|
this.messageListEndFolder = MessageStore.messageListEndFolder;
|
||||||
|
|
||||||
this.messageListChecked = Data.messageListChecked;
|
this.messageListChecked = MessageStore.messageListChecked;
|
||||||
this.messageListCheckedOrSelected = Data.messageListCheckedOrSelected;
|
this.messageListCheckedOrSelected = MessageStore.messageListCheckedOrSelected;
|
||||||
this.messageListCheckedOrSelectedUidsWithSubMails = Data.messageListCheckedOrSelectedUidsWithSubMails;
|
this.messageListCheckedOrSelectedUidsWithSubMails = MessageStore.messageListCheckedOrSelectedUidsWithSubMails;
|
||||||
this.messageListCompleteLoadingThrottle = Data.messageListCompleteLoadingThrottle;
|
this.messageListCompleteLoadingThrottle = MessageStore.messageListCompleteLoadingThrottle;
|
||||||
|
|
||||||
Translator.initOnStartOrLangChange(function () {
|
Translator.initOnStartOrLangChange(function () {
|
||||||
this.emptySubjectValue = Translator.i18n('MESSAGE_LIST/EMPTY_SUBJECT_TEXT');
|
this.emptySubjectValue = Translator.i18n('MESSAGE_LIST/EMPTY_SUBJECT_TEXT');
|
||||||
|
|
@ -91,20 +91,21 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
this.messageListSearchDesc = ko.computed(function () {
|
this.messageListSearchDesc = ko.computed(function () {
|
||||||
var sValue = Data.messageListEndSearch();
|
var sValue = MessageStore.messageListEndSearch();
|
||||||
return '' === sValue ? '' : Translator.i18n('MESSAGE_LIST/SEARCH_RESULT_FOR', {'SEARCH': sValue});
|
return '' === sValue ? '' : Translator.i18n('MESSAGE_LIST/SEARCH_RESULT_FOR', {'SEARCH': sValue});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.messageListPagenator = ko.computed(Utils.computedPagenatorHelper(Data.messageListPage, Data.messageListPageCount));
|
this.messageListPagenator = ko.computed(Utils.computedPagenatorHelper(
|
||||||
|
MessageStore.messageListPage, MessageStore.messageListPageCount));
|
||||||
|
|
||||||
this.checkAll = ko.computed({
|
this.checkAll = ko.computed({
|
||||||
'read': function () {
|
'read': function () {
|
||||||
return 0 < Data.messageListChecked().length;
|
return 0 < MessageStore.messageListChecked().length;
|
||||||
},
|
},
|
||||||
|
|
||||||
'write': function (bValue) {
|
'write': function (bValue) {
|
||||||
bValue = !!bValue;
|
bValue = !!bValue;
|
||||||
_.each(Data.messageList(), function (oMessage) {
|
_.each(MessageStore.messageList(), function (oMessage) {
|
||||||
oMessage.checked(bValue);
|
oMessage.checked(bValue);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -123,8 +124,8 @@
|
||||||
|
|
||||||
this.isIncompleteChecked = ko.computed(function () {
|
this.isIncompleteChecked = ko.computed(function () {
|
||||||
var
|
var
|
||||||
iM = Data.messageList().length,
|
iM = MessageStore.messageList().length,
|
||||||
iC = Data.messageListChecked().length
|
iC = MessageStore.messageListChecked().length
|
||||||
;
|
;
|
||||||
return 0 < iM && 0 < iC && iM > iC;
|
return 0 < iM && 0 < iC && iM > iC;
|
||||||
}, this);
|
}, this);
|
||||||
|
|
@ -173,48 +174,48 @@
|
||||||
this.canBeMoved = this.hasCheckedOrSelectedLines;
|
this.canBeMoved = this.hasCheckedOrSelectedLines;
|
||||||
|
|
||||||
this.clearCommand = Utils.createCommand(this, function () {
|
this.clearCommand = Utils.createCommand(this, function () {
|
||||||
kn.showScreenPopup(require('View/Popup/FolderClear'), [Data.currentFolder()]);
|
kn.showScreenPopup(require('View/Popup/FolderClear'), [FolderStore.currentFolder()]);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.multyForwardCommand = Utils.createCommand(this, function () {
|
this.multyForwardCommand = Utils.createCommand(this, function () {
|
||||||
kn.showScreenPopup(require('View/Popup/Compose'), [
|
kn.showScreenPopup(require('View/Popup/Compose'), [
|
||||||
Enums.ComposeType.ForwardAsAttachment, Data.messageListCheckedOrSelected()]);
|
Enums.ComposeType.ForwardAsAttachment, MessageStore.messageListCheckedOrSelected()]);
|
||||||
}, this.canBeMoved);
|
}, this.canBeMoved);
|
||||||
|
|
||||||
this.deleteWithoutMoveCommand = Utils.createCommand(this, function () {
|
this.deleteWithoutMoveCommand = Utils.createCommand(this, function () {
|
||||||
require('App/User').deleteMessagesFromFolder(Enums.FolderType.Trash,
|
require('App/User').deleteMessagesFromFolder(Enums.FolderType.Trash,
|
||||||
Data.currentFolderFullNameRaw(),
|
FolderStore.currentFolderFullNameRaw(),
|
||||||
Data.messageListCheckedOrSelectedUidsWithSubMails(), false);
|
MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), false);
|
||||||
}, this.canBeMoved);
|
}, this.canBeMoved);
|
||||||
|
|
||||||
this.deleteCommand = Utils.createCommand(this, function () {
|
this.deleteCommand = Utils.createCommand(this, function () {
|
||||||
require('App/User').deleteMessagesFromFolder(Enums.FolderType.Trash,
|
require('App/User').deleteMessagesFromFolder(Enums.FolderType.Trash,
|
||||||
Data.currentFolderFullNameRaw(),
|
FolderStore.currentFolderFullNameRaw(),
|
||||||
Data.messageListCheckedOrSelectedUidsWithSubMails(), true);
|
MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true);
|
||||||
}, this.canBeMoved);
|
}, this.canBeMoved);
|
||||||
|
|
||||||
this.archiveCommand = Utils.createCommand(this, function () {
|
this.archiveCommand = Utils.createCommand(this, function () {
|
||||||
require('App/User').deleteMessagesFromFolder(Enums.FolderType.Archive,
|
require('App/User').deleteMessagesFromFolder(Enums.FolderType.Archive,
|
||||||
Data.currentFolderFullNameRaw(),
|
FolderStore.currentFolderFullNameRaw(),
|
||||||
Data.messageListCheckedOrSelectedUidsWithSubMails(), true);
|
MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true);
|
||||||
}, this.canBeMoved);
|
}, this.canBeMoved);
|
||||||
|
|
||||||
this.spamCommand = Utils.createCommand(this, function () {
|
this.spamCommand = Utils.createCommand(this, function () {
|
||||||
require('App/User').deleteMessagesFromFolder(Enums.FolderType.Spam,
|
require('App/User').deleteMessagesFromFolder(Enums.FolderType.Spam,
|
||||||
Data.currentFolderFullNameRaw(),
|
FolderStore.currentFolderFullNameRaw(),
|
||||||
Data.messageListCheckedOrSelectedUidsWithSubMails(), true);
|
MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true);
|
||||||
}, this.canBeMoved);
|
}, this.canBeMoved);
|
||||||
|
|
||||||
this.notSpamCommand = Utils.createCommand(this, function () {
|
this.notSpamCommand = Utils.createCommand(this, function () {
|
||||||
require('App/User').deleteMessagesFromFolder(Enums.FolderType.NotSpam,
|
require('App/User').deleteMessagesFromFolder(Enums.FolderType.NotSpam,
|
||||||
Data.currentFolderFullNameRaw(),
|
FolderStore.currentFolderFullNameRaw(),
|
||||||
Data.messageListCheckedOrSelectedUidsWithSubMails(), true);
|
MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true);
|
||||||
}, this.canBeMoved);
|
}, this.canBeMoved);
|
||||||
|
|
||||||
this.moveCommand = Utils.createCommand(this, Utils.emptyFunction, this.canBeMoved);
|
this.moveCommand = Utils.createCommand(this, Utils.emptyFunction, this.canBeMoved);
|
||||||
|
|
||||||
this.reloadCommand = Utils.createCommand(this, function () {
|
this.reloadCommand = Utils.createCommand(this, function () {
|
||||||
if (!Data.messageListCompleteLoadingThrottle())
|
if (!MessageStore.messageListCompleteLoadingThrottle())
|
||||||
{
|
{
|
||||||
require('App/User').reloadMessageList(false, true);
|
require('App/User').reloadMessageList(false, true);
|
||||||
}
|
}
|
||||||
|
|
@ -229,18 +230,19 @@
|
||||||
this.selector.on('onItemSelect', _.bind(function (oMessage) {
|
this.selector.on('onItemSelect', _.bind(function (oMessage) {
|
||||||
if (oMessage)
|
if (oMessage)
|
||||||
{
|
{
|
||||||
Data.message(Data.staticMessageList.populateByMessageListItem(oMessage));
|
MessageStore.message(MessageStore.staticMessage.populateByMessageListItem(oMessage));
|
||||||
this.populateMessageBody(Data.message());
|
|
||||||
|
this.populateMessageBody(MessageStore.message());
|
||||||
|
|
||||||
if (Enums.Layout.NoPreview === SettingsStore.layout())
|
if (Enums.Layout.NoPreview === SettingsStore.layout())
|
||||||
{
|
{
|
||||||
kn.setHash(Links.messagePreview(), true);
|
kn.setHash(Links.messagePreview(), true);
|
||||||
Data.message.focused(true);
|
MessageStore.message.focused(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Data.message(null);
|
MessageStore.message(null);
|
||||||
}
|
}
|
||||||
}, this));
|
}, this));
|
||||||
|
|
||||||
|
|
@ -248,23 +250,14 @@
|
||||||
return oMessage ? oMessage.generateUid() : '';
|
return oMessage ? oMessage.generateUid() : '';
|
||||||
});
|
});
|
||||||
|
|
||||||
Data.messageListEndHash.subscribe(function () {
|
MessageStore.messageListEndHash.subscribe(function () {
|
||||||
this.selector.scrollToTop();
|
this.selector.scrollToTop();
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
Data.messageListEndFolder.subscribe(function (sFolder) {
|
|
||||||
var oMessage = Data.message();
|
|
||||||
if (oMessage && sFolder && sFolder !== oMessage.folderFullNameRaw)
|
|
||||||
{
|
|
||||||
Data.message(null);
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
SettingsStore.layout.subscribe(function (mValue) {
|
SettingsStore.layout.subscribe(function (mValue) {
|
||||||
this.selector.autoSelect(Enums.Layout.NoPreview !== mValue);
|
this.selector.autoSelect(Enums.Layout.NoPreview !== mValue);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
|
||||||
SettingsStore.layout.valueHasMutated();
|
SettingsStore.layout.valueHasMutated();
|
||||||
|
|
||||||
Events
|
Events
|
||||||
|
|
@ -318,8 +311,8 @@
|
||||||
if (this.canBeMoved())
|
if (this.canBeMoved())
|
||||||
{
|
{
|
||||||
require('App/User').moveMessagesToFolder(
|
require('App/User').moveMessagesToFolder(
|
||||||
Data.currentFolderFullNameRaw(),
|
FolderStore.currentFolderFullNameRaw(),
|
||||||
Data.messageListCheckedOrSelectedUidsWithSubMails(), sToFolderFullNameRaw, bCopy);
|
MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), sToFolderFullNameRaw, bCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -334,15 +327,15 @@
|
||||||
|
|
||||||
var
|
var
|
||||||
oEl = Utils.draggablePlace(),
|
oEl = Utils.draggablePlace(),
|
||||||
aUids = Data.messageListCheckedOrSelectedUidsWithSubMails()
|
aUids = MessageStore.messageListCheckedOrSelectedUidsWithSubMails()
|
||||||
;
|
;
|
||||||
|
|
||||||
oEl.data('rl-folder', Data.currentFolderFullNameRaw());
|
oEl.data('rl-folder', FolderStore.currentFolderFullNameRaw());
|
||||||
oEl.data('rl-uids', aUids);
|
oEl.data('rl-uids', aUids);
|
||||||
oEl.find('.text').text('' + aUids.length);
|
oEl.find('.text').text('' + aUids.length);
|
||||||
|
|
||||||
_.defer(function () {
|
_.defer(function () {
|
||||||
var aUids = Data.messageListCheckedOrSelectedUidsWithSubMails();
|
var aUids = MessageStore.messageListCheckedOrSelectedUidsWithSubMails();
|
||||||
|
|
||||||
oEl.data('rl-uids', aUids);
|
oEl.data('rl-uids', aUids);
|
||||||
oEl.find('.text').text('' + aUids.length);
|
oEl.find('.text').text('' + aUids.length);
|
||||||
|
|
@ -358,22 +351,22 @@
|
||||||
*/
|
*/
|
||||||
MessageListMailBoxUserView.prototype.onMessageResponse = function (sResult, oData, bCached)
|
MessageListMailBoxUserView.prototype.onMessageResponse = function (sResult, oData, bCached)
|
||||||
{
|
{
|
||||||
Data.hideMessageBodies();
|
MessageStore.hideMessageBodies();
|
||||||
Data.messageLoading(false);
|
MessageStore.messageLoading(false);
|
||||||
|
|
||||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
||||||
{
|
{
|
||||||
Data.setMessage(oData, bCached);
|
MessageStore.setMessage(oData, bCached);
|
||||||
}
|
}
|
||||||
else if (Enums.StorageResultType.Unload === sResult)
|
else if (Enums.StorageResultType.Unload === sResult)
|
||||||
{
|
{
|
||||||
Data.message(null);
|
MessageStore.message(null);
|
||||||
Data.messageError('');
|
MessageStore.messageError('');
|
||||||
}
|
}
|
||||||
else if (Enums.StorageResultType.Abort !== sResult)
|
else if (Enums.StorageResultType.Abort !== sResult)
|
||||||
{
|
{
|
||||||
Data.message(null);
|
MessageStore.message(null);
|
||||||
Data.messageError((oData && oData.ErrorCode ?
|
MessageStore.messageError((oData && oData.ErrorCode ?
|
||||||
Translator.getNotification(oData.ErrorCode) :
|
Translator.getNotification(oData.ErrorCode) :
|
||||||
Translator.getNotification(Enums.Notification.UnknownError)));
|
Translator.getNotification(Enums.Notification.UnknownError)));
|
||||||
}
|
}
|
||||||
|
|
@ -385,7 +378,7 @@
|
||||||
{
|
{
|
||||||
if (Remote.message(this.onMessageResponse, oMessage.folderFullNameRaw, oMessage.uid))
|
if (Remote.message(this.onMessageResponse, oMessage.folderFullNameRaw, oMessage.uid))
|
||||||
{
|
{
|
||||||
Data.messageLoading(true);
|
MessageStore.messageLoading(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -409,7 +402,7 @@
|
||||||
|
|
||||||
if (Utils.isUnd(aMessages))
|
if (Utils.isUnd(aMessages))
|
||||||
{
|
{
|
||||||
aMessages = Data.messageListChecked();
|
aMessages = MessageStore.messageListChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
aUids = _.map(aMessages, function (oMessage) {
|
aUids = _.map(aMessages, function (oMessage) {
|
||||||
|
|
@ -484,7 +477,7 @@
|
||||||
{
|
{
|
||||||
var
|
var
|
||||||
oFolder = null,
|
oFolder = null,
|
||||||
aMessages = Data.messageList()
|
aMessages = MessageStore.messageList()
|
||||||
;
|
;
|
||||||
|
|
||||||
if ('' !== sFolderFullNameRaw)
|
if ('' !== sFolderFullNameRaw)
|
||||||
|
|
@ -530,27 +523,31 @@
|
||||||
|
|
||||||
MessageListMailBoxUserView.prototype.listSetSeen = function ()
|
MessageListMailBoxUserView.prototype.listSetSeen = function ()
|
||||||
{
|
{
|
||||||
this.setAction(Data.currentFolderFullNameRaw(), Enums.MessageSetAction.SetSeen, Data.messageListCheckedOrSelected());
|
this.setAction(FolderStore.currentFolderFullNameRaw(), Enums.MessageSetAction.SetSeen,
|
||||||
|
MessageStore.messageListCheckedOrSelected());
|
||||||
};
|
};
|
||||||
|
|
||||||
MessageListMailBoxUserView.prototype.listSetAllSeen = function ()
|
MessageListMailBoxUserView.prototype.listSetAllSeen = function ()
|
||||||
{
|
{
|
||||||
this.setActionForAll(Data.currentFolderFullNameRaw(), Enums.MessageSetAction.SetSeen);
|
this.setActionForAll(FolderStore.currentFolderFullNameRaw(), Enums.MessageSetAction.SetSeen);
|
||||||
};
|
};
|
||||||
|
|
||||||
MessageListMailBoxUserView.prototype.listUnsetSeen = function ()
|
MessageListMailBoxUserView.prototype.listUnsetSeen = function ()
|
||||||
{
|
{
|
||||||
this.setAction(Data.currentFolderFullNameRaw(), Enums.MessageSetAction.UnsetSeen, Data.messageListCheckedOrSelected());
|
this.setAction(FolderStore.currentFolderFullNameRaw(), Enums.MessageSetAction.UnsetSeen,
|
||||||
|
MessageStore.messageListCheckedOrSelected());
|
||||||
};
|
};
|
||||||
|
|
||||||
MessageListMailBoxUserView.prototype.listSetFlags = function ()
|
MessageListMailBoxUserView.prototype.listSetFlags = function ()
|
||||||
{
|
{
|
||||||
this.setAction(Data.currentFolderFullNameRaw(), Enums.MessageSetAction.SetFlag, Data.messageListCheckedOrSelected());
|
this.setAction(FolderStore.currentFolderFullNameRaw(), Enums.MessageSetAction.SetFlag,
|
||||||
|
MessageStore.messageListCheckedOrSelected());
|
||||||
};
|
};
|
||||||
|
|
||||||
MessageListMailBoxUserView.prototype.listUnsetFlags = function ()
|
MessageListMailBoxUserView.prototype.listUnsetFlags = function ()
|
||||||
{
|
{
|
||||||
this.setAction(Data.currentFolderFullNameRaw(), Enums.MessageSetAction.UnsetFlag, Data.messageListCheckedOrSelected());
|
this.setAction(FolderStore.currentFolderFullNameRaw(), Enums.MessageSetAction.UnsetFlag,
|
||||||
|
MessageStore.messageListCheckedOrSelected());
|
||||||
};
|
};
|
||||||
|
|
||||||
MessageListMailBoxUserView.prototype.flagMessages = function (oCurrentMessage)
|
MessageListMailBoxUserView.prototype.flagMessages = function (oCurrentMessage)
|
||||||
|
|
@ -649,9 +646,9 @@
|
||||||
|
|
||||||
if (oMessage && !oMessage.lastInCollapsedThreadLoading())
|
if (oMessage && !oMessage.lastInCollapsedThreadLoading())
|
||||||
{
|
{
|
||||||
Data.messageListThreadFolder(oMessage.folderFullNameRaw);
|
MessageStore.messageListThreadFolder(oMessage.folderFullNameRaw);
|
||||||
|
|
||||||
aList = Data.messageListThreadUids();
|
aList = MessageStore.messageListThreadUids();
|
||||||
|
|
||||||
if (oMessage.lastInCollapsedThread())
|
if (oMessage.lastInCollapsedThread())
|
||||||
{
|
{
|
||||||
|
|
@ -662,7 +659,7 @@
|
||||||
aList = _.without(aList, 0 < oMessage.parentUid() ? oMessage.parentUid() : oMessage.uid);
|
aList = _.without(aList, 0 < oMessage.parentUid() ? oMessage.parentUid() : oMessage.uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
Data.messageListThreadUids(_.uniq(aList));
|
MessageStore.messageListThreadUids(_.uniq(aList));
|
||||||
|
|
||||||
oMessage.lastInCollapsedThreadLoading(true);
|
oMessage.lastInCollapsedThreadLoading(true);
|
||||||
oMessage.lastInCollapsedThread(!oMessage.lastInCollapsedThread());
|
oMessage.lastInCollapsedThread(!oMessage.lastInCollapsedThread());
|
||||||
|
|
@ -687,9 +684,9 @@
|
||||||
if (oPage)
|
if (oPage)
|
||||||
{
|
{
|
||||||
kn.setHash(Links.mailBox(
|
kn.setHash(Links.mailBox(
|
||||||
Data.currentFolderFullNameHash(),
|
FolderStore.currentFolderFullNameHash(),
|
||||||
oPage.value,
|
oPage.value,
|
||||||
Data.messageListSearch()
|
MessageStore.messageListSearch()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -733,7 +730,7 @@
|
||||||
key('delete, shift+delete, shift+3', Enums.KeyState.MessageList, function (event, handler) {
|
key('delete, shift+delete, shift+3', Enums.KeyState.MessageList, function (event, handler) {
|
||||||
if (event)
|
if (event)
|
||||||
{
|
{
|
||||||
if (0 < Data.messageListCheckedOrSelected().length)
|
if (0 < MessageStore.messageListCheckedOrSelected().length)
|
||||||
{
|
{
|
||||||
if (handler && 'shift+delete' === handler.shortcut)
|
if (handler && 'shift+delete' === handler.shortcut)
|
||||||
{
|
{
|
||||||
|
|
@ -815,7 +812,7 @@
|
||||||
key('tab, shift+tab, left, right', Enums.KeyState.MessageList, function (event, handler) {
|
key('tab, shift+tab, left, right', Enums.KeyState.MessageList, function (event, handler) {
|
||||||
if (event && handler && ('shift+tab' === handler.shortcut || 'left' === handler.shortcut))
|
if (event && handler && ('shift+tab' === handler.shortcut || 'left' === handler.shortcut))
|
||||||
{
|
{
|
||||||
self.folderList.focused(true);
|
FolderStore.folderList.focused(true);
|
||||||
}
|
}
|
||||||
else if (self.message())
|
else if (self.message())
|
||||||
{
|
{
|
||||||
|
|
@ -904,7 +901,7 @@
|
||||||
'disableFolderDragAndDrop': true,
|
'disableFolderDragAndDrop': true,
|
||||||
'hidden': {
|
'hidden': {
|
||||||
'Folder': function () {
|
'Folder': function () {
|
||||||
return Data.currentFolderFullNameRaw();
|
return FolderStore.currentFolderFullNameRaw();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'dragAndDropElement': this.dragOverArea(),
|
'dragAndDropElement': this.dragOverArea(),
|
||||||
|
|
@ -933,13 +930,15 @@
|
||||||
this.dragOver(false);
|
this.dragOver(false);
|
||||||
}, this))
|
}, this))
|
||||||
.on('onSelect', _.bind(function (sUid, oData) {
|
.on('onSelect', _.bind(function (sUid, oData) {
|
||||||
|
|
||||||
if (sUid && oData && 'message/rfc822' === oData['Type'])
|
if (sUid && oData && 'message/rfc822' === oData['Type'])
|
||||||
{
|
{
|
||||||
Data.messageListLoading(true);
|
MessageStore.messageListLoading(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}, this))
|
}, this))
|
||||||
.on('onComplete', _.bind(function () {
|
.on('onComplete', _.bind(function () {
|
||||||
require('App/User').reloadMessageList(true, true);
|
require('App/User').reloadMessageList(true, true);
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,10 @@
|
||||||
SettingsStore = require('Stores/User/Settings'),
|
SettingsStore = require('Stores/User/Settings'),
|
||||||
AccountStore = require('Stores/User/Account'),
|
AccountStore = require('Stores/User/Account'),
|
||||||
FolderStore = require('Stores/User/Folder'),
|
FolderStore = require('Stores/User/Folder'),
|
||||||
|
MessageStore = require('Stores/User/Message'),
|
||||||
|
|
||||||
Local = require('Storage/Client'),
|
Local = require('Storage/Client'),
|
||||||
Cache = require('Storage/User/Cache'),
|
Cache = require('Storage/User/Cache'),
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
Remote = require('Storage/User/Remote'),
|
Remote = require('Storage/User/Remote'),
|
||||||
|
|
||||||
kn = require('Knoin/Knoin'),
|
kn = require('Knoin/Knoin'),
|
||||||
|
|
@ -56,23 +56,23 @@
|
||||||
|
|
||||||
this.pswp = null;
|
this.pswp = null;
|
||||||
|
|
||||||
this.message = Data.message;
|
this.message = MessageStore.message;
|
||||||
this.currentMessage = Data.currentMessage;
|
this.currentMessage = MessageStore.currentMessage;
|
||||||
this.messageListChecked = Data.messageListChecked;
|
this.messageListChecked = MessageStore.messageListChecked;
|
||||||
this.hasCheckedMessages = Data.hasCheckedMessages;
|
this.hasCheckedMessages = MessageStore.hasCheckedMessages;
|
||||||
this.messageListCheckedOrSelectedUidsWithSubMails = Data.messageListCheckedOrSelectedUidsWithSubMails;
|
this.messageListCheckedOrSelectedUidsWithSubMails = MessageStore.messageListCheckedOrSelectedUidsWithSubMails;
|
||||||
this.messageLoading = Data.messageLoading;
|
this.messageLoading = MessageStore.messageLoading;
|
||||||
this.messageLoadingThrottle = Data.messageLoadingThrottle;
|
this.messageLoadingThrottle = MessageStore.messageLoadingThrottle;
|
||||||
this.messagesBodiesDom = Data.messagesBodiesDom;
|
this.messagesBodiesDom = MessageStore.messagesBodiesDom;
|
||||||
this.useThreads = SettingsStore.useThreads;
|
this.useThreads = SettingsStore.useThreads;
|
||||||
this.replySameFolder = SettingsStore.replySameFolder;
|
this.replySameFolder = SettingsStore.replySameFolder;
|
||||||
this.layout = SettingsStore.layout;
|
this.layout = SettingsStore.layout;
|
||||||
this.usePreviewPane = SettingsStore.usePreviewPane;
|
this.usePreviewPane = SettingsStore.usePreviewPane;
|
||||||
this.isMessageSelected = Data.isMessageSelected;
|
this.isMessageSelected = MessageStore.isMessageSelected;
|
||||||
this.messageActiveDom = Data.messageActiveDom;
|
this.messageActiveDom = MessageStore.messageActiveDom;
|
||||||
this.messageError = Data.messageError;
|
this.messageError = MessageStore.messageError;
|
||||||
|
|
||||||
this.fullScreenMode = Data.messageFullScreenMode;
|
this.fullScreenMode = MessageStore.messageFullScreenMode;
|
||||||
|
|
||||||
this.lastReplyAction_ = ko.observable('');
|
this.lastReplyAction_ = ko.observable('');
|
||||||
this.lastReplyAction = ko.computed({
|
this.lastReplyAction = ko.computed({
|
||||||
|
|
@ -113,7 +113,7 @@
|
||||||
|
|
||||||
// commands
|
// commands
|
||||||
this.closeMessage = Utils.createCommand(this, function () {
|
this.closeMessage = Utils.createCommand(this, function () {
|
||||||
Data.message(null);
|
MessageStore.message(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.replyCommand = createCommandHelper(Enums.ComposeType.Reply);
|
this.replyCommand = createCommandHelper(Enums.ComposeType.Reply);
|
||||||
|
|
@ -141,7 +141,7 @@
|
||||||
if (this.message())
|
if (this.message())
|
||||||
{
|
{
|
||||||
require('App/User').deleteMessagesFromFolder(Enums.FolderType.Trash,
|
require('App/User').deleteMessagesFromFolder(Enums.FolderType.Trash,
|
||||||
Data.currentFolderFullNameRaw(),
|
FolderStore.currentFolderFullNameRaw(),
|
||||||
[this.message().uid], false);
|
[this.message().uid], false);
|
||||||
}
|
}
|
||||||
}, this.messageVisibility);
|
}, this.messageVisibility);
|
||||||
|
|
@ -395,7 +395,7 @@
|
||||||
*/
|
*/
|
||||||
MessageViewMailBoxUserView.prototype.replyOrforward = function (sType)
|
MessageViewMailBoxUserView.prototype.replyOrforward = function (sType)
|
||||||
{
|
{
|
||||||
kn.showScreenPopup(require('View/Popup/Compose'), [sType, Data.message()]);
|
kn.showScreenPopup(require('View/Popup/Compose'), [sType, MessageStore.message()]);
|
||||||
};
|
};
|
||||||
|
|
||||||
MessageViewMailBoxUserView.prototype.onBuild = function (oDom)
|
MessageViewMailBoxUserView.prototype.onBuild = function (oDom)
|
||||||
|
|
@ -619,7 +619,7 @@
|
||||||
|
|
||||||
// reply
|
// reply
|
||||||
key('r', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
|
key('r', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
|
||||||
if (Data.message())
|
if (MessageStore.message())
|
||||||
{
|
{
|
||||||
self.replyCommand();
|
self.replyCommand();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -628,7 +628,7 @@
|
||||||
|
|
||||||
// replaAll
|
// replaAll
|
||||||
key('a', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
|
key('a', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
|
||||||
if (Data.message())
|
if (MessageStore.message())
|
||||||
{
|
{
|
||||||
self.replyAllCommand();
|
self.replyAllCommand();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -637,7 +637,7 @@
|
||||||
|
|
||||||
// forward
|
// forward
|
||||||
key('f', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
|
key('f', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
|
||||||
if (Data.message())
|
if (MessageStore.message())
|
||||||
{
|
{
|
||||||
self.forwardCommand();
|
self.forwardCommand();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -646,7 +646,7 @@
|
||||||
|
|
||||||
// message information
|
// message information
|
||||||
// key('i', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
|
// key('i', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
|
||||||
// if (oData.message())
|
// if (MessageStore.message())
|
||||||
// {
|
// {
|
||||||
// self.showFullInfo(!self.showFullInfo());
|
// self.showFullInfo(!self.showFullInfo());
|
||||||
// return false;
|
// return false;
|
||||||
|
|
@ -655,9 +655,9 @@
|
||||||
|
|
||||||
// toggle message blockquotes
|
// toggle message blockquotes
|
||||||
key('b', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
|
key('b', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
|
||||||
if (Data.message() && Data.message().body)
|
if (MessageStore.message() && MessageStore.message().body)
|
||||||
{
|
{
|
||||||
Data.message().body.find('.rlBlockquoteSwitcher').click();
|
MessageStore.message().body.find('.rlBlockquoteSwitcher').click();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -731,7 +731,7 @@
|
||||||
*/
|
*/
|
||||||
MessageViewMailBoxUserView.prototype.isDraftFolder = function ()
|
MessageViewMailBoxUserView.prototype.isDraftFolder = function ()
|
||||||
{
|
{
|
||||||
return Data.message() && FolderStore.draftFolder() === Data.message().folderFullNameRaw;
|
return MessageStore.message() && FolderStore.draftFolder() === MessageStore.message().folderFullNameRaw;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -739,7 +739,7 @@
|
||||||
*/
|
*/
|
||||||
MessageViewMailBoxUserView.prototype.isSentFolder = function ()
|
MessageViewMailBoxUserView.prototype.isSentFolder = function ()
|
||||||
{
|
{
|
||||||
return Data.message() && FolderStore.sentFolder() === Data.message().folderFullNameRaw;
|
return MessageStore.message() && FolderStore.sentFolder() === MessageStore.message().folderFullNameRaw;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -747,7 +747,7 @@
|
||||||
*/
|
*/
|
||||||
MessageViewMailBoxUserView.prototype.isSpamFolder = function ()
|
MessageViewMailBoxUserView.prototype.isSpamFolder = function ()
|
||||||
{
|
{
|
||||||
return Data.message() && FolderStore.spamFolder() === Data.message().folderFullNameRaw;
|
return MessageStore.message() && FolderStore.spamFolder() === MessageStore.message().folderFullNameRaw;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -755,7 +755,7 @@
|
||||||
*/
|
*/
|
||||||
MessageViewMailBoxUserView.prototype.isSpamDisabled = function ()
|
MessageViewMailBoxUserView.prototype.isSpamDisabled = function ()
|
||||||
{
|
{
|
||||||
return Data.message() && FolderStore.spamFolder() === Consts.Values.UnuseOptionValue;
|
return MessageStore.message() && FolderStore.spamFolder() === Consts.Values.UnuseOptionValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -763,7 +763,7 @@
|
||||||
*/
|
*/
|
||||||
MessageViewMailBoxUserView.prototype.isArchiveFolder = function ()
|
MessageViewMailBoxUserView.prototype.isArchiveFolder = function ()
|
||||||
{
|
{
|
||||||
return Data.message() && FolderStore.archiveFolder() === Data.message().folderFullNameRaw;
|
return MessageStore.message() && FolderStore.archiveFolder() === MessageStore.message().folderFullNameRaw;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -771,7 +771,7 @@
|
||||||
*/
|
*/
|
||||||
MessageViewMailBoxUserView.prototype.isArchiveDisabled = function ()
|
MessageViewMailBoxUserView.prototype.isArchiveDisabled = function ()
|
||||||
{
|
{
|
||||||
return Data.message() && FolderStore.archiveFolder() === Consts.Values.UnuseOptionValue;
|
return MessageStore.message() && FolderStore.archiveFolder() === Consts.Values.UnuseOptionValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -789,9 +789,9 @@
|
||||||
|
|
||||||
MessageViewMailBoxUserView.prototype.editMessage = function ()
|
MessageViewMailBoxUserView.prototype.editMessage = function ()
|
||||||
{
|
{
|
||||||
if (Data.message())
|
if (MessageStore.message())
|
||||||
{
|
{
|
||||||
kn.showScreenPopup(require('View/Popup/Compose'), [Enums.ComposeType.Draft, Data.message()]);
|
kn.showScreenPopup(require('View/Popup/Compose'), [Enums.ComposeType.Draft, MessageStore.message()]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,6 @@
|
||||||
var
|
var
|
||||||
_ = require('_'),
|
_ = require('_'),
|
||||||
|
|
||||||
Links = require('Common/Links'),
|
|
||||||
|
|
||||||
Data = require('Storage/User/Data'),
|
|
||||||
Cache = require('Storage/User/Cache'),
|
|
||||||
|
|
||||||
kn = require('Knoin/Knoin'),
|
kn = require('Knoin/Knoin'),
|
||||||
AbstractView = require('Knoin/AbstractView')
|
AbstractView = require('Knoin/AbstractView')
|
||||||
;
|
;
|
||||||
|
|
@ -31,12 +26,13 @@
|
||||||
|
|
||||||
PaneSettingsUserView.prototype.onShow = function ()
|
PaneSettingsUserView.prototype.onShow = function ()
|
||||||
{
|
{
|
||||||
Data.message(null);
|
require('Stores/User/Message').message(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
PaneSettingsUserView.prototype.backToMailBoxClick = function ()
|
PaneSettingsUserView.prototype.backToMailBoxClick = function ()
|
||||||
{
|
{
|
||||||
kn.setHash(Links.inbox(Cache.getFolderInboxName()));
|
kn.setHash(require('Common/Links').inbox(
|
||||||
|
require('Storage/User/Cache').getFolderInboxName()));
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = PaneSettingsUserView;
|
module.exports = PaneSettingsUserView;
|
||||||
|
|
|
||||||
|
|
@ -306,13 +306,14 @@ class SmtpClient extends \MailSo\Net\NetClient
|
||||||
/**
|
/**
|
||||||
* @param string $sFrom
|
* @param string $sFrom
|
||||||
* @param string $sSizeIfSupported = ''
|
* @param string $sSizeIfSupported = ''
|
||||||
|
* @param bool $bDsn = false
|
||||||
*
|
*
|
||||||
* @return \MailSo\Smtp\SmtpClient
|
* @return \MailSo\Smtp\SmtpClient
|
||||||
*
|
*
|
||||||
* @throws \MailSo\Net\Exceptions\Exception
|
* @throws \MailSo\Net\Exceptions\Exception
|
||||||
* @throws \MailSo\Smtp\Exceptions\Exception
|
* @throws \MailSo\Smtp\Exceptions\Exception
|
||||||
*/
|
*/
|
||||||
public function MailFrom($sFrom, $sSizeIfSupported = '')
|
public function MailFrom($sFrom, $sSizeIfSupported = '', $bDsn = false)
|
||||||
{
|
{
|
||||||
$sFrom = \MailSo\Base\Utils::IdnToAscii($sFrom, true);
|
$sFrom = \MailSo\Base\Utils::IdnToAscii($sFrom, true);
|
||||||
$sCmd = 'FROM:<'.$sFrom.'>';
|
$sCmd = 'FROM:<'.$sFrom.'>';
|
||||||
|
|
@ -323,6 +324,11 @@ class SmtpClient extends \MailSo\Net\NetClient
|
||||||
$sCmd .= ' SIZE='.$sSizeIfSupported;
|
$sCmd .= ' SIZE='.$sSizeIfSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($bDsn && $this->IsSupported('DSN'))
|
||||||
|
{
|
||||||
|
$sCmd .= ' RET=HDRS';
|
||||||
|
}
|
||||||
|
|
||||||
$this->sendRequestWithCheck('MAIL', 250, $sCmd);
|
$this->sendRequestWithCheck('MAIL', 250, $sCmd);
|
||||||
|
|
||||||
$this->bMail = true;
|
$this->bMail = true;
|
||||||
|
|
@ -334,13 +340,14 @@ class SmtpClient extends \MailSo\Net\NetClient
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sTo
|
* @param string $sTo
|
||||||
|
* @param bool $bDsn = false
|
||||||
*
|
*
|
||||||
* @return \MailSo\Smtp\SmtpClient
|
* @return \MailSo\Smtp\SmtpClient
|
||||||
*
|
*
|
||||||
* @throws \MailSo\Net\Exceptions\Exception
|
* @throws \MailSo\Net\Exceptions\Exception
|
||||||
* @throws \MailSo\Smtp\Exceptions\Exception
|
* @throws \MailSo\Smtp\Exceptions\Exception
|
||||||
*/
|
*/
|
||||||
public function Rcpt($sTo)
|
public function Rcpt($sTo, $bDsn = false)
|
||||||
{
|
{
|
||||||
if (!$this->bMail)
|
if (!$this->bMail)
|
||||||
{
|
{
|
||||||
|
|
@ -350,7 +357,14 @@ class SmtpClient extends \MailSo\Net\NetClient
|
||||||
}
|
}
|
||||||
|
|
||||||
$sTo = \MailSo\Base\Utils::IdnToAscii($sTo, true);
|
$sTo = \MailSo\Base\Utils::IdnToAscii($sTo, true);
|
||||||
$this->sendRequestWithCheck('RCPT', array(250, 251), 'TO:<'.$sTo.'>');
|
$sCmd = 'TO:<'.$sTo.'>';
|
||||||
|
|
||||||
|
if ($bDsn && $this->IsSupported('DSN'))
|
||||||
|
{
|
||||||
|
$sCmd .= ' NOTIFY=SUCCESS,FAILURE';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sendRequestWithCheck('RCPT', array(250, 251), $sCmd);
|
||||||
|
|
||||||
$this->bRcpt = true;
|
$this->bRcpt = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5752,12 +5752,14 @@ class Actions
|
||||||
* @param \RainLoop\Model\Account $oAccount
|
* @param \RainLoop\Model\Account $oAccount
|
||||||
* @param \MailSo\Mime\Message $oMessage
|
* @param \MailSo\Mime\Message $oMessage
|
||||||
* @param resource $rMessageStream
|
* @param resource $rMessageStream
|
||||||
|
* @param bool $bDsn = true
|
||||||
* @param bool $bAddHiddenRcpt = true
|
* @param bool $bAddHiddenRcpt = true
|
||||||
*
|
*
|
||||||
* @throws \RainLoop\Exceptions\ClientException
|
* @throws \RainLoop\Exceptions\ClientException
|
||||||
* @throws \MailSo\Net\Exceptions\ConnectionException
|
* @throws \MailSo\Net\Exceptions\ConnectionException
|
||||||
*/
|
*/
|
||||||
private function smtpSendMessage($oAccount, $oMessage, &$rMessageStream, &$iMessageStreamSize, $bAddHiddenRcpt = true)
|
private function smtpSendMessage($oAccount, $oMessage,
|
||||||
|
&$rMessageStream, &$iMessageStreamSize, $bDsn = false, $bAddHiddenRcpt = true)
|
||||||
{
|
{
|
||||||
$oRcpt = $oMessage->GetRcpt();
|
$oRcpt = $oMessage->GetRcpt();
|
||||||
if ($oRcpt && 0 < $oRcpt->Count())
|
if ($oRcpt && 0 < $oRcpt->Count())
|
||||||
|
|
@ -5773,9 +5775,9 @@ class Actions
|
||||||
$sFrom = $oFrom instanceof \MailSo\Mime\Email ? $oFrom->GetEmail() : '';
|
$sFrom = $oFrom instanceof \MailSo\Mime\Email ? $oFrom->GetEmail() : '';
|
||||||
$sFrom = empty($sFrom) ? $oAccount->Email() : $sFrom;
|
$sFrom = empty($sFrom) ? $oAccount->Email() : $sFrom;
|
||||||
|
|
||||||
$aHiddenRcpt = array();
|
|
||||||
$this->Plugins()->RunHook('filter.smtp-from', array($oAccount, $oMessage, &$sFrom));
|
$this->Plugins()->RunHook('filter.smtp-from', array($oAccount, $oMessage, &$sFrom));
|
||||||
|
|
||||||
|
$aHiddenRcpt = array();
|
||||||
if ($bAddHiddenRcpt)
|
if ($bAddHiddenRcpt)
|
||||||
{
|
{
|
||||||
$this->Plugins()->RunHook('filter.smtp-hidden-rcpt', array($oAccount, $oMessage, &$aHiddenRcpt));
|
$this->Plugins()->RunHook('filter.smtp-hidden-rcpt', array($oAccount, $oMessage, &$aHiddenRcpt));
|
||||||
|
|
@ -5806,9 +5808,9 @@ class Actions
|
||||||
list($sMailHeaders, $sMailBody) = \explode("\r\n\r\n", $sRawBody, 2);
|
list($sMailHeaders, $sMailBody) = \explode("\r\n\r\n", $sRawBody, 2);
|
||||||
unset($sRawBody);
|
unset($sRawBody);
|
||||||
|
|
||||||
$this->Logger()->WriteDump(array(
|
// $this->Logger()->WriteDump(array(
|
||||||
$sMailTo, $sMailSubject, $sMailBody, $sMailHeaders
|
// $sMailTo, $sMailSubject, $sMailBody, $sMailHeaders
|
||||||
));
|
// ));
|
||||||
|
|
||||||
if (!\mail($sMailTo, $sMailSubject, $sMailBody, $sMailHeaders/*, '-f'.$oFrom->GetEmail()*/))
|
if (!\mail($sMailTo, $sMailSubject, $sMailBody, $sMailHeaders/*, '-f'.$oFrom->GetEmail()*/))
|
||||||
{
|
{
|
||||||
|
|
@ -5824,15 +5826,17 @@ class Actions
|
||||||
}
|
}
|
||||||
else if ($oSmtpClient->IsConnected())
|
else if ($oSmtpClient->IsConnected())
|
||||||
{
|
{
|
||||||
|
$bDsn = false;
|
||||||
|
|
||||||
if (!empty($sFrom))
|
if (!empty($sFrom))
|
||||||
{
|
{
|
||||||
$oSmtpClient->MailFrom($sFrom);
|
$oSmtpClient->MailFrom($sFrom, '', $bDsn);
|
||||||
}
|
}
|
||||||
|
|
||||||
$aRcpt =& $oRcpt->GetAsArray();
|
$aRcpt =& $oRcpt->GetAsArray();
|
||||||
foreach ($aRcpt as /* @var $oEmail \MailSo\Mime\Email */ $oEmail)
|
foreach ($aRcpt as /* @var $oEmail \MailSo\Mime\Email */ $oEmail)
|
||||||
{
|
{
|
||||||
$oSmtpClient->Rcpt($oEmail->GetEmail());
|
$oSmtpClient->Rcpt($oEmail->GetEmail(), $bDsn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($bAddHiddenRcpt && \is_array($aHiddenRcpt) && 0 < \count($aHiddenRcpt))
|
if ($bAddHiddenRcpt && \is_array($aHiddenRcpt) && 0 < \count($aHiddenRcpt))
|
||||||
|
|
@ -5902,6 +5906,7 @@ class Actions
|
||||||
$sDraftUid = $this->GetActionParam('MessageUid', '');
|
$sDraftUid = $this->GetActionParam('MessageUid', '');
|
||||||
$sSentFolder = $this->GetActionParam('SentFolder', '');
|
$sSentFolder = $this->GetActionParam('SentFolder', '');
|
||||||
$aDraftInfo = $this->GetActionParam('DraftInfo', null);
|
$aDraftInfo = $this->GetActionParam('DraftInfo', null);
|
||||||
|
$bDsn = '1' === $this->GetActionParam('Dsn', '0');
|
||||||
|
|
||||||
$oMessage = $this->buildMessage($oAccount, false);
|
$oMessage = $this->buildMessage($oAccount, false);
|
||||||
|
|
||||||
|
|
@ -5922,7 +5927,7 @@ class Actions
|
||||||
|
|
||||||
if (false !== $iMessageStreamSize)
|
if (false !== $iMessageStreamSize)
|
||||||
{
|
{
|
||||||
$this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize);
|
$this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize, $bDsn, true);
|
||||||
|
|
||||||
$this->deleteMessageAttachmnets($oAccount);
|
$this->deleteMessageAttachmnets($oAccount);
|
||||||
|
|
||||||
|
|
@ -6096,7 +6101,7 @@ class Actions
|
||||||
|
|
||||||
if (false !== $iMessageStreamSize)
|
if (false !== $iMessageStreamSize)
|
||||||
{
|
{
|
||||||
$this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize);
|
$this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize, false, false);
|
||||||
|
|
||||||
if (\is_resource($rMessageStream))
|
if (\is_resource($rMessageStream))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="attachmentAreaParent b-content" style="height: 200px; min-height: 200px" data-bind="nano: true, visible: attachmentsPlace, initResizeTrigger: [resizer(), 200, 47]">
|
<div class="attachmentAreaParent b-content" style="height: 200px; min-height: 200px" data-bind="nano: true, visible: attachmentsPlace, initResizeTrigger: [resizer(), 200, 57]">
|
||||||
<div class="content g-scrollbox">
|
<div class="content g-scrollbox">
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<ul class="attachmentList" data-bind="template: { name: 'ComposeAttachment', foreach: attachments }"></ul>
|
<ul class="attachmentList" data-bind="template: { name: 'ComposeAttachment', foreach: attachments }"></ul>
|
||||||
|
|
@ -204,7 +204,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="textAreaParent" style="height: 200px; min-height: 200px"
|
<div class="textAreaParent" style="height: 200px; min-height: 200px"
|
||||||
data-bind="visible: !attachmentsPlace(), initDom: composeEditorArea, initResizeTrigger: [resizer(), 200, 30]"></div>
|
data-bind="visible: !attachmentsPlace(), initDom: composeEditorArea, initResizeTrigger: [resizer(), 200, 40]"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" data-bind="visible: inited() && !serverError()">
|
<div class="row" data-bind="visible: inited() && !serverError()">
|
||||||
<div class="span4">
|
<div class="span5">
|
||||||
<a class="btn" data-bind="click: addFilter">
|
<a class="btn" data-bind="click: addFilter">
|
||||||
<i class="icon-plus"></i>
|
<i class="icon-plus"></i>
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
<span class="i18n" data-i18n-text="SETTINGS_FILTERS/BUTTON_SAVE"></span>
|
<span class="i18n" data-i18n-text="SETTINGS_FILTERS/BUTTON_SAVE"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="span4" style="margin-left: 0;">
|
<div class="span3" style="margin-left: 0;">
|
||||||
<span data-bind="text: saveErrorText"style="color:red"></span>
|
<span data-bind="text: saveErrorText"style="color:red"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue