bluesky appview implementation using microcosm and other services server.reddwarf.app
appview bluesky reddwarf microcosm

ProfileView viewer for following and blocking state

Changed files
+129 -15
shims
lex
app
bsky
actor
feed
+39 -6
main.go
··· 117 117 } else { 118 118 didtest = &didval 119 119 } 120 - profiletest, _, _ := appbskyactordefs.ProfileViewBasic(ctx, *didtest, sl, BSKYIMAGECDN_URL) 120 + profiletest, _, _ := appbskyactordefs.ProfileViewBasic(ctx, *didtest, sl, cs, BSKYIMAGECDN_URL, nil) 121 121 122 122 log.Println(*profiletest.DisplayName) 123 123 log.Println(*profiletest.Avatar) ··· 164 164 165 165 bskyappdid, _ := utils.NewDID("did:plc:z72i7hdynmk6r22z27h6tvur") 166 166 167 - profiletest2, _, _ := appbskyactordefs.ProfileViewDetailed(ctx, bskyappdid, sl, cs, BSKYIMAGECDN_URL) 167 + profiletest2, _, _ := appbskyactordefs.ProfileViewDetailed(ctx, bskyappdid, sl, cs, BSKYIMAGECDN_URL, nil) 168 168 169 169 data, err := json.MarshalIndent(profiletest2, "", " ") 170 170 if err != nil { ··· 176 176 func(c *gin.Context) { 177 177 actors := c.QueryArray("actors") 178 178 179 + rawdid := c.GetString("user_did") 180 + var viewer *utils.DID 181 + didval, errdid := utils.NewDID(rawdid) 182 + if errdid != nil { 183 + viewer = nil 184 + } else { 185 + viewer = &didval 186 + } 187 + 179 188 profiles := make([]*appbsky.ActorDefs_ProfileViewDetailed, 0, len(actors)) 180 189 181 190 for _, v := range actors { ··· 183 192 if err != nil { 184 193 continue 185 194 } 186 - profile, _, _ := appbskyactordefs.ProfileViewDetailed(ctx, did, sl, cs, BSKYIMAGECDN_URL) 195 + profile, _, _ := appbskyactordefs.ProfileViewDetailed(ctx, did, sl, cs, BSKYIMAGECDN_URL, viewer) 187 196 profiles = append(profiles, profile) 188 197 } 189 198 ··· 200 209 c.JSON(http.StatusBadRequest, nil) 201 210 return 202 211 } 203 - profile, _, _ := appbskyactordefs.ProfileViewDetailed(ctx, did, sl, cs, BSKYIMAGECDN_URL) 212 + rawdid := c.GetString("user_did") 213 + var viewer *utils.DID 214 + didval, errdid := utils.NewDID(rawdid) 215 + if errdid != nil { 216 + viewer = nil 217 + } else { 218 + viewer = &didval 219 + } 220 + profile, _, _ := appbskyactordefs.ProfileViewDetailed(ctx, did, sl, cs, BSKYIMAGECDN_URL, viewer) 204 221 c.JSON(http.StatusOK, profile) 205 222 }) 206 223 ··· 226 243 if err != nil { 227 244 continue 228 245 } 229 - labelerprofile, _, _ := appbskyactordefs.ProfileView(ctx, did, sl, BSKYIMAGECDN_URL) 246 + rawdid := c.GetString("user_did") 247 + var viewer *utils.DID 248 + didval, errdid := utils.NewDID(rawdid) 249 + if errdid != nil { 250 + viewer = nil 251 + } else { 252 + viewer = &didval 253 + } 254 + labelerprofile, _, _ := appbskyactordefs.ProfileView(ctx, did, sl, cs, BSKYIMAGECDN_URL, viewer) 230 255 labelerserviceresponse, _ := agnostic.RepoGetRecord(ctx, sl, "", "app.bsky.labeler.service", string(did), "self") 231 256 var labelerservice appbsky.LabelerService 232 257 if labelerserviceresponse != nil { ··· 329 354 if err != nil { 330 355 return 331 356 } 357 + rawdid := c.GetString("user_did") 358 + var viewer *utils.DID 359 + didval, errdid := utils.NewDID(rawdid) 360 + if errdid != nil { 361 + viewer = nil 362 + } else { 363 + viewer = &didval 364 + } 332 365 333 366 // fetch profile and record in parallel too (optional) 334 367 // but to keep it simple, do serial inside this goroutine 335 - profile, _, _ := appbskyactordefs.ProfileView(ctx, repoDID, sl, BSKYIMAGECDN_URL) 368 + profile, _, _ := appbskyactordefs.ProfileView(ctx, repoDID, sl, cs, BSKYIMAGECDN_URL, viewer) 336 369 337 370 rec, err := agnostic.RepoGetRecord(ctx, sl, "", collection, did, rkey) 338 371 if err != nil || rec.Value == nil {
+88 -7
shims/lex/app/bsky/actor/defs/profileview.go
··· 3 3 import ( 4 4 "context" 5 5 "encoding/json" 6 + "log" 6 7 7 8 "github.com/bluesky-social/indigo/api/agnostic" 8 9 appbsky "github.com/bluesky-social/indigo/api/bsky" 10 + "github.com/bluesky-social/indigo/atproto/syntax" 9 11 "tangled.org/whey.party/red-dwarf-server/microcosm" 10 12 "tangled.org/whey.party/red-dwarf-server/microcosm/constellation" 11 13 "tangled.org/whey.party/red-dwarf-server/microcosm/slingshot" 12 14 "tangled.org/whey.party/red-dwarf-server/shims/utils" 13 15 ) 14 16 15 - func ProfileViewBasic(ctx context.Context, did utils.DID, sl *microcosm.MicrocosmClient, imgcdn string) (*appbsky.ActorDefs_ProfileViewBasic, *appbsky.ActorProfile, error) { 16 - profileview, profile, err := ProfileView(ctx, did, sl, imgcdn) 17 + func ProfileViewBasic(ctx context.Context, did utils.DID, sl *microcosm.MicrocosmClient, cs *microcosm.MicrocosmClient, imgcdn string, viewer *utils.DID) (*appbsky.ActorDefs_ProfileViewBasic, *appbsky.ActorProfile, error) { 18 + profileview, profile, err := ProfileView(ctx, did, sl, cs, imgcdn, viewer) 17 19 18 20 if err != nil { 19 21 return nil, nil, err ··· 38 40 }, profile, err 39 41 } 40 42 41 - func ProfileView(ctx context.Context, did utils.DID, sl *microcosm.MicrocosmClient, imgcdn string) (*appbsky.ActorDefs_ProfileView, *appbsky.ActorProfile, error) { 43 + func ProfileView(ctx context.Context, did utils.DID, sl *microcosm.MicrocosmClient, cs *microcosm.MicrocosmClient, imgcdn string, viewer *utils.DID) (*appbsky.ActorDefs_ProfileView, *appbsky.ActorProfile, error) { 42 44 identity, err_i := slingshot.ResolveMiniDoc(ctx, sl, string(did)) 43 45 if err_i != nil { 44 46 identity = nil ··· 76 78 avatar = &url 77 79 } 78 80 81 + var blocking *string 82 + blockedBy := false 83 + var following *string 84 + var followedBy *string 85 + 86 + viewerProfileDID := "" 87 + if viewer != nil { 88 + viewerProfileDID = string(*viewer) 89 + } 90 + targetProfileDID := string(did) 91 + //viewerProfileURI, err_viewerProfileURI := syntax.ParseATURI("at://" + viewerProfileDID + "/app.bsky.actor.profile/self") 92 + //targetProfileURI, err_targetProfileURI := syntax.ParseATURI("at://" + targetProfileDID + "/app.bsky.actor.profile/self") 93 + 94 + log.Println("viewerProfileDID: " + viewerProfileDID + " and targetProfileDID: " + targetProfileDID) 95 + 96 + if viewerProfileDID != "" && targetProfileDID != "" { 97 + blockingBacklink, err_blockingBacklink := constellation.GetBacklinks(ctx, cs, targetProfileDID, "app.bsky.graph.block:subject", []string{viewerProfileDID}, nil, nil) 98 + if err_blockingBacklink == nil && blockingBacklink.Records != nil && len(blockingBacklink.Records) > 0 && blockingBacklink.Total > 0 { 99 + blockingATURI, err_blockingATURI := syntax.ParseATURI("at://" + blockingBacklink.Records[0].Did + "/app.bsky.graph.block/" + blockingBacklink.Records[0].Rkey) 100 + if err_blockingATURI == nil { 101 + blockingString := blockingATURI.String() 102 + blocking = &blockingString 103 + } 104 + } 105 + blockedByBacklink, err_blockedByBacklink := constellation.GetBacklinks(ctx, cs, viewerProfileDID, "app.bsky.graph.block:subject", []string{targetProfileDID}, nil, nil) 106 + if err_blockedByBacklink == nil && blockedByBacklink.Records != nil && len(blockedByBacklink.Records) > 0 && blockedByBacklink.Total > 0 { 107 + _, err_blockedByATURI := syntax.ParseATURI("at://" + blockedByBacklink.Records[0].Did + "/app.bsky.graph.block/" + blockedByBacklink.Records[0].Rkey) 108 + if err_blockedByATURI == nil { 109 + blockedBy = true 110 + } 111 + } 112 + followingBacklink, err_followingBacklink := constellation.GetBacklinks(ctx, cs, targetProfileDID, "app.bsky.graph.follow:subject", []string{viewerProfileDID}, nil, nil) 113 + if err_followingBacklink == nil && followingBacklink.Records != nil && len(followingBacklink.Records) > 0 && followingBacklink.Total > 0 { 114 + followingATURI, err_followingATURI := syntax.ParseATURI("at://" + followingBacklink.Records[0].Did + "/app.bsky.graph.follow/" + followingBacklink.Records[0].Rkey) 115 + if err_followingATURI == nil { 116 + followingString := followingATURI.String() 117 + following = &followingString 118 + } 119 + } 120 + followedByBacklink, err_followedByBacklink := constellation.GetBacklinks(ctx, cs, viewerProfileDID, "app.bsky.graph.follow:subject", []string{targetProfileDID}, nil, nil) 121 + if err_followedByBacklink == nil && followedByBacklink.Records != nil && len(followedByBacklink.Records) > 0 && followedByBacklink.Total > 0 { 122 + followedByATURI, err_followedByATURI := syntax.ParseATURI("at://" + followedByBacklink.Records[0].Did + "/app.bsky.graph.follow/" + followedByBacklink.Records[0].Rkey) 123 + if err_followedByATURI == nil { 124 + followedByString := followedByATURI.String() 125 + followedBy = &followedByString 126 + } 127 + } 128 + 129 + } 130 + 131 + // we dont know before hand, so to make it visible on the page, we must set it to be non zero 132 + nonzeroassociated := int64(1) 133 + 79 134 return &appbsky.ActorDefs_ProfileView{ 80 - Associated: nil, 135 + Associated: &appbsky.ActorDefs_ProfileAssociated{ 136 + // ActivitySubscription *ActorDefs_ProfileAssociatedActivitySubscription `json:"activitySubscription,omitempty" cborgen:"activitySubscription,omitempty"` 137 + // Chat *ActorDefs_ProfileAssociatedChat `json:"chat,omitempty" cborgen:"chat,omitempty"` 138 + // Feedgens *int64 `json:"feedgens,omitempty" cborgen:"feedgens,omitempty"` 139 + Feedgens: &nonzeroassociated, 140 + // Labeler *bool `json:"labeler,omitempty" cborgen:"labeler,omitempty"` 141 + // Lists *int64 `json:"lists,omitempty" cborgen:"lists,omitempty"` 142 + Lists: &nonzeroassociated, 143 + // StarterPacks *int64 `json:"starterPacks,omitempty" cborgen:"starterPacks,omitempty"` 144 + StarterPacks: &nonzeroassociated, 145 + }, 81 146 Avatar: avatar, 82 147 CreatedAt: profile.CreatedAt, 83 148 Debug: nil, ··· 90 155 Pronouns: nil, 91 156 Status: nil, 92 157 Verification: nil, 93 - Viewer: nil, 158 + Viewer: &appbsky.ActorDefs_ViewerState{ 159 + // // activitySubscription: This property is present only in selected cases, as an optimization. 160 + // ActivitySubscription *NotificationDefs_ActivitySubscription `json:"activitySubscription,omitempty" cborgen:"activitySubscription,omitempty"` 161 + // BlockedBy *bool `json:"blockedBy,omitempty" cborgen:"blockedBy,omitempty"` 162 + BlockedBy: &blockedBy, 163 + // Blocking *string `json:"blocking,omitempty" cborgen:"blocking,omitempty"` 164 + Blocking: blocking, 165 + // BlockingByList *GraphDefs_ListViewBasic `json:"blockingByList,omitempty" cborgen:"blockingByList,omitempty"` 166 + // FollowedBy *string `json:"followedBy,omitempty" cborgen:"followedBy,omitempty"` 167 + FollowedBy: followedBy, 168 + // Following *string `json:"following,omitempty" cborgen:"following,omitempty"` 169 + Following: following, 170 + // // knownFollowers: This property is present only in selected cases, as an optimization. 171 + // KnownFollowers *ActorDefs_KnownFollowers `json:"knownFollowers,omitempty" cborgen:"knownFollowers,omitempty"` 172 + // Muted *bool `json:"muted,omitempty" cborgen:"muted,omitempty"` 173 + // MutedByList *GraphDefs_ListViewBasic `json:"mutedByList,omitempty" cborgen:"mutedByList,omitempty"` 174 + }, 94 175 }, &profile, nil 95 176 } 96 177 97 - func ProfileViewDetailed(ctx context.Context, did utils.DID, sl *microcosm.MicrocosmClient, cs *microcosm.MicrocosmClient, imgcdn string) (*appbsky.ActorDefs_ProfileViewDetailed, *appbsky.ActorProfile, error) { 98 - profileview, profile, err := ProfileView(ctx, did, sl, imgcdn) 178 + func ProfileViewDetailed(ctx context.Context, did utils.DID, sl *microcosm.MicrocosmClient, cs *microcosm.MicrocosmClient, imgcdn string, viewer *utils.DID) (*appbsky.ActorDefs_ProfileViewDetailed, *appbsky.ActorProfile, error) { 179 + profileview, profile, err := ProfileView(ctx, did, sl, cs, imgcdn, viewer) 99 180 if err != nil { 100 181 return nil, nil, err 101 182 }
+1 -1
shims/lex/app/bsky/feed/defs/embed.go
··· 291 291 292 292 if collection == "app.bsky.feed.post" { 293 293 //t.EmbedRecord_ViewRecord.LexiconTypeID = "app.bsky.embed.record#viewRecord" 294 - profileViewBasic, _, err := appbskyactordefs.ProfileViewBasic(ctx, utils.DID(aturi.Authority().String()), sl, imgcdn) 294 + profileViewBasic, _, err := appbskyactordefs.ProfileViewBasic(ctx, utils.DID(aturi.Authority().String()), sl, cs, imgcdn, viewer) 295 295 if err != nil { 296 296 log.Println("[EmbedRecord_View_Record] profileviewbasic failed") 297 297 return notFoundRecordEmbed(aturi.String())
+1 -1
shims/lex/app/bsky/feed/defs/postview.go
··· 49 49 } 50 50 //} 51 51 52 - profile, _, err := appbskyactordefs.ProfileViewBasic(ctx, repoDID, sl, imgcdn) 52 + profile, _, err := appbskyactordefs.ProfileViewBasic(ctx, repoDID, sl, cs, imgcdn, viewer) 53 53 if err != nil || profile == nil { 54 54 if profile == nil { 55 55 //log.Println("WHAT!! profile / author field is null?!?!?! whyyy")