Use JMAP rfc8621 section-2 totalEmails, unreadEmails and isSubscribed

This commit is contained in:
the-djmaze 2022-06-01 22:50:35 +02:00
parent c5718057aa
commit 118505f91e
15 changed files with 68 additions and 72 deletions

View file

@ -229,11 +229,11 @@ export class AppUser extends AbstractApp {
setFolderHash(result.Folder, result.Hash); setFolderHash(result.Folder, result.Hash);
folderFromCache.messageCountAll(result.MessageCount); folderFromCache.messageCountAll(result.totalEmails);
let unreadCountChange = (folderFromCache.messageCountUnread() !== result.MessageUnseenCount); let unreadCountChange = (folderFromCache.messageCountUnread() !== result.unreadEmails);
folderFromCache.messageCountUnread(result.MessageUnseenCount); folderFromCache.messageCountUnread(result.unreadEmails);
if (unreadCountChange) { if (unreadCountChange) {
MessageFlagsCache.clearFolder(folderFromCache.fullName); MessageFlagsCache.clearFolder(folderFromCache.fullName);

View file

@ -148,11 +148,11 @@ folderInformationMultiply = (boot = false) => {
setFolderHash(item.Folder, item.Hash); setFolderHash(item.Folder, item.Hash);
folder.messageCountAll(item.MessageCount); folder.messageCountAll(item.totalEmails);
let unreadCountChange = folder.messageCountUnread() !== item.MessageUnseenCount; let unreadCountChange = folder.messageCountUnread() !== item.unreadEmails;
folder.messageCountUnread(item.MessageUnseenCount); folder.messageCountUnread(item.unreadEmails);
if (unreadCountChange) { if (unreadCountChange) {
MessageFlagsCache.clearFolder(folder.fullName); MessageFlagsCache.clearFolder(folder.fullName);

View file

@ -158,19 +158,18 @@ export class FolderCollectionModel extends AbstractCollectionModel
|| !isArray(expandedFolders) || !isArray(expandedFolders)
|| !expandedFolders.includes(oCacheFolder.fullName)); || !expandedFolders.includes(oCacheFolder.fullName));
if (oFolder.Extended) { if (oFolder.Hash) {
if (oFolder.Extended.Hash) { setFolderHash(oCacheFolder.fullName, oFolder.Hash);
setFolderHash(oCacheFolder.fullName, oFolder.Extended.Hash);
}
if (null != oFolder.Extended.MessageCount) {
oCacheFolder.messageCountAll(oFolder.Extended.MessageCount);
}
if (null != oFolder.Extended.MessageUnseenCount) {
oCacheFolder.messageCountUnread(oFolder.Extended.MessageUnseenCount);
}
} }
if (null != oFolder.totalEmails) {
oCacheFolder.messageCountAll(oFolder.totalEmails);
}
if (null != oFolder.unreadEmails) {
oCacheFolder.messageCountUnread(oFolder.unreadEmails);
}
return oCacheFolder; return oCacheFolder;
}); });
@ -252,7 +251,7 @@ export class FolderModel extends AbstractModel {
focused: false, focused: false,
selected: false, selected: false,
edited: false, edited: false,
subscribed: true, isSubscribed: true,
checkable: false, // Check for new messages checkable: false, // Check for new messages
askDelete: false, askDelete: false,
@ -336,7 +335,7 @@ export class FolderModel extends AbstractModel {
hasVisibleSubfolders: () => !!folder.subFolders().find(folder => folder.visible()), hasVisibleSubfolders: () => !!folder.subFolders().find(folder => folder.visible()),
hasSubscriptions: () => folder.subscribed() | !!folder.subFolders().find( hasSubscriptions: () => folder.isSubscribed() | !!folder.subFolders().find(
oFolder => { oFolder => {
const subscribed = oFolder.hasSubscriptions(); const subscribed = oFolder.hasSubscriptions();
return !oFolder.isSystemFolder() && subscribed; return !oFolder.isSystemFolder() && subscribed;
@ -359,13 +358,13 @@ export class FolderModel extends AbstractModel {
* - hasVisibleSubfolders() * - hasVisibleSubfolders()
* Or when all below conditions are true: * Or when all below conditions are true:
* - selectable() * - selectable()
* - subscribed() OR hideUnsubscribed = false * - isSubscribed() OR hideUnsubscribed = false
* - FolderType.User * - FolderType.User
* - not kolabType() * - not kolabType()
*/ */
visible: () => { visible: () => {
const selectable = folder.canBeSelected(), const selectable = folder.canBeSelected(),
visible = (folder.subscribed() | !SettingsUserStore.hideUnsubscribed()) && selectable; visible = (folder.isSubscribed() | !SettingsUserStore.hideUnsubscribed()) && selectable;
return folder.hasVisibleSubfolders() | visible; return folder.hasVisibleSubfolders() | visible;
}, },

View file

@ -17,8 +17,8 @@ export class MessageCollectionModel extends AbstractCollectionModel
this.Folder this.Folder
this.FolderHash this.FolderHash
this.Limit this.Limit
this.MessageCount this.totalEmails
this.MessageUnseenCount this.unreadEmails
this.MessageResultCount this.MessageResultCount
this.NewMessages this.NewMessages
this.Offset this.Offset

View file

@ -71,7 +71,7 @@ export class UserSettingsFolders /*extends AbstractViewSettings*/ {
Remote.abort('Folders').post('FolderRename', FolderUserStore.foldersRenaming, { Remote.abort('Folders').post('FolderRename', FolderUserStore.foldersRenaming, {
Folder: folder.fullName, Folder: folder.fullName,
NewFolderName: nameToEdit, NewFolderName: nameToEdit,
Subscribe: folder.subscribed() ? 1 : 0 Subscribe: folder.isSubscribed() ? 1 : 0
}) })
.then(data => { .then(data => {
folder.name(nameToEdit/*data.Name*/); folder.name(nameToEdit/*data.Name*/);
@ -138,7 +138,7 @@ export class UserSettingsFolders /*extends AbstractViewSettings*/ {
() => { () => {
// folderToRemove.flags.push('\\nonexistent'); // folderToRemove.flags.push('\\nonexistent');
folderToRemove.selectable(false); folderToRemove.selectable(false);
// folderToRemove.subscribed(false); // folderToRemove.isSubscribed(false);
// folderToRemove.checkable(false); // folderToRemove.checkable(false);
if (!folderToRemove.subFolders.length) { if (!folderToRemove.subFolders.length) {
removeFolderFromCacheList(folderToRemove.fullName); removeFolderFromCacheList(folderToRemove.fullName);
@ -170,12 +170,12 @@ export class UserSettingsFolders /*extends AbstractViewSettings*/ {
} }
toggleFolderSubscription(folder) { toggleFolderSubscription(folder) {
let subscribe = !folder.subscribed(); let subscribe = !folder.isSubscribed();
Remote.request('FolderSubscribe', null, { Remote.request('FolderSubscribe', null, {
Folder: folder.fullName, Folder: folder.fullName,
Subscribe: subscribe ? 1 : 0 Subscribe: subscribe ? 1 : 0
}); });
folder.subscribed(subscribe); folder.isSubscribed(subscribe);
} }
toggleFolderCheckable(folder) { toggleFolderCheckable(folder) {

View file

@ -138,7 +138,7 @@ export const FolderUserStore = new class {
folder.selectable() && folder.selectable() &&
folder.exists && folder.exists &&
timeout > folder.expires && timeout > folder.expires &&
(folder.isSystemFolder() || (folder.subscribed() && (folder.checkable() || !bDisplaySpecSetting))) (folder.isSystemFolder() || (folder.isSubscribed() && (folder.checkable() || !bDisplaySpecSetting)))
) { ) {
timeouts.push([folder.expires, folder.fullName]); timeouts.push([folder.expires, folder.fullName]);
} }

View file

@ -193,17 +193,17 @@ MessagelistUserStore.reload = (bDropPagePosition = false, bDropCurrenFolderCache
setFolderHash(collection.Folder, collection.FolderHash); setFolderHash(collection.Folder, collection.FolderHash);
if (null != collection.MessageCount) { if (null != collection.totalEmails) {
folder.messageCountAll(collection.MessageCount); folder.messageCountAll(collection.totalEmails);
} }
if (null != collection.MessageUnseenCount) { if (null != collection.unreadEmails) {
if (pInt(folder.messageCountUnread()) !== pInt(collection.MessageUnseenCount)) { if (pInt(folder.messageCountUnread()) !== pInt(collection.unreadEmails)) {
unreadCountChange = true; unreadCountChange = true;
MessageFlagsCache.clearFolder(folder.fullName); MessageFlagsCache.clearFolder(folder.fullName);
} }
folder.messageCountUnread(collection.MessageUnseenCount); folder.messageCountUnread(collection.unreadEmails);
} }
MessagelistUserStore.initUidNextAndNewMessages(folder.fullName, collection.UidNext, collection.NewMessages); MessagelistUserStore.initUidNextAndNewMessages(folder.fullName, collection.UidNext, collection.NewMessages);

View file

@ -338,14 +338,14 @@ html:not(rl-mobile) {
.flagParent { .flagParent {
padding: 0 10px 0 5px; padding: 0 10px 0 5px;
} }
.flagParent::after {
content: '☆'; /*⚐*/
}
&.flag-\\flagged .flagParent::after, &.flag-\\flagged .flagParent::after,
&.hasFlaggedSubMessage .flagParent::after { &.hasFlaggedSubMessage .flagParent::after {
color: orange; color: orange;
content: '★'; /*⚑*/ content: '★'; /*⚑*/
} }
&:not(.flag-\\flagged):not(.hasFlaggedSubMessage) .flagParent::after {
content: '☆'; /*⚐*/
}
&:not(.flag-\\flagged):not(.hasFlaggedSubMessage) .flagParent:not(:hover) { &:not(.flag-\\flagged):not(.hasFlaggedSubMessage) .flagParent:not(:hover) {
opacity: 0.5; opacity: 0.5;
} }

View file

@ -67,9 +67,8 @@ class FolderInformation implements \JsonSerializable
'Flags' => $this->Flags, 'Flags' => $this->Flags,
'PermanentFlags' => $this->PermanentFlags, 'PermanentFlags' => $this->PermanentFlags,
/* /*
'Messages' => $this->MESSAGES, 'totalEmails' => $this->MESSAGES,
'Unseen' => $this->UNSEEN, 'unreadEmails' => $this->UNSEEN,
'Recent' => $this->RECENT,
'UidNext' => $this->UIDNEXT, 'UidNext' => $this->UIDNEXT,
'UidValidity' => $this->UIDVALIDITY, 'UidValidity' => $this->UIDVALIDITY,
'Highestmodseq' => $this->HIGHESTMODSEQ, 'Highestmodseq' => $this->HIGHESTMODSEQ,

View file

@ -209,8 +209,8 @@ class Folder implements \JsonSerializable
$aStatus = $this->oImapFolder->getStatusItems(); $aStatus = $this->oImapFolder->getStatusItems();
if ($aStatus && isset($aStatus['MESSAGES'], $aStatus['UNSEEN'], $aStatus['UIDNEXT'])) { if ($aStatus && isset($aStatus['MESSAGES'], $aStatus['UNSEEN'], $aStatus['UIDNEXT'])) {
$aExtended = array( $aExtended = array(
'MessageCount' => (int) $aStatus['MESSAGES'], 'totalEmails' => (int) $aStatus['MESSAGES'],
'MessageUnseenCount' => (int) $aStatus['UNSEEN'], 'unreadEmails' => (int) $aStatus['UNSEEN'],
'UidNext' => (int) $aStatus['UIDNEXT'], 'UidNext' => (int) $aStatus['UIDNEXT'],
// 'Hash' => $this->MailClient()->GenerateFolderHash( // 'Hash' => $this->MailClient()->GenerateFolderHash(
// $this->FullName(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'], // $this->FullName(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'],
@ -223,7 +223,7 @@ class Folder implements \JsonSerializable
'Name' => $this->Name(), 'Name' => $this->Name(),
'FullName' => $this->FullName(), 'FullName' => $this->FullName(),
'Delimiter' => (string) $this->Delimiter(), 'Delimiter' => (string) $this->Delimiter(),
'Subscribed' => $this->bSubscribed, 'isSubscribed' => $this->bSubscribed,
'Exists' => $this->bExists, 'Exists' => $this->bExists,
'Selectable' => $this->IsSelectable(), 'Selectable' => $this->IsSelectable(),
'Flags' => $this->FlagsLowerCase(), 'Flags' => $this->FlagsLowerCase(),

View file

@ -546,8 +546,8 @@ class MailClient
return array( return array(
'Folder' => $sFolderName, 'Folder' => $sFolderName,
'Hash' => $this->GenerateFolderHash($sFolderName, $iCount, $iUidNext, $iHighestModSeq), 'Hash' => $this->GenerateFolderHash($sFolderName, $iCount, $iUidNext, $iHighestModSeq),
'MessageCount' => $iCount, 'totalEmails' => $iCount,
'MessageUnseenCount' => $iUnseenCount, 'unreadEmails' => $iUnseenCount,
'UidNext' => $iUidNext, 'UidNext' => $iUidNext,
'MessagesFlags' => $aFlags, 'MessagesFlags' => $aFlags,
'HighestModSeq' => $iHighestModSeq, 'HighestModSeq' => $iHighestModSeq,
@ -836,8 +836,8 @@ class MailClient
$oMessageCollection->Search = $sSearch; $oMessageCollection->Search = $sSearch;
$oMessageCollection->ThreadUid = $oParams->iThreadUid; $oMessageCollection->ThreadUid = $oParams->iThreadUid;
$oMessageCollection->Filtered = '' !== \MailSo\Config::$MessageListPermanentFilter; $oMessageCollection->Filtered = '' !== \MailSo\Config::$MessageListPermanentFilter;
$oMessageCollection->MessageCount = $iMessageRealCount; $oMessageCollection->totalEmails = $iMessageRealCount;
$oMessageCollection->MessageUnseenCount = $iMessageUnseenCount; $oMessageCollection->unreadEmails = $iMessageUnseenCount;
$aUids = array(); $aUids = array();
$aAllThreads = []; $aAllThreads = [];

View file

@ -25,12 +25,12 @@ class MessageCollection extends \MailSo\Base\Collection
/** /**
* @var int * @var int
*/ */
public $MessageCount = 0; public $totalEmails = 0;
/** /**
* @var int * @var int
*/ */
public $MessageUnseenCount = 0; public $unreadEmails = 0;
/** /**
* @var int * @var int
@ -95,8 +95,8 @@ class MessageCollection extends \MailSo\Base\Collection
public function jsonSerialize() public function jsonSerialize()
{ {
return array_merge(parent::jsonSerialize(), array( return array_merge(parent::jsonSerialize(), array(
'MessageCount' => $this->MessageCount, 'totalEmails' => $this->totalEmails,
'MessageUnseenCount' => $this->MessageUnseenCount, 'unreadEmails' => $this->unreadEmails,
'MessageResultCount' => $this->MessageResultCount, 'MessageResultCount' => $this->MessageResultCount,
'Folder' => $this->FolderName, 'Folder' => $this->FolderName,
'FolderHash' => $this->FolderHash, 'FolderHash' => $this->FolderHash,

View file

@ -457,8 +457,8 @@ trait Folders
$aResult[] = [ $aResult[] = [
'Folder' => $aInboxInformation['Folder'], 'Folder' => $aInboxInformation['Folder'],
'Hash' => $aInboxInformation['Hash'], 'Hash' => $aInboxInformation['Hash'],
'MessageCount' => $aInboxInformation['MessageCount'], 'totalEmails' => $aInboxInformation['totalEmails'],
'MessageUnseenCount' => $aInboxInformation['MessageUnseenCount'], 'unreadEmails' => $aInboxInformation['unreadEmails'],
]; ];
} }
} }

View file

@ -266,21 +266,24 @@ trait Response
if ($mResponse instanceof \MailSo\Mail\Folder) if ($mResponse instanceof \MailSo\Mail\Folder)
{ {
$aExtended = null; $aResult = $mResponse->jsonSerialize();
$aStatus = $mResponse->Status(); $aStatus = $mResponse->Status();
if ($aStatus && isset($aStatus['MESSAGES'], $aStatus['UNSEEN'], $aStatus['UIDNEXT'])) { if ($aStatus && isset($aStatus['MESSAGES'], $aStatus['UNSEEN'], $aStatus['UIDNEXT'])) {
$aExtended = array( $aResult = \array_merge(
'MessageCount' => (int) $aStatus['MESSAGES'], $aResult,
'MessageUnseenCount' => (int) $aStatus['UNSEEN'], [
'UidNext' => (int) $aStatus['UIDNEXT'], 'totalEmails' => (int) $aStatus['MESSAGES'],
'Hash' => $this->MailClient()->GenerateFolderHash( 'unreadEmails' => (int) $aStatus['UNSEEN'],
$mResponse->FullName(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'], 'UidNext' => (int) $aStatus['UIDNEXT'],
empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ']) 'Hash' => $this->MailClient()->GenerateFolderHash(
$mResponse->FullName(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'],
empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ'])
]
); );
} }
if (null === $this->aCheckableFolder) if (null === $this->aCheckableFolder) {
{
$aCheckable = \json_decode( $aCheckable = \json_decode(
$this->SettingsProvider(true) $this->SettingsProvider(true)
->Load($this->getAccountFromToken()) ->Load($this->getAccountFromToken())
@ -288,14 +291,9 @@ trait Response
); );
$this->aCheckableFolder = \is_array($aCheckable) ? $aCheckable : array(); $this->aCheckableFolder = \is_array($aCheckable) ? $aCheckable : array();
} }
$aResult['Checkable'] = \in_array($mResponse->FullName(), $this->aCheckableFolder);
return \array_merge( return $aResult;
$mResponse->jsonSerialize(),
array(
'Checkable' => \in_array($mResponse->FullName(), $this->aCheckableFolder),
'Extended' => $aExtended,
)
);
} }
if ($mResponse instanceof \MailSo\Base\Collection) if ($mResponse instanceof \MailSo\Base\Collection)

View file

@ -15,11 +15,11 @@
<span class="e-action fontastic" data-bind="visible: canBeDeleted() && !askDelete(), click: $root.folderForDeletion">🗑</span> <span class="e-action fontastic" data-bind="visible: canBeDeleted() && !askDelete(), click: $root.folderForDeletion">🗑</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="e-action fontastic" data-bind="css: {'unsubscribed-folder':!subscribed()}, visible: canBeSubscribed(), click: $root.toggleFolderSubscription">👁</span> <span class="e-action fontastic" data-bind="css: {'unsubscribed-folder':!isSubscribed()}, visible: canBeSubscribed(), click: $root.toggleFolderSubscription">👁</span>
</td> </td>
<!-- ko if: $root.displaySpecSetting --> <!-- ko if: $root.displaySpecSetting -->
<td data-i18n="[title]SETTINGS_FOLDERS/HELP_CHECK_FOR_NEW_MESSAGES"> <td data-i18n="[title]SETTINGS_FOLDERS/HELP_CHECK_FOR_NEW_MESSAGES">
<span class="e-action" data-bind="css: {'check-folder':checkable(), 'unchecked-folder':!checkable()}, visible: canBeSelected() && subscribed(), click: $root.toggleFolderCheckable"> <span class="e-action" data-bind="css: {'check-folder':checkable(), 'unchecked-folder':!checkable()}, visible: canBeSelected() && isSubscribed(), click: $root.toggleFolderCheckable">
<i class="icon-check-mark-circle-two"></i> <i class="icon-check-mark-circle-two"></i>
</span> </span>
</td> </td>