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

getPostThreadV2 basic impl

Changed files
+127 -5
shims
lex
app
bsky
feed
+122
main.go
··· 587 587 Feed: out, 588 588 }) 589 589 }) 590 + type GetPostThreadOtherV2_Output_WithOtherReplies struct { 591 + appbsky.UnspeccedGetPostThreadOtherV2_Output 592 + HasOtherReplies bool `json:"hasOtherReplies"` 593 + } 594 + router.GET("/xrpc/app.bsky.unspecced.getPostThreadV2", 595 + func(c *gin.Context) { 596 + ctx := c.Request.Context() 590 597 598 + rawdid := c.GetString("user_did") 599 + var viewer *utils.DID 600 + didval, errdid := utils.NewDID(rawdid) 601 + if errdid != nil { 602 + viewer = nil 603 + } else { 604 + viewer = &didval 605 + } 606 + 607 + threadAnchorURIraw := c.Query("anchor") 608 + if threadAnchorURIraw == "" { 609 + c.JSON(http.StatusBadRequest, gin.H{"error": "Missing feed param"}) 610 + return 611 + } 612 + 613 + threadAnchorURI, err := syntax.ParseATURI(threadAnchorURIraw) 614 + if err != nil { 615 + return 616 + } 617 + 618 + //var thread []*appbsky.UnspeccedGetPostThreadOtherV2_ThreadItem 619 + 620 + var skeletonposts []string 621 + skeletonposts = append(skeletonposts, threadAnchorURI.String()) 622 + 623 + emptystrarray := &[]string{} 624 + limit := 100 625 + 626 + // todo: theres a cursor!!! pagination please! 627 + // todo: also i doubt im gonna do proper threadding so make sure to remind me to do it properly thanks 628 + //rootReplies, _ := constellation.GetBacklinks(ctx, cs, string(threadAnchorURI), "app.bsky.feed.post:reply.root.uri", *emptystrarray, &limit, nil) 629 + parentReplies, _ := constellation.GetBacklinks(ctx, cs, string(threadAnchorURI), "app.bsky.feed.post:reply.parent.uri", *emptystrarray, &limit, nil) 630 + 631 + for _, rec := range parentReplies.Records { 632 + recordaturi, err := syntax.ParseATURI("at://" + rec.Did + "/" + rec.Collection + "/" + rec.Rkey) 633 + if err != nil { 634 + continue 635 + } 636 + skeletonposts = append(skeletonposts, recordaturi.String()) 637 + } 638 + concurrentResults := MapConcurrent( 639 + ctx, 640 + skeletonposts, 641 + 20, 642 + func(ctx context.Context, raw string) (*appbsky.UnspeccedGetPostThreadOtherV2_ThreadItem, error) { 643 + post, _, err := appbskyfeeddefs.PostView(ctx, raw, sl, cs, BSKYIMAGECDN_URL, viewer, 3) 644 + if err != nil { 645 + return nil, err 646 + } 647 + if post == nil { 648 + return nil, fmt.Errorf("post not found") 649 + } 650 + 651 + depth := int64(1) 652 + if raw == threadAnchorURI.String() { 653 + depth = 0 654 + } 655 + 656 + return &appbsky.UnspeccedGetPostThreadOtherV2_ThreadItem{ 657 + // Depth int64 `json:"depth" cborgen:"depth"` 658 + Depth: depth, // todo: placeholder 659 + // Uri string `json:"uri" cborgen:"uri"` 660 + Uri: raw, 661 + // Value *UnspeccedGetPostThreadOtherV2_ThreadItem_Value `json:"value" cborgen:"value"` 662 + Value: &appbsky.UnspeccedGetPostThreadOtherV2_ThreadItem_Value{ 663 + // UnspeccedDefs_ThreadItemPost *UnspeccedDefs_ThreadItemPost 664 + UnspeccedDefs_ThreadItemPost: &appbsky.UnspeccedDefs_ThreadItemPost{ 665 + // LexiconTypeID string `json:"$type" cborgen:"$type,const=app.bsky.unspecced.defs#threadItemPost"` 666 + LexiconTypeID: "app.bsky.unspecced.defs#threadItemPost", 667 + // // hiddenByThreadgate: The threadgate created by the author indicates this post as a reply to be hidden for everyone consuming the thread. 668 + // HiddenByThreadgate bool `json:"hiddenByThreadgate" cborgen:"hiddenByThreadgate"` 669 + HiddenByThreadgate: false, // todo: placeholder 670 + // // moreParents: This post has more parents that were not present in the response. This is just a boolean, without the number of parents. 671 + // MoreParents bool `json:"moreParents" cborgen:"moreParents"` 672 + MoreParents: false, // todo: placeholder 673 + // // moreReplies: This post has more replies that were not present in the response. This is a numeric value, which is best-effort and might not be accurate. 674 + // MoreReplies int64 `json:"moreReplies" cborgen:"moreReplies"` 675 + MoreReplies: 0, // todo: placeholder 676 + // // mutedByViewer: This is by an account muted by the viewer requesting it. 677 + // MutedByViewer bool `json:"mutedByViewer" cborgen:"mutedByViewer"` 678 + MutedByViewer: false, // todo: placeholder 679 + // // opThread: This post is part of a contiguous thread by the OP from the thread root. Many different OP threads can happen in the same thread. 680 + // OpThread bool `json:"opThread" cborgen:"opThread"` 681 + OpThread: false, // todo: placeholder 682 + // Post *FeedDefs_PostView `json:"post" cborgen:"post"` 683 + Post: post, 684 + }, 685 + }, 686 + }, nil 687 + }, 688 + ) 689 + 690 + // build final slice 691 + out := make([]*appbsky.UnspeccedGetPostThreadOtherV2_ThreadItem, 0, len(concurrentResults)) 692 + for _, r := range concurrentResults { 693 + if r.Err == nil && r.Value != nil && r.Value.Value != nil && r.Value.Value.UnspeccedDefs_ThreadItemPost != nil && r.Value.Value.UnspeccedDefs_ThreadItemPost.Post != nil { 694 + out = append(out, r.Value) 695 + } 696 + } 697 + 698 + // c.JSON(http.StatusOK, &appbsky.UnspeccedGetPostThreadOtherV2_Output{ 699 + // // Thread []*UnspeccedGetPostThreadOtherV2_ThreadItem `json:"thread" cborgen:"thread"` 700 + // Thread: out, 701 + // HasOtherReplies: false, 702 + // }) 703 + resp := &GetPostThreadOtherV2_Output_WithOtherReplies{ 704 + UnspeccedGetPostThreadOtherV2_Output: appbsky.UnspeccedGetPostThreadOtherV2_Output{ 705 + Thread: out, 706 + }, 707 + HasOtherReplies: false, 708 + } 709 + c.JSON(http.StatusOK, resp) 710 + }) 711 + 712 + // weird stuff 591 713 yourJSONBytes, _ := os.ReadFile("./public/getConfig.json") 592 714 router.GET("/xrpc/app.bsky.unspecced.getConfig", func(c *gin.Context) { 593 715 c.DataFromReader(200, -1, "application/json",
+5 -5
shims/lex/app/bsky/feed/defs/postview.go
··· 76 76 } 77 77 if links != nil && 78 78 links.Links != nil { 79 - like, ok := links.Links["app.bsky.repost.like"] 79 + like, ok := links.Links["app.bsky.feed.repost"] 80 80 if ok && like != nil { 81 81 subj, ok := like[".subject.uri"] 82 82 if ok { ··· 96 96 } 97 97 if links != nil && 98 98 links.Links != nil { 99 - like, ok := links.Links["app.bsky.feed.like"] 99 + like, ok := links.Links["app.bsky.feed.post"] 100 100 if ok && like != nil { 101 101 subj, ok := like[".embed.record.uri"] 102 102 if ok { 103 - likeCount = int64(subj.Records) 103 + quoteCount_noEmbed = int64(subj.Records) 104 104 } 105 105 } 106 106 } 107 107 if links != nil && 108 108 links.Links != nil { 109 - like, ok := links.Links["app.bsky.feed.like"] 109 + like, ok := links.Links["app.bsky.feed.post"] 110 110 if ok && like != nil { 111 111 subj, ok := like[".embed.record.record.uri"] 112 112 if ok { 113 - likeCount = int64(subj.Records) 113 + quoteCount_withEmbed = int64(subj.Records) 114 114 } 115 115 } 116 116 }