Skip to content

Commit dea4bbc

Browse files
committed
client/dbOffline: Simplify stats computation
Avoid using stats names from constant since the indirection makes it harder to reason about for both humans and the TypeScript compiler. Also add a note about the `updateStats` being broken with `itemStatuses` from server since this confused me a bit. For example, if user marks an entry as starred, server will return its unread status as well, and it would increase the statistic. For proper synchronization, we would need journal. Thankfully, the `dbOnline` module passes `updateStats = false`.
1 parent c319098 commit dea4bbc

File tree

1 file changed

+30
-18
lines changed

1 file changed

+30
-18
lines changed

client/js/selfoss-db-offline.ts

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ export type ItemStatus = {
1616
starred?: boolean;
1717
};
1818

19-
const ENTRY_STATUS_NAMES: Array<'unread' | 'starred'> = ['unread', 'starred'];
19+
function statToNumber(stat: boolean | undefined): number {
20+
return stat === undefined ? 0 : stat ? 1 : -1;
21+
}
2022

2123
export default class DbOffline {
2224
/** @var Date the datetime of the newest garbage collected entry, i.e. deleted because not of interest. */
@@ -406,15 +408,15 @@ export default class DbOffline {
406408
}
407409

408410
enqueueStatuses(
409-
statuses: { entryId: string; name: string; value: string }[],
411+
statuses: { entryId: number; name: string; value: boolean }[],
410412
): Promise<void> {
411413
if (statuses) {
412414
this.needsSync = true;
413415
}
414416

415417
const d = new Date();
416418
const newQueuedStatuses = statuses.map((newStatus) => ({
417-
entryId: parseInt(newStatus.entryId),
419+
entryId: newStatus.entryId,
418420
name: newStatus.name,
419421
value: newStatus.value,
420422
datetime: d,
@@ -459,6 +461,16 @@ export default class DbOffline {
459461
return selfoss.dbOnline._syncBegin();
460462
}
461463

464+
/**
465+
* Update `unread` and `starred` statuses of items in the offline database.
466+
*
467+
* @param dequee - also clear the local status updates queued to upload to server
468+
* @param updateStats - also update local statistics
469+
*
470+
* Note: Do not use `updateStats` with `itemStatuses` obtained from the server.
471+
* The server report cannot distinguish which of the status fields was changed
472+
* so both will be considered changed.
473+
*/
462474
storeEntryStatuses(
463475
itemStatuses: ItemStatus[],
464476
dequeue: boolean = false,
@@ -477,21 +489,21 @@ export default class DbOffline {
477489

478490
// update entries statuses
479491
itemStatuses.forEach((itemStatus) => {
480-
const newStatus = {};
481-
482-
ENTRY_STATUS_NAMES.forEach((statusName) => {
483-
if (statusName in itemStatus) {
484-
newStatus[statusName] = itemStatus[statusName];
485-
486-
if (updateStats) {
487-
if (itemStatus[statusName]) {
488-
statsDiff[statusName]++;
489-
} else {
490-
statsDiff[statusName]--;
491-
}
492-
}
493-
}
494-
});
492+
const newStatus = {
493+
...('unread' in itemStatus && {
494+
unread: itemStatus.unread,
495+
}),
496+
...('starred' in itemStatus && {
497+
starred: itemStatus.starred,
498+
}),
499+
};
500+
501+
if (updateStats) {
502+
statsDiff.unread += statToNumber(itemStatus.unread);
503+
statsDiff.starred += statToNumber(
504+
itemStatus.starred,
505+
);
506+
}
495507

496508
const id = itemStatus.id;
497509
selfoss.db.storage.entries.get(id).then(

0 commit comments

Comments
 (0)