Sticker pack download: require just one successful sticker download

This commit is contained in:
Scott Nonnenberg 2022-03-16 12:18:16 -07:00 committed by GitHub
parent 3620309f22
commit 5a7196e464
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 159 additions and 57 deletions

View file

@ -10,6 +10,7 @@ import { dropNull } from '../util/dropNull';
import { makeLookup } from '../util/makeLookup';
import { maybeParseUrl } from '../util/url';
import * as Bytes from '../Bytes';
import * as Errors from './errors';
import { deriveStickerPackKey, decryptAttachment } from '../Crypto';
import type { MIMEType } from './MIME';
import { IMAGE_WEBP } from './MIME';
@ -224,20 +225,17 @@ function doesPackNeedDownload(pack?: StickerPackType): boolean {
}
const { status, stickerCount } = pack;
const stickersDownloaded = Object.keys(pack.stickers || {}).length;
if (
(status === 'installed' || status === 'downloaded') &&
stickerCount > 0 &&
stickersDownloaded >= stickerCount
) {
if ((status === 'installed' || status === 'downloaded') && stickerCount > 0) {
return false;
}
// If we don't understand a pack's status, we'll download it
// If a pack has any other status, we'll download it
// If a pack has zero stickers in it, we'll download it
// If a pack doesn't have enough downloaded stickers, we'll download it
// Note: If a pack downloaded with less than the expected number of stickers, we're
// okay with that.
return true;
}
@ -439,10 +437,20 @@ export async function downloadEphemeralPack(
const downloadStickerJob = async (
stickerProto: Proto.StickerPack.ISticker
): Promise<void> => {
const stickerInfo = await downloadSticker(packId, packKey, stickerProto, {
ephemeral: true,
});
): Promise<boolean> => {
let stickerInfo;
try {
stickerInfo = await downloadSticker(packId, packKey, stickerProto, {
ephemeral: true,
});
} catch (error: unknown) {
log.error(
`downloadEphemeralPack/downloadStickerJob error: ${Errors.toLogFormat(
error
)}`
);
return false;
}
const sticker = {
...stickerInfo,
isCoverOnly: !coverIncludedInList && stickerInfo.id === coverStickerId,
@ -458,15 +466,21 @@ export async function downloadEphemeralPack(
}
stickerAdded(sticker);
return true;
};
// Download the cover first
await downloadStickerJob(coverProto);
// Then the rest
await pMap(nonCoverStickers, downloadStickerJob, {
const jobResults = await pMap(nonCoverStickers, downloadStickerJob, {
concurrency: 3,
});
const successfulStickerCount = jobResults.filter(item => item).length;
if (successfulStickerCount === 0) {
throw new Error('downloadEphemeralPack: All stickers failed to download');
}
} catch (error) {
// Because the user could install this pack while we are still downloading this
// ephemeral pack, we don't want to go change its status unless we're still in
@ -657,24 +671,44 @@ async function doDownloadStickerPack(
try {
const downloadStickerJob = async (
stickerProto: Proto.StickerPack.ISticker
): Promise<void> => {
const stickerInfo = await downloadSticker(packId, packKey, stickerProto);
const sticker = {
...stickerInfo,
isCoverOnly: !coverIncludedInList && stickerInfo.id === coverStickerId,
};
await Data.createOrUpdateSticker(sticker);
stickerAdded(sticker);
): Promise<boolean> => {
try {
const stickerInfo = await downloadSticker(
packId,
packKey,
stickerProto
);
const sticker = {
...stickerInfo,
isCoverOnly:
!coverIncludedInList && stickerInfo.id === coverStickerId,
};
await Data.createOrUpdateSticker(sticker);
stickerAdded(sticker);
return true;
} catch (error: unknown) {
log.error(
`doDownloadStickerPack/downloadStickerJob error: ${Errors.toLogFormat(
error
)}`
);
return false;
}
};
// Download the cover first
await downloadStickerJob(coverProto);
// Then the rest
await pMap(nonCoverStickers, downloadStickerJob, {
const jobResults = await pMap(nonCoverStickers, downloadStickerJob, {
concurrency: 3,
});
const successfulStickerCount = jobResults.filter(item => item).length;
if (successfulStickerCount === 0) {
throw new Error('doDownloadStickerPack: All stickers failed to download');
}
// Allow for the user marking this pack as installed in the middle of our download;
// don't overwrite that status.
const existingStatus = getStickerPackStatus(packId);