diff --git a/ts/background.ts b/ts/background.ts index ef70b3652b10..a81ad678f035 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -524,6 +524,13 @@ type WhatIsThis = import('./window.d').WhatIsThis; await window.Signal.Services.eraseAllStorageServiceState(); } + if ( + lastVersion === 'v1.40.0-beta.1' && + window.isAfterVersion(lastVersion, 'v1.40.0-beta.1') + ) { + await window.Signal.Data.clearAllErrorStickerPackAttempts(); + } + // This one should always be last - it could restart the app if (window.isBeforeVersion(lastVersion, 'v1.15.0-beta.5')) { await window.Signal.Logs.deleteAll(); diff --git a/ts/sql/Client.ts b/ts/sql/Client.ts index bd884181aad4..84563ce9b1fa 100644 --- a/ts/sql/Client.ts +++ b/ts/sql/Client.ts @@ -203,6 +203,7 @@ const dataInterface: ClientInterface = { getAllStickerPacks, getAllStickers, getRecentStickers, + clearAllErrorStickerPackAttempts, updateEmojiUsage, getRecentEmojis, @@ -1333,6 +1334,9 @@ async function getRecentStickers() { return recentStickers; } +async function clearAllErrorStickerPackAttempts() { + await channels.clearAllErrorStickerPackAttempts(); +} // Emojis async function updateEmojiUsage(shortName: string) { diff --git a/ts/sql/Interface.ts b/ts/sql/Interface.ts index 7bb347bafa0a..09680193904a 100644 --- a/ts/sql/Interface.ts +++ b/ts/sql/Interface.ts @@ -169,6 +169,7 @@ export type DataInterface = { getRecentStickers: (options?: { limit?: number; }) => Promise>; + clearAllErrorStickerPackAttempts: () => Promise; updateEmojiUsage: (shortName: string, timeUsed?: number) => Promise; getRecentEmojis: (limit?: number) => Promise>; diff --git a/ts/sql/Server.ts b/ts/sql/Server.ts index 8ccc1a4d0147..31ecc5cd4eca 100644 --- a/ts/sql/Server.ts +++ b/ts/sql/Server.ts @@ -180,6 +180,7 @@ const dataInterface: ServerInterface = { getAllStickerPacks, getAllStickers, getRecentStickers, + clearAllErrorStickerPackAttempts, updateEmojiUsage, getRecentEmojis, @@ -3465,6 +3466,13 @@ async function updateStickerPackStatus( } ); } +async function clearAllErrorStickerPackAttempts(): Promise { + const db = getInstance(); + + await db.run( + "UPDATE sticker_packs SET downloadAttempts = 0 WHERE status = 'error';" + ); +} async function createOrUpdateSticker(sticker: StickerType) { const db = getInstance(); const { diff --git a/ts/test-both/util/makeLookup_test.ts b/ts/test-both/util/makeLookup_test.ts index 635081cb72fc..8fa0da61a2f2 100644 --- a/ts/test-both/util/makeLookup_test.ts +++ b/ts/test-both/util/makeLookup_test.ts @@ -33,13 +33,24 @@ describe('makeLookup', () => { }); }); - it('ignores falsy properties', () => { - const arr = [{}, { foo: '' }, { foo: false }, { foo: null }]; + it('ignores undefined properties', () => { + const arr = [{}, { foo: undefined }]; const result = makeLookup(arr, 'foo'); assert.deepEqual(result, {}); }); + it('allows key of 0', () => { + const arr = [{}, { id: 0 }, { id: 1 }, { id: 2 }]; + const result = makeLookup(arr, 'id'); + + assert.deepEqual(result, { + 0: { id: 0 }, + 1: { id: 1 }, + 2: { id: 2 }, + }); + }); + it('converts the lookup to a string', () => { const arr = [ { foo: 'bar' }, diff --git a/ts/util/makeLookup.ts b/ts/util/makeLookup.ts index c8df84c8f34b..a76b2d89fd2e 100644 --- a/ts/util/makeLookup.ts +++ b/ts/util/makeLookup.ts @@ -6,7 +6,7 @@ export function makeLookup( key: keyof T ): Record { return (items || []).reduce((lookup, item) => { - if (item && item[key]) { + if (item !== undefined && item[key] !== undefined) { // The force cast is necessary if we want the keyof T above, and the flexibility // to pass anything in. And of course we're modifying a parameter! // eslint-disable-next-line no-param-reassign