// Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import { pick } from 'lodash'; import type { MessageAttributesType } from '../model-types.d'; import type { StoryDataType } from '../state/ducks/stories'; import * as log from '../logging/log'; import dataInterface from '../sql/Client'; import { getAttachmentsForMessage } from '../state/selectors/message'; import { isNotNil } from '../util/isNotNil'; import { strictAssert } from '../util/assert'; let storyData: Array | undefined; export async function loadStories(): Promise { storyData = await dataInterface.getOlderStories({}); await repairUnexpiredStories(); } export function getStoryDataFromMessageAttributes( message: MessageAttributesType ): StoryDataType | undefined { const { attachments } = message; const unresolvedAttachment = attachments ? attachments[0] : undefined; if (!unresolvedAttachment) { log.warn( `getStoryDataFromMessageAttributes: ${message.id} does not have an attachment` ); return; } const [attachment] = unresolvedAttachment.path ? getAttachmentsForMessage(message) : [unresolvedAttachment]; return { attachment, messageId: message.id, ...pick(message, [ 'conversationId', 'deletedForEveryone', 'reactions', 'readStatus', 'sendStateByConversationId', 'source', 'sourceUuid', 'timestamp', 'type', ]), }; } export function getStoriesForRedux(): Array { strictAssert(storyData, 'storyData has not been loaded'); const stories = storyData .map(getStoryDataFromMessageAttributes) .filter(isNotNil); storyData = undefined; return stories; } async function repairUnexpiredStories(): Promise { strictAssert(storyData, 'Could not load stories'); const storiesWithExpiry = storyData .filter(story => !story.expirationStartTimestamp) .map(story => ({ ...story, expirationStartTimestamp: Math.min( story.serverTimestamp || story.timestamp, Date.now() ), })); if (!storiesWithExpiry.length) { return; } log.info( 'repairUnexpiredStories: repairing number of stories', storiesWithExpiry.length ); await Promise.all( storiesWithExpiry.map(messageAttributes => { return window.Signal.Data.saveMessage(messageAttributes, { ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), }); }) ); }