+54
-28
appview/repo/opengraph.go
+54
-28
appview/repo/opengraph.go
···
35
35
// Split content horizontally: main content (80%) and avatar area (20%)
36
36
mainContent, avatarArea := contentCard.Split(true, 80)
37
37
38
-
// Split main content: 50% for name/description, 50% for spacing
39
-
topSection, _ := mainContent.Split(false, 50)
38
+
// Use main content area for both repo name and description to allow dynamic wrapping.
39
+
mainContent.SetMargin(10)
40
40
41
-
// Split top section: 40% for repo name, 60% for description
42
-
repoNameCard, descriptionCard := topSection.Split(false, 50)
43
-
44
-
// Draw repo name with owner in regular and repo name in bold
45
-
repoNameCard.SetMargin(10)
46
41
var ownerHandle string
47
42
owner, err := rp.idResolver.ResolveIdent(context.Background(), repo.Did)
48
43
if err != nil {
···
51
46
ownerHandle = "@" + owner.Handle.String()
52
47
}
53
48
54
-
// Draw repo name with wrapping support
55
-
repoNameCard.SetMargin(10)
56
-
bounds := repoNameCard.Img.Bounds()
57
-
startX := bounds.Min.X + repoNameCard.Margin
58
-
startY := bounds.Min.Y + repoNameCard.Margin
49
+
bounds := mainContent.Img.Bounds()
50
+
startX := bounds.Min.X + mainContent.Margin
51
+
startY := bounds.Min.Y + mainContent.Margin
59
52
currentX := startX
53
+
currentY := startY
54
+
lineHeight := 64 // Font size 54 + padding
60
55
textColor := color.RGBA{88, 96, 105, 255}
61
56
62
-
// Draw owner handle in gray
63
-
ownerWidth, err := repoNameCard.DrawTextAtWithWidth(ownerHandle, currentX, startY, textColor, 54, ogcard.Top, ogcard.Left)
57
+
// Draw owner handle
58
+
ownerWidth, err := mainContent.DrawTextAtWithWidth(ownerHandle, currentX, currentY, textColor, 54, ogcard.Top, ogcard.Left)
64
59
if err != nil {
65
60
return nil, err
66
61
}
67
62
currentX += ownerWidth
68
63
69
64
// Draw separator
70
-
sepWidth, err := repoNameCard.DrawTextAtWithWidth(" / ", currentX, startY, textColor, 54, ogcard.Top, ogcard.Left)
65
+
sepWidth, err := mainContent.DrawTextAtWithWidth(" / ", currentX, currentY, textColor, 54, ogcard.Top, ogcard.Left)
71
66
if err != nil {
72
67
return nil, err
73
68
}
74
69
currentX += sepWidth
75
70
76
-
// Draw repo name in bold
77
-
_, err = repoNameCard.DrawBoldText(repo.Name, currentX, startY, color.Black, 54, ogcard.Top, ogcard.Left)
78
-
if err != nil {
79
-
return nil, err
71
+
words := strings.Fields(repo.Name)
72
+
spaceWidth, _ := mainContent.DrawTextAtWithWidth(" ", -1000, -1000, color.Black, 54, ogcard.Top, ogcard.Left)
73
+
if spaceWidth == 0 {
74
+
spaceWidth = 15
80
75
}
81
76
82
-
// Draw description (DrawText handles multi-line wrapping automatically)
83
-
descriptionCard.SetMargin(10)
84
-
description := repo.Description
85
-
if len(description) > 70 {
86
-
description = description[:70] + "…"
77
+
for _, word := range words {
78
+
// estimate bold width by measuring regular width and adding a multiplier
79
+
regularWidth, _ := mainContent.DrawTextAtWithWidth(word, -1000, -1000, color.Black, 54, ogcard.Top, ogcard.Left)
80
+
estimatedBoldWidth := int(float64(regularWidth) * 1.15) // Heuristic for bold text
81
+
82
+
if currentX+estimatedBoldWidth > (bounds.Max.X - mainContent.Margin) {
83
+
currentX = startX
84
+
currentY += lineHeight
85
+
}
86
+
87
+
_, err := mainContent.DrawBoldText(word, currentX, currentY, color.Black, 54, ogcard.Top, ogcard.Left)
88
+
if err != nil {
89
+
return nil, err
90
+
}
91
+
currentX += estimatedBoldWidth + spaceWidth
87
92
}
88
93
89
-
_, err = descriptionCard.DrawText(description, color.RGBA{88, 96, 105, 255}, 36, ogcard.Top, ogcard.Left)
90
-
if err != nil {
91
-
log.Printf("failed to draw description: %v", err)
92
-
return nil, err
94
+
// update Y position for the description
95
+
currentY += lineHeight
96
+
97
+
// draw description
98
+
if currentY < bounds.Max.Y-mainContent.Margin {
99
+
totalHeight := float64(bounds.Dy())
100
+
repoNameHeight := float64(currentY - bounds.Min.Y)
101
+
102
+
if totalHeight > 0 && repoNameHeight < totalHeight {
103
+
repoNamePercent := (repoNameHeight / totalHeight) * 100
104
+
if repoNamePercent < 95 { // Ensure there's space left for description
105
+
_, descriptionCard := mainContent.Split(false, int(repoNamePercent))
106
+
descriptionCard.SetMargin(8)
107
+
108
+
description := repo.Description
109
+
if len(description) > 70 {
110
+
description = description[:70] + "…"
111
+
}
112
+
113
+
_, err = descriptionCard.DrawText(description, color.RGBA{88, 96, 105, 255}, 36, ogcard.Top, ogcard.Left)
114
+
if err != nil {
115
+
log.Printf("failed to draw description: %v", err)
116
+
}
117
+
}
118
+
}
93
119
}
94
120
95
121
// Draw avatar circle on the right side