Resolve issue #112

This commit is contained in:
djmaze 2021-08-19 15:14:47 +02:00
parent 1f9e96f107
commit ba477e25ff
12 changed files with 82 additions and 106 deletions

View file

@ -1,8 +1,10 @@
import { ComposeType, FolderType } from 'Common/EnumsUser'; import { ComposeType/*, FolderType*/ } from 'Common/EnumsUser';
import { EmailModel } from 'Model/Email'; import { EmailModel } from 'Model/Email';
import { encodeHtml } from 'Common/Html'; import { encodeHtml } from 'Common/Html';
import { isArray } from 'Common/Utils'; import { isArray } from 'Common/Utils';
import { createElement } from 'Common/Globals'; import { createElement } from 'Common/Globals';
import { FolderUserStore } from 'Stores/User/Folder';
import { SettingsUserStore } from 'Stores/User/Settings';
/** /**
* @param {(string|number)} value * @param {(string|number)} value
@ -213,24 +215,20 @@ rl.Utils = {
/** /**
* @param {Array} aSystem * @param {Array} aSystem
* @param {Array} aList
* @param {Array=} aDisabled * @param {Array=} aDisabled
* @param {Array=} aHeaderLines * @param {Array=} aHeaderLines
* @param {Function=} fDisableCallback * @param {Function=} fDisableCallback
* @param {Function=} fRenameCallback * @param {Function=} fRenameCallback
* @param {boolean=} bSystem * @param {boolean=} bNoSelectSelectable Used in FolderCreatePopupView
* @param {boolean=} bBuildUnvisible
* @returns {Array} * @returns {Array}
*/ */
export function folderListOptionsBuilder( export function folderListOptionsBuilder(
aSystem, aSystem,
aList,
aDisabled, aDisabled,
aHeaderLines, aHeaderLines,
fDisableCallback,
fRenameCallback, fRenameCallback,
bSystem, fDisableCallback,
bBuildUnvisible bNoSelectSelectable
) { ) {
let /** let /**
* @type {?FolderModel} * @type {?FolderModel}
@ -238,71 +236,67 @@ export function folderListOptionsBuilder(
bSep = false, bSep = false,
aResult = []; aResult = [];
const sDeepPrefix = '\u00A0\u00A0\u00A0'; const sDeepPrefix = '\u00A0\u00A0\u00A0',
// FolderSystemPopupView should always be true
showUnsubscribed = (aSystem.length || bNoSelectSelectable) ? !SettingsUserStore.hideUnsubscribed() : true;
bBuildUnvisible = undefined === bBuildUnvisible ? false : !!bBuildUnvisible; fDisableCallback = fDisableCallback || (() => false);
bSystem = null == bSystem ? 0 < aSystem.length : bSystem; fRenameCallback = fRenameCallback || (oItem => oItem.name());
fDisableCallback = null != fDisableCallback ? fDisableCallback : null;
fRenameCallback = null != fRenameCallback ? fRenameCallback : null;
if (!isArray(aDisabled)) { if (!isArray(aDisabled)) {
aDisabled = []; aDisabled = [];
} }
if (!isArray(aHeaderLines)) { isArray(aHeaderLines) && aHeaderLines.forEach(line =>
aHeaderLines = [];
}
aHeaderLines.forEach(line => {
aResult.push({ aResult.push({
id: line[0], id: line[0],
name: line[1], name: line[1],
system: false, system: false,
dividerbar: false, dividerbar: false,
disabled: false disabled: false
}); })
}); );
bSep = true; bSep = true;
aSystem.forEach(oItem => { aSystem.forEach(oItem => {
aResult.push({ aResult.push({
id: oItem.fullNameRaw, id: oItem.fullNameRaw,
name: fRenameCallback ? fRenameCallback(oItem) : oItem.name(), name: fRenameCallback(oItem),
system: true, system: true,
dividerbar: bSep, dividerbar: bSep,
disabled: disabled:
!oItem.selectable || !oItem.selectable ||
aDisabled.includes(oItem.fullNameRaw) || aDisabled.includes(oItem.fullNameRaw) ||
(fDisableCallback ? fDisableCallback(oItem) : false) fDisableCallback(oItem)
}); });
bSep = false; bSep = false;
}); });
bSep = true; bSep = true;
aList.forEach(oItem => { FolderUserStore.folderList().forEach(oItem => {
// if (oItem.subscribed() || !oItem.exists || bBuildUnvisible) /*
if ( if ((oItem.subscribed() || !oItem.exists || bBuildUnvisible)
(oItem.subscribed() || !oItem.exists || bBuildUnvisible) && && (oItem.selectable || oItem.hasSubscribedSubfolders())
(oItem.selectable || oItem.hasSubscribedSubfolders()) && (FolderType.User === oItem.type() || !bSystem || oItem.hasSubscribedSubfolders()) {
) { ) {
if (FolderType.User === oItem.type() || !bSystem || oItem.hasSubscribedSubfolders()) { */
aResult.push({ if (showUnsubscribed || oItem.subscribed() || !oItem.exists || oItem.hasSubscribedSubfolders()) {
id: oItem.fullNameRaw, aResult.push({
name: id: oItem.fullNameRaw,
sDeepPrefix.repeat(oItem.deep + 1) + name:
(fRenameCallback ? fRenameCallback(oItem) : oItem.name()), sDeepPrefix.repeat(oItem.deep) +
system: false, fRenameCallback(oItem),
dividerbar: bSep, system: false,
disabled: dividerbar: bSep,
!oItem.selectable || disabled: !bNoSelectSelectable && (
aDisabled.includes(oItem.fullNameRaw) || !oItem.selectable ||
(fDisableCallback ? fDisableCallback(oItem) : false) aDisabled.includes(oItem.fullNameRaw) ||
}); fDisableCallback(oItem))
bSep = false; });
} bSep = false;
} }
if (oItem.subscribed() && oItem.subFolders.length) { if (oItem.subFolders.length) {
aResult = aResult.concat( aResult = aResult.concat(
folderListOptionsBuilder( folderListOptionsBuilder(
[], [],
@ -311,8 +305,7 @@ export function folderListOptionsBuilder(
[], [],
fDisableCallback, fDisableCallback,
fRenameCallback, fRenameCallback,
bSystem, bNoSelectSelectable
bBuildUnvisible
) )
); );
} }

View file

@ -257,13 +257,13 @@ export class FolderModel extends AbstractModel {
oFolder => (oFolder.subscribed() || oFolder.hasSubscribedSubfolders()) && !oFolder.isSystemFolder() oFolder => (oFolder.subscribed() || oFolder.hasSubscribedSubfolders()) && !oFolder.isSystemFolder()
), ),
canBeEdited: () => FolderType.User === folder.type() && folder.exists && folder.selectable, canBeEdited: () => FolderType.User === folder.type() && folder.exists/* && folder.selectable*/,
visible: () => { visible: () => {
const isSubscribed = folder.subscribed(), const isSubscribed = folder.subscribed(),
isSubFolders = folder.hasSubscribedSubfolders(); isSubFolders = folder.hasSubscribedSubfolders();
return isSubscribed || (isSubFolders && (!folder.exists || !folder.selectable)); return isSubscribed || (isSubFolders && (!folder.exists/* || !folder.selectable*/));
}, },
isSystemFolder: () => FolderType.User !== folder.type(), isSystemFolder: () => FolderType.User !== folder.type(),

View file

@ -118,25 +118,16 @@ export class FoldersUserSettings {
} }
} }
subscribeFolder(folder) { toggleFolderSubscription(folder) {
let subscribe = !folder.subscribed();
Local.set(ClientSideKeyName.FoldersLashHash, ''); Local.set(ClientSideKeyName.FoldersLashHash, '');
Remote.folderSetSubscribe(()=>0, folder.fullNameRaw, true); Remote.folderSetSubscribe(()=>0, folder.fullNameRaw, subscribe);
folder.subscribed(true); folder.subscribed(subscribe);
} }
unSubscribeFolder(folder) { toggleFolderCheckable(folder) {
Local.set(ClientSideKeyName.FoldersLashHash, ''); let checkable = !folder.checkable();
Remote.folderSetSubscribe(()=>0, folder.fullNameRaw, false); Remote.folderSetCheckable(()=>0, folder.fullNameRaw, checkable);
folder.subscribed(false); folder.checkable(checkable);
}
checkableTrueFolder(folder) {
Remote.folderSetCheckable(()=>0, folder.fullNameRaw, true);
folder.checkable(true);
}
checkableFalseFolder(folder) {
Remote.folderSetCheckable(()=>0, folder.fullNameRaw, false);
folder.checkable(false);
} }
} }

View file

@ -3,7 +3,6 @@ import ko from 'ko';
import { FolderType, FolderSortMode } from 'Common/EnumsUser'; import { FolderType, FolderSortMode } from 'Common/EnumsUser';
import { UNUSED_OPTION_VALUE } from 'Common/Consts'; import { UNUSED_OPTION_VALUE } from 'Common/Consts';
import { addObservablesTo, addSubscribablesTo } from 'Common/Utils'; import { addObservablesTo, addSubscribablesTo } from 'Common/Utils';
import { folderListOptionsBuilder } from 'Common/UtilsUser';
import { getFolderInboxName, getFolderFromCacheList } from 'Common/Cache'; import { getFolderInboxName, getFolderFromCacheList } from 'Common/Cache';
import { SettingsGet } from 'Common/Globals'; import { SettingsGet } from 'Common/Globals';
@ -107,28 +106,6 @@ export const FolderUserStore = new class {
this.folderListSystemNames().map(name => getFolderFromCacheList(name)).filter(v => v) this.folderListSystemNames().map(name => getFolderFromCacheList(name)).filter(v => v)
); );
this.folderMenuForMove = ko.computed(() =>
folderListOptionsBuilder(
this.folderListSystem(),
this.folderList(),
[this.currentFolderFullNameRaw()],
[],
null,
(item) => (item ? item.localName() : '')
)
);
this.folderMenuForFilters = ko.computed(() =>
folderListOptionsBuilder(
this.folderListSystem(),
this.folderList(),
[this.sieveAllowFileintoInbox ? '' : 'INBOX'],
[['', '']],
null,
(item) => (item ? item.localName() : '')
)
);
const const
fRemoveSystemFolderType = (observable) => () => { fRemoveSystemFolderType = (observable) => () => {
const folder = getFolderFromCacheList(observable()); const folder = getFolderFromCacheList(observable());

View file

@ -111,6 +111,9 @@
color: var(--folders-selected-color, #eee); color: var(--folders-selected-color, #eee);
} }
} }
&:not(.selectable) {
font-style: italic;
}
&.focused { &.focused {
background-color: #888; background-color: #888;

View file

@ -34,6 +34,10 @@
.folder-item { .folder-item {
&:not(.selectable) {
font-style: italic;
}
&.system .folder-name { &.system .folder-name {
font-weight: bold; font-weight: bold;
} }

View file

@ -11,6 +11,8 @@ import { SieveUserStore } from 'Stores/User/Sieve';
import { decorateKoCommands } from 'Knoin/Knoin'; import { decorateKoCommands } from 'Knoin/Knoin';
import { AbstractViewPopup } from 'Knoin/AbstractViews'; import { AbstractViewPopup } from 'Knoin/AbstractViews';
import { folderListOptionsBuilder } from 'Common/UtilsUser';
class FilterPopupView extends AbstractViewPopup { class FilterPopupView extends AbstractViewPopup {
constructor() { constructor() {
super('Filter'); super('Filter');
@ -25,7 +27,15 @@ class FilterPopupView extends AbstractViewPopup {
this.fTrueCallback = null; this.fTrueCallback = null;
this.defaultOptionsAfterRender = defaultOptionsAfterRender; this.defaultOptionsAfterRender = defaultOptionsAfterRender;
this.folderSelectList = FolderUserStore.folderMenuForFilters; this.folderSelectList = ko.computed(() =>
folderListOptionsBuilder(
FolderUserStore.folderListSystem(),
[FolderUserStore.sieveAllowFileintoInbox ? '' : 'INBOX'],
[['', '']],
item => item ? item.localName() : ''
)
);
this.selectedFolderValue.subscribe(() => this.filter() && this.filter().actionValueError(false)); this.selectedFolderValue.subscribe(() => this.filter() && this.filter().actionValueError(false));

View file

@ -25,14 +25,14 @@ class FolderCreatePopupView extends AbstractViewPopup {
this.parentFolderSelectList = ko.computed(() => this.parentFolderSelectList = ko.computed(() =>
folderListOptionsBuilder( folderListOptionsBuilder(
[], [],
FolderUserStore.folderList(),
[], [],
[['', '']], [['', '']],
oItem =>
oItem ? (oItem.isSystemFolder() ? oItem.name() + ' ' + oItem.manageFolderSystemName() : oItem.name()) : '',
FolderUserStore.namespace FolderUserStore.namespace
? item => FolderUserStore.namespace !== item.fullNameRaw.substr(0, FolderUserStore.namespace.length) ? item => FolderUserStore.namespace !== item.fullNameRaw.substr(0, FolderUserStore.namespace.length)
: null, : null,
oItem => true
oItem ? (oItem.isSystemFolder() ? oItem.name() + ' ' + oItem.manageFolderSystemName() : oItem.name()) : ''
) )
); );

View file

@ -30,16 +30,11 @@ class FolderSystemPopupView extends AbstractViewPopup {
this.folderSelectList = ko.computed(() => this.folderSelectList = ko.computed(() =>
folderListOptionsBuilder( folderListOptionsBuilder(
[], [],
FolderUserStore.folderList(),
FolderUserStore.folderListSystemNames(), FolderUserStore.folderListSystemNames(),
[ [
['', this.sChooseOnText], ['', this.sChooseOnText],
[UNUSED_OPTION_VALUE, this.sUnuseText] [UNUSED_OPTION_VALUE, this.sUnuseText]
], ]
null,
null,
null,
true
) )
); );

View file

@ -15,7 +15,7 @@ import { UNUSED_OPTION_VALUE } from 'Common/Consts';
import { doc, leftPanelDisabled, moveAction, Settings, SettingsGet } from 'Common/Globals'; import { doc, leftPanelDisabled, moveAction, Settings, SettingsGet } from 'Common/Globals';
import { computedPaginatorHelper, showMessageComposer } from 'Common/UtilsUser'; import { computedPaginatorHelper, showMessageComposer, folderListOptionsBuilder } from 'Common/UtilsUser';
import { FileInfo } from 'Common/File'; import { FileInfo } from 'Common/File';
import { mailBox, serverRequest } from 'Common/Links'; import { mailBox, serverRequest } from 'Common/Links';
@ -78,7 +78,14 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
this.isMessageSelected = MessageUserStore.isMessageSelected; this.isMessageSelected = MessageUserStore.isMessageSelected;
this.messageListSearch = MessageUserStore.listSearch; this.messageListSearch = MessageUserStore.listSearch;
this.messageListError = MessageUserStore.listError; this.messageListError = MessageUserStore.listError;
this.folderMenuForMove = FolderUserStore.folderMenuForMove; this.folderMenuForMove = ko.computed(() =>
folderListOptionsBuilder(
FolderUserStore.folderListSystem(),
[FolderUserStore.currentFolderFullNameRaw()],
[],
item => item ? item.localName() : ''
)
);
this.useCheckboxesInList = SettingsUserStore.useCheckboxesInList; this.useCheckboxesInList = SettingsUserStore.useCheckboxesInList;

View file

@ -233,7 +233,7 @@ class Folder implements \JsonSerializable
'FullName' => $this->FullName(), 'FullName' => $this->FullName(),
'FullNameRaw' => $this->FullNameRaw(), 'FullNameRaw' => $this->FullNameRaw(),
'Delimiter' => (string) $this->Delimiter(), 'Delimiter' => (string) $this->Delimiter(),
'HasVisibleSubFolders' => $this->HasVisibleSubFolders(), // 'HasVisibleSubFolders' => $this->HasVisibleSubFolders(),
'Subscribed' => $this->bSubscribed, 'Subscribed' => $this->bSubscribed,
'Exists' => $this->bExists, 'Exists' => $this->bExists,
'Selectable' => $this->IsSelectable(), 'Selectable' => $this->IsSelectable(),

View file

@ -14,14 +14,10 @@
<span class="delete-folder e-action fontastic" data-bind="visible: canBeDeleted() && !deleteAccess(), click: function (oFolder) { $root.folderForDeletion(oFolder); }">🗑</span> <span class="delete-folder e-action fontastic" data-bind="visible: canBeDeleted() && !deleteAccess(), click: function (oFolder) { $root.folderForDeletion(oFolder); }">🗑</span>
</td> </td>
<td data-i18n="[title]SETTINGS_FOLDERS/HELP_SHOW_HIDE_FOLDER"> <td data-i18n="[title]SETTINGS_FOLDERS/HELP_SHOW_HIDE_FOLDER">
<span class="unsubscribed-folder e-action fontastic" data-bind="visible: canBeSubscribed() && !subscribed(), click: function(oFolder) { $root.subscribeFolder(oFolder); }">👁</span> <span class="e-action fontastic" data-bind="css: {'unsubscribed-folder':!subscribed()}, visible: canBeSubscribed(), click: function(oFolder) { $root.toggleFolderSubscription(oFolder); }">👁</span>
<span class="e-action fontastic" data-bind="visible: canBeSubscribed() && subscribed(), click: function(oFolder) { $root.unSubscribeFolder(oFolder); }">👁</span>
</td> </td>
<td data-bind="visible: $root.displaySpecSetting" data-i18n="[title]SETTINGS_FOLDERS/HELP_CHECK_FOR_NEW_MESSAGES"> <td data-bind="visible: $root.displaySpecSetting" data-i18n="[title]SETTINGS_FOLDERS/HELP_CHECK_FOR_NEW_MESSAGES">
<span class="unchecked-folder e-action" data-bind="visible: canBeSelected() && subscribed() && !checkable(), click: function(oFolder) { $root.checkableTrueFolder(oFolder); }"> <span class="e-action" data-bind="css: {'check-folder':checkable(), 'unchecked-folder':!checkable()}, visible: canBeSelected() && subscribed(), click: function(oFolder) { $root.toggleFolderCheckable(oFolder); }">
<i class="icon-check-mark-circle-two"></i>
</span>
<span class="check-folder e-action" data-bind="visible: canBeSelected() && subscribed() && checkable(), click: function(oFolder) { $root.checkableFalseFolder(oFolder); }">
<i class="icon-check-mark-circle-two"></i> <i class="icon-check-mark-circle-two"></i>
</span> </span>
</td> </td>