Monorepo for Tangled

appview/pages: get avatar cid to bust cache

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.org>

authored by

Anirudh Oppiliappan and committed by tangled.org 2e71ee92 c7fbb98c

+38 -10
+32 -7
appview/pages/funcmap.go
··· 26 26 "github.com/go-enry/go-enry/v2" 27 27 "github.com/yuin/goldmark" 28 28 emoji "github.com/yuin/goldmark-emoji" 29 + "tangled.org/core/appview/db" 29 30 "tangled.org/core/appview/models" 30 31 "tangled.org/core/appview/oauth" 31 32 "tangled.org/core/appview/pages/markup" ··· 485 486 return identity.Handle.String() 486 487 } 487 488 488 - func (p *Pages) AvatarUrl(handle, size string) string { 489 - handle = strings.TrimPrefix(handle, "@") 489 + func (p *Pages) AvatarUrl(actor, size string) string { 490 + actor = strings.TrimPrefix(actor, "@") 490 491 491 - handle = p.resolveDid(handle) 492 + identity, err := p.resolver.ResolveIdent(context.Background(), actor) 493 + var did string 494 + if err != nil { 495 + did = actor 496 + } else { 497 + did = identity.DID.String() 498 + } 492 499 493 500 secret := p.avatar.SharedSecret 494 501 h := hmac.New(sha256.New, []byte(secret)) 495 - h.Write([]byte(handle)) 502 + h.Write([]byte(did)) 496 503 signature := hex.EncodeToString(h.Sum(nil)) 497 504 498 - sizeArg := "" 505 + // Get avatar CID for cache busting 506 + profile, err := db.GetProfile(p.db, did) 507 + version := "" 508 + if err == nil && profile != nil && profile.Avatar != "" { 509 + // Use first 8 chars of avatar CID as version 510 + if len(profile.Avatar) > 8 { 511 + version = profile.Avatar[:8] 512 + } else { 513 + version = profile.Avatar 514 + } 515 + } 516 + 517 + baseUrl := fmt.Sprintf("%s/%s/%s", p.avatar.Host, signature, did) 499 518 if size != "" { 500 - sizeArg = fmt.Sprintf("size=%s", size) 519 + if version != "" { 520 + return fmt.Sprintf("%s?size=%s&v=%s", baseUrl, size, version) 521 + } 522 + return fmt.Sprintf("%s?size=%s", baseUrl, size) 523 + } 524 + if version != "" { 525 + return fmt.Sprintf("%s?v=%s", baseUrl, version) 501 526 } 502 - return fmt.Sprintf("%s/%s/%s?%s", p.avatar.Host, signature, handle, sizeArg) 527 + return baseUrl 503 528 } 504 529 505 530 func (p *Pages) icon(name string, classes []string) (template.HTML, error) {
+1 -1
appview/pages/funcmap_test.go
··· 22 22 } 23 23 for _, tt := range tests { 24 24 t.Run(tt.name, func(t *testing.T) { 25 - p := NewPages(tt.config, tt.res, tt.l) 25 + p := NewPages(tt.config, tt.res, nil, tt.l) 26 26 got := p.funcMap() 27 27 // TODO: update the condition below to compare got with tt.want. 28 28 if true {
+4 -1
appview/pages/pages.go
··· 19 19 "tangled.org/core/api/tangled" 20 20 "tangled.org/core/appview/commitverify" 21 21 "tangled.org/core/appview/config" 22 + "tangled.org/core/appview/db" 22 23 "tangled.org/core/appview/models" 23 24 "tangled.org/core/appview/oauth" 24 25 "tangled.org/core/appview/pages/markup" ··· 42 43 43 44 avatar config.AvatarConfig 44 45 resolver *idresolver.Resolver 46 + db *db.DB 45 47 dev bool 46 48 embedFS fs.FS 47 49 templateDir string // Path to templates on disk for dev mode ··· 49 51 logger *slog.Logger 50 52 } 51 53 52 - func NewPages(config *config.Config, res *idresolver.Resolver, logger *slog.Logger) *Pages { 54 + func NewPages(config *config.Config, res *idresolver.Resolver, database *db.DB, logger *slog.Logger) *Pages { 53 55 // initialized with safe defaults, can be overriden per use 54 56 rctx := &markup.RenderContext{ 55 57 IsDev: config.Core.Dev, ··· 66 68 avatar: config.Avatar, 67 69 rctx: rctx, 68 70 resolver: res, 71 + db: database, 69 72 templateDir: "appview/pages", 70 73 logger: logger, 71 74 }
+1 -1
appview/state/state.go
··· 92 92 return nil, fmt.Errorf("failed to create posthog client: %w", err) 93 93 } 94 94 95 - pages := pages.NewPages(config, res, log.SubLogger(logger, "pages")) 95 + pages := pages.NewPages(config, res, d, log.SubLogger(logger, "pages")) 96 96 oauth, err := oauth.New(config, posthog, d, enforcer, res, log.SubLogger(logger, "oauth")) 97 97 if err != nil { 98 98 return nil, fmt.Errorf("failed to start oauth handler: %w", err)