Reinitialize redux after importing a backup
This commit is contained in:
parent
19e0eb4444
commit
abdef4847a
21 changed files with 437 additions and 264 deletions
|
@ -48,11 +48,6 @@ import {
|
||||||
update as updateExpiringMessagesService,
|
update as updateExpiringMessagesService,
|
||||||
} from './services/expiringMessagesDeletion';
|
} from './services/expiringMessagesDeletion';
|
||||||
import { tapToViewMessagesDeletionService } from './services/tapToViewMessagesDeletionService';
|
import { tapToViewMessagesDeletionService } from './services/tapToViewMessagesDeletionService';
|
||||||
import { getStoriesForRedux, loadStories } from './services/storyLoader';
|
|
||||||
import {
|
|
||||||
getDistributionListsForRedux,
|
|
||||||
loadDistributionLists,
|
|
||||||
} from './services/distributionListLoader';
|
|
||||||
import { senderCertificateService } from './services/senderCertificate';
|
import { senderCertificateService } from './services/senderCertificate';
|
||||||
import { GROUP_CREDENTIALS_KEY } from './services/groupCredentialFetcher';
|
import { GROUP_CREDENTIALS_KEY } from './services/groupCredentialFetcher';
|
||||||
import * as KeyboardLayout from './services/keyboardLayout';
|
import * as KeyboardLayout from './services/keyboardLayout';
|
||||||
|
@ -112,7 +107,6 @@ import { UpdateKeysListener } from './textsecure/UpdateKeysListener';
|
||||||
import { isDirectConversation } from './util/whatTypeOfConversation';
|
import { isDirectConversation } from './util/whatTypeOfConversation';
|
||||||
import { BackOff, FIBONACCI_TIMEOUTS } from './util/BackOff';
|
import { BackOff, FIBONACCI_TIMEOUTS } from './util/BackOff';
|
||||||
import { AppViewType } from './state/ducks/app';
|
import { AppViewType } from './state/ducks/app';
|
||||||
import type { BadgesStateType } from './state/ducks/badges';
|
|
||||||
import { areAnyCallsActiveOrRinging } from './state/selectors/calling';
|
import { areAnyCallsActiveOrRinging } from './state/selectors/calling';
|
||||||
import { badgeImageFileDownloader } from './badges/badgeImageFileDownloader';
|
import { badgeImageFileDownloader } from './badges/badgeImageFileDownloader';
|
||||||
import * as Deletes from './messageModifiers/Deletes';
|
import * as Deletes from './messageModifiers/Deletes';
|
||||||
|
@ -148,10 +142,8 @@ import {
|
||||||
import { isAciString } from './util/isAciString';
|
import { isAciString } from './util/isAciString';
|
||||||
import { normalizeAci } from './util/normalizeAci';
|
import { normalizeAci } from './util/normalizeAci';
|
||||||
import * as log from './logging/log';
|
import * as log from './logging/log';
|
||||||
import { loadRecentEmojis } from './util/loadRecentEmojis';
|
|
||||||
import { deleteAllLogs } from './util/deleteAllLogs';
|
import { deleteAllLogs } from './util/deleteAllLogs';
|
||||||
import { startInteractionMode } from './services/InteractionMode';
|
import { startInteractionMode } from './services/InteractionMode';
|
||||||
import type { MainWindowStatsType } from './windows/context';
|
|
||||||
import { ReactionSource } from './reactions/ReactionSource';
|
import { ReactionSource } from './reactions/ReactionSource';
|
||||||
import { singleProtoJobQueue } from './jobs/singleProtoJobQueue';
|
import { singleProtoJobQueue } from './jobs/singleProtoJobQueue';
|
||||||
import {
|
import {
|
||||||
|
@ -178,26 +170,15 @@ import {
|
||||||
import { RetryPlaceholders } from './util/retryPlaceholders';
|
import { RetryPlaceholders } from './util/retryPlaceholders';
|
||||||
import { setBatchingStrategy } from './util/messageBatcher';
|
import { setBatchingStrategy } from './util/messageBatcher';
|
||||||
import { parseRemoteClientExpiration } from './util/parseRemoteClientExpiration';
|
import { parseRemoteClientExpiration } from './util/parseRemoteClientExpiration';
|
||||||
import { makeLookup } from './util/makeLookup';
|
|
||||||
import { addGlobalKeyboardShortcuts } from './services/addGlobalKeyboardShortcuts';
|
import { addGlobalKeyboardShortcuts } from './services/addGlobalKeyboardShortcuts';
|
||||||
import { createEventHandler } from './quill/signal-clipboard/util';
|
import { createEventHandler } from './quill/signal-clipboard/util';
|
||||||
import { onCallLogEventSync } from './util/onCallLogEventSync';
|
import { onCallLogEventSync } from './util/onCallLogEventSync';
|
||||||
import {
|
|
||||||
getCallsHistoryForRedux,
|
|
||||||
getCallsHistoryUnreadCountForRedux,
|
|
||||||
loadCallsHistory,
|
|
||||||
} from './services/callHistoryLoader';
|
|
||||||
import {
|
|
||||||
getCallLinksForRedux,
|
|
||||||
loadCallLinks,
|
|
||||||
} from './services/callLinksLoader';
|
|
||||||
import { backupsService } from './services/backups';
|
import { backupsService } from './services/backups';
|
||||||
import {
|
import {
|
||||||
getCallIdFromEra,
|
getCallIdFromEra,
|
||||||
updateLocalGroupCallHistoryTimestamp,
|
updateLocalGroupCallHistoryTimestamp,
|
||||||
} from './util/callDisposition';
|
} from './util/callDisposition';
|
||||||
import { deriveStorageServiceKey } from './Crypto';
|
import { deriveStorageServiceKey } from './Crypto';
|
||||||
import { getThemeType } from './util/getThemeType';
|
|
||||||
import { AttachmentDownloadManager } from './jobs/AttachmentDownloadManager';
|
import { AttachmentDownloadManager } from './jobs/AttachmentDownloadManager';
|
||||||
import { onCallLinkUpdateSync } from './util/onCallLinkUpdateSync';
|
import { onCallLinkUpdateSync } from './util/onCallLinkUpdateSync';
|
||||||
import { CallMode } from './types/CallDisposition';
|
import { CallMode } from './types/CallDisposition';
|
||||||
|
@ -211,6 +192,7 @@ import { getConversationIdForLogging } from './util/idForLogging';
|
||||||
import { encryptConversationAttachments } from './util/encryptConversationAttachments';
|
import { encryptConversationAttachments } from './util/encryptConversationAttachments';
|
||||||
import { DataReader, DataWriter } from './sql/Client';
|
import { DataReader, DataWriter } from './sql/Client';
|
||||||
import { restoreRemoteConfigFromStorage } from './RemoteConfig';
|
import { restoreRemoteConfigFromStorage } from './RemoteConfig';
|
||||||
|
import { getParametersForRedux, loadAll } from './services/allLoaders';
|
||||||
|
|
||||||
export function isOverHourIntoPast(timestamp: number): boolean {
|
export function isOverHourIntoPast(timestamp: number): boolean {
|
||||||
return isNumber(timestamp) && isOlderThan(timestamp, HOUR);
|
return isNumber(timestamp) && isOlderThan(timestamp, HOUR);
|
||||||
|
@ -255,13 +237,6 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
await initializeMessageCounter();
|
await initializeMessageCounter();
|
||||||
|
|
||||||
let initialBadgesState: BadgesStateType = { byId: {} };
|
|
||||||
async function loadInitialBadgesState(): Promise<void> {
|
|
||||||
initialBadgesState = {
|
|
||||||
byId: makeLookup(await DataReader.getAllBadges(), 'id'),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize WebAPI as early as possible
|
// Initialize WebAPI as early as possible
|
||||||
let server: WebAPIType | undefined;
|
let server: WebAPIType | undefined;
|
||||||
let messageReceiver: MessageReceiver | undefined;
|
let messageReceiver: MessageReceiver | undefined;
|
||||||
|
@ -1110,21 +1085,6 @@ export async function startApp(): Promise<void> {
|
||||||
drop(window.Events.cleanupDownloads());
|
drop(window.Events.cleanupDownloads());
|
||||||
}, DAY);
|
}, DAY);
|
||||||
|
|
||||||
let mainWindowStats = {
|
|
||||||
isMaximized: false,
|
|
||||||
isFullScreen: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let menuOptions = {
|
|
||||||
development: false,
|
|
||||||
devTools: false,
|
|
||||||
includeSetup: false,
|
|
||||||
isProduction: true,
|
|
||||||
platform: 'unknown',
|
|
||||||
};
|
|
||||||
|
|
||||||
let theme: ThemeType = window.systemTheme;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// This needs to load before we prime the data because we expect
|
// This needs to load before we prime the data because we expect
|
||||||
// ConversationController to be loaded and ready to use by then.
|
// ConversationController to be loaded and ready to use by then.
|
||||||
|
@ -1132,23 +1092,8 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
window.ConversationController.getOrCreateSignalConversation(),
|
window.ConversationController.getOrCreateSignalConversation(),
|
||||||
Stickers.load(),
|
|
||||||
loadRecentEmojis(),
|
|
||||||
loadInitialBadgesState(),
|
|
||||||
loadStories(),
|
|
||||||
loadDistributionLists(),
|
|
||||||
loadCallsHistory(),
|
|
||||||
loadCallLinks(),
|
|
||||||
window.textsecure.storage.protocol.hydrateCaches(),
|
window.textsecure.storage.protocol.hydrateCaches(),
|
||||||
(async () => {
|
loadAll(),
|
||||||
mainWindowStats = await window.SignalContext.getMainWindowStats();
|
|
||||||
})(),
|
|
||||||
(async () => {
|
|
||||||
menuOptions = await window.SignalContext.getMenuOptions();
|
|
||||||
})(),
|
|
||||||
(async () => {
|
|
||||||
theme = await getThemeType();
|
|
||||||
})(),
|
|
||||||
]);
|
]);
|
||||||
await window.ConversationController.checkForConflicts();
|
await window.ConversationController.checkForConflicts();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -1157,7 +1102,7 @@ export async function startApp(): Promise<void> {
|
||||||
Errors.toLogFormat(error)
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setupAppState({ mainWindowStats, menuOptions, theme });
|
setupAppState();
|
||||||
drop(start());
|
drop(start());
|
||||||
window.Signal.Services.initializeNetworkObserver(
|
window.Signal.Services.initializeNetworkObserver(
|
||||||
window.reduxActions.network
|
window.reduxActions.network
|
||||||
|
@ -1189,26 +1134,8 @@ export async function startApp(): Promise<void> {
|
||||||
log.info('Storage fetch');
|
log.info('Storage fetch');
|
||||||
drop(window.storage.fetch());
|
drop(window.storage.fetch());
|
||||||
|
|
||||||
function setupAppState({
|
function setupAppState() {
|
||||||
mainWindowStats,
|
initializeRedux(getParametersForRedux());
|
||||||
menuOptions,
|
|
||||||
theme,
|
|
||||||
}: {
|
|
||||||
mainWindowStats: MainWindowStatsType;
|
|
||||||
menuOptions: MenuOptionsType;
|
|
||||||
theme: ThemeType;
|
|
||||||
}) {
|
|
||||||
initializeRedux({
|
|
||||||
callLinks: getCallLinksForRedux(),
|
|
||||||
callsHistory: getCallsHistoryForRedux(),
|
|
||||||
callsHistoryUnreadCount: getCallsHistoryUnreadCountForRedux(),
|
|
||||||
initialBadgesState,
|
|
||||||
mainWindowStats,
|
|
||||||
menuOptions,
|
|
||||||
stories: getStoriesForRedux(),
|
|
||||||
storyDistributionLists: getDistributionListsForRedux(),
|
|
||||||
theme,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Here we set up a full redux store with initial state for our LeftPane Root
|
// Here we set up a full redux store with initial state for our LeftPane Root
|
||||||
const convoCollection = window.getConversations();
|
const convoCollection = window.getConversations();
|
||||||
|
|
60
ts/services/allLoaders.ts
Normal file
60
ts/services/allLoaders.ts
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
// Copyright 2023 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// loader services
|
||||||
|
import { getBadgesForRedux, loadBadges } from './badgeLoader';
|
||||||
|
import {
|
||||||
|
getCallsHistoryForRedux,
|
||||||
|
getCallsHistoryUnreadCountForRedux,
|
||||||
|
loadCallHistory,
|
||||||
|
} from './callHistoryLoader';
|
||||||
|
import { getCallLinksForRedux, loadCallLinks } from './callLinksLoader';
|
||||||
|
import {
|
||||||
|
getDistributionListsForRedux,
|
||||||
|
loadDistributionLists,
|
||||||
|
} from './distributionListLoader';
|
||||||
|
import { getStoriesForRedux, loadStories } from './storyLoader';
|
||||||
|
import { getUserDataForRedux, loadUserData } from './userLoader';
|
||||||
|
|
||||||
|
// old-style loaders
|
||||||
|
import {
|
||||||
|
getEmojiReducerState,
|
||||||
|
loadRecentEmojis,
|
||||||
|
} from '../util/loadRecentEmojis';
|
||||||
|
import {
|
||||||
|
load as loadStickers,
|
||||||
|
getInitialState as getStickersReduxState,
|
||||||
|
} from '../types/Stickers';
|
||||||
|
|
||||||
|
import type { ReduxInitData } from '../state/initializeRedux';
|
||||||
|
|
||||||
|
export async function loadAll(): Promise<void> {
|
||||||
|
await Promise.all([
|
||||||
|
loadBadges(),
|
||||||
|
loadCallHistory(),
|
||||||
|
loadCallLinks(),
|
||||||
|
loadDistributionLists(),
|
||||||
|
loadRecentEmojis(),
|
||||||
|
loadStickers(),
|
||||||
|
loadStories(),
|
||||||
|
loadUserData(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getParametersForRedux(): ReduxInitData {
|
||||||
|
const { mainWindowStats, menuOptions, theme } = getUserDataForRedux();
|
||||||
|
|
||||||
|
return {
|
||||||
|
badgesState: getBadgesForRedux(),
|
||||||
|
callHistory: getCallsHistoryForRedux(),
|
||||||
|
callHistoryUnreadCount: getCallsHistoryUnreadCountForRedux(),
|
||||||
|
callLinks: getCallLinksForRedux(),
|
||||||
|
mainWindowStats,
|
||||||
|
menuOptions,
|
||||||
|
recentEmoji: getEmojiReducerState(),
|
||||||
|
stickers: getStickersReduxState(),
|
||||||
|
stories: getStoriesForRedux(),
|
||||||
|
storyDistributionLists: getDistributionListsForRedux(),
|
||||||
|
theme,
|
||||||
|
};
|
||||||
|
}
|
|
@ -88,7 +88,6 @@ import { canBeSynced as canPreferredReactionEmojiBeSynced } from '../../reaction
|
||||||
import { SendStatus } from '../../messages/MessageSendState';
|
import { SendStatus } from '../../messages/MessageSendState';
|
||||||
import { BACKUP_VERSION } from './constants';
|
import { BACKUP_VERSION } from './constants';
|
||||||
import { getMessageIdForLogging } from '../../util/idForLogging';
|
import { getMessageIdForLogging } from '../../util/idForLogging';
|
||||||
import { getCallsHistoryForRedux } from '../callHistoryLoader';
|
|
||||||
import { makeLookup } from '../../util/makeLookup';
|
import { makeLookup } from '../../util/makeLookup';
|
||||||
import type {
|
import type {
|
||||||
CallHistoryDetails,
|
CallHistoryDetails,
|
||||||
|
@ -470,7 +469,7 @@ export class BackupExportStream extends Readable {
|
||||||
|
|
||||||
let cursor: PageMessagesCursorType | undefined;
|
let cursor: PageMessagesCursorType | undefined;
|
||||||
|
|
||||||
const callHistory = getCallsHistoryForRedux();
|
const callHistory = await DataReader.getAllCallHistory();
|
||||||
const callHistoryByCallId = makeLookup(callHistory, 'callId');
|
const callHistoryByCallId = makeLookup(callHistory, 'callId');
|
||||||
|
|
||||||
const me = window.ConversationController.getOurConversationOrThrow();
|
const me = window.ConversationController.getOurConversationOrThrow();
|
||||||
|
|
|
@ -34,6 +34,8 @@ import { getKeyMaterial } from './crypto';
|
||||||
import { BackupCredentials } from './credentials';
|
import { BackupCredentials } from './credentials';
|
||||||
import { BackupAPI } from './api';
|
import { BackupAPI } from './api';
|
||||||
import { validateBackup } from './validator';
|
import { validateBackup } from './validator';
|
||||||
|
import { reinitializeRedux } from '../../state/reinitializeRedux';
|
||||||
|
import { getParametersForRedux, loadAll } from '../allLoaders';
|
||||||
|
|
||||||
const IV_LENGTH = 16;
|
const IV_LENGTH = 16;
|
||||||
|
|
||||||
|
@ -192,15 +194,28 @@ export class BackupsService {
|
||||||
'importBackup: Bad MAC, second pass'
|
'importBackup: Bad MAC, second pass'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await this.resetStateAfterImport();
|
||||||
|
|
||||||
log.info('importBackup: finished...');
|
log.info('importBackup: finished...');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.info(`importBackup: failed, error: ${Errors.toLogFormat(error)}`);
|
log.info(`importBackup: failed, error: ${Errors.toLogFormat(error)}`);
|
||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
this.isRunning = false;
|
this.isRunning = false;
|
||||||
|
|
||||||
|
if (window.SignalCI) {
|
||||||
|
window.SignalCI.handleEvent('backupImportComplete', null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async resetStateAfterImport(): Promise<void> {
|
||||||
|
window.ConversationController.reset();
|
||||||
|
await window.ConversationController.load();
|
||||||
|
await loadAll();
|
||||||
|
reinitializeRedux(getParametersForRedux());
|
||||||
|
}
|
||||||
|
|
||||||
public async fetchAndSaveBackupCdnObjectMetadata(): Promise<void> {
|
public async fetchAndSaveBackupCdnObjectMetadata(): Promise<void> {
|
||||||
log.info('fetchAndSaveBackupCdnObjectMetadata: clearing existing metadata');
|
log.info('fetchAndSaveBackupCdnObjectMetadata: clearing existing metadata');
|
||||||
await DataWriter.clearAllBackupCdnObjectMetadata();
|
await DataWriter.clearAllBackupCdnObjectMetadata();
|
||||||
|
|
22
ts/services/badgeLoader.ts
Normal file
22
ts/services/badgeLoader.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2023 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { DataReader } from '../sql/Client';
|
||||||
|
import { strictAssert } from '../util/assert';
|
||||||
|
import { makeLookup } from '../util/makeLookup';
|
||||||
|
|
||||||
|
import type { BadgeType } from '../badges/types';
|
||||||
|
import type { BadgesStateType } from '../state/ducks/badges';
|
||||||
|
|
||||||
|
let badges: Array<BadgeType> | undefined;
|
||||||
|
|
||||||
|
export async function loadBadges(): Promise<void> {
|
||||||
|
badges = await DataReader.getAllBadges();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBadgesForRedux(): BadgesStateType {
|
||||||
|
strictAssert(badges != null, 'badges have not been loaded');
|
||||||
|
return {
|
||||||
|
byId: makeLookup(badges, 'id'),
|
||||||
|
};
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ import { strictAssert } from '../util/assert';
|
||||||
let callsHistoryData: ReadonlyArray<CallHistoryDetails>;
|
let callsHistoryData: ReadonlyArray<CallHistoryDetails>;
|
||||||
let callsHistoryUnreadCount: number;
|
let callsHistoryUnreadCount: number;
|
||||||
|
|
||||||
export async function loadCallsHistory(): Promise<void> {
|
export async function loadCallHistory(): Promise<void> {
|
||||||
await DataWriter.cleanupCallHistoryMessages();
|
await DataWriter.cleanupCallHistoryMessages();
|
||||||
callsHistoryData = await DataReader.getAllCallHistory();
|
callsHistoryData = await DataReader.getAllCallHistory();
|
||||||
callsHistoryUnreadCount = await DataReader.getCallHistoryUnreadCount();
|
callsHistoryUnreadCount = await DataReader.getCallHistoryUnreadCount();
|
||||||
|
|
39
ts/services/userLoader.ts
Normal file
39
ts/services/userLoader.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright 2023 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { strictAssert } from '../util/assert';
|
||||||
|
import { getThemeType } from '../util/getThemeType';
|
||||||
|
|
||||||
|
import type { MenuOptionsType } from '../types/menu';
|
||||||
|
import type { MainWindowStatsType } from '../windows/context';
|
||||||
|
import type { ThemeType } from '../types/Util';
|
||||||
|
|
||||||
|
let mainWindowStats: MainWindowStatsType | undefined;
|
||||||
|
let menuOptions: MenuOptionsType | undefined;
|
||||||
|
let theme: ThemeType | undefined;
|
||||||
|
|
||||||
|
export async function loadUserData(): Promise<void> {
|
||||||
|
await Promise.all([
|
||||||
|
(async () => {
|
||||||
|
mainWindowStats = await window.SignalContext.getMainWindowStats();
|
||||||
|
})(),
|
||||||
|
(async () => {
|
||||||
|
menuOptions = await window.SignalContext.getMenuOptions();
|
||||||
|
})(),
|
||||||
|
(async () => {
|
||||||
|
theme = await getThemeType();
|
||||||
|
})(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getUserDataForRedux(): {
|
||||||
|
mainWindowStats: MainWindowStatsType;
|
||||||
|
menuOptions: MenuOptionsType;
|
||||||
|
theme: ThemeType;
|
||||||
|
} {
|
||||||
|
strictAssert(
|
||||||
|
mainWindowStats != null && menuOptions != null && theme != null,
|
||||||
|
'user data has not been loaded'
|
||||||
|
);
|
||||||
|
return { mainWindowStats, menuOptions, theme };
|
||||||
|
}
|
|
@ -26,7 +26,7 @@ import {
|
||||||
import {
|
import {
|
||||||
getCallsHistoryForRedux,
|
getCallsHistoryForRedux,
|
||||||
getCallsHistoryUnreadCountForRedux,
|
getCallsHistoryUnreadCountForRedux,
|
||||||
loadCallsHistory,
|
loadCallHistory,
|
||||||
} from '../../services/callHistoryLoader';
|
} from '../../services/callHistoryLoader';
|
||||||
import { makeLookup } from '../../util/makeLookup';
|
import { makeLookup } from '../../util/makeLookup';
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ export function reloadCallHistory(): ThunkAction<
|
||||||
> {
|
> {
|
||||||
return async dispatch => {
|
return async dispatch => {
|
||||||
try {
|
try {
|
||||||
await loadCallsHistory();
|
await loadCallHistory();
|
||||||
const callsHistory = getCallsHistoryForRedux();
|
const callsHistory = getCallsHistoryForRedux();
|
||||||
const callsHistoryUnreadCount = getCallsHistoryUnreadCountForRedux();
|
const callsHistoryUnreadCount = getCallsHistoryUnreadCountForRedux();
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -234,6 +234,7 @@ export const actions = {
|
||||||
addCallHistory,
|
addCallHistory,
|
||||||
removeCallHistory,
|
removeCallHistory,
|
||||||
resetCallHistory,
|
resetCallHistory,
|
||||||
|
reloadCallHistory,
|
||||||
clearAllCallHistory,
|
clearAllCallHistory,
|
||||||
updateCallHistoryUnreadCount,
|
updateCallHistoryUnreadCount,
|
||||||
markCallHistoryRead,
|
markCallHistoryRead,
|
||||||
|
|
|
@ -59,7 +59,7 @@ function useEmoji(payload: string): UseEmojiAction {
|
||||||
|
|
||||||
// Reducer
|
// Reducer
|
||||||
|
|
||||||
function getEmptyState(): EmojisStateType {
|
export function getEmptyState(): EmojisStateType {
|
||||||
return {
|
return {
|
||||||
recents: [],
|
recents: [],
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,75 +1,175 @@
|
||||||
// Copyright 2022 Signal Messenger, LLC
|
// Copyright 2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { getEmptyState as accounts } from './ducks/accounts';
|
import { getEmptyState as accountsEmptyState } from './ducks/accounts';
|
||||||
import { getEmptyState as app } from './ducks/app';
|
import { getEmptyState as appEmptyState } from './ducks/app';
|
||||||
import { getEmptyState as audioPlayer } from './ducks/audioPlayer';
|
import { getEmptyState as audioPlayerEmptyState } from './ducks/audioPlayer';
|
||||||
import { getEmptyState as audioRecorder } from './ducks/audioRecorder';
|
import { getEmptyState as audioRecorderEmptyState } from './ducks/audioRecorder';
|
||||||
import { getEmptyState as callHistory } from './ducks/callHistory';
|
import { getEmptyState as badgesEmptyState } from './ducks/badges';
|
||||||
import { getEmptyState as calling } from './ducks/calling';
|
import { getEmptyState as callHistoryEmptyState } from './ducks/callHistory';
|
||||||
import { getEmptyState as composer } from './ducks/composer';
|
import { getEmptyState as callingEmptyState } from './ducks/calling';
|
||||||
import { getEmptyState as conversations } from './ducks/conversations';
|
import { getEmptyState as composerEmptyState } from './ducks/composer';
|
||||||
import { getEmptyState as crashReports } from './ducks/crashReports';
|
import { getEmptyState as conversationsEmptyState } from './ducks/conversations';
|
||||||
import { getEmptyState as expiration } from './ducks/expiration';
|
import { getEmptyState as crashReportsEmptyState } from './ducks/crashReports';
|
||||||
import { getEmptyState as globalModals } from './ducks/globalModals';
|
import { getEmptyState as emojiEmptyState } from './ducks/emojis';
|
||||||
import { getEmptyState as inbox } from './ducks/inbox';
|
import { getEmptyState as itemsEmptyState } from './ducks/items';
|
||||||
import { getEmptyState as lightbox } from './ducks/lightbox';
|
import { getEmptyState as stickersEmptyState } from './ducks/stickers';
|
||||||
import { getEmptyState as linkPreviews } from './ducks/linkPreviews';
|
import { getEmptyState as expirationEmptyState } from './ducks/expiration';
|
||||||
import { getEmptyState as mediaGallery } from './ducks/mediaGallery';
|
import { getEmptyState as globalModalsEmptyState } from './ducks/globalModals';
|
||||||
import { getEmptyState as nav } from './ducks/nav';
|
import { getEmptyState as inboxEmptyState } from './ducks/inbox';
|
||||||
import { getEmptyState as network } from './ducks/network';
|
import { getEmptyState as lightboxEmptyState } from './ducks/lightbox';
|
||||||
import { getEmptyState as preferredReactions } from './ducks/preferredReactions';
|
import { getEmptyState as linkPreviewsEmptyState } from './ducks/linkPreviews';
|
||||||
import { getEmptyState as safetyNumber } from './ducks/safetyNumber';
|
import { getEmptyState as mediaGalleryEmptyState } from './ducks/mediaGallery';
|
||||||
import { getEmptyState as search } from './ducks/search';
|
import { getEmptyState as navEmptyState } from './ducks/nav';
|
||||||
import { getEmptyState as getStoriesEmptyState } from './ducks/stories';
|
import { getEmptyState as networkEmptyState } from './ducks/network';
|
||||||
import { getEmptyState as getStoryDistributionListsEmptyState } from './ducks/storyDistributionLists';
|
import { getEmptyState as preferredReactionsEmptyState } from './ducks/preferredReactions';
|
||||||
import { getEmptyState as getToastEmptyState } from './ducks/toast';
|
import { getEmptyState as safetyNumberEmptyState } from './ducks/safetyNumber';
|
||||||
import { getEmptyState as updates } from './ducks/updates';
|
import { getEmptyState as searchEmptyState } from './ducks/search';
|
||||||
import { getEmptyState as user } from './ducks/user';
|
import { getEmptyState as storiesEmptyState } from './ducks/stories';
|
||||||
import { getEmptyState as username } from './ducks/username';
|
import { getEmptyState as storyDistributionListsEmptyState } from './ducks/storyDistributionLists';
|
||||||
|
import { getEmptyState as toastEmptyState } from './ducks/toast';
|
||||||
|
import { getEmptyState as updatesEmptyState } from './ducks/updates';
|
||||||
|
import { getEmptyState as userEmptyState } from './ducks/user';
|
||||||
|
import { getEmptyState as usernameEmptyState } from './ducks/username';
|
||||||
|
|
||||||
import type { StateType } from './reducer';
|
|
||||||
import type { BadgesStateType } from './ducks/badges';
|
|
||||||
import type { MainWindowStatsType } from '../windows/context';
|
|
||||||
import type { MenuOptionsType } from '../types/menu';
|
|
||||||
import type { StoryDataType } from './ducks/stories';
|
|
||||||
import type { StoryDistributionListDataType } from './ducks/storyDistributionLists';
|
|
||||||
import OS from '../util/os/osMain';
|
import OS from '../util/os/osMain';
|
||||||
import { getEmojiReducerState as emojis } from '../util/loadRecentEmojis';
|
|
||||||
import { getInitialState as stickers } from '../types/Stickers';
|
|
||||||
import { getInteractionMode } from '../services/InteractionMode';
|
import { getInteractionMode } from '../services/InteractionMode';
|
||||||
import { makeLookup } from '../util/makeLookup';
|
import { makeLookup } from '../util/makeLookup';
|
||||||
import type { CallHistoryDetails } from '../types/CallDisposition';
|
|
||||||
import type { ThemeType } from '../types/Util';
|
|
||||||
import type { CallLinkType } from '../types/CallLink';
|
|
||||||
|
|
||||||
export function getInitialState({
|
import type { StateType } from './reducer';
|
||||||
badges,
|
import type { MainWindowStatsType } from '../windows/context';
|
||||||
callLinks,
|
import type { ConversationsStateType } from './ducks/conversations';
|
||||||
callsHistory,
|
import type { MenuOptionsType } from '../types/menu';
|
||||||
callsHistoryUnreadCount,
|
import type {
|
||||||
stories,
|
StoryDistributionListDataType,
|
||||||
storyDistributionLists,
|
StoryDistributionListStateType,
|
||||||
mainWindowStats,
|
} from './ducks/storyDistributionLists';
|
||||||
menuOptions,
|
import type { ThemeType } from '../types/Util';
|
||||||
theme,
|
import type { UserStateType } from './ducks/user';
|
||||||
}: {
|
import type { ReduxInitData } from './initializeRedux';
|
||||||
badges: BadgesStateType;
|
|
||||||
callLinks: ReadonlyArray<CallLinkType>;
|
export function getInitialState(
|
||||||
callsHistory: ReadonlyArray<CallHistoryDetails>;
|
{
|
||||||
callsHistoryUnreadCount: number;
|
badgesState,
|
||||||
stories: Array<StoryDataType>;
|
callLinks,
|
||||||
storyDistributionLists: Array<StoryDistributionListDataType>;
|
callHistory: calls,
|
||||||
mainWindowStats: MainWindowStatsType;
|
callHistoryUnreadCount,
|
||||||
menuOptions: MenuOptionsType;
|
mainWindowStats,
|
||||||
theme: ThemeType;
|
menuOptions,
|
||||||
}): StateType {
|
recentEmoji,
|
||||||
|
stickers,
|
||||||
|
stories,
|
||||||
|
storyDistributionLists,
|
||||||
|
theme,
|
||||||
|
}: ReduxInitData,
|
||||||
|
existingState?: StateType
|
||||||
|
): StateType {
|
||||||
const items = window.storage.getItemsState();
|
const items = window.storage.getItemsState();
|
||||||
|
|
||||||
|
const baseState: StateType = existingState ?? getEmptyState();
|
||||||
|
|
||||||
|
return {
|
||||||
|
...baseState,
|
||||||
|
badges: badgesState,
|
||||||
|
callHistory: {
|
||||||
|
...callHistoryEmptyState(),
|
||||||
|
callHistoryByCallId: makeLookup(calls, 'callId'),
|
||||||
|
unreadCount: callHistoryUnreadCount,
|
||||||
|
},
|
||||||
|
calling: {
|
||||||
|
...callingEmptyState(),
|
||||||
|
callLinks: makeLookup(callLinks, 'roomId'),
|
||||||
|
},
|
||||||
|
emojis: recentEmoji,
|
||||||
|
items,
|
||||||
|
stickers,
|
||||||
|
stories: {
|
||||||
|
...storiesEmptyState(),
|
||||||
|
stories,
|
||||||
|
},
|
||||||
|
storyDistributionLists: generateStoryDistributionListState(
|
||||||
|
storyDistributionLists
|
||||||
|
),
|
||||||
|
user: generateUserState({
|
||||||
|
mainWindowStats,
|
||||||
|
menuOptions,
|
||||||
|
theme,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateConversationsState(): ConversationsStateType {
|
||||||
const convoCollection = window.getConversations();
|
const convoCollection = window.getConversations();
|
||||||
const formattedConversations = convoCollection.map(conversation =>
|
const formattedConversations = convoCollection.map(conversation =>
|
||||||
conversation.format()
|
conversation.format()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...conversationsEmptyState(),
|
||||||
|
conversationLookup: makeLookup(formattedConversations, 'id'),
|
||||||
|
conversationsByE164: makeLookup(formattedConversations, 'e164'),
|
||||||
|
conversationsByServiceId: {
|
||||||
|
...makeLookup(formattedConversations, 'serviceId'),
|
||||||
|
...makeLookup(formattedConversations, 'pni'),
|
||||||
|
},
|
||||||
|
conversationsByGroupId: makeLookup(formattedConversations, 'groupId'),
|
||||||
|
conversationsByUsername: makeLookup(formattedConversations, 'username'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEmptyState(): StateType {
|
||||||
|
return {
|
||||||
|
accounts: accountsEmptyState(),
|
||||||
|
app: appEmptyState(),
|
||||||
|
audioPlayer: audioPlayerEmptyState(),
|
||||||
|
audioRecorder: audioRecorderEmptyState(),
|
||||||
|
badges: badgesEmptyState(),
|
||||||
|
callHistory: callHistoryEmptyState(),
|
||||||
|
calling: callingEmptyState(),
|
||||||
|
composer: composerEmptyState(),
|
||||||
|
conversations: generateConversationsState(),
|
||||||
|
crashReports: crashReportsEmptyState(),
|
||||||
|
emojis: emojiEmptyState(),
|
||||||
|
expiration: expirationEmptyState(),
|
||||||
|
globalModals: globalModalsEmptyState(),
|
||||||
|
inbox: inboxEmptyState(),
|
||||||
|
items: itemsEmptyState(),
|
||||||
|
lightbox: lightboxEmptyState(),
|
||||||
|
linkPreviews: linkPreviewsEmptyState(),
|
||||||
|
mediaGallery: mediaGalleryEmptyState(),
|
||||||
|
nav: navEmptyState(),
|
||||||
|
network: networkEmptyState(),
|
||||||
|
preferredReactions: preferredReactionsEmptyState(),
|
||||||
|
safetyNumber: safetyNumberEmptyState(),
|
||||||
|
search: searchEmptyState(),
|
||||||
|
stickers: stickersEmptyState(),
|
||||||
|
stories: storiesEmptyState(),
|
||||||
|
storyDistributionLists: storyDistributionListsEmptyState(),
|
||||||
|
toast: toastEmptyState(),
|
||||||
|
updates: updatesEmptyState(),
|
||||||
|
user: userEmptyState(),
|
||||||
|
username: usernameEmptyState(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateStoryDistributionListState(
|
||||||
|
storyDistributionLists: ReadonlyArray<StoryDistributionListDataType>
|
||||||
|
): StoryDistributionListStateType {
|
||||||
|
return {
|
||||||
|
...storyDistributionListsEmptyState(),
|
||||||
|
distributionLists: storyDistributionLists || [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateUserState({
|
||||||
|
mainWindowStats,
|
||||||
|
menuOptions,
|
||||||
|
theme,
|
||||||
|
}: {
|
||||||
|
mainWindowStats: MainWindowStatsType;
|
||||||
|
menuOptions: MenuOptionsType;
|
||||||
|
theme: ThemeType;
|
||||||
|
}): UserStateType {
|
||||||
const ourNumber = window.textsecure.storage.user.getNumber();
|
const ourNumber = window.textsecure.storage.user.getNumber();
|
||||||
const ourAci = window.textsecure.storage.user.getAci();
|
const ourAci = window.textsecure.storage.user.getAci();
|
||||||
const ourPni = window.textsecure.storage.user.getPni();
|
const ourPni = window.textsecure.storage.user.getPni();
|
||||||
|
@ -88,79 +188,25 @@ export function getInitialState({
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
accounts: accounts(),
|
...userEmptyState(),
|
||||||
app: app(),
|
attachmentsPath: window.BasePaths.attachments,
|
||||||
audioPlayer: audioPlayer(),
|
i18n: window.i18n,
|
||||||
audioRecorder: audioRecorder(),
|
interactionMode: getInteractionMode(),
|
||||||
badges,
|
isMainWindowFullScreen: mainWindowStats.isFullScreen,
|
||||||
callHistory: {
|
isMainWindowMaximized: mainWindowStats.isMaximized,
|
||||||
...callHistory(),
|
localeMessages: window.i18n.getLocaleMessages(),
|
||||||
callHistoryByCallId: makeLookup(callsHistory, 'callId'),
|
menuOptions,
|
||||||
unreadCount: callsHistoryUnreadCount,
|
osName,
|
||||||
},
|
ourAci,
|
||||||
calling: {
|
ourConversationId,
|
||||||
...calling(),
|
ourDeviceId,
|
||||||
callLinks: makeLookup(callLinks, 'roomId'),
|
ourNumber,
|
||||||
},
|
ourPni,
|
||||||
composer: composer(),
|
platform: window.platform,
|
||||||
conversations: {
|
regionCode: window.storage.get('regionCode'),
|
||||||
...conversations(),
|
stickersPath: window.BasePaths.stickers,
|
||||||
conversationLookup: makeLookup(formattedConversations, 'id'),
|
tempPath: window.BasePaths.temp,
|
||||||
conversationsByE164: makeLookup(formattedConversations, 'e164'),
|
theme,
|
||||||
conversationsByServiceId: {
|
version: window.getVersion(),
|
||||||
...makeLookup(formattedConversations, 'serviceId'),
|
|
||||||
...makeLookup(formattedConversations, 'pni'),
|
|
||||||
},
|
|
||||||
conversationsByGroupId: makeLookup(formattedConversations, 'groupId'),
|
|
||||||
conversationsByUsername: makeLookup(formattedConversations, 'username'),
|
|
||||||
},
|
|
||||||
crashReports: crashReports(),
|
|
||||||
emojis: emojis(),
|
|
||||||
expiration: expiration(),
|
|
||||||
globalModals: globalModals(),
|
|
||||||
inbox: inbox(),
|
|
||||||
items,
|
|
||||||
lightbox: lightbox(),
|
|
||||||
linkPreviews: linkPreviews(),
|
|
||||||
mediaGallery: mediaGallery(),
|
|
||||||
nav: nav(),
|
|
||||||
network: network(),
|
|
||||||
preferredReactions: preferredReactions(),
|
|
||||||
safetyNumber: safetyNumber(),
|
|
||||||
search: search(),
|
|
||||||
stickers: stickers(),
|
|
||||||
stories: {
|
|
||||||
...getStoriesEmptyState(),
|
|
||||||
stories,
|
|
||||||
},
|
|
||||||
storyDistributionLists: {
|
|
||||||
...getStoryDistributionListsEmptyState(),
|
|
||||||
distributionLists: storyDistributionLists || [],
|
|
||||||
},
|
|
||||||
toast: getToastEmptyState(),
|
|
||||||
updates: updates(),
|
|
||||||
user: {
|
|
||||||
...user(),
|
|
||||||
attachmentsPath: window.BasePaths.attachments,
|
|
||||||
i18n: window.i18n,
|
|
||||||
interactionMode: getInteractionMode(),
|
|
||||||
isMainWindowFullScreen: mainWindowStats.isFullScreen,
|
|
||||||
isMainWindowMaximized: mainWindowStats.isMaximized,
|
|
||||||
localeMessages: window.i18n.getLocaleMessages(),
|
|
||||||
menuOptions,
|
|
||||||
osName,
|
|
||||||
ourAci,
|
|
||||||
ourConversationId,
|
|
||||||
ourDeviceId,
|
|
||||||
ourNumber,
|
|
||||||
ourPni,
|
|
||||||
platform: window.platform,
|
|
||||||
regionCode: window.storage.get('regionCode'),
|
|
||||||
stickersPath: window.BasePaths.stickers,
|
|
||||||
tempPath: window.BasePaths.temp,
|
|
||||||
theme,
|
|
||||||
version: window.getVersion(),
|
|
||||||
},
|
|
||||||
username: username(),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,50 +2,37 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
|
import { actionCreators } from './actions';
|
||||||
|
import { createStore } from './createStore';
|
||||||
|
import { getInitialState } from './getInitialState';
|
||||||
|
|
||||||
import type { BadgesStateType } from './ducks/badges';
|
import type { BadgesStateType } from './ducks/badges';
|
||||||
import type { CallHistoryDetails } from '../types/CallDisposition';
|
import type { CallHistoryDetails } from '../types/CallDisposition';
|
||||||
import type { MainWindowStatsType } from '../windows/context';
|
import type { MainWindowStatsType } from '../windows/context';
|
||||||
import type { MenuOptionsType } from '../types/menu';
|
import type { MenuOptionsType } from '../types/menu';
|
||||||
import type { StoryDataType } from './ducks/stories';
|
import type { StoryDataType } from './ducks/stories';
|
||||||
import type { StoryDistributionListDataType } from './ducks/storyDistributionLists';
|
import type { StoryDistributionListDataType } from './ducks/storyDistributionLists';
|
||||||
import { actionCreators } from './actions';
|
|
||||||
import { createStore } from './createStore';
|
|
||||||
import { getInitialState } from './getInitialState';
|
|
||||||
import type { ThemeType } from '../types/Util';
|
import type { ThemeType } from '../types/Util';
|
||||||
import type { CallLinkType } from '../types/CallLink';
|
import type { CallLinkType } from '../types/CallLink';
|
||||||
|
import type { RecentEmojiObjectType } from '../util/loadRecentEmojis';
|
||||||
|
import type { StickersStateType } from './ducks/stickers';
|
||||||
|
|
||||||
export function initializeRedux({
|
export type ReduxInitData = {
|
||||||
callLinks,
|
badgesState: BadgesStateType;
|
||||||
callsHistory,
|
callHistory: ReadonlyArray<CallHistoryDetails>;
|
||||||
callsHistoryUnreadCount,
|
callHistoryUnreadCount: number;
|
||||||
initialBadgesState,
|
|
||||||
mainWindowStats,
|
|
||||||
menuOptions,
|
|
||||||
stories,
|
|
||||||
storyDistributionLists,
|
|
||||||
theme,
|
|
||||||
}: {
|
|
||||||
callLinks: ReadonlyArray<CallLinkType>;
|
callLinks: ReadonlyArray<CallLinkType>;
|
||||||
callsHistory: ReadonlyArray<CallHistoryDetails>;
|
|
||||||
callsHistoryUnreadCount: number;
|
|
||||||
initialBadgesState: BadgesStateType;
|
|
||||||
mainWindowStats: MainWindowStatsType;
|
mainWindowStats: MainWindowStatsType;
|
||||||
menuOptions: MenuOptionsType;
|
menuOptions: MenuOptionsType;
|
||||||
|
recentEmoji: RecentEmojiObjectType;
|
||||||
|
stickers: StickersStateType;
|
||||||
stories: Array<StoryDataType>;
|
stories: Array<StoryDataType>;
|
||||||
storyDistributionLists: Array<StoryDistributionListDataType>;
|
storyDistributionLists: Array<StoryDistributionListDataType>;
|
||||||
theme: ThemeType;
|
theme: ThemeType;
|
||||||
}): void {
|
};
|
||||||
const initialState = getInitialState({
|
|
||||||
badges: initialBadgesState,
|
export function initializeRedux(data: ReduxInitData): void {
|
||||||
callLinks,
|
const initialState = getInitialState(data);
|
||||||
callsHistory,
|
|
||||||
callsHistoryUnreadCount,
|
|
||||||
mainWindowStats,
|
|
||||||
menuOptions,
|
|
||||||
stories,
|
|
||||||
storyDistributionLists,
|
|
||||||
theme,
|
|
||||||
});
|
|
||||||
|
|
||||||
const store = createStore(initialState);
|
const store = createStore(initialState);
|
||||||
window.reduxStore = store;
|
window.reduxStore = store;
|
||||||
|
|
57
ts/state/reinitializeRedux.ts
Normal file
57
ts/state/reinitializeRedux.ts
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright 2023 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import type { AnyAction } from 'redux';
|
||||||
|
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
import { getInitialState } from './getInitialState';
|
||||||
|
import { reducer as normalReducer } from './reducer';
|
||||||
|
|
||||||
|
import type { StateType } from './reducer';
|
||||||
|
import type { ReduxInitData } from './initializeRedux';
|
||||||
|
|
||||||
|
const REPLACE_STATE = 'resetReducer/REPLACE';
|
||||||
|
|
||||||
|
export function reinitializeRedux(options: ReduxInitData): void {
|
||||||
|
const logId = 'initializeRedux';
|
||||||
|
const existingState = window.reduxStore.getState();
|
||||||
|
const newInitialState = getInitialState(options, existingState);
|
||||||
|
|
||||||
|
const resetReducer = (
|
||||||
|
state: StateType | undefined,
|
||||||
|
action: AnyAction
|
||||||
|
): StateType => {
|
||||||
|
if (state == null) {
|
||||||
|
log.info(
|
||||||
|
`${logId}/resetReducer: Got null incoming state, returning newInitialState`
|
||||||
|
);
|
||||||
|
return newInitialState;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { type } = action;
|
||||||
|
if (type === REPLACE_STATE) {
|
||||||
|
log.info(
|
||||||
|
`${logId}/resetReducer: Got REPLACE_STATE action, returning newInitialState`
|
||||||
|
);
|
||||||
|
return newInitialState;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
`${logId}/resetReducer: Got action with type ${type}, returning original state`
|
||||||
|
);
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
log.info(`${logId}: installing resetReducer`);
|
||||||
|
window.reduxStore.replaceReducer(resetReducer);
|
||||||
|
|
||||||
|
log.info(`${logId}: dispatching REPLACE_STATE event`);
|
||||||
|
window.reduxStore.dispatch({
|
||||||
|
type: REPLACE_STATE,
|
||||||
|
});
|
||||||
|
|
||||||
|
log.info(`${logId}: restoring original reducer`);
|
||||||
|
window.reduxStore.replaceReducer(normalReducer);
|
||||||
|
|
||||||
|
log.info(`${logId}: complete!`);
|
||||||
|
}
|
|
@ -14,7 +14,6 @@ import { DataWriter } from '../../sql/Client';
|
||||||
import { type AciString, generateAci } from '../../types/ServiceId';
|
import { type AciString, generateAci } from '../../types/ServiceId';
|
||||||
import { ReadStatus } from '../../messages/MessageReadStatus';
|
import { ReadStatus } from '../../messages/MessageReadStatus';
|
||||||
import { SeenStatus } from '../../MessageSeenStatus';
|
import { SeenStatus } from '../../MessageSeenStatus';
|
||||||
import { loadCallsHistory } from '../../services/callHistoryLoader';
|
|
||||||
import { setupBasics, asymmetricRoundtripHarness } from './helpers';
|
import { setupBasics, asymmetricRoundtripHarness } from './helpers';
|
||||||
import {
|
import {
|
||||||
AUDIO_MP3,
|
AUDIO_MP3,
|
||||||
|
@ -31,6 +30,7 @@ import { isVoiceMessage, type AttachmentType } from '../../types/Attachment';
|
||||||
import { strictAssert } from '../../util/assert';
|
import { strictAssert } from '../../util/assert';
|
||||||
import { SignalService } from '../../protobuf';
|
import { SignalService } from '../../protobuf';
|
||||||
import { getRandomBytes } from '../../Crypto';
|
import { getRandomBytes } from '../../Crypto';
|
||||||
|
import { loadAll } from '../../services/allLoaders';
|
||||||
|
|
||||||
const CONTACT_A = generateAci();
|
const CONTACT_A = generateAci();
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ describe('backup/attachments', () => {
|
||||||
{ systemGivenName: 'CONTACT_A' }
|
{ systemGivenName: 'CONTACT_A' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await loadCallsHistory();
|
await loadAll();
|
||||||
|
|
||||||
sandbox = sinon.createSandbox();
|
sandbox = sinon.createSandbox();
|
||||||
const getAbsoluteAttachmentPath = sandbox.stub(
|
const getAbsoluteAttachmentPath = sandbox.stub(
|
||||||
|
|
|
@ -12,7 +12,6 @@ import type { MessageAttributesType } from '../../model-types';
|
||||||
import type { GroupV2ChangeType } from '../../groups';
|
import type { GroupV2ChangeType } from '../../groups';
|
||||||
import { getRandomBytes } from '../../Crypto';
|
import { getRandomBytes } from '../../Crypto';
|
||||||
import * as Bytes from '../../Bytes';
|
import * as Bytes from '../../Bytes';
|
||||||
import { loadCallsHistory } from '../../services/callHistoryLoader';
|
|
||||||
import { strictAssert } from '../../util/assert';
|
import { strictAssert } from '../../util/assert';
|
||||||
import { DurationInSeconds } from '../../util/durations';
|
import { DurationInSeconds } from '../../util/durations';
|
||||||
import {
|
import {
|
||||||
|
@ -24,6 +23,7 @@ import {
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
import { ReadStatus } from '../../messages/MessageReadStatus';
|
import { ReadStatus } from '../../messages/MessageReadStatus';
|
||||||
import { SeenStatus } from '../../MessageSeenStatus';
|
import { SeenStatus } from '../../MessageSeenStatus';
|
||||||
|
import { loadAll } from '../../services/allLoaders';
|
||||||
|
|
||||||
// Note: this should be kept up to date with GroupV2Change.stories.tsx, to
|
// Note: this should be kept up to date with GroupV2Change.stories.tsx, to
|
||||||
// maintain the comprehensive set of GroupV2 notifications we need to handle
|
// maintain the comprehensive set of GroupV2 notifications we need to handle
|
||||||
|
@ -114,7 +114,7 @@ describe('backup/groupv2/notifications', () => {
|
||||||
name: 'Rock Enthusiasts',
|
name: 'Rock Enthusiasts',
|
||||||
});
|
});
|
||||||
|
|
||||||
await loadCallsHistory();
|
await loadAll();
|
||||||
});
|
});
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
await DataWriter.removeAll();
|
await DataWriter.removeAll();
|
||||||
|
|
|
@ -13,7 +13,6 @@ import * as Bytes from '../../Bytes';
|
||||||
import { generateAci } from '../../types/ServiceId';
|
import { generateAci } from '../../types/ServiceId';
|
||||||
import { ReadStatus } from '../../messages/MessageReadStatus';
|
import { ReadStatus } from '../../messages/MessageReadStatus';
|
||||||
import { SeenStatus } from '../../MessageSeenStatus';
|
import { SeenStatus } from '../../MessageSeenStatus';
|
||||||
import { loadCallsHistory } from '../../services/callHistoryLoader';
|
|
||||||
import { ID_V1_LENGTH } from '../../groups';
|
import { ID_V1_LENGTH } from '../../groups';
|
||||||
import { DurationInSeconds, WEEK } from '../../util/durations';
|
import { DurationInSeconds, WEEK } from '../../util/durations';
|
||||||
import {
|
import {
|
||||||
|
@ -22,6 +21,7 @@ import {
|
||||||
symmetricRoundtripHarness,
|
symmetricRoundtripHarness,
|
||||||
OUR_ACI,
|
OUR_ACI,
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
|
import { loadAll } from '../../services/allLoaders';
|
||||||
|
|
||||||
const CONTACT_A = generateAci();
|
const CONTACT_A = generateAci();
|
||||||
const CONTACT_B = generateAci();
|
const CONTACT_B = generateAci();
|
||||||
|
@ -67,7 +67,7 @@ describe('backup/bubble messages', () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
await loadCallsHistory();
|
await loadAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('roundtrips incoming edited message', async () => {
|
it('roundtrips incoming edited message', async () => {
|
||||||
|
|
|
@ -14,7 +14,6 @@ import * as Bytes from '../../Bytes';
|
||||||
import { getRandomBytes } from '../../Crypto';
|
import { getRandomBytes } from '../../Crypto';
|
||||||
import { DataReader, DataWriter } from '../../sql/Client';
|
import { DataReader, DataWriter } from '../../sql/Client';
|
||||||
import { generateAci } from '../../types/ServiceId';
|
import { generateAci } from '../../types/ServiceId';
|
||||||
import { loadCallsHistory } from '../../services/callHistoryLoader';
|
|
||||||
import { setupBasics, symmetricRoundtripHarness } from './helpers';
|
import { setupBasics, symmetricRoundtripHarness } from './helpers';
|
||||||
import {
|
import {
|
||||||
AdhocCallStatus,
|
AdhocCallStatus,
|
||||||
|
@ -30,6 +29,7 @@ import { fromAdminKeyBytes } from '../../util/callLinks';
|
||||||
import { ReadStatus } from '../../messages/MessageReadStatus';
|
import { ReadStatus } from '../../messages/MessageReadStatus';
|
||||||
import { SeenStatus } from '../../MessageSeenStatus';
|
import { SeenStatus } from '../../MessageSeenStatus';
|
||||||
import { deriveGroupID, deriveGroupSecretParams } from '../../util/zkgroup';
|
import { deriveGroupID, deriveGroupSecretParams } from '../../util/zkgroup';
|
||||||
|
import { loadAll } from '../../services/allLoaders';
|
||||||
|
|
||||||
const CONTACT_A = generateAci();
|
const CONTACT_A = generateAci();
|
||||||
const GROUP_MASTER_KEY = getRandomBytes(32);
|
const GROUP_MASTER_KEY = getRandomBytes(32);
|
||||||
|
@ -78,7 +78,7 @@ describe('backup/calling', () => {
|
||||||
|
|
||||||
await DataWriter.insertCallLink(callLink);
|
await DataWriter.insertCallLink(callLink);
|
||||||
|
|
||||||
await loadCallsHistory();
|
await loadAll();
|
||||||
});
|
});
|
||||||
after(async () => {
|
after(async () => {
|
||||||
await DataWriter.removeAll();
|
await DataWriter.removeAll();
|
||||||
|
@ -99,7 +99,7 @@ describe('backup/calling', () => {
|
||||||
timestamp: now,
|
timestamp: now,
|
||||||
};
|
};
|
||||||
await DataWriter.saveCallHistory(callHistory);
|
await DataWriter.saveCallHistory(callHistory);
|
||||||
await loadCallsHistory();
|
await loadAll();
|
||||||
|
|
||||||
const messageUnseen: MessageAttributesType = {
|
const messageUnseen: MessageAttributesType = {
|
||||||
id: generateGuid(),
|
id: generateGuid(),
|
||||||
|
@ -146,7 +146,7 @@ describe('backup/calling', () => {
|
||||||
timestamp: now,
|
timestamp: now,
|
||||||
};
|
};
|
||||||
await DataWriter.saveCallHistory(callHistory);
|
await DataWriter.saveCallHistory(callHistory);
|
||||||
await loadCallsHistory();
|
await loadAll();
|
||||||
|
|
||||||
const messageUnseen: MessageAttributesType = {
|
const messageUnseen: MessageAttributesType = {
|
||||||
id: generateGuid(),
|
id: generateGuid(),
|
||||||
|
@ -231,7 +231,7 @@ describe('backup/calling', () => {
|
||||||
timestamp: now,
|
timestamp: now,
|
||||||
};
|
};
|
||||||
await DataWriter.saveCallHistory(callHistory);
|
await DataWriter.saveCallHistory(callHistory);
|
||||||
await loadCallsHistory();
|
await loadAll();
|
||||||
|
|
||||||
await symmetricRoundtripHarness([]);
|
await symmetricRoundtripHarness([]);
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ describe('backup/calling', () => {
|
||||||
timestamp: now,
|
timestamp: now,
|
||||||
};
|
};
|
||||||
await DataWriter.saveCallHistory(callHistory);
|
await DataWriter.saveCallHistory(callHistory);
|
||||||
await loadCallsHistory();
|
await loadAll();
|
||||||
|
|
||||||
await symmetricRoundtripHarness([]);
|
await symmetricRoundtripHarness([]);
|
||||||
|
|
||||||
|
|
|
@ -18,13 +18,13 @@ import { MessageRequestResponseEvent } from '../../types/MessageRequestResponseE
|
||||||
import { DurationInSeconds } from '../../util/durations';
|
import { DurationInSeconds } from '../../util/durations';
|
||||||
import { ReadStatus } from '../../messages/MessageReadStatus';
|
import { ReadStatus } from '../../messages/MessageReadStatus';
|
||||||
import { SeenStatus } from '../../MessageSeenStatus';
|
import { SeenStatus } from '../../MessageSeenStatus';
|
||||||
import { loadCallsHistory } from '../../services/callHistoryLoader';
|
|
||||||
import {
|
import {
|
||||||
setupBasics,
|
setupBasics,
|
||||||
asymmetricRoundtripHarness,
|
asymmetricRoundtripHarness,
|
||||||
symmetricRoundtripHarness,
|
symmetricRoundtripHarness,
|
||||||
OUR_ACI,
|
OUR_ACI,
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
|
import { loadAll } from '../../services/allLoaders';
|
||||||
|
|
||||||
const CONTACT_A = generateAci();
|
const CONTACT_A = generateAci();
|
||||||
const GROUP_ID = Bytes.toBase64(getRandomBytes(32));
|
const GROUP_ID = Bytes.toBase64(getRandomBytes(32));
|
||||||
|
@ -56,7 +56,7 @@ describe('backup/non-bubble messages', () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
await loadCallsHistory();
|
await loadAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('roundtrips END_SESSION simple update', async () => {
|
it('roundtrips END_SESSION simple update', async () => {
|
||||||
|
|
|
@ -344,6 +344,11 @@ export class Bootstrap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extraConfig?.ciBackupPath) {
|
||||||
|
debug('waiting for backup import to complete');
|
||||||
|
await app.waitForBackupImportComplete();
|
||||||
|
}
|
||||||
|
|
||||||
await this.phone.waitForSync(this.desktop);
|
await this.phone.waitForSync(this.desktop);
|
||||||
this.phone.resetSyncState(this.desktop);
|
this.phone.resetSyncState(this.desktop);
|
||||||
|
|
||||||
|
@ -512,7 +517,9 @@ export class Bootstrap {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug('screenshot difference', numPixels);
|
debug(
|
||||||
|
`screenshot difference for ${name}: ${numPixels}/${width * height}`
|
||||||
|
);
|
||||||
|
|
||||||
const outDir = await this.getArtifactsDir(test?.fullTitle());
|
const outDir = await this.getArtifactsDir(test?.fullTitle());
|
||||||
if (outDir != null) {
|
if (outDir != null) {
|
||||||
|
|
|
@ -114,6 +114,10 @@ export class App extends EventEmitter {
|
||||||
return this.waitForEvent('app-loaded');
|
return this.waitForEvent('app-loaded');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async waitForBackupImportComplete(): Promise<void> {
|
||||||
|
return this.waitForEvent('backupImportComplete');
|
||||||
|
}
|
||||||
|
|
||||||
public async waitForMessageSend(): Promise<MessageSendInfoType> {
|
public async waitForMessageSend(): Promise<MessageSendInfoType> {
|
||||||
return this.waitForEvent('message:send-complete');
|
return this.waitForEvent('message:send-complete');
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import { take } from 'lodash';
|
import { take } from 'lodash';
|
||||||
import { DataReader } from '../sql/Client';
|
import { DataReader } from '../sql/Client';
|
||||||
|
|
||||||
type RecentEmojiObjectType = {
|
export type RecentEmojiObjectType = {
|
||||||
recents: Array<string>;
|
recents: Array<string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -99,10 +99,10 @@ window.testUtilities = {
|
||||||
await Stickers.load();
|
await Stickers.load();
|
||||||
|
|
||||||
initializeRedux({
|
initializeRedux({
|
||||||
|
badgesState: { byId: {} },
|
||||||
callLinks: [],
|
callLinks: [],
|
||||||
callsHistory: [],
|
callHistory: [],
|
||||||
callsHistoryUnreadCount: 0,
|
callHistoryUnreadCount: 0,
|
||||||
initialBadgesState: { byId: {} },
|
|
||||||
mainWindowStats: {
|
mainWindowStats: {
|
||||||
isFullScreen: false,
|
isFullScreen: false,
|
||||||
isMaximized: false,
|
isMaximized: false,
|
||||||
|
@ -114,8 +114,17 @@ window.testUtilities = {
|
||||||
isProduction: false,
|
isProduction: false,
|
||||||
platform: 'test',
|
platform: 'test',
|
||||||
},
|
},
|
||||||
|
recentEmoji: {
|
||||||
|
recents: [],
|
||||||
|
},
|
||||||
stories: [],
|
stories: [],
|
||||||
storyDistributionLists: [],
|
storyDistributionLists: [],
|
||||||
|
stickers: {
|
||||||
|
installedPack: null,
|
||||||
|
packs: {},
|
||||||
|
recentStickers: [],
|
||||||
|
blessedPacks: {},
|
||||||
|
},
|
||||||
theme: ThemeType.dark,
|
theme: ThemeType.dark,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue