Easier SystemFolders handling

This commit is contained in:
djmaze 2021-12-01 13:54:35 +01:00
parent 31db5ee238
commit 547d66ebcb
13 changed files with 75 additions and 85 deletions

View file

@ -12,6 +12,8 @@ export const
forEachObjectValue = (obj, fn) => Object.values(obj).forEach(fn),
forEachObjectEntry = (obj, fn) => Object.entries(obj).forEach(([key, value]) => fn(key, value)),
pInt = (value, defaultValue = 0) => {
value = parseInt(value, 10);
return isNaN(value) || !isFinite(value) ? defaultValue : value;
@ -28,14 +30,14 @@ export const
&& domItem.classList.toggle('disabled', domItem.disabled = item.disabled),
addObservablesTo = (target, observables) =>
Object.entries(observables).forEach(([key, value]) =>
forEachObjectEntry(observables, (key, value) =>
target[key] = /*isArray(value) ? ko.observableArray(value) :*/ ko.observable(value) ),
addComputablesTo = (target, computables) =>
Object.entries(computables).forEach(([key, fn]) => target[key] = ko.computed(fn)),
forEachObjectEntry(computables, (key, fn) => target[key] = ko.computed(fn)),
addSubscribablesTo = (target, subscribables) =>
Object.entries(subscribables).forEach(([key, fn]) => target[key].subscribe(fn)),
forEachObjectEntry(subscribables, (key, fn) => target[key].subscribe(fn)),
inFocus = () => {
try {

View file

@ -1,7 +1,7 @@
import { AbstractCollectionModel } from 'Model/AbstractCollection';
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
import { isArray, getKeyByValue } from 'Common/Utils';
import { isArray, getKeyByValue, forEachObjectEntry } from 'Common/Utils';
import { ClientSideKeyName, FolderType, FolderMetadataKeys } from 'Common/EnumsUser';
import * as Cache from 'Common/Cache';
import { Settings, SettingsGet } from 'Common/Globals';
@ -27,8 +27,14 @@ normalizeFolder = sFolderFullName => ('' === sFolderFullName
? sFolderFullName
: '';
// index is FolderType value
let SystemFolders = [0,'','','','','','',''];
const SystemFolders = {
Inbox: 0,
Sent: 0,
Drafts: 0,
Spam: 0,
Trash: 0,
Archive: 0
};
export class FolderCollectionModel extends AbstractCollectionModel
{
@ -52,24 +58,14 @@ export class FolderCollectionModel extends AbstractCollectionModel
static reviveFromJson(object) {
const expandedFolders = Local.get(ClientSideKeyName.ExpandedFolders);
if (object && object.SystemFolders) {
let sf = object.SystemFolders;
SystemFolders = [
/* USER */ 0,
/* INBOX */ sf[1],
SettingsGet('SentFolder') || sf[2],
SettingsGet('DraftFolder') || sf[3],
SettingsGet('SpamFolder') || sf[4],
SettingsGet('TrashFolder') || sf[5],
SettingsGet('ArchiveFolder') || sf[12]
// SettingsGet('TemplatesFolder') || sf[19]
// IMPORTANT: sf[10],
// FLAGGED: sf[11],
// ALL: sf[13]
];
forEachObjectEntry(SystemFolders, key =>
SystemFolders[key] = SettingsGet(key+'Folder') || object.SystemFolders[FolderType[key]]
);
}
return super.reviveFromJson(object, oFolder => {
let oCacheFolder = Cache.getFolderFromCacheList(oFolder.FullName);
let oCacheFolder = Cache.getFolderFromCacheList(oFolder.FullName),
type = FolderType[getKeyByValue(SystemFolders, oFolder.FullName)];
if (oCacheFolder) {
oFolder.SubFolders = FolderCollectionModel.reviveFromJson(oFolder.SubFolders);
@ -79,14 +75,13 @@ export class FolderCollectionModel extends AbstractCollectionModel
if (!oCacheFolder)
return null;
if (1 == SystemFolders.indexOf(oFolder.FullName)) {
if (1 == type) {
oCacheFolder.type(FolderType.Inbox);
Cache.setFolderInboxName(oFolder.FullName);
}
Cache.setFolder(oCacheFolder.fullNameHash, oFolder.FullName, oCacheFolder);
}
let type = SystemFolders.indexOf(oFolder.FullName);
if (1 < type) {
oCacheFolder.type(type);
}
@ -115,22 +110,15 @@ export class FolderCollectionModel extends AbstractCollectionModel
storeIt() {
FolderUserStore.displaySpecSetting(Settings.app('folderSpecLimit') < this.CountRec);
if (SystemFolders &&
!(
if (!(
SettingsGet('SentFolder') +
SettingsGet('DraftFolder') +
SettingsGet('DraftsFolder') +
SettingsGet('SpamFolder') +
SettingsGet('TrashFolder') +
SettingsGet('ArchiveFolder')
)
) {
FolderUserStore.saveSystemFolders({
SentFolder: SystemFolders[FolderType.Sent],
DraftFolder: SystemFolders[FolderType.Drafts],
SpamFolder: SystemFolders[FolderType.Spam],
TrashFolder: SystemFolders[FolderType.Trash],
ArchiveFolder: SystemFolders[FolderType.Archive]
});
FolderUserStore.saveSystemFolders(SystemFolders);
}
FolderUserStore.folderList(this);
@ -144,11 +132,11 @@ export class FolderCollectionModel extends AbstractCollectionModel
FolderUserStore.quotaLimit(this.quotaLimit);
FolderUserStore.capabilities(this.Capabilities);
FolderUserStore.sentFolder(normalizeFolder(SettingsGet('SentFolder') || SystemFolders[2]));
FolderUserStore.draftFolder(normalizeFolder(SettingsGet('DraftFolder') || SystemFolders[3]));
FolderUserStore.spamFolder(normalizeFolder(SettingsGet('SpamFolder') || SystemFolders[4]));
FolderUserStore.trashFolder(normalizeFolder(SettingsGet('TrashFolder') || SystemFolders[5]));
FolderUserStore.archiveFolder(normalizeFolder(SettingsGet('ArchiveFolder') || SystemFolders[6]));
FolderUserStore.sentFolder(normalizeFolder(SystemFolders.Sent));
FolderUserStore.draftsFolder(normalizeFolder(SystemFolders.Drafts));
FolderUserStore.spamFolder(normalizeFolder(SystemFolders.Spam));
FolderUserStore.trashFolder(normalizeFolder(SystemFolders.Trash));
FolderUserStore.archiveFolder(normalizeFolder(SystemFolders.Archive));
// FolderUserStore.folderList.valueHasMutated();

View file

@ -178,7 +178,7 @@ export class MessageModel extends AbstractModel {
}
computeSenderEmail() {
const list = [FolderUserStore.sentFolder(), FolderUserStore.draftFolder()].includes(this.folder) ? 'to' : 'from';
const list = [FolderUserStore.sentFolder(), FolderUserStore.draftsFolder()].includes(this.folder) ? 'to' : 'from';
this.senderEmailsString(this[list].toString(true));
this.senderClearEmailsString(this[list].toStringClear());
}

View file

@ -2,7 +2,7 @@ import ko from 'ko';
import { FolderType, FolderSortMode } from 'Common/EnumsUser';
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
import { addObservablesTo, addSubscribablesTo, addComputablesTo } from 'Common/Utils';
import { addObservablesTo, addSubscribablesTo, addComputablesTo, forEachObjectEntry } from 'Common/Utils';
import { getFolderInboxName, getFolderFromCacheList } from 'Common/Cache';
import { Settings } from 'Common/Globals';
//import Remote from 'Remote/User/Fetch'; Circular dependency
@ -26,7 +26,7 @@ export const FolderUserStore = new class {
quotaUsage: 0,
sentFolder: '',
draftFolder: '',
draftsFolder: '',
spamFolder: '',
trashFolder: '',
archiveFolder: '',
@ -46,7 +46,7 @@ export const FolderUserStore = new class {
self.namespace = '';
self.folderList = ko.observableArray();
self.folderList = ko.observableArray(/*new FolderCollectionModel*/);
self.capabilities = ko.observableArray();
@ -54,7 +54,7 @@ export const FolderUserStore = new class {
addComputablesTo(self, {
draftFolderNotEnabled: () => !self.draftFolder() || UNUSED_OPTION_VALUE === self.draftFolder(),
draftsFolderNotEnabled: () => !self.draftsFolder() || UNUSED_OPTION_VALUE === self.draftsFolder(),
currentFolderFullName: () => (self.currentFolder() ? self.currentFolder().fullName : ''),
currentFolderFullNameHash: () => (self.currentFolder() ? self.currentFolder().fullNameHash : ''),
@ -64,7 +64,7 @@ export const FolderUserStore = new class {
folderListSystemNames: () => {
const list = [getFolderInboxName()],
others = [self.sentFolder(), self.draftFolder(), self.spamFolder(), self.trashFolder(), self.archiveFolder()];
others = [self.sentFolder(), self.draftsFolder(), self.spamFolder(), self.trashFolder(), self.archiveFolder()];
self.folderList().length &&
others.forEach(name => name && UNUSED_OPTION_VALUE !== name && list.push(name));
@ -87,14 +87,14 @@ export const FolderUserStore = new class {
};
self.sentFolder.subscribe(fRemoveSystemFolderType(self.sentFolder), self, 'beforeChange');
self.draftFolder.subscribe(fRemoveSystemFolderType(self.draftFolder), self, 'beforeChange');
self.draftsFolder.subscribe(fRemoveSystemFolderType(self.draftsFolder), self, 'beforeChange');
self.spamFolder.subscribe(fRemoveSystemFolderType(self.spamFolder), self, 'beforeChange');
self.trashFolder.subscribe(fRemoveSystemFolderType(self.trashFolder), self, 'beforeChange');
self.archiveFolder.subscribe(fRemoveSystemFolderType(self.archiveFolder), self, 'beforeChange');
addSubscribablesTo(self, {
sentFolder: fSetSystemFolderType(FolderType.Sent),
draftFolder: fSetSystemFolderType(FolderType.Drafts),
draftsFolder: fSetSystemFolderType(FolderType.Drafts),
spamFolder: fSetSystemFolderType(FolderType.Spam),
trashFolder: fSetSystemFolderType(FolderType.Trash),
archiveFolder: fSetSystemFolderType(FolderType.Archive)
@ -160,13 +160,13 @@ export const FolderUserStore = new class {
saveSystemFolders(folders) {
folders = folders || {
SentFolder: FolderUserStore.sentFolder(),
DraftFolder: FolderUserStore.draftFolder(),
SpamFolder: FolderUserStore.spamFolder(),
TrashFolder: FolderUserStore.trashFolder(),
ArchiveFolder: FolderUserStore.archiveFolder()
Sent: FolderUserStore.sentFolder(),
Drafts: FolderUserStore.draftsFolder(),
Spam: FolderUserStore.spamFolder(),
Trash: FolderUserStore.trashFolder(),
Archive: FolderUserStore.archiveFolder()
};
Object.entries(folders).forEach(([k,v])=>Settings.set(k,v));
forEachObjectEntry(folders, (k,v)=>Settings.set(k+'Folder',v));
rl.app.Remote.saveSystemFolders(null, folders);
}
};

View file

@ -169,7 +169,7 @@ class ComposePopupView extends AbstractViewPopup {
showBcc: false,
showReplyTo: false,
draftFolder: '',
draftsFolder: '',
draftUid: 0,
sending: false,
saving: false,
@ -250,7 +250,7 @@ class ComposePopupView extends AbstractViewPopup {
attachmentsCount: () => this.attachments.length,
attachmentsInErrorCount: () => this.attachmentsInError.length,
attachmentsInProcessCount: () => this.attachmentsInProcess.length,
isDraftFolderMessage: () => this.draftFolder() && this.draftUid(),
isDraftFolderMessage: () => this.draftsFolder() && this.draftUid(),
identitiesOptions: () =>
IdentityUserStore.map(item => ({
@ -338,7 +338,7 @@ class ComposePopupView extends AbstractViewPopup {
}
return {
IdentityID: this.currentIdentity() ? this.currentIdentity().id() : '',
MessageFolder: this.draftFolder(),
MessageFolder: this.draftsFolder(),
MessageUid: this.draftUid(),
SaveFolder: sSaveFolder,
To: this.to(),
@ -412,7 +412,7 @@ class ComposePopupView extends AbstractViewPopup {
sSentFolder = UNUSED_OPTION_VALUE === sSentFolder ? '' : sSentFolder;
setFolderHash(this.draftFolder(), '');
setFolderHash(this.draftsFolder(), '');
setFolderHash(sSentFolder, '');
Remote.sendMessage(
@ -441,7 +441,7 @@ class ComposePopupView extends AbstractViewPopup {
}
saveCommand() {
if (FolderUserStore.draftFolderNotEnabled()) {
if (FolderUserStore.draftsFolderNotEnabled()) {
showScreenPopup(FolderSystemPopupView, [SetSystemFoldersNotification.Draft]);
} else {
this.savedError(false);
@ -449,7 +449,7 @@ class ComposePopupView extends AbstractViewPopup {
this.autosaveStart();
setFolderHash(FolderUserStore.draftFolder(), '');
setFolderHash(FolderUserStore.draftsFolder(), '');
Remote.saveMessage(
(iError, oData) => {
@ -463,18 +463,18 @@ class ComposePopupView extends AbstractViewPopup {
if (this.bFromDraft) {
const message = MessageUserStore.message();
if (message && this.draftFolder() === message.folder && this.draftUid() == message.uid) {
if (message && this.draftsFolder() === message.folder && this.draftUid() == message.uid) {
MessageUserStore.message(null);
}
}
this.draftFolder(oData.Result.NewFolder);
this.draftsFolder(oData.Result.NewFolder);
this.draftUid(oData.Result.NewUid);
this.savedTime(new Date);
if (this.bFromDraft) {
setFolderHash(this.draftFolder(), '');
setFolderHash(this.draftsFolder(), '');
}
}
}
@ -486,7 +486,7 @@ class ComposePopupView extends AbstractViewPopup {
this.reloadDraftFolder();
},
this.getMessageRequestParams(FolderUserStore.draftFolder())
this.getMessageRequestParams(FolderUserStore.draftsFolder())
);
}
@ -499,7 +499,7 @@ class ComposePopupView extends AbstractViewPopup {
i18n('POPUPS_ASK/DESC_WANT_DELETE_MESSAGES'),
() => {
if (this.modalVisibility()) {
rl.app.deleteMessagesFromFolderWithoutCheck(this.draftFolder(), [this.draftUid()]);
rl.app.deleteMessagesFromFolderWithoutCheck(this.draftsFolder(), [this.draftUid()]);
this.closeCommand();
}
}
@ -514,7 +514,7 @@ class ComposePopupView extends AbstractViewPopup {
this.modalVisibility() &&
!this.saving() &&
!this.sending() &&
!FolderUserStore.draftFolderNotEnabled() &&
!FolderUserStore.draftsFolderNotEnabled() &&
SettingsUserStore.allowDraftAutosave()
) {
this.saveCommand();
@ -536,7 +536,7 @@ class ComposePopupView extends AbstractViewPopup {
clearTimeout(this.iTimer);
this.iTimer = setTimeout(()=>{
if (this.modalVisibility()
&& !FolderUserStore.draftFolderNotEnabled()
&& !FolderUserStore.draftsFolderNotEnabled()
&& SettingsUserStore.allowDraftAutosave()
&& !this.isEmptyForm(false)
&& !this.saving()
@ -568,13 +568,13 @@ class ComposePopupView extends AbstractViewPopup {
}
reloadDraftFolder() {
const draftFolder = FolderUserStore.draftFolder();
if (draftFolder && UNUSED_OPTION_VALUE !== draftFolder) {
setFolderHash(draftFolder, '');
if (FolderUserStore.currentFolderFullName() === draftFolder) {
const draftsFolder = FolderUserStore.draftsFolder();
if (draftsFolder && UNUSED_OPTION_VALUE !== draftsFolder) {
setFolderHash(draftsFolder, '');
if (FolderUserStore.currentFolderFullName() === draftsFolder) {
rl.app.reloadMessageList(true);
} else {
rl.app.folderInformation(draftFolder);
rl.app.folderInformation(draftsFolder);
}
}
}
@ -884,7 +884,7 @@ class ComposePopupView extends AbstractViewPopup {
this.bFromDraft = true;
this.draftFolder(message.folder);
this.draftsFolder(message.folder);
this.draftUid(message.uid);
this.subject(sSubject);
@ -1422,7 +1422,7 @@ class ComposePopupView extends AbstractViewPopup {
this.dragAndDropOver(false);
this.dragAndDropVisible(false);
this.draftFolder('');
this.draftsFolder('');
this.draftUid(0);
this.sending(false);

View file

@ -36,7 +36,7 @@ class FolderSystemPopupView extends AbstractViewPopup {
);
this.sentFolder = FolderUserStore.sentFolder;
this.draftFolder = FolderUserStore.draftFolder;
this.draftsFolder = FolderUserStore.draftsFolder;
this.spamFolder = FolderUserStore.spamFolder;
this.trashFolder = FolderUserStore.trashFolder;
this.archiveFolder = FolderUserStore.archiveFolder;
@ -45,7 +45,7 @@ class FolderSystemPopupView extends AbstractViewPopup {
addSubscribablesTo(FolderUserStore, {
sentFolder: fSaveSystemFolders,
draftFolder: fSaveSystemFolders,
draftsFolder: fSaveSystemFolders,
spamFolder: fSaveSystemFolders,
trashFolder: fSaveSystemFolders,
archiveFolder: fSaveSystemFolders

View file

@ -148,7 +148,7 @@ export class MailMessageList extends AbstractViewRight {
isTrashFolder: () => (FolderUserStore.trashFolder() || 0) === MessageUserStore.listEndFolder(),
isDraftFolder: () => (FolderUserStore.draftFolder() || 0) === MessageUserStore.listEndFolder(),
isDraftFolder: () => (FolderUserStore.draftsFolder() || 0) === MessageUserStore.listEndFolder(),
isSentFolder: () => (FolderUserStore.sentFolder() || 0) === MessageUserStore.listEndFolder(),

View file

@ -493,7 +493,7 @@ export class MailMessageView extends AbstractViewRight {
* @returns {boolean}
*/
isDraftFolder() {
return MessageUserStore.message() && FolderUserStore.draftFolder() === MessageUserStore.message().folder;
return MessageUserStore.message() && FolderUserStore.draftsFolder() === MessageUserStore.message().folder;
}
/**

View file

@ -24,9 +24,9 @@ abstract class FolderType
const DRAFTS = 3;
const JUNK = 4;
const TRASH = 5;
const ARCHIVE = 6;
const IMPORTANT = 10;
const FLAGGED = 11;
const ARCHIVE = 12;
const ALL = 13;
// TODO: SnappyMail

View file

@ -957,7 +957,7 @@ class Actions
if ($oSettingsLocal instanceof Settings) {
$aResult['SentFolder'] = (string)$oSettingsLocal->GetConf('SentFolder', '');
$aResult['DraftFolder'] = (string)$oSettingsLocal->GetConf('DraftFolder', '');
$aResult['DraftsFolder'] = (string)$oSettingsLocal->GetConf('DraftFolder', '');
$aResult['SpamFolder'] = (string)$oSettingsLocal->GetConf('SpamFolder', '');
$aResult['TrashFolder'] = (string)$oSettingsLocal->GetConf('TrashFolder', '');
$aResult['ArchiveFolder'] = (string)$oSettingsLocal->GetConf('ArchiveFolder', '');

View file

@ -137,7 +137,7 @@ trait Accounts
$oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount);
if ($oSettingsLocal instanceof \RainLoop\Settings) {
$aResult['SentFolder'] = (string) $oSettingsLocal->GetConf('SentFolder', '');
$aResult['DraftFolder'] = (string) $oSettingsLocal->GetConf('DraftFolder', '');
$aResult['DraftsFolder'] = (string) $oSettingsLocal->GetConf('DraftFolder', '');
$aResult['SpamFolder'] = (string) $oSettingsLocal->GetConf('SpamFolder', '');
$aResult['TrashFolder'] = (string) $oSettingsLocal->GetConf('TrashFolder', '');
$aResult['ArchiveFolder'] = (string) $oSettingsLocal->GetConf('ArchiveFolder', '');

View file

@ -457,11 +457,11 @@ trait Folders
$oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount);
$oSettingsLocal->SetConf('SentFolder', $this->GetActionParam('SentFolder', ''));
$oSettingsLocal->SetConf('DraftFolder', $this->GetActionParam('DraftFolder', ''));
$oSettingsLocal->SetConf('SpamFolder', $this->GetActionParam('SpamFolder', ''));
$oSettingsLocal->SetConf('TrashFolder', $this->GetActionParam('TrashFolder', ''));
$oSettingsLocal->SetConf('ArchiveFolder', $this->GetActionParam('ArchiveFolder', ''));
$oSettingsLocal->SetConf('SentFolder', $this->GetActionParam('Sent', ''));
$oSettingsLocal->SetConf('DraftFolder', $this->GetActionParam('Drafts', ''));
$oSettingsLocal->SetConf('SpamFolder', $this->GetActionParam('Spam', ''));
$oSettingsLocal->SetConf('TrashFolder', $this->GetActionParam('Trash', ''));
$oSettingsLocal->SetConf('ArchiveFolder', $this->GetActionParam('Archive', ''));
return $this->DefaultResponse(__FUNCTION__,
$this->SettingsProvider(true)->Save($oAccount, $oSettingsLocal));

View file

@ -12,7 +12,7 @@
</div>
<div class="control-group">
<label data-i18n="FOLDER_LIST/DRAFTS_NAME"></label>
<select data-bind="options: folderSelectList, value: draftFolder,
<select data-bind="options: folderSelectList, value: draftsFolder,
optionsText: 'name', optionsValue: 'id', optionsAfterRender: defaultOptionsAfterRender"></select>
</div>
<div class="control-group">