Import/export sticker packs

This commit is contained in:
Fedor Indutny 2024-06-12 13:47:56 -07:00 committed by GitHub
parent 111bb70188
commit 511a7f1646
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 62 additions and 15 deletions

View file

@ -1043,17 +1043,8 @@ message GroupExpirationTimerUpdate {
message StickerPack {
bytes packId = 1;
bytes packKey = 2;
string title = 3;
string author = 4;
repeated StickerPackSticker stickers = 5; // First one should be cover sticker.
}
message StickerPackSticker {
string emoji = 1;
uint32 id = 2;
}
message ChatStyle {
message Gradient {
uint32 angle = 1; // degrees

View file

@ -212,6 +212,7 @@ export class BackupExportStream extends Readable {
distributionLists: 0,
messages: 0,
skippedMessages: 0,
stickerPacks: 0,
};
for (const { attributes } of window.ConversationController.getAll()) {
@ -284,6 +285,21 @@ export class BackupExportStream extends Readable {
stats.distributionLists += 1;
}
const stickerPacks = await Data.getInstalledStickerPacks();
for (const { id, key } of stickerPacks) {
this.pushFrame({
stickerPack: {
packId: Bytes.fromHex(id),
packKey: Bytes.fromBase64(key),
},
});
// eslint-disable-next-line no-await-in-loop
await this.flush();
stats.stickerPacks += 1;
}
const pinnedConversationIds =
window.storage.get('pinnedConversationIds') || [];

View file

@ -26,6 +26,7 @@ import {
import {
STICKERPACK_ID_BYTE_LEN,
STICKERPACK_KEY_BYTE_LEN,
downloadStickerPack,
} from '../../types/Stickers';
import type {
ConversationAttributesType,
@ -386,6 +387,8 @@ export class BackupImportStream extends Writable {
}
await this.fromChatItem(frame.chatItem, { aboutMe });
} else if (frame.stickerPack) {
await this.fromStickerPack(frame.stickerPack);
} else {
log.warn(`${this.logId}: unsupported frame item ${frame.item}`);
}
@ -2311,4 +2314,26 @@ export class BackupImportStream extends Writable {
throw new Error('Not implemented');
}
}
private async fromStickerPack({
packId: id,
packKey: key,
}: Backups.IStickerPack): Promise<void> {
strictAssert(
id?.length === STICKERPACK_ID_BYTE_LEN,
'Sticker pack must have a valid pack id'
);
const logId = `fromStickerPack(${Bytes.toHex(id).slice(-2)})`;
strictAssert(
key?.length === STICKERPACK_KEY_BYTE_LEN,
`${logId}: must have a valid pack key`
);
drop(
downloadStickerPack(Bytes.toHex(id), Bytes.toBase64(key), {
fromBackup: true,
})
);
}
}

View file

@ -214,7 +214,11 @@ function downloadStickerPack(
function installStickerPack(
packId: string,
packKey: string,
options: { fromSync?: boolean; fromStorageService?: boolean } = {}
options: {
fromSync?: boolean;
fromStorageService?: boolean;
fromBackup?: boolean;
} = {}
): InstallStickerPackAction {
return {
type: 'stickers/INSTALL_STICKER_PACK',
@ -224,19 +228,27 @@ function installStickerPack(
async function doInstallStickerPack(
packId: string,
packKey: string,
options: { fromSync?: boolean; fromStorageService?: boolean } = {}
options: {
fromSync?: boolean;
fromStorageService?: boolean;
fromBackup?: boolean;
} = {}
): Promise<InstallStickerPackPayloadType> {
const { fromSync = false, fromStorageService = false } = options;
const {
fromSync = false,
fromStorageService = false,
fromBackup = false,
} = options;
const timestamp = Date.now();
await dataInterface.installStickerPack(packId, timestamp);
if (!fromSync && !fromStorageService) {
if (!fromSync && !fromStorageService && !fromBackup) {
// Kick this off, but don't wait for it
void sendStickerPackSync(packId, packKey, true);
}
if (!fromStorageService) {
if (!fromStorageService && !fromBackup) {
storageServiceUploadJob();
}

View file

@ -552,6 +552,7 @@ export type DownloadStickerPackOptions = Readonly<{
messageId?: string;
fromSync?: boolean;
fromStorageService?: boolean;
fromBackup?: boolean;
finalStatus?: StickerPackStatusType;
suppressError?: boolean;
}>;
@ -582,6 +583,7 @@ async function doDownloadStickerPack(
messageId,
fromSync = false,
fromStorageService = false,
fromBackup = false,
suppressError = false,
}: DownloadStickerPackOptions
): Promise<void> {
@ -703,7 +705,7 @@ async function doDownloadStickerPack(
status: 'pending',
createdAt: Date.now(),
stickers: {},
storageNeedsSync: !fromStorageService,
storageNeedsSync: !fromStorageService && !fromBackup,
title: proto.title ?? '',
author: proto.author ?? '',
};
@ -788,6 +790,7 @@ async function doDownloadStickerPack(
await installStickerPack(packId, packKey, {
fromSync,
fromStorageService,
fromBackup,
});
} else {
// Mark the pack as complete