···
import { DEFAULT_STALE_TIME } from "@/lib/consts";
2
-
import type { AtUri, Did } from "@/lib/types/atproto";
2
+
import type { Did } from "@/lib/types/atproto";
import type { LatticeSessionInfo } from "@/lib/types/handshake";
4
-
import { systemsGmstnDevelopmentChannelRecordSchema } from "@/lib/types/lexicon/systems.gmstn.development.channels";
5
-
import { getRecordFromFullAtUri, stringToAtUri } from "@/lib/utils/atproto";
4
+
import type { SystemsGmstnDevelopmentChannelMembership } from "@/lib/types/lexicon/systems.gmstn.development.channel.membership";
5
+
import type { SystemsGmstnDevelopmentChannel } from "@/lib/types/lexicon/systems.gmstn.development.channels";
6
+
import { stringToAtUri } from "@/lib/utils/atproto";
10
+
} from "@/providers/authed/ChannelsProvider";
12
+
MembershipsProvider,
14
+
} from "@/providers/authed/MembershipsProvider";
15
+
import type { OAuth } from "@/providers/OAuthProvider";
import { useOAuthValue } from "@/providers/OAuthProvider";
7
-
import { getMembershipRecordsFromPds } from "@/queries/get-membership-from-pds";
import { initiateHandshakeTo } from "@/queries/initiate-handshake-to";
9
-
import type { OAuthSession } from "@atproto/oauth-client";
10
-
import { useQueries, useQuery } from "@tanstack/react-query";
18
+
import { useQueries } from "@tanstack/react-query";
import type { ReactNode } from "react";
import { createContext, useContext, useMemo } from "react";
···
27
-
export const LatticeSessionsProvider = ({
35
+
export const useLatticeSession = () => {
36
+
const value = useContext(LatticeSessionsContext);
39
+
"Lattice session context not inited. Or ordering of providers was wrong.",
41
+
return value.sessions;
44
+
const LatticeSessionsProviderInner = ({
51
+
isInitialising: membershipsInitialising,
52
+
error: membershipError,
53
+
} = useMemberships();
56
+
isInitialising: channelsInitialising,
57
+
error: channelsError,
58
+
} = useChannelRecords();
const oauth = useOAuthValue();
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Explicit guard
···
const { session, isLoading, agent, client } = oauth;
const isOAuthReady = !isLoading && !!agent && !!client && !!session;
43
-
const membershipsQuery = useQuery({
44
-
queryKey: ["membership", session?.did],
45
-
enabled: isOAuthReady,
46
-
queryFn: async () => {
47
-
if (!session) throw new Error("We need an OAuth session");
48
-
return await membershipQueryFn(session);
50
-
staleTime: DEFAULT_STALE_TIME,
53
-
// TODO: group channel memberships by
55
-
const channelsQueries = useQueries({
56
-
queries: !membershipsQuery.data
58
-
: membershipsQuery.data.map((membershipQueryResult) => ({
59
-
enabled: membershipsQuery.isSuccess,
62
-
membershipQueryResult.membership.channel.uri,
64
-
queryFn: () => channelQueryFn(membershipQueryResult.atUri),
65
-
staleTime: DEFAULT_STALE_TIME,
const handshakeQueries = useQueries({
70
-
queries: channelsQueries
71
-
.map((queryResult) =>
74
-
queryKey: ["handshakes", queryResult.data.name],
75
-
queryFn: async () => {
76
-
const { routeThrough } = queryResult.data;
77
-
const latticeAtUri = stringToAtUri(
80
-
if (!latticeAtUri.ok) {
82
-
"Lattice AT URI did not resolve properly",
87
-
"Something went wrong while initiating handshakes",
90
-
// TODO: unfuck this.
92
-
`did:web:${encodeURIComponent(latticeAtUri.data.rKey ?? "")}` as Did;
93
-
const handshakeResult = await initiateHandshakeTo(
97
-
membershipsQuery.data?.map(
99
-
queryResult.membership,
105
-
if (!handshakeResult.ok) {
110
-
handshakeResult.error,
112
-
throw new Error("Handshake failed.");
117
-
sessionInfo: handshakeResult.data,
120
-
staleTime: DEFAULT_STALE_TIME,
124
-
.filter((query) => query !== undefined),
71
+
queries: channels.map((channelObj) => ({
72
+
queryKey: ["handshakes", channelObj.channel.name],
75
+
channel: channelObj.channel,
76
+
memberships: memberships.map(
77
+
({ membership }) => membership,
81
+
staleTime: DEFAULT_STALE_TIME,
128
-
membershipsQuery.isLoading ||
129
-
channelsQueries.some((q) => q.isLoading) ||
87
+
membershipsInitialising ||
88
+
channelsInitialising ||
handshakeQueries.some((q) => q.isLoading);
133
-
membershipsQuery.error ??
134
-
channelsQueries.find((q) => q.error)?.error ??
handshakeQueries.find((q) => q.error)?.error ??
···
163
-
const membershipQueryFn = async (session: OAuthSession) => {
164
-
const memberships = await getMembershipRecordsFromPds({
165
-
pdsEndpoint: session.serverMetadata.issuer,
169
-
if (!memberships.ok) {
170
-
console.error("getMembershipRecordsFromPds error.", memberships.error);
172
-
`Something went wrong while getting the user's membership records.}`,
122
+
const handshakesQueryFn = async ({
127
+
channel: SystemsGmstnDevelopmentChannel;
128
+
memberships: Array<SystemsGmstnDevelopmentChannelMembership>;
131
+
const { routeThrough } = channel;
132
+
const latticeAtUri = stringToAtUri(routeThrough.uri);
133
+
if (!latticeAtUri.ok) {
135
+
"Lattice AT URI did not resolve properly",
137
+
latticeAtUri.error,
139
+
throw new Error("Something went wrong while initiating handshakes");
175
-
const { data } = memberships;
176
-
const membershipAtUris = data.map((membership) => {
177
-
const convertResult = stringToAtUri(membership.channel.uri);
178
-
if (!convertResult.ok) {
180
-
"Could not convert",
182
-
"into at:// URI object.",
183
-
convertResult.error,
187
-
return { membership, atUri: convertResult.data };
141
+
// TODO: unfuck this.
143
+
`did:web:${encodeURIComponent(latticeAtUri.data.rKey ?? "")}` as Did;
144
+
const handshakeResult = await initiateHandshakeTo({
190
-
return membershipAtUris.filter((membership) => membership !== undefined);
193
-
// FIXME: holy shit don't do this. we will build prism and use that to resolve
194
-
// our memberships into channels. for now we resolve the at-uri manually.
195
-
const channelQueryFn = async (membership: AtUri) => {
196
-
const res = await getRecordFromFullAtUri(membership);
198
-
console.error("Could not retrieve record from full at uri", res.error);
199
-
throw new Error("Something went wrong while fetching channel records");
205
-
} = systemsGmstnDevelopmentChannelRecordSchema.safeParse(res.data);
150
+
if (!handshakeResult.ok) {
209
-
"did not resolve to a valid channel record",
155
+
handshakeResult.error,
212
-
throw new Error("Something went wrong while fetching channel records");
157
+
throw new Error("Handshake failed.");
162
+
sessionInfo: handshakeResult.data,
217
-
export const useLatticeSession = () => {
218
-
const value = useContext(LatticeSessionsContext);
219
-
if (value === null)
221
-
"Lattice session context not inited. Or ordering of providers was wrong.",
223
-
return value.sessions;
166
+
export const LatticeSessionsProvider = ({
169
+
children: ReactNode;
171
+
// Memberships must be above channels
172
+
// channels must be above lattice sessions inner
173
+
// do it this way to preserve the order if we need to move them around some day
175
+
<MembershipsProvider>
177
+
<LatticeSessionsProviderInner>
179
+
</LatticeSessionsProviderInner>
180
+
</ChannelsProvider>
181
+
</MembershipsProvider>