Merge branch 'lf/hark-final-fix'

This commit is contained in:
Liam Fitzgerald 2021-03-24 12:17:27 +10:00
commit dfb313dba3
No known key found for this signature in database
GPG Key ID: D390E12C61D1CFFB
6 changed files with 93 additions and 33 deletions

View File

@ -293,7 +293,7 @@
~(tap by unreads-count)
|= [=stats-index:store count=@ud]
:* stats-index
~(wyt in (~(gut by by-index) stats-index ~))
(~(gut by by-index) stats-index ~)
[%count count]
(~(gut by last-seen) stats-index *time)
==
@ -304,7 +304,7 @@
~(tap by unreads-each)
|= [=stats-index:store indices=(set index:graph-store)]
:* stats-index
~(wyt in (~(gut by by-index) stats-index ~))
(~(gut by by-index) stats-index ~)
[%each indices]
(~(gut by last-seen) stats-index *time)
==
@ -317,7 +317,7 @@
~
:- ~
:* stats-index
~(wyt in nots)
nots
[%count 0]
*time
==

View File

@ -151,7 +151,7 @@
^- json
%- pairs
:~ unreads+(unread unreads.s)
notifications+(numb notifications.s)
notifications+a+(turn ~(tap in notifications.s) notif-ref)
last+(time last-seen.s)
==
++ added

View File

@ -150,7 +150,7 @@
[index notification]
::
+$ stats
[notifications=@ud =unreads last-seen=@da]
[notifications=(set [time index]) =unreads last-seen=@da]
::
+$ unreads
$% [%count num=@ud]

View File

@ -1783,30 +1783,36 @@
"dependencies": {
"@babel/runtime": {
"version": "7.12.5",
"bundled": true,
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
"integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
},
"@types/lodash": {
"version": "4.14.168",
"bundled": true
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz",
"integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q=="
},
"@urbit/eslint-config": {
"version": "1.0.0",
"bundled": true
"resolved": "https://registry.npmjs.org/@urbit/eslint-config/-/eslint-config-1.0.0.tgz",
"integrity": "sha512-Xmzb6MvM7KorlPJEq/hURZZ4BHSVy/7CoQXWogsBSTv5MOZnMqwNKw6yt24k2AO/2UpHwjGptimaNLqFfesJbw=="
},
"big-integer": {
"version": "1.6.48",
"bundled": true
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
},
"lodash": {
"version": "4.17.20",
"bundled": true
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
},
"regenerator-runtime": {
"version": "0.13.7",
"bundled": true
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
}
}
},

View File

@ -8,11 +8,11 @@ import {
} from '@urbit/api';
import { makePatDa } from '~/logic/lib/util';
import _ from 'lodash';
import { StoreState } from '../store/type';
import { BigIntOrderedMap } from '../lib/BigIntOrderedMap';
import useHarkState, { HarkState } from '../state/hark';
import { compose } from 'lodash/fp';
import { reduceState } from '../state/base';
import bigInt, {BigInteger} from 'big-integer';
export const HarkReducer = (json: any) => {
const data = _.get(json, 'harkUpdate', false);
@ -56,9 +56,24 @@ function reduce(data) {
seenIndex,
removeGraph,
readAll,
calculateCount
]);
}
function calculateCount(state: HarkState) {
let count = 0;
_.forEach(state.unreads.graph, (graphs) => {
_.forEach(graphs, graph => {
count += (graph?.notifications || []).length;
});
});
_.forEach(state.unreads.group, group => {
count += (group?.notifications || []).length;
})
state.notificationsCount = count;
return state;
}
function groupInitial(json: any, state: HarkState): HarkState {
const data = _.get(json, 'initial', false);
if (data) {
@ -191,8 +206,10 @@ function unreads(json: any, state: HarkState): HarkState {
if(data) {
data.forEach(({ index, stats }) => {
const { unreads, notifications, last } = stats;
state = updateNotificationStats(state, index, 'notifications', x => x + notifications);
state = updateNotificationStats(state, index, 'last', () => last);
updateNotificationStats(state, index, 'last', () => last);
_.each(notifications, ({ time, index }) => {
addNotificationToUnread(state, index, makePatDa(time));
});
if('count' in unreads) {
state = updateUnreadCount(state, index, (u = 0) => u + unreads.count);
} else {
@ -251,18 +268,53 @@ function updateUnreads(state: HarkState, index: NotifIndex, f: (us: Set<string>)
return state;
}
function updateNotificationStats(state: HarkState, index: NotifIndex, statField: 'notifications' | 'unreads' | 'last', f: (x: number) => number): HarkState {
if(statField === 'notifications') {
state.notificationsCount = f(state.notificationsCount);
function addNotificationToUnread(state: HarkState, index: NotifIndex, time: BigInteger) {
if('graph' in index) {
const path = [index.graph.graph, index.graph.index, 'notifications'];
const curr = _.get(state.unreads.graph, path, []);
_.set(state.unreads.graph, path,
[
...curr.filter(c => !(c.time.eq(time) && notifIdxEqual(c.index, index))),
{ time, index}
]
);
} else if ('group' in index) {
const path = [index.group.group, 'notifications'];
const curr = _.get(state.unreads.group, path, []);
_.set(state.unreads.group, path,
[
...curr.filter(c => !(c.time.eq(time) && notifIdxEqual(c.index, index))),
{ time, index}
]
);
}
if ('graph' in index) {
const curr = _.get(state.unreads.graph, [index.graph.graph, index.graph.index, statField], 0);
_.set(state.unreads.graph, [index.graph.graph, index.graph.index, statField], f(curr));
} else if('group' in index) {
const curr = _.get(state.unreads.group, [index.group, statField], 0);
_.set(state.unreads.group, [index.group, statField], f(curr));
}
function removeNotificationFromUnread(state: HarkState, index: NotifIndex, time: BigInteger) {
if('graph' in index) {
const path = [index.graph.graph, index.graph.index, 'notifications'];
const curr = _.get(state.unreads.graph, path, []);
_.set(state.unreads.graph, path,
curr.filter(c => !(c.time.eq(time) && notifIdxEqual(c.index, index))),
);
} else if ('group' in index) {
const path = [index.group.group, 'notifications'];
const curr = _.get(state.unreads.group, path, []);
_.set(state.unreads.group, path,
curr.filter(c => !(c.time.eq(time) && notifIdxEqual(c.index, index))),
);
}
return state;
}
function updateNotificationStats(state: HarkState, index: NotifIndex, statField: 'unreads' | 'last', f: (x: number) => number) {
if('graph' in index) {
const curr = _.get(state.unreads.graph, [index.graph.graph, index.graph.index, statField], 0);
_.set(state.unreads.graph, [index.graph.graph, index.graph.index, statField], f(curr));
} else if('group' in index) {
const curr = _.get(state.unreads.group, [index.group.group, statField], 0);
_.set(state.unreads.group, [index.group.group, statField], f(curr));
}
}
function added(json: any, state: HarkState): HarkState {
@ -271,18 +323,15 @@ function added(json: any, state: HarkState): HarkState {
const { index, notification } = data;
const time = makePatDa(data.time);
const timebox = state.notifications.get(time) || [];
addNotificationToUnread(state, index, time);
const arrIdx = timebox.findIndex(idxNotif =>
notifIdxEqual(index, idxNotif.index)
);
if (arrIdx !== -1) {
if (timebox[arrIdx]?.notification?.read) {
state = updateNotificationStats(state, index, 'notifications', x => x+1);
}
timebox[arrIdx] = { index, notification };
state.notifications.set(time, timebox);
} else {
state = updateNotificationStats(state, index, 'notifications', x => x+1);
state.notifications.set(time, [...timebox, { index, notification }]);
}
}
@ -361,7 +410,7 @@ function read(json: any, state: HarkState): HarkState {
const data = _.get(json, 'read-note', false);
if (data) {
const { time, index } = data;
state = updateNotificationStats(state, index, 'notifications', x => x-1);
removeNotificationFromUnread(state, index, makePatDa(time));
setRead(time, index, true, state);
}
return state;
@ -371,7 +420,7 @@ function unread(json: any, state: HarkState): HarkState {
const data = _.get(json, 'unread-note', false);
if (data) {
const { time, index } = data;
state = updateNotificationStats(state, index, 'notifications', x => x+1);
addNotificationToUnread(state, index, makePatDa(time));
setRead(time, index, false, state);
}
return state;
@ -381,6 +430,7 @@ function archive(json: any, state: HarkState): HarkState {
const data = _.get(json, 'archive', false);
if (data) {
const { index } = data;
removeNotificationFromUnread(state, index, makePatDa(data.time))
const time = makePatDa(data.time);
const timebox = state.notifications.get(time);
if (!timebox) {
@ -396,8 +446,6 @@ function archive(json: any, state: HarkState): HarkState {
} else {
state.notifications.set(time, unarchived);
}
const newlyRead = archived.filter(x => !x.notification.read).length;
state = updateNotificationStats(state, index, 'notifications', x => x - newlyRead);
}
return state;
}

View File

@ -1,15 +1,21 @@
import { Post } from "../graph/types";
import { GroupUpdate } from "../groups/types";
import BigIntOrderedMap from "../lib/BigIntOrderedMap";
import {BigInteger} from "big-integer";
export type GraphNotifDescription = "link" | "comment" | "note" | "mention" | "message";
export interface UnreadStats {
unreads: Set<string> | number;
notifications: number;
notifications: NotifRef[];
last: number;
}
interface NotifRef {
time: BigInteger;
index: NotifIndex;
}
export interface GraphNotifIndex {
graph: string;
group: string;