grain.social is a photo sharing platform built on atproto.
at main 138 lines 3.0 kB view raw
1import { Record as GrainFollow } from "$lexicon/types/social/grain/graph/follow.ts"; 2import { BffContext, WithBffMeta } from "@bigmoves/bff"; 3import { getActorProfile } from "./actor.ts"; 4 5export function getFollow( 6 followeeDid: string, 7 followerDid: string, 8 ctx: BffContext, 9) { 10 const { 11 items: [follow], 12 } = ctx.indexService.getRecords< 13 WithBffMeta<GrainFollow> 14 >( 15 "social.grain.graph.follow", 16 { 17 where: { 18 AND: [{ 19 field: "did", 20 equals: followerDid, 21 }, { 22 field: "subject", 23 equals: followeeDid, 24 }], 25 }, 26 }, 27 ); 28 29 return follow; 30} 31 32export function getFollowers( 33 followeeDid: string, 34 ctx: BffContext, 35): WithBffMeta<GrainFollow>[] { 36 const { items: followers } = ctx.indexService.getRecords< 37 WithBffMeta<GrainFollow> 38 >( 39 "social.grain.graph.follow", 40 { 41 orderBy: [{ field: "createdAt", direction: "desc" }], 42 where: [{ 43 field: "subject", 44 equals: followeeDid, 45 }], 46 }, 47 ); 48 return followers; 49} 50 51export function getFollowing( 52 followerDid: string, 53 ctx: BffContext, 54): WithBffMeta<GrainFollow>[] { 55 const { items: following } = ctx.indexService.getRecords< 56 WithBffMeta<GrainFollow> 57 >( 58 "social.grain.graph.follow", 59 { 60 orderBy: [{ field: "createdAt", direction: "desc" }], 61 where: [{ 62 field: "did", 63 equals: followerDid, 64 }], 65 }, 66 ); 67 return following; 68} 69 70export function getFollowersWithProfiles( 71 followeeDid: string, 72 ctx: BffContext, 73) { 74 const followers = getFollowers(followeeDid, ctx); 75 return followers 76 .map((follow) => getActorProfile(follow.did, ctx)) 77 .filter((profile): profile is NonNullable<typeof profile> => 78 profile != null 79 ); 80} 81 82export function getFollowingWithProfiles( 83 followerDid: string, 84 ctx: BffContext, 85) { 86 const following = getFollowing(followerDid, ctx); 87 return following 88 .map((follow) => getActorProfile(follow.subject, ctx)) 89 .filter((profile): profile is NonNullable<typeof profile> => 90 profile != null 91 ); 92} 93 94export function getFollowersCount( 95 followeeDid: string, 96 ctx: BffContext, 97): number { 98 return ctx.indexService.countRecords( 99 "social.grain.graph.follow", 100 { 101 orderBy: [{ field: "createdAt", direction: "desc" }], 102 where: [{ 103 field: "subject", 104 equals: followeeDid, 105 }], 106 }, 107 ); 108} 109 110export function getFollowsCount( 111 followerDid: string, 112 ctx: BffContext, 113): number { 114 return ctx.indexService.countRecords( 115 "social.grain.graph.follow", 116 { 117 orderBy: [{ field: "createdAt", direction: "desc" }], 118 where: [{ 119 field: "did", 120 equals: followerDid, 121 }], 122 }, 123 ); 124} 125 126export async function createFollow( 127 followeeDid: string, 128 ctx: BffContext, 129): Promise<string> { 130 const followUri = await ctx.createRecord<GrainFollow>( 131 "social.grain.graph.follow", 132 { 133 subject: followeeDid, 134 createdAt: new Date().toISOString(), 135 }, 136 ); 137 return followUri; 138}