feat: sync GIFv and saved GIF support

This commit is contained in:
A 2026-07-11 21:43:13 +08:00
parent c0088f1160
commit 5f7c0b9804
21 changed files with 641 additions and 50 deletions

View file

@ -0,0 +1,5 @@
DROP INDEX IF EXISTS user_sticker_collections_order_idx;
CREATE INDEX user_sticker_collections_order_idx
ON user_sticker_collections (owner_user_id, kind, used_at DESC);
ALTER TABLE user_sticker_collections DROP COLUMN IF EXISTS order_key;
DROP SEQUENCE IF EXISTS user_sticker_collections_order_key_seq;

View file

@ -0,0 +1,81 @@
CREATE SEQUENCE IF NOT EXISTS user_sticker_collections_order_key_seq;
ALTER TABLE user_sticker_collections ADD COLUMN order_key bigint;
WITH ordered AS (
SELECT ctid, row_number() OVER (
ORDER BY owner_user_id, kind, used_at, document_id
) AS n
FROM user_sticker_collections
)
UPDATE user_sticker_collections AS c
SET order_key = ordered.n
FROM ordered
WHERE c.ctid = ordered.ctid;
SELECT setval(
'user_sticker_collections_order_key_seq',
GREATEST(COALESCE((SELECT max(order_key) FROM user_sticker_collections), 0), 1),
true
);
ALTER TABLE user_sticker_collections
ALTER COLUMN order_key SET DEFAULT nextval('user_sticker_collections_order_key_seq'),
ALTER COLUMN order_key SET NOT NULL;
DROP INDEX IF EXISTS user_sticker_collections_order_idx;
CREATE INDEX user_sticker_collections_order_idx
ON user_sticker_collections (owner_user_id, kind, order_key DESC);
-- Saved GIFs must reference canonical GIFv documents. Remove dangling/raw-GIF
-- entries explicitly instead of making getSavedGifs silently skip bad state.
DELETE FROM user_sticker_collections AS c
WHERE c.kind = 'gif'
AND NOT EXISTS (
SELECT 1
FROM documents AS d
WHERE d.id = c.document_id
AND lower(d.mime_type) = 'video/mp4'
AND EXISTS (
SELECT 1 FROM jsonb_array_elements(d.attributes) a
WHERE a->>'kind' = 'animated'
)
AND EXISTS (
SELECT 1 FROM jsonb_array_elements(d.attributes) a
WHERE a->>'kind' = 'video'
AND COALESCE((a->>'round_message')::boolean, false) = false
AND COALESCE((a->>'w')::int, 0) > 0
AND COALESCE((a->>'h')::int, 0) > 0
AND COALESCE((a->>'duration')::double precision, 0) > 0
)
);
-- Legacy raw image/gif rows are ordinary files, not TDesktop GIFv. Repair the
-- durable shared-media indexes without pretending their bytes were transcoded.
DELETE FROM message_box_media AS i
USING message_boxes AS b
WHERE i.owner_user_id = b.owner_user_id
AND i.box_id = b.box_id
AND i.category = 3
AND lower(COALESCE(b.media #>> '{document,mime_type}', '')) = 'image/gif';
INSERT INTO message_box_media (owner_user_id, box_id, peer_id, category, message_date)
SELECT b.owner_user_id, b.box_id, b.peer_id, 4, b.message_date
FROM message_boxes AS b
WHERE NOT b.deleted
AND lower(COALESCE(b.media #>> '{document,mime_type}', '')) = 'image/gif'
ON CONFLICT DO NOTHING;
DELETE FROM channel_message_media AS i
USING channel_messages AS m
WHERE i.channel_id = m.channel_id
AND i.id = m.id
AND i.category = 3
AND lower(COALESCE(m.media #>> '{document,mime_type}', '')) = 'image/gif';
INSERT INTO channel_message_media (channel_id, id, category, message_date)
SELECT m.channel_id, m.id, 4, m.message_date
FROM channel_messages AS m
WHERE NOT m.deleted
AND lower(COALESCE(m.media #>> '{document,mime_type}', '')) = 'image/gif'
ON CONFLICT DO NOTHING;