diff --git a/internal/rpc/convert_media.go b/internal/rpc/convert_media.go index fd9a1caa..91ba7e2c 100644 --- a/internal/rpc/convert_media.go +++ b/internal/rpc/convert_media.go @@ -429,18 +429,17 @@ func compactPhotoSizeClasses(in []tg.PhotoSizeClass) []tg.PhotoSizeClass { } func tgDocumentAttributes(mimeType string, attrs []domain.DocumentAttribute) []tg.DocumentAttributeClass { - out := make([]tg.DocumentAttributeClass, 0, len(attrs)+1) - hasAnimated := false - hasStickerLike := false + out := make([]tg.DocumentAttributeClass, 0, len(attrs)) for _, a := range attrs { switch a.Kind { case domain.DocAttrImageSize: out = append(out, &tg.DocumentAttributeImageSize{W: a.W, H: a.H}) case domain.DocAttrAnimated: - hasAnimated = true + if mimeType == mimeApplicationXTGSticker { + continue + } out = append(out, &tg.DocumentAttributeAnimated{}) case domain.DocAttrSticker: - hasStickerLike = true out = append(out, &tg.DocumentAttributeSticker{ Mask: a.Mask, Alt: a.Alt, @@ -468,7 +467,6 @@ func tgDocumentAttributes(mimeType string, attrs []domain.DocumentAttribute) []t case domain.DocAttrFilename: out = append(out, &tg.DocumentAttributeFilename{FileName: a.FileName}) case domain.DocAttrCustomEmoji: - hasStickerLike = true out = append(out, &tg.DocumentAttributeCustomEmoji{ Free: a.Free, TextColor: a.TextColor, @@ -477,9 +475,6 @@ func tgDocumentAttributes(mimeType string, attrs []domain.DocumentAttribute) []t }) } } - if mimeType == mimeApplicationXTGSticker && hasStickerLike && !hasAnimated { - out = append(out, &tg.DocumentAttributeAnimated{}) - } return out } diff --git a/internal/rpc/effects_rpc_test.go b/internal/rpc/effects_rpc_test.go index 74c1a729..02cc18ca 100644 --- a/internal/rpc/effects_rpc_test.go +++ b/internal/rpc/effects_rpc_test.go @@ -15,7 +15,18 @@ import ( // Documents 数组、optional 字段(static/anim/premium)正确编码、hash 命中回 NotModified。 func TestMessagesGetAvailableEffects(t *testing.T) { doc := func(id int64) domain.Document { - return domain.Document{ID: id, AccessHash: id * 10, MimeType: "application/x-tgsticker", DCID: 2} + return domain.Document{ + ID: id, + AccessHash: id * 10, + MimeType: "application/x-tgsticker", + DCID: 2, + Attributes: []domain.DocumentAttribute{ + {Kind: domain.DocAttrImageSize, W: 512, H: 512}, + {Kind: domain.DocAttrSticker, Alt: "\U0001f525", StickerSetID: 10, StickerSetAccessHash: 20}, + {Kind: domain.DocAttrAnimated}, + {Kind: domain.DocAttrFilename, FileName: "AnimatedSticker.tgs"}, + }, + } } files := &fakeFiles{ docs: map[int64]domain.Document{1: doc(1), 2: doc(2), 3: doc(3)}, @@ -45,6 +56,28 @@ func TestMessagesGetAvailableEffects(t *testing.T) { if len(full.Documents) != 3 { t.Fatalf("documents = %d, want 3 deduped", len(full.Documents)) } + for _, item := range full.Documents { + d, ok := item.(*tg.Document) + if !ok { + t.Fatalf("document = %T, want *tg.Document", item) + } + hasSticker := false + hasAnimated := false + for _, attr := range d.Attributes { + switch attr.(type) { + case *tg.DocumentAttributeSticker: + hasSticker = true + case *tg.DocumentAttributeAnimated: + hasAnimated = true + } + } + if !hasSticker { + t.Fatalf("document %d missing sticker attribute", d.ID) + } + if hasAnimated { + t.Fatalf("document %d has documentAttributeAnimated; TDesktop treats TGS stickers as plain animations", d.ID) + } + } e0 := full.Effects[0] if e0.ID != 100 || e0.Emoticon != "\U0001f525" || e0.EffectStickerID != 2 { t.Fatalf("effect0 = %#v", e0) diff --git a/internal/rpc/stickers_test.go b/internal/rpc/stickers_test.go index bc54cd93..28400575 100644 --- a/internal/rpc/stickers_test.go +++ b/internal/rpc/stickers_test.go @@ -609,7 +609,7 @@ func TestTGDocumentDropsSeedSyntheticTGSPreviewThumb(t *testing.T) { } } -func TestTGDocumentAddsAnimatedAttributeForTGSSticker(t *testing.T) { +func TestTGDocumentDoesNotEmitAnimatedAttributeForTGSSticker(t *testing.T) { doc := tgDocument(domain.Document{ ID: 100, AccessHash: 1, @@ -618,6 +618,7 @@ func TestTGDocumentAddsAnimatedAttributeForTGSSticker(t *testing.T) { Attributes: []domain.DocumentAttribute{ {Kind: domain.DocAttrImageSize, W: 512, H: 512}, {Kind: domain.DocAttrSticker, Alt: "🙂", StickerSetID: 10, StickerSetAccessHash: 20}, + {Kind: domain.DocAttrAnimated}, {Kind: domain.DocAttrFilename, FileName: "AnimatedSticker.tgs"}, }, }) @@ -638,8 +639,8 @@ func TestTGDocumentAddsAnimatedAttributeForTGSSticker(t *testing.T) { if !hasSticker { t.Fatal("TGS sticker document missing sticker attribute") } - if !hasAnimated { - t.Fatal("TGS sticker document missing synthesized animated attribute") + if hasAnimated { + t.Fatal("TGS sticker document has documentAttributeAnimated; TDesktop treats it as a non-sticker animation") } }