-
Notifications
You must be signed in to change notification settings - Fork 0
/
direct-contacts-query.ts
107 lines (99 loc) · 3.1 KB
/
direct-contacts-query.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { ChatQueries } from "./queries";
import { DirectContact, useKeysQuery, useNostrFetchQuery } from "../nostr";
import { Event, Kind } from "nostr-tools";
import { useContext } from "react";
import { ChatContext } from "../chat-context-provider";
import { isAfter } from "date-fns";
function convertEventToDirectContacts(
events: Event[],
activeUserContact?: DirectContact,
) {
// Get first event with profile info
// note: events could be duplicated
const profileEvent = events.find((event) => event.kind === Kind.Contacts);
if (profileEvent) {
const contacts: DirectContact[] = profileEvent.tags
.filter(([tag]) => tag === "p")
.map(([_, pubkey, __, name]) => ({
pubkey,
name,
}));
profileEvent.tags
.filter(([tag]) => tag === "lastSeenDate")
.forEach(([_, pubkey, value]) => {
const contactIndex = contacts.findIndex((c) => c.pubkey === pubkey);
if (contactIndex > -1) {
contacts[contactIndex].lastSeenDate = new Date(+value);
}
});
profileEvent.tags
.filter(([tag]) => tag === "pinned")
.forEach(([_, pubkey, value]) => {
const contactIndex = contacts.findIndex((c) => c.pubkey === pubkey);
if (contactIndex > -1) {
contacts[contactIndex].pinned = value === "true";
}
});
if (
activeUserContact &&
contacts.every((c) => c.pubkey !== activeUserContact.pubkey)
) {
contacts.push(activeUserContact);
}
return contacts;
}
return activeUserContact ? [activeUserContact] : [];
}
/**
* Original direct contacts uses for storing only Nostr contacts w/o any modification
* As direct contacts query could be updated to many reasons so this query should be read-only
*/
export function useOriginalDirectContactsQuery() {
const { activeUsername } = useContext(ChatContext);
const { hasKeys, publicKey } = useKeysQuery();
return useNostrFetchQuery<DirectContact[]>(
[ChatQueries.ORIGINAL_DIRECT_CONTACTS, activeUsername],
[Kind.Contacts],
(events) =>
convertEventToDirectContacts(events, {
name: activeUsername!,
pubkey: publicKey!,
}),
{
initialData: [],
enabled: hasKeys,
refetchOnMount: false,
},
);
}
export function useDirectContactsQuery() {
const { activeUsername } = useContext(ChatContext);
const { hasKeys, publicKey } = useKeysQuery();
return useNostrFetchQuery<DirectContact[]>(
[ChatQueries.DIRECT_CONTACTS, activeUsername],
[Kind.Contacts],
(events) =>
convertEventToDirectContacts(events, {
name: activeUsername!,
pubkey: publicKey!,
}),
{
initialData: [],
enabled: hasKeys,
refetchOnMount: false,
select: (data) =>
data
.sort((a, b) => {
if (
a.lastSeenDate instanceof Date &&
b.lastSeenDate instanceof Date &&
isAfter(a.lastSeenDate, b.lastSeenDate)
) {
return -1;
}
return 0;
})
.sort((a, b) => +(b.pinned ?? false) - +(a.pinned ?? false)),
},
);
}