fix: restore sticker placeholders and media history

(cherry picked from commit 488e409a1898e9c739cc0bd24cb9791636dfd6b3)
This commit is contained in:
A 2026-06-07 20:28:37 +08:00
parent 27970adf46
commit 23a2b2aff7
11 changed files with 225 additions and 165 deletions

View file

@ -338,8 +338,13 @@ func (s *Service) importDocument(ctx context.Context, dj seedDocumentJSON, binDi
stats.Blobs++
}
// 缩略图:PhotoPathSize 内联;小的 PhotoSize 静态图同时写 blob 并作为
// PhotoCachedSize 返回,让 TDesktop 处理 document 元数据时即可填本地 image cache。
// 缩略图保留两类并存(与官方 sticker 一致):
// - PhotoPathSize 矢量轮廓:随 document 元数据内联下发,是 TDesktop 对 animated
// sticker 在完整 .tgs 下载完成前唯一可即时渲染的占位(history_view_sticker 显式
// 禁用了 stripped 内联占位,cached 字节又经 RPC 出口转成 downloadable);丢掉它会让
// 打开会话时 sticker 先空白、并多触发一次缩略图 getFile。
// - 小 PhotoSize 静态图:写 blob 并暂存为 PhotoCachedSize(RPC 出口再转 downloadable
// photoSize m),供 sticker 面板等需要小缩略图的场景下载。
thumbs := make([]domain.PhotoSize, 0, len(dj.Thumbs))
for _, tj := range dj.Thumbs {
ps, downloadable := seedPhotoSize(tj)
@ -375,7 +380,7 @@ func (s *Service) importDocument(ctx context.Context, dj seedDocumentJSON, binDi
}
thumbs = append(thumbs, ps)
}
doc.Thumbs = seedPreferRasterDocumentThumbs(thumbs)
doc.Thumbs = thumbs
if err := s.media.PutDocument(ctx, doc); err != nil {
return domain.Document{}, err
@ -607,20 +612,6 @@ func seedInlineCachedDocumentThumb(ps domain.PhotoSize, data []byte) domain.Phot
return ps
}
func seedPreferRasterDocumentThumbs(sizes []domain.PhotoSize) []domain.PhotoSize {
if !documentThumbsHaveRaster(sizes) {
return sizes
}
out := sizes[:0]
for _, size := range sizes {
if size.Kind == domain.PhotoSizeKindPath {
continue
}
out = append(out, size)
}
return out
}
func seedThumbMimeType(data []byte) string {
switch {
case len(data) >= 12 && data[0] == 'R' && data[1] == 'I' && data[2] == 'F' && data[3] == 'F' &&
@ -677,9 +668,6 @@ func (s *Service) documentsNeedInlineCachedThumbs(ctx context.Context, ids []int
return false, err
}
for _, doc := range docs {
if documentThumbsHaveRaster(doc.Thumbs) && documentThumbsHavePath(doc.Thumbs) {
return true, nil
}
for _, thumb := range doc.Thumbs {
if thumb.Kind == domain.PhotoSizeKindDefault && thumb.Size > 0 && thumb.Size <= seedInlineCachedDocumentThumbMaxBytes {
return true, nil
@ -701,35 +689,6 @@ func (s *Service) documentsNeedInlineCachedThumbs(ctx context.Context, ids []int
return false, nil
}
func documentThumbsHaveRaster(sizes []domain.PhotoSize) bool {
for _, size := range sizes {
switch size.Kind {
case domain.PhotoSizeKindCached:
if len(size.Bytes) > 0 {
return true
}
case domain.PhotoSizeKindDefault:
if size.Type != "" && size.Size > 0 {
return true
}
case domain.PhotoSizeKindProgressive:
if size.Type != "" && len(size.Sizes) > 0 {
return true
}
}
}
return false
}
func documentThumbsHavePath(sizes []domain.PhotoSize) bool {
for _, size := range sizes {
if size.Kind == domain.PhotoSizeKindPath && len(size.Bytes) > 0 {
return true
}
}
return false
}
func seedStickerPacks(setPacks, resultPacks []seedStickerPackJSON, docIDBySource map[int64]int64) []domain.StickerPack {
packs := setPacks
if len(packs) == 0 {

View file

@ -334,8 +334,8 @@ func TestSeedMediaFromRealExport(t *testing.T) {
if want := seedThumbMimeType(thumb.Bytes); blob.MimeType != want {
t.Fatalf("sample sticker thumb mime = %q, want %q", blob.MimeType, want)
}
if hasPathThumb(doc.Thumbs) {
t.Fatalf("sample sticker document still exposes path thumb together with raster: %+v", doc.Thumbs)
if !hasPathThumb(doc.Thumbs) {
t.Fatalf("sample sticker document dropped its PhotoPathSize placeholder: %+v", doc.Thumbs)
}
}
}
@ -397,25 +397,6 @@ func TestSeedThumbMimeType(t *testing.T) {
}
}
func TestSeedPreferRasterDocumentThumbsDropsPathWhenRasterExists(t *testing.T) {
sizes := []domain.PhotoSize{
{Kind: domain.PhotoSizeKindPath, Type: "j", Bytes: []byte("path")},
{Kind: domain.PhotoSizeKindCached, Type: "m", Bytes: []byte("webp")},
}
got := seedPreferRasterDocumentThumbs(sizes)
if hasPathThumb(got) {
t.Fatalf("path thumb should be dropped when raster exists: %+v", got)
}
if !hasCachedThumb(got) {
t.Fatalf("cached thumb should be kept: %+v", got)
}
onlyPath := []domain.PhotoSize{{Kind: domain.PhotoSizeKindPath, Type: "j", Bytes: []byte("path")}}
if got := seedPreferRasterDocumentThumbs(onlyPath); !hasPathThumb(got) {
t.Fatalf("path-only thumbs should be kept: %+v", got)
}
}
func TestDocumentsNeedInlineCachedThumbsDetectsStaleMime(t *testing.T) {
ctx := context.Background()
media := newFakeMediaStore()
@ -453,34 +434,6 @@ func TestDocumentsNeedInlineCachedThumbsDetectsStaleMime(t *testing.T) {
}
}
func TestDocumentsNeedInlineCachedThumbsDetectsPathWithRaster(t *testing.T) {
ctx := context.Background()
media := newFakeMediaStore()
doc := domain.Document{
ID: 100,
Thumbs: []domain.PhotoSize{
{Kind: domain.PhotoSizeKindPath, Type: "j", Bytes: []byte("path")},
{Kind: domain.PhotoSizeKindCached, Type: "m", Bytes: []byte("webp")},
},
}
if err := media.PutDocument(ctx, doc); err != nil {
t.Fatalf("put doc: %v", err)
}
svc := NewService(media, nil, 2)
stale, err := svc.documentsNeedInlineCachedThumbs(ctx, []int64{doc.ID})
if err != nil {
t.Fatalf("documentsNeedInlineCachedThumbs: %v", err)
}
if !stale {
t.Fatal("path thumb with raster should require repair")
}
}
func hasCachedThumb(sizes []domain.PhotoSize) bool {
_, ok := findCachedThumb(sizes)
return ok
}
func findCachedThumb(sizes []domain.PhotoSize) (domain.PhotoSize, bool) {
for _, size := range sizes {
if size.Kind == domain.PhotoSizeKindCached && len(size.Bytes) > 0 {