mirror of
https://github.com/urbit/shrub.git
synced 2024-12-19 08:32:39 +03:00
Merge dc503a826b
into release/next-js
This commit is contained in:
commit
88906db6bd
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:bb221ce7316346bfaf1ddd953927c0f2afe7eaf5b160bed545f67ec7e5ccb005
|
||||
size 9410487
|
||||
oid sha256:59dee48309ab19979b2a96ec80b45a4e6eacca97a32bad1940cae0e140ec5e4e
|
||||
size 9474074
|
||||
|
@ -5,7 +5,7 @@
|
||||
/- glob
|
||||
/+ default-agent, verb, dbug
|
||||
|%
|
||||
++ hash 0vtbs05.a6mkl.r5ark.jfj84.3fa4h
|
||||
++ hash 0v5.3d6ao.5f5kl.i84k6.oqf1e.njnvh
|
||||
+$ state-0 [%0 hash=@uv glob=(unit (each glob:glob tid=@ta))]
|
||||
+$ all-states
|
||||
$% state-0
|
||||
|
@ -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
|
||||
==
|
||||
|
@ -24,6 +24,6 @@
|
||||
<div id="portal-root"></div>
|
||||
<script src="/~landscape/js/channel.js"></script>
|
||||
<script src="/~landscape/js/session.js"></script>
|
||||
<script src="/~landscape/js/bundle/index.6bb292037c57ac3279cf.js"></script>
|
||||
<script src="/~landscape/js/bundle/index.f837e790b34dd62226f6.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
18
pkg/interface/package-lock.json
generated
18
pkg/interface/package-lock.json
generated
@ -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=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user