tuiter 2006
1package main
2
3import (
4 "log"
5 "net/http"
6 "strings"
7
8 bsky "github.com/bluesky-social/indigo/api/bsky"
9)
10
11func handlePost(w http.ResponseWriter, r *http.Request) {
12 c, didStr, err := getClientFromSession(r.Context(), r)
13 if err != nil {
14 http.Redirect(w, r, "/signin", http.StatusFound)
15 return
16 }
17
18 data, err := preparePostPageData(r.Context(), r, c, didStr)
19 if err != nil {
20 http.Error(w, "Failed to prepare post page: "+err.Error(), http.StatusInternalServerError)
21 return
22 }
23
24 executeTemplate(w, "post.html", data)
25}
26
27func handleProfile(w http.ResponseWriter, r *http.Request) {
28 c, myDid, err := getClientFromSession(r.Context(), r)
29 if err != nil {
30 http.Redirect(w, r, "/signin", http.StatusFound)
31 return
32 }
33
34 path := strings.TrimPrefix(r.URL.Path, "/profile/")
35 profileHandle := path
36 if profileHandle == "" {
37 profileHandle = myDid
38 }
39
40 profileView, err := fetchProfile(r.Context(), c, profileHandle)
41 if err != nil {
42 http.Error(w, err.Error(), http.StatusInternalServerError)
43 return
44 }
45 if profileView == nil {
46 http.Error(w, "Profile not found", http.StatusNotFound)
47 return
48 }
49
50 authorFeed, err := bsky.FeedGetAuthorFeed(r.Context(), c, profileView.Did, "", "", false, 50)
51 if err != nil {
52 http.Error(w, err.Error(), http.StatusInternalServerError)
53 return
54 }
55
56 myProfile, err := fetchProfile(r.Context(), c, myDid)
57 if err != nil {
58 http.Error(w, err.Error(), http.StatusInternalServerError)
59 return
60 }
61
62 followsList := fetchFollows(r.Context(), c, profileView.Did, 50)
63
64 postBoxHandle := ""
65 if profileView.Handle != "" {
66 postBoxHandle = profileView.Handle
67 }
68
69 // Collect parent URIs from the author's feed and batch-fetch previews
70 parentURIsSet := map[string]struct{}{}
71 if authorFeed != nil && authorFeed.Feed != nil {
72 for _, fv := range authorFeed.Feed {
73 if fv == nil || fv.Post == nil {
74 continue
75 }
76 if uri := extractReplyParentURI(fv.Post); uri != "" {
77 parentURIsSet[uri] = struct{}{}
78 }
79 chain := GetReplyChainInfos(fv.Post)
80 for _, pi := range chain {
81 if pi.Uri != "" {
82 parentURIsSet[pi.Uri] = struct{}{}
83 }
84 }
85 }
86 }
87
88 var parentURIs []string
89 for u := range parentURIsSet {
90 parentURIs = append(parentURIs, u)
91 }
92
93 parentPreviews := map[string]ParentInfo{}
94 if len(parentURIs) > 0 {
95 const batchSize = 25
96 for i := 0; i < len(parentURIs); i += batchSize {
97 end := i + batchSize
98 if end > len(parentURIs) {
99 end = len(parentURIs)
100 }
101 batch := parentURIs[i:end]
102 postsMap, err := fetchPostsBatch(r.Context(), c, batch)
103 if err != nil {
104 log.Printf("DEBUG: handleProfile - fetchPostsBatch error: %v", err)
105 continue
106 }
107 for uri, pv := range postsMap {
108 if pv == nil {
109 continue
110 }
111 pi := ParentInfo{Uri: uri}
112 if pv.Author != nil {
113 if pv.Author.DisplayName != nil && *pv.Author.DisplayName != "" {
114 pi.AuthorName = *pv.Author.DisplayName
115 } else if pv.Author.Handle != "" {
116 pi.AuthorName = pv.Author.Handle
117 }
118 if pv.Author.Handle != "" {
119 pi.AuthorHandle = pv.Author.Handle
120 }
121 if pv.Author.Avatar != nil {
122 pi.Avatar = *pv.Author.Avatar
123 }
124 }
125 pi.Text = getPostText(pv.Record)
126 if pv.Uri != "" {
127 pi.PostURL = getPostURL(pv)
128 }
129 pi.IndexedAt = pv.IndexedAt
130 // populate media preview if present
131 if m := GetPostMedia(pv); m != nil {
132 pi.Media = m
133 }
134 // like count if available
135 if pv.LikeCount != nil {
136 pi.LikeCount = int(*pv.LikeCount)
137 }
138 pi.IsFav = getIsFav(pv)
139 parentPreviews[uri] = pi
140 }
141 }
142 }
143
144 data := ProfilePageData{
145 Title: "Profile - Tuiter 2006",
146 Profile: profileView,
147 Feed: authorFeed,
148 Follows: followsList,
149 Posts: PostsList{Items: authorFeed.Feed, Cursor: getCursorFromAuthorFeed(authorFeed), ParentPreviews: parentPreviews},
150 PostBoxHandle: postBoxHandle,
151 // provide the signed-in profile explicitly
152 SignedIn: myProfile,
153 }
154
155 executeTemplate(w, "profile.html", data)
156}