-
Notifications
You must be signed in to change notification settings - Fork 0
/
public-messages-query.ts
110 lines (101 loc) · 3.85 KB
/
public-messages-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
108
109
110
import { Kind } from "nostr-tools";
import { convertEvent } from "../utils/event-converter";
import { NostrQueries } from "./queries";
import { Channel, Message } from "../types";
import { useNostrInfiniteFetchQuery } from "../core/nostr-infinite-fetch-query";
import { useContext } from "react";
import { ChatContext } from "../../chat-context-provider";
import { useNostrFetchMutation } from "../core";
import { ChatQueries } from "../../queries";
import { convertHiddenMessagesEvents, convertMutedUsersEvents } from "../utils";
import { useFindAndAssignParentPublicMessage } from "./use-find-and-assign-parent-public-message";
/**
* Use this query to retrieve filtered channel messages
* @param channel Current channel
* @param joinedCommunityTeamKeys Represents list of public keys of community members which may hide messages or block users
*/
export function usePublicMessagesQuery(
channel?: Channel,
joinedCommunityTeamKeys: string[] = [],
) {
const { activeUsername } = useContext(ChatContext);
const { mutateAsync: fetchHiddenMessages } = useNostrFetchMutation(
[ChatQueries.HIDDEN_CHANNEL_MESSAGES, activeUsername, channel?.id],
[],
);
const { mutateAsync: fetchBlockedUsers } = useNostrFetchMutation(
[ChatQueries.BLOCKED_USERS, activeUsername, channel?.id],
[],
);
const findAndAssignParentMessage = useFindAndAssignParentPublicMessage();
return useNostrInfiniteFetchQuery<Message[]>(
[NostrQueries.PUBLIC_MESSAGES, activeUsername, channel?.id],
[
{
kinds: [Kind.ChannelMessage],
"#e": [channel?.id ?? ""],
limit: 50,
},
],
async (events) => {
// 1. Fetch messages and convert them
let messagesPage = events
.map((event) => convertEvent(event))
.filter((message) => !!message) as Message[];
await findAndAssignParentMessage(messagesPage);
// 2. Fetch blocked users and filter only by community team members
// note: same behavior as in hidden messages
const blockedUsersEvents = await fetchBlockedUsers(
Array.from(new Set(messagesPage.map((m) => m.creator)).values()).map(
(creator) => ({
kinds: [Kind.ChannelMuteUser],
"#p": [creator],
"#e": [channel?.id ?? ""],
}),
),
);
const blockedUsersIds = convertMutedUsersEvents(
blockedUsersEvents,
joinedCommunityTeamKeys,
);
console.debug(
"[ns-query] Hidden users by community team IDs are",
channel,
blockedUsersIds,
);
// 2.1 Filter out messages page by hidden users
// note: it should be done first to decrease events count for hidden messages fetching
messagesPage = messagesPage.filter(
(m) => !blockedUsersIds.includes(m.creator),
);
// 3. Fetch hidden messages and filter by only community team members
// note: Since any Nostr user can publish hidden message event We have to make sure that it was by community team
const hiddenMessagesEvents = await fetchHiddenMessages(
messagesPage.map((m) => ({
kinds: [Kind.ChannelHideMessage],
"#e": [m.id],
})),
);
// 3. Extract message IDs and filter hidden messages event by creator
const hiddenMessagesIds = convertHiddenMessagesEvents(
hiddenMessagesEvents,
channel!.id,
joinedCommunityTeamKeys,
);
console.debug(
"[ns-query] Hidden messages by community team are",
channel,
hiddenMessagesIds,
);
return messagesPage.filter((m) => !hiddenMessagesIds.includes(m.id));
},
{
enabled: !!channel?.id,
initialPageParam: undefined,
initialData: { pages: [[]], pageParams: [] },
getNextPageParam: (lastPage) =>
lastPage?.sort((a, b) => a.created - b.created)?.[0]?.created,
refetchOnMount: false,
},
);
}