···
+
import { Loading } from "@/components/primitives/Loading";
import { Text } from "@/components/primitives/Text";
+
import { useFacet } from "@/lib/facet";
+
import type { AtUri, DidPlc, DidWeb } from "@/lib/types/atproto";
+
import { systemsGmstnDevelopmentChannelInviteRecordSchema } from "@/lib/types/lexicon/systems.gmstn.development.channel.invite";
+
import { partition } from "@/lib/utils/arrays";
+
getCommitFromFullAtUri,
+
getRecordFromFullAtUri,
+
} from "@/lib/utils/atproto";
+
import { addMembership } from "@/lib/utils/gmstn";
+
import { useMemberships } from "@/providers/authed/MembershipsProvider";
+
useOAuthAgentGuaranteed,
+
useOAuthSessionGuaranteed,
+
} from "@/providers/OAuthProvider";
+
import { useCurrentPalette } from "@/providers/ThemeProvider";
+
import { useConstellationInvitesQuery } from "@/queries/hooks/useConstellationInvitesQuery";
+
import { useMutation, useQueryClient } from "@tanstack/react-query";
+
import { Check, Mail, MailOpen, X } from "lucide-react-native";
+
import { FlatList, Pressable, View } from "react-native";
export const Invites = () => {
+
const { semantic } = useCurrentPalette();
+
const { atoms, typography } = useFacet();
+
const { memberships } = useMemberships();
+
const session = useOAuthSessionGuaranteed();
+
useConstellationInvitesQuery(session);
+
const { data: invites, isLoading } = useQuery();
+
const membershipAtUris: Array<Required<AtUri>> = memberships
+
.map((membershipRecord) => {
+
const res = stringToAtUri(membershipRecord.membership.invite.uri);
+
return res.data as Required<AtUri>;
+
.filter((membership) => membership !== undefined);
+
const [existingInvites, pendingInvites] = partition(
+
invites?.invites ?? [],
+
(membership) => invite.rkey === membership.rKey,
+
console.log({existingInvites, pendingInvites})
···
+
borderColor: semantic.borderVariant,
+
borderRadius: atoms.radii.lg,
+
typography.weights.byName.medium,
+
contentContainerStyle={{ gap: 4 }}
+
renderItem={({ item: invite }) => (
+
authority: invite.did as
+
collection: invite.collection,
+
borderColor: semantic.borderVariant,
+
borderRadius: atoms.radii.lg,
+
typography.weights.byName.medium,
+
renderItem={({ item: invite }) => (
+
<Text>{invite.rkey}</Text>
+
const PendingInvite = ({ inviteAtUri }: { inviteAtUri: Required<AtUri> }) => {
+
const { semantic } = useCurrentPalette();
+
const { atoms } = useFacet();
+
const session = useOAuthSessionGuaranteed();
+
const agent = useOAuthAgentGuaranteed();
+
const { queryKey: constellationInvitesQueryKey } =
+
useConstellationInvitesQuery(session);
+
const queryClient = useQueryClient();
+
const queryKeysToInvalidate = constellationInvitesQueryKey.concat(["membership", session.did])
+
const { mutate: mutateInvites, error: inviteMutationError } = useMutation({
+
mutationFn: async (state: "accepted" | "rejected") => {
+
const inviteCommitRes = await getCommitFromFullAtUri(inviteAtUri);
+
if (!inviteCommitRes.ok)
+
"Could not resolve invite record from user's PDS.",
+
const { data: inviteCommit } = inviteCommitRes;
+
data: inviteRecordParsed,
+
} = systemsGmstnDevelopmentChannelInviteRecordSchema.safeParse(
+
`Could not validate invite record schema. ${z.prettifyError(parseError)}`,
+
const { uri, cid } = inviteCommit;
+
"Invite commit record did not have a cid somehow. Ensure that the data on PDS is not malformed.",
+
const creationResult = await addMembership({
+
channel: inviteRecordParsed.channel,
+
if(!creationResult.ok) throw new Error(`Error when submitting data. Check the inputs. ${creationResult.error}`)
+
onSuccess: async () => {
+
await queryClient.invalidateQueries({
+
queryKey: queryKeysToInvalidate,
+
<View style={{ flexDirection: "row", alignItems: "center", gap: 2 }}>
+
<Text>{inviteAtUri.rKey}</Text>
+
<Pressable style={{ marginLeft: 2 }} onPress={() => {
+
mutateInvites("accepted")
+
color={semantic.positive}
+
backgroundColor: hovered
+
? semantic.surfaceVariant
+
borderRadius: atoms.radii.sm,
+
<Pressable style={{ marginLeft: 2 }} onPress={() => {
+
mutateInvites("rejected")
+
color={semantic.negative}
+
backgroundColor: hovered
+
? semantic.surfaceVariant
+
borderRadius: atoms.radii.sm,