grid: fix notification state

This commit is contained in:
Liam Fitzgerald 2021-09-20 14:30:08 +10:00
parent 0655d72fd4
commit a49399269b
4 changed files with 61 additions and 122 deletions

View File

@ -28,7 +28,10 @@ module.exports = {
rules: {
'no-undef': 'off',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': ['error'],
'@typescript-eslint/no-unused-vars': [
'error',
{ vars: 'all', args: 'after-used', ignoreRestSiblings: false }
],
'no-unused-expressions': ['error', { allowShortCircuit: true }],
'no-use-before-define': 'off',
'no-param-reassign': ['error', { props: true, ignorePropertyModificationsFor: ['draft'] }],

View File

@ -1,43 +1,12 @@
import React, { useEffect } from 'react';
import { Link, NavLink, Route, Switch } from 'react-router-dom';
import { Notification, HarkLid } from '@urbit/api';
import { useLeapStore } from './Nav';
import { Button } from '../components/Button';
import { BasicNotification } from './notifications/BasicNotification';
import {
BaseBlockedNotification,
RuntimeLagNotification
} from './notifications/SystemNotification';
import { useNotifications } from '../state/notifications';
import { useHarkStore } from '../state/hark';
import { OnboardingNotification } from './notifications/OnboardingNotification';
import { Inbox } from './notifications/Inbox';
function renderNotification(notification: Notification, key: string, lid: HarkLid) {
// Special casing
if (notification.bin.place.desk === window.desk) {
if (notification.bin.place.path === '/lag') {
return <RuntimeLagNotification key={key} />;
}
if (notification.bin.place.path === '/blocked') {
return <BaseBlockedNotification key={key} />;
}
if (notification.bin.place.path === '/onboard') {
return <OnboardingNotification key={key} unread />
}
}
return <BasicNotification key={key} notification={notification} lid={lid} />;
}
const Empty = () => (
<section className="flex justify-center items-center min-h-[480px] text-gray-400 space-y-2">
<span className="h4">All clear!</span>
</section>
);
export const Notifications = () => {
const select = useLeapStore((s) => s.select);
const { unseen, seen, hasAnyNotifications } = useNotifications();
const markAllAsRead = () => {
const { archiveAll } = useHarkStore.getState();
archiveAll();
@ -45,12 +14,12 @@ export const Notifications = () => {
useEffect(() => {
select('Notifications');
const { getMore } = useHarkStore.getState();
getMore();
function visibilitychange() {
if (document.visibilityState === 'hidden') {
useHarkStore.getState().opened();
}
}
document.addEventListener('visibilitychange', visibilitychange);
return () => {

View File

@ -1,8 +1,5 @@
import React, { useEffect } from 'react';
import { Link } from 'react-router-dom';
import { HarkLid, Notification } from '@urbit/api';
import { useLeapStore } from '../Nav';
import { Button } from '../../components/Button';
import { BasicNotification } from './BasicNotification';
import { BaseBlockedNotification, RuntimeLagNotification } from './SystemNotification';
import { useNotifications } from '../../state/notifications';
@ -32,34 +29,14 @@ const Empty = () => (
);
export const Inbox = ({ archived = false }) => {
const select = useLeapStore((s) => s.select);
const { unseen, seen, hasAnyNotifications } = useNotifications();
const { unseen, seen } = useNotifications();
const archive = useHarkStore((s) => s.archive);
const markAllAsRead = () => {};
useEffect(() => {
useHarkStore.getState().getMore();
}, [archived]);
useEffect(() => {
select('Notifications');
const { getMore } = useHarkStore.getState();
getMore();
function visibilitychange() {
setTimeout(() => useHarkStore.getState().opened(), 100);
}
document.addEventListener('visibilitychange', visibilitychange);
return () => {
document.removeEventListener('visibilitychange', visibilitychange);
visibilitychange();
};
}, []);
// const select = useLeapStore((s) => s.select);
if (false) {
if (archived ? archive.size === 0 : Object.keys({ ...seen, ...unseen }).length === 0) {
return <Empty />;
}
@ -69,7 +46,9 @@ export const Inbox = ({ archived = false }) => {
Array.from(archive).map(([key, box]) => {
return Object.entries(box)
.sort(([, a], [, b]) => b.time - a.time)
.map(([binId, n], index) => renderNotification(n, `${key.toString}-${binId}`, { time: key.toString() }));
.map(([binId, n]) =>
renderNotification(n, `${key.toString}-${binId}`, { time: key.toString() })
);
})
) : (
<>
@ -77,13 +56,13 @@ export const Inbox = ({ archived = false }) => {
<section className="space-y-2">
{Object.entries(unseen)
.sort(([, a], [, b]) => b.time - a.time)
.map(([binId, n], index) => renderNotification(n, `unseen-${binId}`, { unseen: null }))}
.map(([binId, n]) => renderNotification(n, `unseen-${binId}`, { unseen: null }))}
</section>
<header>Seen</header>
<section className="space-y-2">
{Object.entries(seen)
.sort(([, a], [, b]) => b.time - a.time)
.map(([binId, n], index) => renderNotification(n, `seen-${binId}`, { seen: null }))}
.map(([binId, n]) => renderNotification(n, `seen-${binId}`, { seen: null }))}
</section>
</>
)}

View File

@ -1,10 +1,6 @@
/* eslint-disable no-param-reassign */
import create from 'zustand';
import {
Notification as HarkNotification,
harkBinEq,
makePatDa,
readAll,
decToUd,
unixToDa,
Timebox,
@ -14,17 +10,15 @@ import {
HarkLid,
archive,
HarkContent,
NotificationGraphConfig
NotificationGraphConfig,
archiveAll
} from '@urbit/api';
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
/* eslint-disable-next-line camelcase */
import { unstable_batchedUpdates } from 'react-dom';
import produce from 'immer';
import _, { map } from 'lodash';
import _ from 'lodash';
import api from './api';
import { useMockData } from './util';
import { mockNotifications } from './mock-data';
import useDocketState from './docket';
import { useSettingsState } from './settings';
import { BaseState, createState, createSubscription, reduceStateN } from './base';
@ -67,7 +61,6 @@ export const reduceGraph = [
})
];
export const useHarkStore = createState<HarkState>(
'Hark',
(set, get) => ({
@ -85,7 +78,9 @@ export const useHarkStore = createState<HarkState>(
const newState = produce(get(), f);
set(newState);
},
archiveAll: async () => {},
archiveAll: async () => {
await api.poke(archiveAll);
},
archiveNote: async (bin, lid) => {
await api.poke(archive(bin, lid));
},
@ -93,8 +88,8 @@ export const useHarkStore = createState<HarkState>(
await api.poke(opened);
},
getMore: async () => {
const { archive } = get();
const idx = decToUd((archive.peekSmallest()?.[0] || unixToDa(Date.now() * 1000)).toString());
const { archive: arch } = get();
const idx = decToUd((arch?.peekSmallest()?.[0] || unixToDa(Date.now() * 1000)).toString());
const update = await api.scry({
app: 'hark-store',
path: `/recent/inbox/${idx}/5`
@ -102,7 +97,7 @@ export const useHarkStore = createState<HarkState>(
reduceHark(update);
}
}),
[],
['archive'],
[
(set, get) =>
createSubscription('hark-graph-hook', '/updates', (j) => {
@ -111,8 +106,8 @@ export const useHarkStore = createState<HarkState>(
reduceStateN(get(), graphHookData, reduceGraph);
}
}),
(set, get) =>
createSubscription('hark-store', '/updates', u => {
() =>
createSubscription('hark-store', '/updates', (u) => {
/* eslint-ignore-next-line camelcase */
unstable_batchedUpdates(() => {
reduceHark(u);
@ -140,20 +135,16 @@ function reduceHark(u: any) {
});
} else if ('timebox' in u) {
const { timebox } = u;
console.log(timebox);
const { lid, notifications } = timebox;
if ('archive' in lid) {
set((draft) => {
const time = makePatDa(lid.archive);
const timebox = draft.archive.get(time) || {};
console.log(timebox);
const old = draft.archive.get(time) || {};
notifications.forEach((note: any) => {
console.log(note);
const binId = harkBinToId(note.bin);
timebox[binId] = note;
old[binId] = note;
});
console.log(notifications);
draft.archive = draft.archive.set(time, timebox);
draft.archive = draft.archive.set(time, old);
});
} else {
set((draft) => {
@ -166,13 +157,12 @@ function reduceHark(u: any) {
}
} else if ('archived' in u) {
const { lid, notification } = u.archived;
console.log(u.archived);
set((draft) => {
const seen = 'seen' in lid ? 'seen' : 'unseen';
const binId = harkBinToId(notification.bin);
delete draft[seen][binId];
const time = makePatDa(u.archived.time);
const timebox = draft.archive.get(time) || {};
const timebox = draft.archive?.get(time) || {};
timebox[binId] = notification;
draft.archive = draft.archive.set(time, timebox);
});
@ -218,20 +208,18 @@ api.subscribe({
event: (u: any) => {
if ('add-note' in u) {
if (useSettingsState.getState().display.doNotDisturb) {
//return;
return;
}
const { bin, body } = u['add-note'];
const binId = harkBinToId(bin);
const { title, content } = body;
const image = useDocketState.getState().charges[bin.desk]?.image;
const notification = new Notification(harkContentsToPlainText(title), {
const note = new Notification(harkContentsToPlainText(title), {
body: harkContentsToPlainText(content),
tag: binId,
renotify: true
});
note.onclick = () => {};
}
}
});