This commit is contained in:
djmaze 2021-08-24 15:53:39 +02:00
parent 2def2fc118
commit 327d6c32ca
9 changed files with 115 additions and 112 deletions

View file

@ -25,7 +25,7 @@ const
INBOX: 1,
SENT: 2,
DRAFTS: 3,
JUNK: 4,
SPAM: 4, // JUNK
TRASH: 5,
// IMPORTANT: 10,
// FLAGGED: 11,
@ -39,6 +39,8 @@ normalizeFolder = sFolderFullNameRaw => ('' === sFolderFullNameRaw
? sFolderFullNameRaw
: '';
let SystemFolders = {};
export class FolderCollectionModel extends AbstractCollectionModel
{
/*
@ -59,7 +61,11 @@ export class FolderCollectionModel extends AbstractCollectionModel
*/
static reviveFromJson(object) {
const expandedFolders = Local.get(ClientSideKeyName.ExpandedFolders);
return super.reviveFromJson(object, (oFolder, self) => {
if (object && object.SystemFolders) {
SystemFolders = object.SystemFolders;
}
return super.reviveFromJson(object, oFolder => {
let oCacheFolder = Cache.getFolderFromCacheList(oFolder.FullNameRaw);
/*
if (oCacheFolder) {
@ -68,7 +74,7 @@ export class FolderCollectionModel extends AbstractCollectionModel
}
*/
if (!oCacheFolder && (oCacheFolder = FolderModel.reviveFromJson(oFolder))) {
if (oFolder.FullNameRaw == self.SystemFolders[ServerFolderType.INBOX]) {
if (oFolder.FullNameRaw == SystemFolders[ServerFolderType.INBOX]) {
oCacheFolder.type(FolderType.Inbox);
Cache.setFolderInboxName(oFolder.FullNameRaw);
}
@ -76,6 +82,25 @@ export class FolderCollectionModel extends AbstractCollectionModel
}
if (oCacheFolder) {
switch (oFolder.FullNameRaw)
{
case (SettingsGet('SentFolder') || SystemFolders[ServerFolderType.SENT]):
oCacheFolder.type(FolderType.Sent);
break;
case (SettingsGet('DraftFolder') || SystemFolders[ServerFolderType.DRAFTS]):
oCacheFolder.type(FolderType.Drafts);
break;
case (SettingsGet('SpamFolder') || SystemFolders[ServerFolderType.SPAM]):
oCacheFolder.type(FolderType.Spam);
break;
case (SettingsGet('TrashFolder') || SystemFolders[ServerFolderType.TRASH]):
oCacheFolder.type(FolderType.Trash);
break;
case (SettingsGet('ArchiveFolder') || SystemFolders[ServerFolderType.ARCHIVE]):
oCacheFolder.type(FolderType.Archive);
break;
}
oCacheFolder.collapsed(!expandedFolders
|| !isArray(expandedFolders)
|| !expandedFolders.includes(oCacheFolder.fullNameHash));
@ -104,6 +129,23 @@ export class FolderCollectionModel extends AbstractCollectionModel
FolderUserStore.displaySpecSetting(0 >= cnt
|| Math.max(10, Math.min(100, pInt(Settings.app('folderSpecLimit')))) < cnt);
if (SystemFolders &&
!('' +
SettingsGet('SentFolder') +
SettingsGet('DraftFolder') +
SettingsGet('SpamFolder') +
SettingsGet('TrashFolder') +
SettingsGet('ArchiveFolder'))
) {
FolderUserStore.saveSystemFolders({
SentFolder: SystemFolders[ServerFolderType.SENT] || null,
DraftFolder: SystemFolders[ServerFolderType.DRAFTS] || null,
SpamFolder: SystemFolders[ServerFolderType.SPAM] || null,
TrashFolder: SystemFolders[ServerFolderType.TRASH] || null,
ArchiveFolder: SystemFolders[ServerFolderType.ARCHIVE] || null
});
}
FolderUserStore.folderList(this);
if (undefined !== this.Namespace) {
@ -115,41 +157,13 @@ export class FolderCollectionModel extends AbstractCollectionModel
FolderUserStore.folderListOptimized(!!this.Optimized);
FolderUserStore.sortSupported(!!this.IsSortSupported);
let update = false;
if (
this.SystemFolders &&
!('' +
SettingsGet('SentFolder') +
SettingsGet('DraftFolder') +
SettingsGet('SpamFolder') +
SettingsGet('TrashFolder') +
SettingsGet('ArchiveFolder'))
) {
Settings.set('SentFolder', this.SystemFolders[ServerFolderType.SENT] || null);
Settings.set('DraftFolder', this.SystemFolders[ServerFolderType.DRAFTS] || null);
Settings.set('SpamFolder', this.SystemFolders[ServerFolderType.JUNK] || null);
Settings.set('TrashFolder', this.SystemFolders[ServerFolderType.TRASH] || null);
Settings.set('ArchiveFolder', this.SystemFolders[ServerFolderType.ARCHIVE] || null);
update = true;
}
FolderUserStore.sentFolder(normalizeFolder(SettingsGet('SentFolder')));
FolderUserStore.draftFolder(normalizeFolder(SettingsGet('DraftFolder')));
FolderUserStore.spamFolder(normalizeFolder(SettingsGet('SpamFolder')));
FolderUserStore.trashFolder(normalizeFolder(SettingsGet('TrashFolder')));
FolderUserStore.archiveFolder(normalizeFolder(SettingsGet('ArchiveFolder')));
if (update) {
rl.app.Remote.saveSystemFolders(()=>0, {
SentFolder: FolderUserStore.sentFolder(),
DraftFolder: FolderUserStore.draftFolder(),
SpamFolder: FolderUserStore.spamFolder(),
TrashFolder: FolderUserStore.trashFolder(),
ArchiveFolder: FolderUserStore.archiveFolder()
});
}
// FolderUserStore.folderList.valueHasMutated();
Local.set(ClientSideKeyName.FoldersLashHash, this.FoldersHash);
}
@ -254,26 +268,22 @@ export class FolderModel extends AbstractModel {
hasSubscribedSubfolders:
() =>
!!folder.subFolders.find(
!!folder.subFolders().find(
oFolder => (oFolder.subscribed() || oFolder.hasSubscribedSubfolders()) && !oFolder.isSystemFolder()
),
canBeEdited: () => FolderType.User === folder.type() && folder.exists/* && folder.selectable*/,
visible: () => {
const isSubscribed = folder.subscribed(),
isSubFolders = folder.hasSubscribedSubfolders();
return isSubscribed || (isSubFolders && (!folder.exists/* || !folder.selectable*/));
const hasSubFolders = folder.hasSubscribedSubfolders();
return folder.subscribed() || hasSubFolders;
},
isSystemFolder: () => FolderType.User !== folder.type(),
hidden: () => {
const isSystem = folder.isSystemFolder(),
isSubFolders = folder.hasSubscribedSubfolders();
return (isSystem && !isSubFolders) || (!folder.selectable && !isSubFolders);
let hasSubFolders = folder.hasSubscribedSubfolders();
return (folder.isSystemFolder() || !folder.selectable) && !hasSubFolders;
},
printableUnreadCount: () => {
@ -298,7 +308,7 @@ export class FolderModel extends AbstractModel {
return null;
},
canBeDeleted: () => !folder.isSystemFolder() && !folder.subFolders.length,
canBeDeleted: () => !folder.isSystemFolder() && !folder.subFolders().length,
canBeSubscribed: () => !folder.isSystemFolder()
&& SettingsUserStore.hideUnsubscribed()
@ -329,16 +339,16 @@ export class FolderModel extends AbstractModel {
},
collapsed: {
read: () => !folder.hidden() && folder.collapsedPrivate(),
write: (value) => {
folder.collapsedPrivate(value);
}
read: () => folder.isInbox() && FolderUserStore.singleRootFolder()
? false
: !folder.hidden() && folder.collapsedPrivate(),
write: value => folder.collapsedPrivate(value)
},
hasUnreadMessages: () => 0 < folder.messageCountUnread() && folder.printableUnreadCount(),
hasSubscribedUnreadMessagesSubfolders: () =>
!!folder.subFolders.find(
!!folder.subFolders().find(
folder => folder.hasUnreadMessages() || folder.hasSubscribedUnreadMessagesSubfolders()
)
});

View file

@ -4,7 +4,7 @@ import { FolderType, FolderSortMode } from 'Common/EnumsUser';
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
import { addObservablesTo, addSubscribablesTo } from 'Common/Utils';
import { getFolderInboxName, getFolderFromCacheList } from 'Common/Cache';
import { SettingsGet } from 'Common/Globals';
import { Settings, SettingsGet } from 'Common/Globals';
export const FolderUserStore = new class {
constructor() {
@ -55,9 +55,17 @@ export const FolderUserStore = new class {
() => !this.draftFolder() || UNUSED_OPTION_VALUE === this.draftFolder()
);
this.foldersListWithSingleInboxRootFolder = ko.computed(
() => !this.folderList.find(folder => folder && !folder.isSystemFolder() && folder.visible())
);
// foldersListWithSingleInboxRootFolder
/** returns true when there are no non-system folders in the root of the folders tree */
this.singleRootFolder = ko.computed(() => {
let multiple = false;
this.folderList.forEach(folder => {
let subscribed = folder.subscribed(),
hasSub = folder.hasSubscribedSubfolders();
multiple |= (!folder.isSystemFolder() || (hasSub && !folder.isInbox())) && (subscribed || hasSub)
});
return !multiple;
});
this.currentFolderFullNameRaw = ko.computed(() => (this.currentFolder() ? this.currentFolder().fullNameRaw : ''));
@ -156,4 +164,16 @@ export const FolderUserStore = new class {
return result.filter((value, index, self) => self.indexOf(value) == index);
}
saveSystemFolders(folders) {
folders = folders || {
SentFolder: FolderUserStore.sentFolder(),
DraftFolder: FolderUserStore.draftFolder(),
SpamFolder: FolderUserStore.spamFolder(),
TrashFolder: FolderUserStore.trashFolder(),
ArchiveFolder: FolderUserStore.archiveFolder()
};
Object.entries(folders).forEach(([k,v])=>Settings.set(k,v));
rl.app.Remote.saveSystemFolders(()=>0, folders);
}
};

View file

@ -4,6 +4,10 @@
.b-folders {
ul {
margin: 0;
}
.move-action-content-wrapper {
z-index: -1;
position: fixed;
@ -60,8 +64,8 @@
border-bottom: 1px solid #999;
}
.e-item {
li {
display: block;
overflow: hidden;
white-space: nowrap;
@ -143,7 +147,7 @@
font-weight: bold;
}
.b-sub-folders.collapsed {
ul.collapsed {
max-height: 0;
height: 0;
display: none;
@ -182,45 +186,39 @@
}
}
.b-folder-system-item {
.b-folders-system {
font-weight: bold;
}
.b-sub-folders .e-item a {
li li a {
padding-left: @subPadding * 1 + @folderItemPadding;
}
.b-sub-folders .b-sub-folders .e-item a {
li li li a {
padding-left: @subPadding * 2 + @folderItemPadding;
}
.b-sub-folders .b-sub-folders .b-sub-folders .e-item a {
li li li li a {
padding-left: @subPadding * 3 + @folderItemPadding;
}
.b-sub-folders .b-sub-folders .b-sub-folders .b-sub-folders .e-item a {
li li li li li a {
padding-left: @subPadding * 4 + @folderItemPadding;
}
/**/
&.single-root-inbox a.i-am-inbox {
&.single-root-inbox .b-folders-user > li > a {
display: none !important;
}
&.single-root-inbox .i-am-inbox-wrapper > .b-sub-folders {
max-height: none !important;
height: inherit !important;
display: block !important;
}
&.single-root-inbox .i-am-inbox-wrapper {
.b-sub-folders .e-item a {
&.single-root-inbox {
li li a {
padding-left: @folderItemPadding;
}
.b-sub-folders .b-sub-folders .e-item a {
li li li a {
padding-left: @subPadding * 1 + @folderItemPadding;
}
.b-sub-folders .b-sub-folders .b-sub-folders .e-item a {
li li li li a {
padding-left: @subPadding * 2 + @folderItemPadding;
}
.b-sub-folders .b-sub-folders .b-sub-folders .b-sub-folders .e-item a {
li li li li li a {
padding-left: @subPadding * 3 + @folderItemPadding;
}
}

View file

@ -2,15 +2,12 @@ import ko from 'ko';
import { SetSystemFoldersNotification } from 'Common/EnumsUser';
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
import { Settings } from 'Common/Globals';
import { defaultOptionsAfterRender, addSubscribablesTo } from 'Common/Utils';
import { folderListOptionsBuilder } from 'Common/UtilsUser';
import { initOnStartOrLangChange, i18n } from 'Common/Translator';
import { FolderUserStore } from 'Stores/User/Folder';
import Remote from 'Remote/User/Fetch';
import { AbstractViewPopup } from 'Knoin/AbstractViews';
class FolderSystemPopupView extends AbstractViewPopup {
@ -43,35 +40,14 @@ class FolderSystemPopupView extends AbstractViewPopup {
this.trashFolder = FolderUserStore.trashFolder;
this.archiveFolder = FolderUserStore.archiveFolder;
const settingsSet = Settings.set,
fSetSystemFolders = () => {
settingsSet('SentFolder', FolderUserStore.sentFolder());
settingsSet('DraftFolder', FolderUserStore.draftFolder());
settingsSet('SpamFolder', FolderUserStore.spamFolder());
settingsSet('TrashFolder', FolderUserStore.trashFolder());
settingsSet('ArchiveFolder', FolderUserStore.archiveFolder());
},
fSaveSystemFolders = (()=>{
fSetSystemFolders();
Remote.saveSystemFolders(()=>0, {
SentFolder: FolderUserStore.sentFolder(),
DraftFolder: FolderUserStore.draftFolder(),
SpamFolder: FolderUserStore.spamFolder(),
TrashFolder: FolderUserStore.trashFolder(),
ArchiveFolder: FolderUserStore.archiveFolder()
});
}).debounce(1000),
fCallback = () => {
fSetSystemFolders();
fSaveSystemFolders();
};
const fSaveSystemFolders = (()=>FolderUserStore.saveSystemFolders()).debounce(1000);
addSubscribablesTo(FolderUserStore, {
sentFolder: fCallback,
draftFolder: fCallback,
spamFolder: fCallback,
trashFolder: fCallback,
archiveFolder: fCallback
sentFolder: fSaveSystemFolders,
draftFolder: fSaveSystemFolders,
spamFolder: fSaveSystemFolders,
trashFolder: fSaveSystemFolders,
archiveFolder: fSaveSystemFolders
});
this.defaultOptionsAfterRender = defaultOptionsAfterRender;

View file

@ -32,7 +32,7 @@ export class FolderListMailBoxUserView extends AbstractViewLeft {
this.moveAction = moveAction;
this.foldersListWithSingleInboxRootFolder = FolderUserStore.foldersListWithSingleInboxRootFolder;
this.foldersListWithSingleInboxRootFolder = FolderUserStore.singleRootFolder;
this.leftPanelDisabled = leftPanelDisabled;

View file

@ -157,8 +157,7 @@ class FolderCollection extends \MailSo\Base\Collection
'IsSortSupported' => $this->IsSortSupported,
'Optimized' => $this->Optimized,
'CountRec' => $this->CountRec(),
'SystemFolders' => isset($this->SystemFolders) && \is_array($this->SystemFolders) ?
$this->SystemFolders : array()
'SystemFolders' => empty($this->SystemFolders) ? null : $this->SystemFolders
));
}
}

View file

@ -7,9 +7,9 @@
<a class="btn buttonContacts fontastic" data-bind="visible: allowContacts, click: contactsClick" data-i18n="[title]GLOBAL/CONTACTS">📇</a>
</div>
<div class="b-content">
<div class="b-folders-system" data-bind="template: { name: 'MailFolderListSystemItem', foreach: folderListSystem }"></div>
<ul class="b-folders-system" data-bind="template: { name: 'MailFolderListSystemItem', foreach: folderListSystem }"></ul>
<hr/>
<div class="b-folders-user" data-bind="template: { name: 'MailFolderListItem', foreach: folderList }"></div>
<ul class="b-folders-user" data-bind="template: { name: 'MailFolderListItem', foreach: folderList }"></ul>
<div class="move-action-content-wrapper" data-bind="visible: moveAction"></div>
</div>
<div class="b-content show-on-panel-disabled" data-bind="click: function () { leftPanelDisabled(false); }"></div>

View file

@ -1,11 +1,11 @@
<div class="e-item" data-bind="visible: visible, css: { 'i-am-inbox-wrapper': isInbox }">
<li data-bind="visible: visible">
<a data-bind="dropmessages: $data,
css: { 'i-am-inbox': isInbox, 'selected': selected() && !isSystemFolder(), 'selectable': canBeSelected, 'hidden' : hidden, 'unread-sub': hasSubscribedUnreadMessagesSubfolders, 'system': isSystemFolder, 'anim-action-class': actionBlink },
css: { 'selected': selected() && !isSystemFolder(), 'selectable': canBeSelected, 'hidden' : hidden, 'unread-sub': hasSubscribedUnreadMessagesSubfolders, 'system': isSystemFolder, 'anim-action-class': actionBlink },
attr: { 'data-unread': printableUnreadCount }">
<i data-bind="css: collapsedCss()"></i>
<!-- ko text: name --><!-- /ko -->
</a>
<!-- ko if: subFolders.length -->
<div class="b-sub-folders" data-bind="template: { name: 'MailFolderListItem', foreach: subFolders }, css: { 'collapsed': collapsed() }"></div>
<ul data-bind="template: { name: 'MailFolderListItem', foreach: subFolders }, css: { 'collapsed': collapsed() }"></ul>
<!-- /ko -->
</div>
</li>

View file

@ -1,4 +1,4 @@
<div class="e-item b-folder-system-item">
<li>
<a data-bind="dropmessages: $data,
css: { 'selected': selected, 'selectable': selectable, 'anim-action-class': actionBlink },
attr: { 'data-unread': printableUnreadCount }">
@ -7,4 +7,4 @@
<span class="inbox-star-icon fontastic"></span>
<!-- /ko -->
</a>
</div>
</li>