mirror of
https://github.com/urbit/shrub.git
synced 2024-11-28 05:22:27 +03:00
Merge branch 'lf/hark-final-fix'
This commit is contained in:
commit
dfb313dba3
@ -293,7 +293,7 @@
|
|||||||
~(tap by unreads-count)
|
~(tap by unreads-count)
|
||||||
|= [=stats-index:store count=@ud]
|
|= [=stats-index:store count=@ud]
|
||||||
:* stats-index
|
:* stats-index
|
||||||
~(wyt in (~(gut by by-index) stats-index ~))
|
(~(gut by by-index) stats-index ~)
|
||||||
[%count count]
|
[%count count]
|
||||||
(~(gut by last-seen) stats-index *time)
|
(~(gut by last-seen) stats-index *time)
|
||||||
==
|
==
|
||||||
@ -304,7 +304,7 @@
|
|||||||
~(tap by unreads-each)
|
~(tap by unreads-each)
|
||||||
|= [=stats-index:store indices=(set index:graph-store)]
|
|= [=stats-index:store indices=(set index:graph-store)]
|
||||||
:* stats-index
|
:* stats-index
|
||||||
~(wyt in (~(gut by by-index) stats-index ~))
|
(~(gut by by-index) stats-index ~)
|
||||||
[%each indices]
|
[%each indices]
|
||||||
(~(gut by last-seen) stats-index *time)
|
(~(gut by last-seen) stats-index *time)
|
||||||
==
|
==
|
||||||
@ -317,7 +317,7 @@
|
|||||||
~
|
~
|
||||||
:- ~
|
:- ~
|
||||||
:* stats-index
|
:* stats-index
|
||||||
~(wyt in nots)
|
nots
|
||||||
[%count 0]
|
[%count 0]
|
||||||
*time
|
*time
|
||||||
==
|
==
|
||||||
|
@ -151,7 +151,7 @@
|
|||||||
^- json
|
^- json
|
||||||
%- pairs
|
%- pairs
|
||||||
:~ unreads+(unread unreads.s)
|
:~ unreads+(unread unreads.s)
|
||||||
notifications+(numb notifications.s)
|
notifications+a+(turn ~(tap in notifications.s) notif-ref)
|
||||||
last+(time last-seen.s)
|
last+(time last-seen.s)
|
||||||
==
|
==
|
||||||
++ added
|
++ added
|
||||||
|
@ -150,7 +150,7 @@
|
|||||||
[index notification]
|
[index notification]
|
||||||
::
|
::
|
||||||
+$ stats
|
+$ stats
|
||||||
[notifications=@ud =unreads last-seen=@da]
|
[notifications=(set [time index]) =unreads last-seen=@da]
|
||||||
::
|
::
|
||||||
+$ unreads
|
+$ unreads
|
||||||
$% [%count num=@ud]
|
$% [%count num=@ud]
|
||||||
|
18
pkg/interface/package-lock.json
generated
18
pkg/interface/package-lock.json
generated
@ -1783,30 +1783,36 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": {
|
"@babel/runtime": {
|
||||||
"version": "7.12.5",
|
"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": {
|
"requires": {
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/lodash": {
|
"@types/lodash": {
|
||||||
"version": "4.14.168",
|
"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": {
|
"@urbit/eslint-config": {
|
||||||
"version": "1.0.0",
|
"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": {
|
"big-integer": {
|
||||||
"version": "1.6.48",
|
"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": {
|
"lodash": {
|
||||||
"version": "4.17.20",
|
"version": "4.17.20",
|
||||||
"bundled": true
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||||
|
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||||
},
|
},
|
||||||
"regenerator-runtime": {
|
"regenerator-runtime": {
|
||||||
"version": "0.13.7",
|
"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=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -8,11 +8,11 @@ import {
|
|||||||
} from '@urbit/api';
|
} from '@urbit/api';
|
||||||
import { makePatDa } from '~/logic/lib/util';
|
import { makePatDa } from '~/logic/lib/util';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { StoreState } from '../store/type';
|
|
||||||
import { BigIntOrderedMap } from '../lib/BigIntOrderedMap';
|
import { BigIntOrderedMap } from '../lib/BigIntOrderedMap';
|
||||||
import useHarkState, { HarkState } from '../state/hark';
|
import useHarkState, { HarkState } from '../state/hark';
|
||||||
import { compose } from 'lodash/fp';
|
import { compose } from 'lodash/fp';
|
||||||
import { reduceState } from '../state/base';
|
import { reduceState } from '../state/base';
|
||||||
|
import bigInt, {BigInteger} from 'big-integer';
|
||||||
|
|
||||||
export const HarkReducer = (json: any) => {
|
export const HarkReducer = (json: any) => {
|
||||||
const data = _.get(json, 'harkUpdate', false);
|
const data = _.get(json, 'harkUpdate', false);
|
||||||
@ -56,9 +56,24 @@ function reduce(data) {
|
|||||||
seenIndex,
|
seenIndex,
|
||||||
removeGraph,
|
removeGraph,
|
||||||
readAll,
|
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 {
|
function groupInitial(json: any, state: HarkState): HarkState {
|
||||||
const data = _.get(json, 'initial', false);
|
const data = _.get(json, 'initial', false);
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -191,8 +206,10 @@ function unreads(json: any, state: HarkState): HarkState {
|
|||||||
if(data) {
|
if(data) {
|
||||||
data.forEach(({ index, stats }) => {
|
data.forEach(({ index, stats }) => {
|
||||||
const { unreads, notifications, last } = stats;
|
const { unreads, notifications, last } = stats;
|
||||||
state = updateNotificationStats(state, index, 'notifications', x => x + notifications);
|
updateNotificationStats(state, index, 'last', () => last);
|
||||||
state = updateNotificationStats(state, index, 'last', () => last);
|
_.each(notifications, ({ time, index }) => {
|
||||||
|
addNotificationToUnread(state, index, makePatDa(time));
|
||||||
|
});
|
||||||
if('count' in unreads) {
|
if('count' in unreads) {
|
||||||
state = updateUnreadCount(state, index, (u = 0) => u + unreads.count);
|
state = updateUnreadCount(state, index, (u = 0) => u + unreads.count);
|
||||||
} else {
|
} else {
|
||||||
@ -251,18 +268,53 @@ function updateUnreads(state: HarkState, index: NotifIndex, f: (us: Set<string>)
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateNotificationStats(state: HarkState, index: NotifIndex, statField: 'notifications' | 'unreads' | 'last', f: (x: number) => number): HarkState {
|
function addNotificationToUnread(state: HarkState, index: NotifIndex, time: BigInteger) {
|
||||||
if(statField === 'notifications') {
|
if('graph' in index) {
|
||||||
state.notificationsCount = f(state.notificationsCount);
|
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));
|
function removeNotificationFromUnread(state: HarkState, index: NotifIndex, time: BigInteger) {
|
||||||
} else if('group' in index) {
|
if('graph' in index) {
|
||||||
const curr = _.get(state.unreads.group, [index.group, statField], 0);
|
const path = [index.graph.graph, index.graph.index, 'notifications'];
|
||||||
_.set(state.unreads.group, [index.group, statField], f(curr));
|
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 {
|
function added(json: any, state: HarkState): HarkState {
|
||||||
@ -271,18 +323,15 @@ function added(json: any, state: HarkState): HarkState {
|
|||||||
const { index, notification } = data;
|
const { index, notification } = data;
|
||||||
const time = makePatDa(data.time);
|
const time = makePatDa(data.time);
|
||||||
const timebox = state.notifications.get(time) || [];
|
const timebox = state.notifications.get(time) || [];
|
||||||
|
addNotificationToUnread(state, index, time);
|
||||||
|
|
||||||
const arrIdx = timebox.findIndex(idxNotif =>
|
const arrIdx = timebox.findIndex(idxNotif =>
|
||||||
notifIdxEqual(index, idxNotif.index)
|
notifIdxEqual(index, idxNotif.index)
|
||||||
);
|
);
|
||||||
if (arrIdx !== -1) {
|
if (arrIdx !== -1) {
|
||||||
if (timebox[arrIdx]?.notification?.read) {
|
|
||||||
state = updateNotificationStats(state, index, 'notifications', x => x+1);
|
|
||||||
}
|
|
||||||
timebox[arrIdx] = { index, notification };
|
timebox[arrIdx] = { index, notification };
|
||||||
state.notifications.set(time, timebox);
|
state.notifications.set(time, timebox);
|
||||||
} else {
|
} else {
|
||||||
state = updateNotificationStats(state, index, 'notifications', x => x+1);
|
|
||||||
state.notifications.set(time, [...timebox, { index, notification }]);
|
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);
|
const data = _.get(json, 'read-note', false);
|
||||||
if (data) {
|
if (data) {
|
||||||
const { time, index } = data;
|
const { time, index } = data;
|
||||||
state = updateNotificationStats(state, index, 'notifications', x => x-1);
|
removeNotificationFromUnread(state, index, makePatDa(time));
|
||||||
setRead(time, index, true, state);
|
setRead(time, index, true, state);
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
@ -371,7 +420,7 @@ function unread(json: any, state: HarkState): HarkState {
|
|||||||
const data = _.get(json, 'unread-note', false);
|
const data = _.get(json, 'unread-note', false);
|
||||||
if (data) {
|
if (data) {
|
||||||
const { time, index } = data;
|
const { time, index } = data;
|
||||||
state = updateNotificationStats(state, index, 'notifications', x => x+1);
|
addNotificationToUnread(state, index, makePatDa(time));
|
||||||
setRead(time, index, false, state);
|
setRead(time, index, false, state);
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
@ -381,6 +430,7 @@ function archive(json: any, state: HarkState): HarkState {
|
|||||||
const data = _.get(json, 'archive', false);
|
const data = _.get(json, 'archive', false);
|
||||||
if (data) {
|
if (data) {
|
||||||
const { index } = data;
|
const { index } = data;
|
||||||
|
removeNotificationFromUnread(state, index, makePatDa(data.time))
|
||||||
const time = makePatDa(data.time);
|
const time = makePatDa(data.time);
|
||||||
const timebox = state.notifications.get(time);
|
const timebox = state.notifications.get(time);
|
||||||
if (!timebox) {
|
if (!timebox) {
|
||||||
@ -396,8 +446,6 @@ function archive(json: any, state: HarkState): HarkState {
|
|||||||
} else {
|
} else {
|
||||||
state.notifications.set(time, unarchived);
|
state.notifications.set(time, unarchived);
|
||||||
}
|
}
|
||||||
const newlyRead = archived.filter(x => !x.notification.read).length;
|
|
||||||
state = updateNotificationStats(state, index, 'notifications', x => x - newlyRead);
|
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
import { Post } from "../graph/types";
|
import { Post } from "../graph/types";
|
||||||
import { GroupUpdate } from "../groups/types";
|
import { GroupUpdate } from "../groups/types";
|
||||||
import BigIntOrderedMap from "../lib/BigIntOrderedMap";
|
import BigIntOrderedMap from "../lib/BigIntOrderedMap";
|
||||||
|
import {BigInteger} from "big-integer";
|
||||||
|
|
||||||
export type GraphNotifDescription = "link" | "comment" | "note" | "mention" | "message";
|
export type GraphNotifDescription = "link" | "comment" | "note" | "mention" | "message";
|
||||||
|
|
||||||
export interface UnreadStats {
|
export interface UnreadStats {
|
||||||
unreads: Set<string> | number;
|
unreads: Set<string> | number;
|
||||||
notifications: number;
|
notifications: NotifRef[];
|
||||||
last: number;
|
last: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface NotifRef {
|
||||||
|
time: BigInteger;
|
||||||
|
index: NotifIndex;
|
||||||
|
}
|
||||||
|
|
||||||
export interface GraphNotifIndex {
|
export interface GraphNotifIndex {
|
||||||
graph: string;
|
graph: string;
|
||||||
group: string;
|
group: string;
|
||||||
|
Loading…
Reference in New Issue
Block a user