Signed-off-by: Anirudh Oppiliappan anirudh@tangled.org
appview/pages/funcmap.go
appview/pages/funcmap.go
This file has not been changed.
appview/pages/templates/fragments/dolly/silhouette.svg
appview/pages/templates/fragments/dolly/silhouette.svg
This file has not been changed.
+38
-55
appview/repo/opengraph.go
+38
-55
appview/repo/opengraph.go
···
4
4
"bytes"
5
5
"context"
6
6
"encoding/hex"
7
-
"encoding/json"
8
7
"fmt"
9
8
"image/color"
10
9
"image/png"
11
10
"log"
12
11
"net/http"
12
+
"sort"
13
13
"strings"
14
14
15
-
indigoxrpc "github.com/bluesky-social/indigo/xrpc"
16
-
"tangled.org/core/api/tangled"
15
+
"github.com/go-enry/go-enry/v2"
16
+
"tangled.org/core/appview/db"
17
17
"tangled.org/core/appview/models"
18
18
"tangled.org/core/appview/repo/ogcard"
19
19
"tangled.org/core/types"
···
103
103
104
104
// Get avatar URL and draw it
105
105
avatarURL := rp.pages.AvatarUrl(ownerHandle, "256")
106
-
log.Printf("Fetching avatar from: %s", avatarURL)
107
106
err = avatarArea.DrawCircularExternalImage(avatarURL, avatarX, avatarY, avatarSize)
108
107
if err != nil {
109
108
log.Printf("failed to draw avatar (non-fatal): %v", err)
···
112
111
// Split bottom area: icons area (65%) and language bar (35%)
113
112
iconsArea, languageBarCard := bottomArea.Split(false, 75)
114
113
115
-
// Split icons area: left side for stats (85%), right side for dolly (15%)
116
-
statsArea, dollyArea := iconsArea.Split(true, 85)
114
+
// Split icons area: left side for stats (80%), right side for dolly (20%)
115
+
statsArea, dollyArea := iconsArea.Split(true, 80)
117
116
118
117
// Draw stats with icons in the stats area
119
118
starsText := repo.RepoStats.StarCount
···
126
125
127
126
// Position stats in the middle of the stats area
128
127
statsBounds := statsArea.Img.Bounds()
129
-
log.Printf("Stats area bounds: %v", statsBounds)
130
128
statsX := statsBounds.Min.X + 60 // left padding
131
129
statsY := statsBounds.Min.Y
132
130
currentX = statsX
133
131
labelSize := 22.0
134
-
log.Printf("Stats starting position: X=%d, Y=%d", statsX, statsY)
135
132
// Draw star icon, count, and label
136
133
// Align icon baseline with text baseline
137
134
iconBaselineOffset := int(textSize) / 2
···
153
150
// Draw "stars" label below and centered under the icon+text group
154
151
labelY := statsY + iconSize + 15
155
152
labelX := starIconX + starGroupWidth/2
156
-
log.Printf("Drawing 'stars' label at X=%d, Y=%d, bounds: %v", labelX, labelY, statsBounds)
157
153
err = iconsArea.DrawTextAt("stars", labelX, labelY, iconColor, labelSize, ogcard.Top, ogcard.Center)
158
154
if err != nil {
159
155
log.Printf("failed to draw stars label: %v", err)
160
-
} else {
161
-
log.Printf("Successfully drew 'stars' label")
162
156
}
163
157
164
158
currentX += starTextWidth + 50
···
181
175
182
176
// Draw "issues" label below and centered under the icon+text group
183
177
labelX = issueStartX + issueGroupWidth/2
184
-
log.Printf("Drawing 'issues' label at X=%d, Y=%d", labelX, labelY)
185
178
err = iconsArea.DrawTextAt("issues", labelX, labelY, iconColor, labelSize, ogcard.Top, ogcard.Center)
186
179
if err != nil {
187
180
log.Printf("failed to draw issues label: %v", err)
188
-
} else {
189
-
log.Printf("Successfully drew 'issues' label")
190
181
}
191
182
192
183
currentX += issueTextWidth + 50
···
209
200
210
201
// Draw "pulls" label below and centered under the icon+text group
211
202
labelX = prStartX + prGroupWidth/2
212
-
log.Printf("Drawing 'pulls' label at X=%d, Y=%d", labelX, labelY)
213
203
err = iconsArea.DrawTextAt("pulls", labelX, labelY, iconColor, labelSize, ogcard.Top, ogcard.Center)
214
204
if err != nil {
215
205
log.Printf("failed to draw pulls label: %v", err)
216
-
} else {
217
-
log.Printf("Successfully drew 'pulls' label")
218
206
}
219
207
220
208
dollyBounds := dollyArea.Img.Bounds()
···
320
308
return
321
309
}
322
310
323
-
// Get language stats
324
-
scheme := "http"
325
-
if !rp.config.Core.Dev {
326
-
scheme = "https"
327
-
}
328
-
host := fmt.Sprintf("%s://%s", scheme, f.Knot)
329
-
xrpcc := &indigoxrpc.Client{
330
-
Host: host,
331
-
}
332
-
333
-
// Get default branch/ref for language stats
311
+
// Get language stats directly from database
334
312
var languageStats []types.RepoLanguageDetails
335
-
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
313
+
langs, err := db.GetRepoLanguages(
314
+
rp.db,
315
+
db.FilterEq("repo_at", f.RepoAt()),
316
+
db.FilterEq("is_default_ref", 1),
317
+
)
318
+
if err != nil {
319
+
log.Printf("failed to get language stats from db: %v", err)
320
+
// non-fatal, continue without language stats
321
+
} else if len(langs) > 0 {
322
+
var total int64
323
+
for _, l := range langs {
324
+
total += l.Bytes
325
+
}
336
326
337
-
// Fetch branches to get default branch
338
-
branchesBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
339
-
if err == nil {
340
-
var branchesResp types.RepoBranchesResponse
341
-
if err := json.Unmarshal(branchesBytes, &branchesResp); err == nil {
342
-
// Find default branch
343
-
var defaultRef string
344
-
for _, branch := range branchesResp.Branches {
345
-
if branch.IsDefault {
346
-
defaultRef = branch.Name
347
-
break
348
-
}
349
-
}
327
+
for _, l := range langs {
328
+
percentage := float32(l.Bytes) / float32(total) * 100
329
+
color := enry.GetColor(l.Language)
330
+
languageStats = append(languageStats, types.RepoLanguageDetails{
331
+
Name: l.Language,
332
+
Percentage: percentage,
333
+
Color: color,
334
+
})
335
+
}
350
336
351
-
// If no default branch, use first branch
352
-
if defaultRef == "" && len(branchesResp.Branches) > 0 {
353
-
defaultRef = branchesResp.Branches[0].Name
337
+
sort.Slice(languageStats, func(i, j int) bool {
338
+
if languageStats[i].Name == enry.OtherLanguage {
339
+
return false
354
340
}
355
-
356
-
if defaultRef != "" {
357
-
langStats, err := rp.getLanguageInfo(r.Context(), f, xrpcc, defaultRef, true)
358
-
if err != nil {
359
-
log.Println("failed to get language stats for opengraph", err)
360
-
// non-fatal, continue without language stats
361
-
} else {
362
-
languageStats = langStats
363
-
}
341
+
if languageStats[j].Name == enry.OtherLanguage {
342
+
return true
364
343
}
365
-
}
344
+
if languageStats[i].Percentage != languageStats[j].Percentage {
345
+
return languageStats[i].Percentage > languageStats[j].Percentage
346
+
}
347
+
return languageStats[i].Name < languageStats[j].Name
348
+
})
366
349
}
367
350
368
351
card, err := rp.drawRepoSummaryCard(&f.Repo, languageStats)
appview/repo/router.go
appview/repo/router.go
This file has not been changed.
go.mod
go.mod
This file has not been changed.
go.sum
go.sum
This file has not been changed.
History
2 rounds
2 comments
anirudh.fi
submitted
#1
1 commit
expand
collapse
appview/repo: construct and serve og image for repos
Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.org>
expand 0 comments
pull request successfully merged
anirudh.fi
submitted
#0
1 commit
expand
collapse
appview/repo: construct and serve og image for repos
Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.org>
do not call out to the knot here, use language data from the appview.