forked from Kieran/snort
feat: mark all dms read
This commit is contained in:
parent
2f3c46629d
commit
621bb5f6ee
@ -1,33 +1,38 @@
|
||||
import "./DM.css";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useInView } from 'react-intersection-observer';
|
||||
|
||||
import useEventPublisher from "../feed/EventPublisher";
|
||||
import Event from "../nostr/Event";
|
||||
import NoteTime from "./NoteTime";
|
||||
import Text from "./Text";
|
||||
import { lastReadDm, setLastReadDm } from "../pages/MessagesPage";
|
||||
import { setLastReadDm } from "../pages/MessagesPage";
|
||||
import { RootState } from "../state/Store";
|
||||
import { HexKey, TaggedRawEvent } from "../nostr";
|
||||
import { incDmInteraction } from "../state/Login";
|
||||
|
||||
export type DMProps = {
|
||||
data: any
|
||||
data: TaggedRawEvent
|
||||
}
|
||||
|
||||
export default function DM(props: DMProps) {
|
||||
const pubKey = useSelector<any>(s => s.login.publicKey);
|
||||
const dispatch = useDispatch();
|
||||
const pubKey = useSelector<RootState, HexKey | undefined>(s => s.login.publicKey);
|
||||
const publisher = useEventPublisher();
|
||||
const [content, setContent] = useState("Loading...");
|
||||
const [decrypted, setDecrypted] = useState(false);
|
||||
const { ref, inView, entry } = useInView();
|
||||
const { ref, inView } = useInView();
|
||||
const isMe = props.data.pubkey === pubKey;
|
||||
|
||||
async function decrypt() {
|
||||
let e = new Event(props.data);
|
||||
if (!isMe) {
|
||||
setLastReadDm(e.PubKey);
|
||||
}
|
||||
let decrypted = await publisher.decryptDm(e);
|
||||
setContent(decrypted || "<ERROR>");
|
||||
if (!isMe) {
|
||||
setLastReadDm(e.PubKey);
|
||||
dispatch(incDmInteraction());
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { useMemo } from "react";
|
||||
import { useSelector } from "react-redux"
|
||||
import { useDispatch, useSelector } from "react-redux"
|
||||
|
||||
import { HexKey, RawEvent } from "../nostr";
|
||||
import ProfileImage from "../element/ProfileImage";
|
||||
import { hexToBech32 } from "../Util";
|
||||
import { incDmInteraction } from "../state/Login";
|
||||
import { RootState } from "../state/Store";
|
||||
|
||||
type DmChat = {
|
||||
pubkey: HexKey,
|
||||
@ -12,12 +14,14 @@ type DmChat = {
|
||||
}
|
||||
|
||||
export default function MessagesPage() {
|
||||
const myPubKey = useSelector<any, string>(s => s.login.publicKey);
|
||||
const dms = useSelector<any, RawEvent[]>(s => s.login.dms);
|
||||
const dispatch = useDispatch();
|
||||
const myPubKey = useSelector<RootState, HexKey | undefined>(s => s.login.publicKey);
|
||||
const dms = useSelector<RootState, RawEvent[]>(s => s.login.dms);
|
||||
const dmInteraction = useSelector<RootState, number>(s => s.login.dmInteraction);
|
||||
|
||||
const chats = useMemo(() => {
|
||||
return extractChats(dms, myPubKey);
|
||||
}, [dms]);
|
||||
return extractChats(dms, myPubKey!);
|
||||
}, [dms, myPubKey, dmInteraction]);
|
||||
|
||||
function person(chat: DmChat) {
|
||||
return (
|
||||
@ -30,9 +34,19 @@ export default function MessagesPage() {
|
||||
)
|
||||
}
|
||||
|
||||
function markAllRead() {
|
||||
for (let c of chats) {
|
||||
setLastReadDm(c.pubkey);
|
||||
}
|
||||
dispatch(incDmInteraction());
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3>Messages</h3>
|
||||
<div className="flex">
|
||||
<h3 className="f-grow">Messages</h3>
|
||||
<div className="btn" onClick={() => markAllRead()}>Mark All Read</div>
|
||||
</div>
|
||||
{chats.sort((a, b) => b.newestMessage - a.newestMessage).map(person)}
|
||||
</>
|
||||
)
|
||||
@ -81,7 +95,6 @@ function newestMessage(dms: RawEvent[], myPubKey: HexKey, pk: HexKey) {
|
||||
return dmsInChat(dms, pk).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, dmTo(a)]).flat();
|
||||
const filteredKeys = Array.from(new Set<string>(keys));
|
||||
|
@ -52,9 +52,27 @@ interface LoginStore {
|
||||
/**
|
||||
* Encrypted DM's
|
||||
*/
|
||||
dms: TaggedRawEvent[]
|
||||
dms: TaggedRawEvent[],
|
||||
|
||||
/**
|
||||
* Counter to trigger refresh of unread dms
|
||||
*/
|
||||
dmInteraction: 0
|
||||
};
|
||||
|
||||
const InitState = {
|
||||
loggedOut: undefined,
|
||||
publicKey: undefined,
|
||||
privateKey: undefined,
|
||||
relays: {},
|
||||
latestRelays: 0,
|
||||
follows: [],
|
||||
notifications: [],
|
||||
readNotifications: 0,
|
||||
dms: [],
|
||||
dmInteraction: 0
|
||||
} as LoginStore;
|
||||
|
||||
export interface SetRelaysPayload {
|
||||
relays: Record<string, RelaySettings>,
|
||||
createdAt: number
|
||||
@ -62,14 +80,7 @@ export interface SetRelaysPayload {
|
||||
|
||||
const LoginSlice = createSlice({
|
||||
name: "Login",
|
||||
initialState: <LoginStore>{
|
||||
relays: {},
|
||||
latestRelays: 0,
|
||||
follows: [],
|
||||
notifications: [],
|
||||
readNotifications: 0,
|
||||
dms: []
|
||||
},
|
||||
initialState: InitState,
|
||||
reducers: {
|
||||
init: (state) => {
|
||||
state.privateKey = window.localStorage.getItem(PrivateKeyItem) ?? undefined;
|
||||
@ -182,17 +193,14 @@ const LoginSlice = createSlice({
|
||||
];
|
||||
}
|
||||
},
|
||||
incDmInteraction: (state) => {
|
||||
state.dmInteraction += 1;
|
||||
},
|
||||
logout: (state) => {
|
||||
window.localStorage.removeItem(PrivateKeyItem);
|
||||
window.localStorage.removeItem(PublicKeyItem);
|
||||
window.localStorage.removeItem(NotificationsReadItem);
|
||||
state.privateKey = undefined;
|
||||
state.publicKey = undefined;
|
||||
state.follows = [];
|
||||
state.notifications = [];
|
||||
window.localStorage.clear();
|
||||
Object.assign(state, InitState);
|
||||
state.loggedOut = true;
|
||||
state.readNotifications = 0;
|
||||
state.dms = [];
|
||||
state.relays = Object.fromEntries(DefaultRelays.entries());
|
||||
},
|
||||
markNotificationsRead: (state) => {
|
||||
state.readNotifications = new Date().getTime();
|
||||
@ -210,6 +218,7 @@ export const {
|
||||
setFollows,
|
||||
addNotifications,
|
||||
addDirectMessage,
|
||||
incDmInteraction,
|
||||
logout,
|
||||
markNotificationsRead
|
||||
} = LoginSlice.actions;
|
||||
|
Loading…
Reference in New Issue
Block a user