snort/src/pages/MessagesPage.tsx

83 lines
2.5 KiB
TypeScript
Raw Normal View History

2023-01-12 09:48:39 +00:00
import { useMemo } from "react";
import { useSelector } from "react-redux"
2023-01-17 10:47:00 +00:00
import { HexKey, RawEvent } from "../nostr";
2023-01-12 09:48:39 +00:00
import ProfileImage from "../element/ProfileImage";
import { hexToBech32 } from "../Util";
2023-01-17 10:47:00 +00:00
type DmChat = {
pubkey: HexKey,
lastRead: number,
unreadMessages: number,
newestMessage: number
}
2023-01-12 09:48:39 +00:00
export default function MessagesPage() {
2023-01-17 10:47:00 +00:00
const myPubKey = useSelector<any, string>(s => s.login.publicKey);
2023-01-12 09:48:39 +00:00
const dms = useSelector<any, RawEvent[]>(s => s.login.dms);
2023-01-17 10:47:00 +00:00
const chats = useMemo(() => {
return extractChats(dms, myPubKey);
2023-01-12 09:48:39 +00:00
}, [dms]);
2023-01-17 10:47:00 +00:00
function person(chat: DmChat) {
2023-01-12 09:48:39 +00:00
return (
2023-01-17 10:47:00 +00:00
<div className="flex mb10" key={chat.pubkey}>
<ProfileImage pubkey={chat.pubkey} className="f-grow" link={`/messages/${hexToBech32("npub", chat.pubkey)}`} />
2023-01-12 09:48:39 +00:00
<span className="pill">
2023-01-17 10:47:00 +00:00
{chat.unreadMessages}
2023-01-12 09:48:39 +00:00
</span>
</div>
)
}
return (
<>
<h3>Messages</h3>
2023-01-17 10:47:00 +00:00
{chats.sort((a, b) => b.newestMessage - a.newestMessage).map(person)}
2023-01-12 09:48:39 +00:00
</>
)
2023-01-17 10:47:00 +00:00
}
export function lastReadDm(pk: HexKey) {
let k = `dm:seen:${pk}`;
return parseInt(window.localStorage.getItem(k) ?? "0");
}
export function setLastReadDm(pk: HexKey) {
const now = Math.floor(new Date().getTime() / 1000);
let current = lastReadDm(pk);
if (current >= now) {
return;
}
let k = `dm:seen:${pk}`;
window.localStorage.setItem(k, now.toString());
}
export function totalUnread(dms: RawEvent[], myPubKey: HexKey) {
return extractChats(dms, myPubKey).reduce((acc, v) => acc += v.unreadMessages, 0);
}
function unreadDms(dms: RawEvent[], myPubKey: HexKey, pk: HexKey) {
let lastRead = lastReadDm(pk);
return dms?.filter(a => a.pubkey === pk && a.pubkey !== myPubKey && a.created_at >= lastRead).length;
}
function newestMessage(dms: RawEvent[], myPubKey: HexKey, pk: HexKey) {
return dms.filter(a => a.pubkey === pk && a.pubkey !== myPubKey).reduce((acc, v) => acc = v.created_at > acc ? v.created_at : acc, 0);
}
export function extractChats(dms: RawEvent[], myPubKey: HexKey) {
const keys = dms.map(a => [a.pubkey, ...a.tags.filter(b => b[0] === "p").map(b => b[1])]).flat();
const filteredKeys = Array.from(new Set<string>(keys));
return filteredKeys.map(a => {
return {
pubkey: a,
lastRead: lastReadDm(a),
unreadMessages: unreadDms(dms, myPubKey, a),
newestMessage: newestMessage(dms, myPubKey, a)
} as DmChat;
})
2023-01-12 09:48:39 +00:00
}