background.ts: Introduce types for redux initialState
This commit is contained in:
parent
3673b6d101
commit
4763831d3e
42 changed files with 315 additions and 238 deletions
|
@ -155,7 +155,7 @@
|
|||
"react-sortable-hoc": "1.9.1",
|
||||
"react-virtualized": "9.21.0",
|
||||
"read-last-lines": "1.8.0",
|
||||
"redux": "4.0.2",
|
||||
"redux": "4.1.2",
|
||||
"redux-logger": "3.0.6",
|
||||
"redux-promise-middleware": "6.1.0",
|
||||
"redux-thunk": "2.3.0",
|
||||
|
|
|
@ -91,7 +91,6 @@ import { RotateSignedPreKeyListener } from './textsecure/RotateSignedPreKeyListe
|
|||
import { isDirectConversation, isGroupV2 } from './util/whatTypeOfConversation';
|
||||
import { BackOff, FIBONACCI_TIMEOUTS } from './util/BackOff';
|
||||
import { AppViewType } from './state/ducks/app';
|
||||
import { UsernameSaveState } from './state/ducks/conversationsEnums';
|
||||
import type { BadgesStateType } from './state/ducks/badges';
|
||||
import { badgeImageFileDownloader } from './badges/badgeImageFileDownloader';
|
||||
import { isIncoming } from './state/selectors/message';
|
||||
|
@ -116,7 +115,6 @@ import { ReadStatus } from './messages/MessageReadStatus';
|
|||
import type { SendStateByConversationId } from './messages/MessageSendState';
|
||||
import { SendStatus } from './messages/MessageSendState';
|
||||
import * as AttachmentDownloads from './messageModifiers/AttachmentDownloads';
|
||||
import * as preferredReactions from './state/ducks/preferredReactions';
|
||||
import * as Conversation from './types/Conversation';
|
||||
import * as Stickers from './types/Stickers';
|
||||
import * as Errors from './types/errors';
|
||||
|
@ -128,10 +126,7 @@ import { RemoveAllConfiguration } from './types/RemoveAllConfiguration';
|
|||
import { isValidUuid, UUIDKind } from './types/UUID';
|
||||
import type { UUID } from './types/UUID';
|
||||
import * as log from './logging/log';
|
||||
import {
|
||||
loadRecentEmojis,
|
||||
getEmojiReducerState,
|
||||
} from './util/loadRecentEmojis';
|
||||
import { loadRecentEmojis } from './util/loadRecentEmojis';
|
||||
import { deleteAllLogs } from './util/deleteAllLogs';
|
||||
import { ToastCaptchaFailed } from './components/ToastCaptchaFailed';
|
||||
import { ToastCaptchaSolved } from './components/ToastCaptchaSolved';
|
||||
|
@ -143,6 +138,7 @@ import { deliveryReceiptsJobQueue } from './jobs/deliveryReceiptsJobQueue';
|
|||
import { updateOurUsername } from './util/updateOurUsername';
|
||||
import { ReactionSource } from './reactions/ReactionSource';
|
||||
import { singleProtoJobQueue } from './jobs/singleProtoJobQueue';
|
||||
import { getInitialState } from './state/getInitialState';
|
||||
|
||||
const MAX_ATTACHMENT_DOWNLOAD_AGE = 3600 * 72 * 1000;
|
||||
|
||||
|
@ -890,70 +886,7 @@ export async function startApp(): Promise<void> {
|
|||
function initializeRedux() {
|
||||
// Here we set up a full redux store with initial state for our LeftPane Root
|
||||
const convoCollection = window.getConversations();
|
||||
const conversations = convoCollection.map(conversation =>
|
||||
conversation.format()
|
||||
);
|
||||
const ourNumber = window.textsecure.storage.user.getNumber();
|
||||
const ourUuid = window.textsecure.storage.user.getUuid()?.toString();
|
||||
const ourConversationId =
|
||||
window.ConversationController.getOurConversationId();
|
||||
const ourDeviceId = window.textsecure.storage.user.getDeviceId();
|
||||
|
||||
const themeSetting = window.Events.getThemeSetting();
|
||||
const theme = themeSetting === 'system' ? window.systemTheme : themeSetting;
|
||||
|
||||
// TODO: DESKTOP-3125
|
||||
const initialState = {
|
||||
badges: initialBadgesState,
|
||||
conversations: {
|
||||
conversationLookup: window.Signal.Util.makeLookup(conversations, 'id'),
|
||||
conversationsByE164: window.Signal.Util.makeLookup(
|
||||
conversations,
|
||||
'e164'
|
||||
),
|
||||
conversationsByUuid: window.Signal.Util.makeLookup(
|
||||
conversations,
|
||||
'uuid'
|
||||
),
|
||||
conversationsByGroupId: window.Signal.Util.makeLookup(
|
||||
conversations,
|
||||
'groupId'
|
||||
),
|
||||
conversationsByUsername: window.Signal.Util.makeLookup(
|
||||
conversations,
|
||||
'username'
|
||||
),
|
||||
messagesByConversation: {},
|
||||
messagesLookup: {},
|
||||
verificationDataByConversation: {},
|
||||
selectedConversationId: undefined,
|
||||
selectedMessage: undefined,
|
||||
selectedMessageCounter: 0,
|
||||
selectedConversationPanelDepth: 0,
|
||||
selectedConversationTitle: '',
|
||||
showArchived: false,
|
||||
usernameSaveState: UsernameSaveState.None,
|
||||
},
|
||||
emojis: getEmojiReducerState(),
|
||||
items: window.storage.getItemsState(),
|
||||
preferredReactions: preferredReactions.getInitialState(),
|
||||
stickers: Stickers.getInitialState(),
|
||||
user: {
|
||||
attachmentsPath: window.baseAttachmentsPath,
|
||||
stickersPath: window.baseStickersPath,
|
||||
tempPath: window.baseTempPath,
|
||||
regionCode: window.storage.get('regionCode'),
|
||||
ourConversationId,
|
||||
ourDeviceId,
|
||||
ourNumber,
|
||||
ourUuid,
|
||||
platform: window.platform,
|
||||
i18n: window.i18n,
|
||||
interactionMode: window.getInteractionMode(),
|
||||
theme,
|
||||
version: window.getVersion(),
|
||||
},
|
||||
};
|
||||
const initialState = getInitialState({ badges: initialBadgesState });
|
||||
|
||||
const store = window.Signal.State.createStore(initialState);
|
||||
window.reduxStore = store;
|
||||
|
|
|
@ -40,15 +40,10 @@ import type {
|
|||
StartCallType,
|
||||
} from '../state/ducks/calling';
|
||||
import type { LocalizerType, ThemeType } from '../types/Util';
|
||||
import type { UUIDStringType } from '../types/UUID';
|
||||
import { missingCaseError } from '../util/missingCaseError';
|
||||
|
||||
const GROUP_CALL_RING_DURATION = 60 * 1000;
|
||||
|
||||
type MeType = ConversationType & {
|
||||
uuid: UUIDStringType;
|
||||
};
|
||||
|
||||
export type PropsType = {
|
||||
activeCall?: ActiveCallType;
|
||||
availableCameras: Array<MediaDeviceInfo>;
|
||||
|
@ -83,7 +78,7 @@ export type PropsType = {
|
|||
declineCall: (_: DeclineCallType) => void;
|
||||
i18n: LocalizerType;
|
||||
isGroupCallOutboundRingEnabled: boolean;
|
||||
me: MeType;
|
||||
me: ConversationType;
|
||||
notifyForCall: (title: string, isVideoCall: boolean) => unknown;
|
||||
openSystemPreferencesAction: () => unknown;
|
||||
playRingtone: () => unknown;
|
||||
|
|
|
@ -150,14 +150,14 @@ const createProps = (
|
|||
getPresentingSources: action('get-presenting-sources'),
|
||||
hangUpActiveCall: action('hang-up'),
|
||||
i18n,
|
||||
me: {
|
||||
me: getDefaultConversation({
|
||||
color: AvatarColors[1],
|
||||
id: '6146087e-f7ef-457e-9a8d-47df1fdd6b25',
|
||||
name: 'Morty Smith',
|
||||
profileName: 'Morty Smith',
|
||||
title: 'Morty Smith',
|
||||
uuid: '3c134598-eecb-42ab-9ad3-2b0873f771b2',
|
||||
},
|
||||
}),
|
||||
openSystemPreferencesAction: action('open-system-preferences-action'),
|
||||
setGroupCallVideoRequest: action('set-group-call-video-request'),
|
||||
setLocalAudio: action('set-local-audio'),
|
||||
|
|
|
@ -28,7 +28,6 @@ import {
|
|||
GroupCallConnectionState,
|
||||
GroupCallJoinState,
|
||||
} from '../types/Calling';
|
||||
import type { AvatarColorType } from '../types/Colors';
|
||||
import { AvatarColors } from '../types/Colors';
|
||||
import type { ConversationType } from '../state/ducks/conversations';
|
||||
import { CallingToastManager } from './CallingToastManager';
|
||||
|
@ -37,7 +36,6 @@ import { GroupCallRemoteParticipants } from './GroupCallRemoteParticipants';
|
|||
import type { LocalizerType } from '../types/Util';
|
||||
import { NeedsScreenRecordingPermissionsModal } from './NeedsScreenRecordingPermissionsModal';
|
||||
import { missingCaseError } from '../util/missingCaseError';
|
||||
import type { UUIDStringType } from '../types/UUID';
|
||||
import * as KeyboardLayout from '../services/keyboardLayout';
|
||||
import { useActivateSpeakerViewOnPresenting } from '../hooks/useActivateSpeakerViewOnPresenting';
|
||||
|
||||
|
@ -49,16 +47,7 @@ export type PropsType = {
|
|||
hangUpActiveCall: () => void;
|
||||
i18n: LocalizerType;
|
||||
joinedAt?: number;
|
||||
me: {
|
||||
avatarPath?: string;
|
||||
color?: AvatarColorType;
|
||||
id: string;
|
||||
name?: string;
|
||||
phoneNumber?: string;
|
||||
profileName?: string;
|
||||
title: string;
|
||||
uuid: UUIDStringType;
|
||||
};
|
||||
me: ConversationType;
|
||||
openSystemPreferencesAction: () => unknown;
|
||||
setGroupCallVideoRequest: (_: Array<GroupCallVideoRequest>) => void;
|
||||
setLocalAudio: (_: SetLocalAudioType) => void;
|
||||
|
|
|
@ -61,11 +61,13 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => {
|
|||
isGroupCall,
|
||||
isGroupCallOutboundRingEnabled: true,
|
||||
isCallFull: boolean('isCallFull', overrideProps.isCallFull || false),
|
||||
me: overrideProps.me || {
|
||||
color: AvatarColors[0],
|
||||
id: UUID.generate().toString(),
|
||||
uuid: UUID.generate().toString(),
|
||||
},
|
||||
me:
|
||||
overrideProps.me ||
|
||||
getDefaultConversation({
|
||||
color: AvatarColors[0],
|
||||
id: UUID.generate().toString(),
|
||||
uuid: UUID.generate().toString(),
|
||||
}),
|
||||
onCallCanceled: action('on-call-canceled'),
|
||||
onJoinCall: action('on-join-call'),
|
||||
outgoingRing: boolean('outgoingRing', Boolean(overrideProps.outgoingRing)),
|
||||
|
@ -105,12 +107,12 @@ story.add('No Camera, no avatar', () => {
|
|||
story.add('No Camera, local avatar', () => {
|
||||
const props = createProps({
|
||||
availableCameras: [],
|
||||
me: {
|
||||
me: getDefaultConversation({
|
||||
avatarPath: '/fixtures/kitten-4-112-112.jpg',
|
||||
color: AvatarColors[0],
|
||||
id: UUID.generate().toString(),
|
||||
uuid: UUID.generate().toString(),
|
||||
},
|
||||
}),
|
||||
});
|
||||
return <CallingLobby {...props} />;
|
||||
});
|
||||
|
@ -146,10 +148,10 @@ story.add('Group Call - 1 peeked participant (self)', () => {
|
|||
const uuid = UUID.generate().toString();
|
||||
const props = createProps({
|
||||
isGroupCall: true,
|
||||
me: {
|
||||
me: getDefaultConversation({
|
||||
id: UUID.generate().toString(),
|
||||
uuid,
|
||||
},
|
||||
}),
|
||||
peekedParticipants: [fakePeekedParticipant({ title: 'Ash', uuid })],
|
||||
});
|
||||
return <CallingLobby {...props} />;
|
||||
|
|
|
@ -19,9 +19,7 @@ import {
|
|||
CallingLobbyJoinButton,
|
||||
CallingLobbyJoinButtonVariant,
|
||||
} from './CallingLobbyJoinButton';
|
||||
import type { AvatarColorType } from '../types/Colors';
|
||||
import type { LocalizerType } from '../types/Util';
|
||||
import type { UUIDStringType } from '../types/UUID';
|
||||
import { useIsOnline } from '../hooks/useIsOnline';
|
||||
import * as KeyboardLayout from '../services/keyboardLayout';
|
||||
import type { ConversationType } from '../state/ducks/conversations';
|
||||
|
@ -51,12 +49,7 @@ export type PropsType = {
|
|||
isGroupCall: boolean;
|
||||
isGroupCallOutboundRingEnabled: boolean;
|
||||
isCallFull?: boolean;
|
||||
me: {
|
||||
avatarPath?: string;
|
||||
id: string;
|
||||
color?: AvatarColorType;
|
||||
uuid: UUIDStringType;
|
||||
};
|
||||
me: Readonly<Pick<ConversationType, 'avatarPath' | 'color' | 'id' | 'uuid'>>;
|
||||
onCallCanceled: () => void;
|
||||
onJoinCall: () => void;
|
||||
outgoingRing: boolean;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// Copyright 2020-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
/* eslint-disable react/no-array-index-key */
|
||||
|
@ -24,7 +24,7 @@ type ParticipantType = ConversationType & {
|
|||
export type PropsType = {
|
||||
readonly i18n: LocalizerType;
|
||||
readonly onClose: () => void;
|
||||
readonly ourUuid: string;
|
||||
readonly ourUuid: string | undefined;
|
||||
readonly participants: Array<ParticipantType>;
|
||||
};
|
||||
|
||||
|
@ -113,7 +113,7 @@ export const CallingParticipantsList = React.memo(
|
|||
sharedGroupNames={participant.sharedGroupNames}
|
||||
size={32}
|
||||
/>
|
||||
{participant.uuid === ourUuid ? (
|
||||
{ourUuid && participant.uuid === ourUuid ? (
|
||||
<span className="module-calling-participants-list__name">
|
||||
{i18n('you')}
|
||||
</span>
|
||||
|
|
|
@ -88,7 +88,7 @@ export type PropsType = {
|
|||
preferredWidthFromStorage: number;
|
||||
selectedConversationId: undefined | string;
|
||||
selectedMessageId: undefined | string;
|
||||
regionCode: string;
|
||||
regionCode: string | undefined;
|
||||
challengeStatus: 'idle' | 'required' | 'pending';
|
||||
setChallengeStatus: (status: 'idle') => void;
|
||||
crashReportCount: number;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// Copyright 2020-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { ReactElement } from 'react';
|
||||
|
@ -22,7 +22,7 @@ import { Modal } from '../Modal';
|
|||
|
||||
export type PropsDataType = {
|
||||
groupName?: string;
|
||||
ourUuid: UUIDStringType;
|
||||
ourUuid?: UUIDStringType;
|
||||
change: GroupV2ChangeType;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ export type LeftPaneComposePropsType = {
|
|||
composeContacts: ReadonlyArray<ContactListItemConversationType>;
|
||||
composeGroups: ReadonlyArray<ConversationListItemPropsType>;
|
||||
|
||||
regionCode: string;
|
||||
regionCode: string | undefined;
|
||||
searchTerm: string;
|
||||
isFetchingUsername: boolean;
|
||||
isUsernamesEnabled: boolean;
|
||||
|
@ -355,7 +355,7 @@ function focusRef(el: HTMLElement | null) {
|
|||
|
||||
function parsePhoneNumber(
|
||||
str: string,
|
||||
regionCode: string
|
||||
regionCode: string | undefined
|
||||
): undefined | PhoneNumber {
|
||||
let result: PhoneNumber;
|
||||
try {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020 Signal Messenger, LLC
|
||||
// Copyright 2020-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { LocalizerType } from './types/Util';
|
||||
|
@ -20,7 +20,7 @@ export type StringRendererType<T> = (
|
|||
export type RenderOptionsType<T> = {
|
||||
from?: UUIDStringType;
|
||||
i18n: LocalizerType;
|
||||
ourUuid: UUIDStringType;
|
||||
ourUuid?: UUIDStringType;
|
||||
renderContact: SmartContactRendererType<T>;
|
||||
renderString: StringRendererType<T>;
|
||||
};
|
||||
|
@ -47,7 +47,7 @@ export function renderChangeDetail<T>(
|
|||
options: RenderOptionsType<T>
|
||||
): T | string {
|
||||
const { from, i18n, ourUuid, renderContact, renderString } = options;
|
||||
const fromYou = Boolean(from && from === ourUuid);
|
||||
const fromYou = Boolean(from && ourUuid && from === ourUuid);
|
||||
|
||||
if (detail.type === 'create') {
|
||||
if (fromYou) {
|
||||
|
@ -209,7 +209,7 @@ export function renderChangeDetail<T>(
|
|||
}
|
||||
if (detail.type === 'member-add') {
|
||||
const { uuid } = detail;
|
||||
const weAreJoiner = uuid === ourUuid;
|
||||
const weAreJoiner = Boolean(ourUuid && uuid === ourUuid);
|
||||
|
||||
if (weAreJoiner) {
|
||||
if (fromYou) {
|
||||
|
@ -239,8 +239,8 @@ export function renderChangeDetail<T>(
|
|||
}
|
||||
if (detail.type === 'member-add-from-invite') {
|
||||
const { uuid, inviter } = detail;
|
||||
const weAreJoiner = uuid === ourUuid;
|
||||
const weAreInviter = Boolean(inviter && inviter === ourUuid);
|
||||
const weAreJoiner = Boolean(ourUuid && uuid === ourUuid);
|
||||
const weAreInviter = Boolean(inviter && ourUuid && inviter === ourUuid);
|
||||
|
||||
if (!from || from !== uuid) {
|
||||
if (weAreJoiner) {
|
||||
|
@ -302,7 +302,7 @@ export function renderChangeDetail<T>(
|
|||
if (detail.type === 'member-add-from-link') {
|
||||
const { uuid } = detail;
|
||||
|
||||
if (fromYou && uuid === ourUuid) {
|
||||
if (fromYou && ourUuid && uuid === ourUuid) {
|
||||
return renderString('GroupV2--member-add-from-link--you--you', i18n);
|
||||
}
|
||||
if (from && uuid === from) {
|
||||
|
@ -320,7 +320,7 @@ export function renderChangeDetail<T>(
|
|||
}
|
||||
if (detail.type === 'member-add-from-admin-approval') {
|
||||
const { uuid } = detail;
|
||||
const weAreJoiner = uuid === ourUuid;
|
||||
const weAreJoiner = Boolean(ourUuid && uuid === ourUuid);
|
||||
|
||||
if (weAreJoiner) {
|
||||
if (from) {
|
||||
|
@ -371,7 +371,7 @@ export function renderChangeDetail<T>(
|
|||
}
|
||||
if (detail.type === 'member-remove') {
|
||||
const { uuid } = detail;
|
||||
const weAreLeaver = uuid === ourUuid;
|
||||
const weAreLeaver = Boolean(ourUuid && uuid === ourUuid);
|
||||
|
||||
if (weAreLeaver) {
|
||||
if (fromYou) {
|
||||
|
@ -407,7 +407,7 @@ export function renderChangeDetail<T>(
|
|||
}
|
||||
if (detail.type === 'member-privilege') {
|
||||
const { uuid, newPrivilege } = detail;
|
||||
const weAreMember = uuid === ourUuid;
|
||||
const weAreMember = Boolean(ourUuid && uuid === ourUuid);
|
||||
|
||||
if (newPrivilege === RoleEnum.ADMINISTRATOR) {
|
||||
if (weAreMember) {
|
||||
|
@ -493,7 +493,7 @@ export function renderChangeDetail<T>(
|
|||
}
|
||||
if (detail.type === 'pending-add-one') {
|
||||
const { uuid } = detail;
|
||||
const weAreInvited = uuid === ourUuid;
|
||||
const weAreInvited = Boolean(ourUuid && uuid === ourUuid);
|
||||
if (weAreInvited) {
|
||||
if (from) {
|
||||
return renderString('GroupV2--pending-add--one--you--other', i18n, [
|
||||
|
@ -534,8 +534,8 @@ export function renderChangeDetail<T>(
|
|||
}
|
||||
if (detail.type === 'pending-remove-one') {
|
||||
const { inviter, uuid } = detail;
|
||||
const weAreInviter = Boolean(inviter && inviter === ourUuid);
|
||||
const weAreInvited = uuid === ourUuid;
|
||||
const weAreInviter = Boolean(inviter && ourUuid && inviter === ourUuid);
|
||||
const weAreInvited = Boolean(ourUuid && uuid === ourUuid);
|
||||
const sentByInvited = Boolean(from && from === uuid);
|
||||
const sentByInviter = Boolean(from && inviter && from === inviter);
|
||||
|
||||
|
@ -629,7 +629,7 @@ export function renderChangeDetail<T>(
|
|||
}
|
||||
if (detail.type === 'pending-remove-many') {
|
||||
const { count, inviter } = detail;
|
||||
const weAreInviter = Boolean(inviter && inviter === ourUuid);
|
||||
const weAreInviter = Boolean(inviter && ourUuid && inviter === ourUuid);
|
||||
|
||||
if (weAreInviter) {
|
||||
if (fromYou) {
|
||||
|
@ -709,7 +709,7 @@ export function renderChangeDetail<T>(
|
|||
}
|
||||
if (detail.type === 'admin-approval-add-one') {
|
||||
const { uuid } = detail;
|
||||
const weAreJoiner = uuid === ourUuid;
|
||||
const weAreJoiner = Boolean(ourUuid && uuid === ourUuid);
|
||||
|
||||
if (weAreJoiner) {
|
||||
return renderString('GroupV2--admin-approval-add-one--you', i18n);
|
||||
|
@ -720,7 +720,7 @@ export function renderChangeDetail<T>(
|
|||
}
|
||||
if (detail.type === 'admin-approval-remove-one') {
|
||||
const { uuid } = detail;
|
||||
const weAreJoiner = uuid === ourUuid;
|
||||
const weAreJoiner = Boolean(ourUuid && uuid === ourUuid);
|
||||
|
||||
if (weAreJoiner) {
|
||||
if (fromYou) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// Copyright 2021-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { makeEnumParser } from '../util/enum';
|
||||
|
@ -150,10 +150,12 @@ export const someSendStatus = (
|
|||
|
||||
export const isMessageJustForMe = (
|
||||
sendStateByConversationId: undefined | Readonly<SendStateByConversationId>,
|
||||
ourConversationId: string
|
||||
ourConversationId: string | undefined
|
||||
): boolean => {
|
||||
const conversationIds = Object.keys(sendStateByConversationId || {});
|
||||
return (
|
||||
conversationIds.length === 1 && conversationIds[0] === ourConversationId
|
||||
return Boolean(
|
||||
ourConversationId &&
|
||||
conversationIds.length === 1 &&
|
||||
conversationIds[0] === ourConversationId
|
||||
);
|
||||
};
|
||||
|
|
|
@ -389,7 +389,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
|||
},
|
||||
contactNameColorSelector: (
|
||||
conversationId: string,
|
||||
contactId: string
|
||||
contactId: string | undefined
|
||||
) => {
|
||||
const state = window.reduxStore.getState();
|
||||
const contactNameColorSelector = getContactNameColorSelector(state);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// Copyright 2019-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import type { DeepPartial, Store } from 'redux';
|
||||
import type { Store } from 'redux';
|
||||
import { applyMiddleware, createStore as reduxCreateStore } from 'redux';
|
||||
|
||||
import promise from 'redux-promise-middleware';
|
||||
|
@ -54,5 +54,5 @@ const middlewareList = [
|
|||
const enhancer = applyMiddleware(...middlewareList);
|
||||
|
||||
export const createStore = (
|
||||
initialState: DeepPartial<StateType>
|
||||
initialState: Readonly<StateType>
|
||||
): Store<StateType> => reduxCreateStore(reducer, initialState, enhancer);
|
||||
|
|
|
@ -48,7 +48,7 @@ function setActiveAudioID(
|
|||
|
||||
// Reducer
|
||||
|
||||
function getEmptyState(): AudioPlayerStateType {
|
||||
export function getEmptyState(): AudioPlayerStateType {
|
||||
return {
|
||||
activeAudioID: undefined,
|
||||
activeAudioContext: undefined,
|
||||
|
|
|
@ -205,7 +205,7 @@ function errorRecording(
|
|||
|
||||
// Reducer
|
||||
|
||||
function getEmptyState(): AudioPlayerStateType {
|
||||
export function getEmptyState(): AudioPlayerStateType {
|
||||
return {
|
||||
recordingState: RecordingState.Idle,
|
||||
};
|
||||
|
|
|
@ -82,12 +82,12 @@ function updateOrCreate(
|
|||
|
||||
// Reducer
|
||||
|
||||
export function getInitialState(): BadgesStateType {
|
||||
export function getEmptyState(): BadgesStateType {
|
||||
return { byId: {} };
|
||||
}
|
||||
|
||||
export function reducer(
|
||||
state: Readonly<BadgesStateType> = getInitialState(),
|
||||
state: Readonly<BadgesStateType> = getEmptyState(),
|
||||
action: Readonly<ImageFileDownloadedActionType | UpdateOrCreateActionType>
|
||||
): BadgesStateType {
|
||||
switch (action.type) {
|
||||
|
|
|
@ -832,11 +832,14 @@ function groupCallStateChange(
|
|||
didSomeoneStartPresenting = false;
|
||||
}
|
||||
|
||||
const { ourUuid } = getState().user;
|
||||
strictAssert(ourUuid, 'groupCallStateChange failed to fetch our uuid');
|
||||
|
||||
dispatch({
|
||||
type: GROUP_CALL_STATE_CHANGE,
|
||||
payload: {
|
||||
...payload,
|
||||
ourUuid: getState().user.ourUuid,
|
||||
ourUuid,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ export const actions = {
|
|||
|
||||
// Reducer
|
||||
|
||||
function getEmptyState(): ExpirationStateType {
|
||||
export function getEmptyState(): ExpirationStateType {
|
||||
return {
|
||||
hasExpired: false,
|
||||
};
|
||||
|
|
|
@ -274,7 +274,7 @@ function savePreferredLeftPaneWidth(
|
|||
|
||||
// Reducer
|
||||
|
||||
function getEmptyState(): ItemsStateType {
|
||||
export function getEmptyState(): ItemsStateType {
|
||||
return {
|
||||
defaultConversationColor: {
|
||||
color: ConversationColors[0],
|
||||
|
|
|
@ -200,12 +200,12 @@ function selectDraftEmojiToBeReplaced(
|
|||
|
||||
// Reducer
|
||||
|
||||
export function getInitialState(): PreferredReactionsStateType {
|
||||
export function getEmptyState(): PreferredReactionsStateType {
|
||||
return {};
|
||||
}
|
||||
|
||||
export function reducer(
|
||||
state: Readonly<PreferredReactionsStateType> = getInitialState(),
|
||||
state: Readonly<PreferredReactionsStateType> = getEmptyState(),
|
||||
action: Readonly<
|
||||
| CancelCustomizePreferredReactionsModalActionType
|
||||
| DeselectDraftEmojiActionType
|
||||
|
|
|
@ -157,7 +157,7 @@ export const actions = {
|
|||
toggleVerified,
|
||||
};
|
||||
|
||||
function getEmptyState(): SafetyNumberStateType {
|
||||
export function getEmptyState(): SafetyNumberStateType {
|
||||
return {
|
||||
contacts: {},
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// Copyright 2019-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { ThunkAction, ThunkDispatch } from 'redux-thunk';
|
||||
|
@ -24,6 +24,7 @@ import type {
|
|||
} from './conversations';
|
||||
import { getQuery, getSearchConversation } from '../selectors/search';
|
||||
import { getIntl, getUserConversationId } from '../selectors/user';
|
||||
import { strictAssert } from '../../util/assert';
|
||||
|
||||
const {
|
||||
searchConversations: dataSearchConversations,
|
||||
|
@ -157,11 +158,16 @@ function updateSearchTerm(
|
|||
});
|
||||
|
||||
const state = getState();
|
||||
const ourConversationId = getUserConversationId(state);
|
||||
strictAssert(
|
||||
ourConversationId,
|
||||
'updateSearchTerm our conversation is missing'
|
||||
);
|
||||
|
||||
doSearch({
|
||||
dispatch,
|
||||
noteToSelf: getIntl(state)('noteToSelf').toLowerCase(),
|
||||
ourConversationId: getUserConversationId(state),
|
||||
ourConversationId,
|
||||
query: getQuery(state),
|
||||
searchConversationId: getSearchConversation(state)?.id,
|
||||
});
|
||||
|
|
|
@ -324,7 +324,7 @@ async function doUseSticker(
|
|||
|
||||
// Reducer
|
||||
|
||||
function getEmptyState(): StickersStateType {
|
||||
export function getEmptyState(): StickersStateType {
|
||||
return {
|
||||
installedPack: null,
|
||||
packs: {},
|
||||
|
|
|
@ -123,7 +123,7 @@ export const actions = {
|
|||
|
||||
// Reducer
|
||||
|
||||
function getEmptyState(): UpdatesStateType {
|
||||
export function getEmptyState(): UpdatesStateType {
|
||||
return {
|
||||
dialogType: DialogType.None,
|
||||
didSnooze: false,
|
||||
|
|
|
@ -14,12 +14,12 @@ export type UserStateType = {
|
|||
attachmentsPath: string;
|
||||
stickersPath: string;
|
||||
tempPath: string;
|
||||
ourConversationId: string;
|
||||
ourDeviceId: number;
|
||||
ourUuid: UUIDStringType;
|
||||
ourNumber: string;
|
||||
ourConversationId: string | undefined;
|
||||
ourDeviceId: number | undefined;
|
||||
ourUuid: UUIDStringType | undefined;
|
||||
ourNumber: string | undefined;
|
||||
platform: string;
|
||||
regionCode: string;
|
||||
regionCode: string | undefined;
|
||||
i18n: LocalizerType;
|
||||
interactionMode: 'mouse' | 'keyboard';
|
||||
theme: ThemeType;
|
||||
|
|
108
ts/state/getInitialState.ts
Normal file
108
ts/state/getInitialState.ts
Normal file
|
@ -0,0 +1,108 @@
|
|||
// Copyright 2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { getEmptyState as accounts } from './ducks/accounts';
|
||||
import { getEmptyState as app } from './ducks/app';
|
||||
import { getEmptyState as audioPlayer } from './ducks/audioPlayer';
|
||||
import { getEmptyState as audioRecorder } from './ducks/audioRecorder';
|
||||
import { getEmptyState as calling } from './ducks/calling';
|
||||
import { getEmptyState as composer } from './ducks/composer';
|
||||
import { getEmptyState as conversations } from './ducks/conversations';
|
||||
import { getEmptyState as crashReports } from './ducks/crashReports';
|
||||
import { getEmptyState as expiration } from './ducks/expiration';
|
||||
import { getEmptyState as globalModals } from './ducks/globalModals';
|
||||
import { getEmptyState as linkPreviews } from './ducks/linkPreviews';
|
||||
import { getEmptyState as network } from './ducks/network';
|
||||
import { getEmptyState as preferredReactions } from './ducks/preferredReactions';
|
||||
import { getEmptyState as safetyNumber } from './ducks/safetyNumber';
|
||||
import { getEmptyState as search } from './ducks/search';
|
||||
import { getEmptyState as updates } from './ducks/updates';
|
||||
import { getEmptyState as user } from './ducks/user';
|
||||
|
||||
import type { StateType } from './reducer';
|
||||
|
||||
import type { BadgesStateType } from './ducks/badges';
|
||||
import { getInitialState as stickers } from '../types/Stickers';
|
||||
import { getEmojiReducerState as emojis } from '../util/loadRecentEmojis';
|
||||
|
||||
export function getInitialState({
|
||||
badges,
|
||||
}: {
|
||||
badges: BadgesStateType;
|
||||
}): StateType {
|
||||
const items = window.storage.getItemsState();
|
||||
|
||||
const convoCollection = window.getConversations();
|
||||
const formattedConversations = convoCollection.map(conversation =>
|
||||
conversation.format()
|
||||
);
|
||||
const ourNumber = window.textsecure.storage.user.getNumber();
|
||||
const ourUuid = window.textsecure.storage.user.getUuid()?.toString();
|
||||
const ourConversationId =
|
||||
window.ConversationController.getOurConversationId();
|
||||
const ourDeviceId = window.textsecure.storage.user.getDeviceId();
|
||||
|
||||
const themeSetting = window.Events.getThemeSetting();
|
||||
const theme = themeSetting === 'system' ? window.systemTheme : themeSetting;
|
||||
|
||||
return {
|
||||
accounts: accounts(),
|
||||
app: app(),
|
||||
audioPlayer: audioPlayer(),
|
||||
audioRecorder: audioRecorder(),
|
||||
badges,
|
||||
calling: calling(),
|
||||
composer: composer(),
|
||||
conversations: {
|
||||
...conversations(),
|
||||
conversationLookup: window.Signal.Util.makeLookup(
|
||||
formattedConversations,
|
||||
'id'
|
||||
),
|
||||
conversationsByE164: window.Signal.Util.makeLookup(
|
||||
formattedConversations,
|
||||
'e164'
|
||||
),
|
||||
conversationsByUuid: window.Signal.Util.makeLookup(
|
||||
formattedConversations,
|
||||
'uuid'
|
||||
),
|
||||
conversationsByGroupId: window.Signal.Util.makeLookup(
|
||||
formattedConversations,
|
||||
'groupId'
|
||||
),
|
||||
conversationsByUsername: window.Signal.Util.makeLookup(
|
||||
formattedConversations,
|
||||
'username'
|
||||
),
|
||||
},
|
||||
crashReports: crashReports(),
|
||||
emojis: emojis(),
|
||||
expiration: expiration(),
|
||||
globalModals: globalModals(),
|
||||
items,
|
||||
linkPreviews: linkPreviews(),
|
||||
network: network(),
|
||||
preferredReactions: preferredReactions(),
|
||||
safetyNumber: safetyNumber(),
|
||||
search: search(),
|
||||
stickers: stickers(),
|
||||
updates: updates(),
|
||||
user: {
|
||||
...user(),
|
||||
attachmentsPath: window.baseAttachmentsPath,
|
||||
stickersPath: window.baseStickersPath,
|
||||
tempPath: window.baseTempPath,
|
||||
regionCode: window.storage.get('regionCode'),
|
||||
ourConversationId,
|
||||
ourDeviceId,
|
||||
ourNumber,
|
||||
ourUuid,
|
||||
platform: window.platform,
|
||||
i18n: window.i18n,
|
||||
interactionMode: window.getInteractionMode(),
|
||||
theme,
|
||||
version: window.getVersion(),
|
||||
},
|
||||
};
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// Copyright 2020-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { createSelector } from 'reselect';
|
||||
|
@ -62,7 +62,12 @@ export const getIncomingCall = createSelector(
|
|||
getUserUuid,
|
||||
(
|
||||
callsByConversation: CallsByConversationType,
|
||||
ourUuid: UUIDStringType
|
||||
): undefined | DirectCallStateType | GroupCallStateType =>
|
||||
getIncomingCallHelper(callsByConversation, ourUuid)
|
||||
ourUuid: UUIDStringType | undefined
|
||||
): undefined | DirectCallStateType | GroupCallStateType => {
|
||||
if (!ourUuid) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getIncomingCallHelper(callsByConversation, ourUuid);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -365,9 +365,13 @@ export const getMe = createSelector(
|
|||
[getConversationLookup, getUserConversationId],
|
||||
(
|
||||
lookup: ConversationLookupType,
|
||||
ourConversationId: string
|
||||
ourConversationId: string | undefined
|
||||
): ConversationType => {
|
||||
return lookup[ourConversationId];
|
||||
if (!ourConversationId) {
|
||||
return getPlaceholderContact();
|
||||
}
|
||||
|
||||
return lookup[ourConversationId] || getPlaceholderContact();
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -654,8 +658,6 @@ export const getConversationSelector = createSelector(
|
|||
): GetConversationByIdType => {
|
||||
return (id?: string) => {
|
||||
if (!id) {
|
||||
log.warn(`getConversationSelector: Called with a falsey id ${id}`);
|
||||
// This will return a placeholder contact
|
||||
return selector(undefined);
|
||||
}
|
||||
|
||||
|
@ -714,10 +716,10 @@ const getCachedConversationMemberColorsSelector = createSelector(
|
|||
getUserConversationId,
|
||||
(
|
||||
conversationSelector: GetConversationByIdType,
|
||||
ourConversationId: string
|
||||
ourConversationId: string | undefined
|
||||
) => {
|
||||
return memoizee(
|
||||
(conversationId: string) => {
|
||||
(conversationId: string | undefined) => {
|
||||
const contactNameColors: Map<string, ContactNameColorType> = new Map();
|
||||
const {
|
||||
sortedGroupMembers = [],
|
||||
|
@ -726,7 +728,9 @@ const getCachedConversationMemberColorsSelector = createSelector(
|
|||
} = conversationSelector(conversationId);
|
||||
|
||||
if (type === 'direct') {
|
||||
contactNameColors.set(ourConversationId, ContactNameColors[0]);
|
||||
if (ourConversationId) {
|
||||
contactNameColors.set(ourConversationId, ContactNameColors[0]);
|
||||
}
|
||||
contactNameColors.set(theirId, ContactNameColors[0]);
|
||||
return contactNameColors;
|
||||
}
|
||||
|
@ -751,7 +755,7 @@ const getCachedConversationMemberColorsSelector = createSelector(
|
|||
|
||||
export type ContactNameColorSelectorType = (
|
||||
conversationId: string,
|
||||
contactId: string
|
||||
contactId: string | undefined
|
||||
) => ContactNameColorType;
|
||||
|
||||
export const getContactNameColorSelector = createSelector(
|
||||
|
@ -759,8 +763,13 @@ export const getContactNameColorSelector = createSelector(
|
|||
conversationMemberColorsSelector => {
|
||||
return (
|
||||
conversationId: string,
|
||||
contactId: string
|
||||
contactId: string | undefined
|
||||
): ContactNameColorType => {
|
||||
if (!contactId) {
|
||||
log.warn('No color generated for missing contactId');
|
||||
return ContactNameColors[0];
|
||||
}
|
||||
|
||||
const contactNameColors =
|
||||
conversationMemberColorsSelector(conversationId);
|
||||
const color = contactNameColors.get(contactId);
|
||||
|
@ -792,10 +801,10 @@ export const getMessageSelector = createSelector(
|
|||
messageLookup: MessageLookupType,
|
||||
selectedMessage: SelectedMessageType | undefined,
|
||||
conversationSelector: GetConversationByIdType,
|
||||
regionCode: string,
|
||||
ourNumber: string,
|
||||
ourUuid: UUIDStringType,
|
||||
ourConversationId: string,
|
||||
regionCode: string | undefined,
|
||||
ourNumber: string | undefined,
|
||||
ourUuid: UUIDStringType | undefined,
|
||||
ourConversationId: string | undefined,
|
||||
callSelector: CallSelectorType,
|
||||
activeCall: undefined | CallStateType,
|
||||
accountSelector: AccountSelectorType,
|
||||
|
|
|
@ -104,12 +104,12 @@ type PropsForUnsupportedMessage = {
|
|||
|
||||
export type GetPropsForBubbleOptions = Readonly<{
|
||||
conversationSelector: GetConversationByIdType;
|
||||
ourConversationId: string;
|
||||
ourConversationId?: string;
|
||||
ourNumber?: string;
|
||||
ourUuid: UUIDStringType;
|
||||
ourUuid?: UUIDStringType;
|
||||
selectedMessageId?: string;
|
||||
selectedMessageCounter?: number;
|
||||
regionCode: string;
|
||||
regionCode?: string;
|
||||
callSelector: CallSelectorType;
|
||||
activeCall?: CallStateType;
|
||||
accountSelector: AccountSelectorType;
|
||||
|
@ -195,7 +195,7 @@ export function getContactId(
|
|||
ourNumber,
|
||||
ourUuid,
|
||||
}: GetContactOptions
|
||||
): string {
|
||||
): string | undefined {
|
||||
const source = getSource(message, ourNumber);
|
||||
const sourceUuid = getSourceUuid(message, ourUuid);
|
||||
|
||||
|
@ -1286,7 +1286,7 @@ export function getMessagePropStatus(
|
|||
MessageWithUIFieldsType,
|
||||
'type' | 'errors' | 'sendStateByConversationId'
|
||||
>,
|
||||
ourConversationId: string
|
||||
ourConversationId: string | undefined
|
||||
): LastMessageStatus | undefined {
|
||||
if (!isOutgoing(message)) {
|
||||
return undefined;
|
||||
|
@ -1298,7 +1298,10 @@ export function getMessagePropStatus(
|
|||
|
||||
const { sendStateByConversationId = {} } = message;
|
||||
|
||||
if (isMessageJustForMe(sendStateByConversationId, ourConversationId)) {
|
||||
if (
|
||||
ourConversationId &&
|
||||
isMessageJustForMe(sendStateByConversationId, ourConversationId)
|
||||
) {
|
||||
const status =
|
||||
sendStateByConversationId[ourConversationId]?.status ??
|
||||
SendStatus.Pending;
|
||||
|
@ -1313,7 +1316,9 @@ export function getMessagePropStatus(
|
|||
}
|
||||
|
||||
const sendStates = Object.values(
|
||||
omit(sendStateByConversationId, ourConversationId)
|
||||
ourConversationId
|
||||
? omit(sendStateByConversationId, ourConversationId)
|
||||
: sendStateByConversationId
|
||||
);
|
||||
const highestSuccessfulStatus = sendStates.reduce(
|
||||
(result: SendStatus, { status }) => maxStatus(result, status),
|
||||
|
@ -1343,7 +1348,7 @@ export function getMessagePropStatus(
|
|||
|
||||
export function getPropsForEmbeddedContact(
|
||||
message: MessageWithUIFieldsType,
|
||||
regionCode: string,
|
||||
regionCode: string | undefined,
|
||||
accountSelector: (identifier?: string) => boolean
|
||||
): EmbeddedContactType | undefined {
|
||||
const contacts = message.contact;
|
||||
|
@ -1427,7 +1432,7 @@ function canReplyOrReact(
|
|||
MessageWithUIFieldsType,
|
||||
'deletedForEveryone' | 'sendStateByConversationId' | 'type'
|
||||
>,
|
||||
ourConversationId: string,
|
||||
ourConversationId: string | undefined,
|
||||
conversation: undefined | Readonly<ConversationType>
|
||||
): boolean {
|
||||
const { deletedForEveryone, sendStateByConversationId } = message;
|
||||
|
@ -1455,7 +1460,12 @@ function canReplyOrReact(
|
|||
if (isOutgoing(message)) {
|
||||
return (
|
||||
isMessageJustForMe(sendStateByConversationId, ourConversationId) ||
|
||||
someSendStatus(omit(sendStateByConversationId, ourConversationId), isSent)
|
||||
someSendStatus(
|
||||
ourConversationId
|
||||
? omit(sendStateByConversationId, ourConversationId)
|
||||
: sendStateByConversationId,
|
||||
isSent
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1475,7 +1485,7 @@ export function canReply(
|
|||
| 'sendStateByConversationId'
|
||||
| 'type'
|
||||
>,
|
||||
ourConversationId: string,
|
||||
ourConversationId: string | undefined,
|
||||
conversationSelector: GetConversationByIdType
|
||||
): boolean {
|
||||
const conversation = getConversation(message, conversationSelector);
|
||||
|
@ -1496,7 +1506,7 @@ export function canReact(
|
|||
| 'sendStateByConversationId'
|
||||
| 'type'
|
||||
>,
|
||||
ourConversationId: string,
|
||||
ourConversationId: string | undefined,
|
||||
conversationSelector: GetConversationByIdType
|
||||
): boolean {
|
||||
const conversation = getConversation(message, conversationSelector);
|
||||
|
|
|
@ -211,7 +211,7 @@ export const getMessageSearchResultSelector = createSelector(
|
|||
selectedMessageId: string | undefined,
|
||||
conversationSelector: GetConversationByIdType,
|
||||
searchConversationId: string | undefined,
|
||||
ourConversationId: string
|
||||
ourConversationId: string | undefined
|
||||
): GetMessageSearchResultByIdType => {
|
||||
return (id: string) => {
|
||||
const message = messageSearchResultLookup[id];
|
||||
|
|
|
@ -15,27 +15,27 @@ export const getUser = (state: StateType): UserStateType => state.user;
|
|||
|
||||
export const getUserNumber = createSelector(
|
||||
getUser,
|
||||
(state: UserStateType): string => state.ourNumber
|
||||
(state: UserStateType): string | undefined => state.ourNumber
|
||||
);
|
||||
|
||||
export const getUserDeviceId = createSelector(
|
||||
getUser,
|
||||
(state: UserStateType): number => state.ourDeviceId
|
||||
(state: UserStateType): number | undefined => state.ourDeviceId
|
||||
);
|
||||
|
||||
export const getRegionCode = createSelector(
|
||||
getUser,
|
||||
(state: UserStateType): string => state.regionCode
|
||||
(state: UserStateType): string | undefined => state.regionCode
|
||||
);
|
||||
|
||||
export const getUserConversationId = createSelector(
|
||||
getUser,
|
||||
(state: UserStateType): string => state.ourConversationId
|
||||
(state: UserStateType): string | undefined => state.ourConversationId
|
||||
);
|
||||
|
||||
export const getUserUuid = createSelector(
|
||||
getUser,
|
||||
(state: UserStateType): UUIDStringType => state.ourUuid
|
||||
(state: UserStateType): UUIDStringType | undefined => state.ourUuid
|
||||
);
|
||||
|
||||
export const getIntl = createSelector(
|
||||
|
|
|
@ -7,7 +7,7 @@ import { memoize } from 'lodash';
|
|||
import { mapDispatchToProps } from '../actions';
|
||||
import { CallManager } from '../../components/CallManager';
|
||||
import { calling as callingService } from '../../services/calling';
|
||||
import { getUserUuid, getIntl, getTheme } from '../selectors/user';
|
||||
import { getIntl, getTheme } from '../selectors/user';
|
||||
import { getMe, getConversationSelector } from '../selectors/conversations';
|
||||
import { getActiveCall } from '../ducks/calling';
|
||||
import type { ConversationType } from '../ducks/conversations';
|
||||
|
@ -323,12 +323,7 @@ const mapStateToProps = (state: StateType) => ({
|
|||
i18n: getIntl(state),
|
||||
isGroupCallOutboundRingEnabled: isGroupCallOutboundRingEnabled(),
|
||||
incomingCall: mapStateToIncomingCallProp(state),
|
||||
me: {
|
||||
...getMe(state),
|
||||
// `getMe` returns a `ConversationType` which might not have a UUID, at least
|
||||
// according to the type. This ensures one is set.
|
||||
uuid: getUserUuid(state),
|
||||
},
|
||||
me: getMe(state),
|
||||
notifyForCall,
|
||||
playRingtone,
|
||||
stopRingtone,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// Copyright 2020-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -21,6 +21,7 @@ import { getUserUuid, getIntl, getTheme } from '../selectors/user';
|
|||
import { getOwn } from '../../util/getOwn';
|
||||
import { missingCaseError } from '../../util/missingCaseError';
|
||||
import { isConversationSMSOnly } from '../../util/isConversationSMSOnly';
|
||||
import { strictAssert } from '../../util/assert';
|
||||
|
||||
export type OwnProps = {
|
||||
id: string;
|
||||
|
@ -46,6 +47,8 @@ const getOutgoingCallButtonStyle = (
|
|||
state: StateType
|
||||
): OutgoingCallButtonStyle => {
|
||||
const { calling } = state;
|
||||
const ourUuid = getUserUuid(state);
|
||||
strictAssert(ourUuid, 'getOutgoingCallButtonStyle missing our uuid');
|
||||
|
||||
if (getActiveCall(calling)) {
|
||||
return OutgoingCallButtonStyle.None;
|
||||
|
@ -61,7 +64,7 @@ const getOutgoingCallButtonStyle = (
|
|||
const call = getOwn(calling.callsByConversation, conversation.id);
|
||||
if (
|
||||
call?.callMode === CallMode.Group &&
|
||||
isAnybodyElseInGroupCall(call.peekInfo, getUserUuid(state))
|
||||
isAnybodyElseInGroupCall(call.peekInfo, ourUuid)
|
||||
) {
|
||||
return OutgoingCallButtonStyle.Join;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// Copyright 2021-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
|
|
@ -222,6 +222,20 @@ describe('message send state utilities', () => {
|
|||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('returns false if the message is for you but we have no conversationId', () => {
|
||||
assert.isFalse(
|
||||
isMessageJustForMe(
|
||||
{
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: 123,
|
||||
},
|
||||
},
|
||||
undefined
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sendStateReducer', () => {
|
||||
|
|
|
@ -10,7 +10,7 @@ import { noopAction } from '../../../state/ducks/noop';
|
|||
import type { PreferredReactionsStateType } from '../../../state/ducks/preferredReactions';
|
||||
import {
|
||||
actions,
|
||||
getInitialState,
|
||||
getEmptyState,
|
||||
reducer,
|
||||
} from '../../../state/ducks/preferredReactions';
|
||||
|
||||
|
@ -26,7 +26,7 @@ describe('preferred reactions duck', () => {
|
|||
});
|
||||
|
||||
const stateWithOpenCustomizationModal = {
|
||||
...getInitialState(),
|
||||
...getEmptyState(),
|
||||
customizePreferredReactionsModal: {
|
||||
draftPreferredReactions: ['✨', '❇️', '🎇', '🦈', '💖', '🅿️'],
|
||||
originalPreferredReactions: ['💙', '👍', '👎', '😂', '😮', '😢'],
|
||||
|
@ -59,7 +59,7 @@ describe('preferred reactions duck', () => {
|
|||
|
||||
it("does nothing if the modal isn't open", () => {
|
||||
const action = cancelCustomizePreferredReactionsModal();
|
||||
const result = reducer(getInitialState(), action);
|
||||
const result = reducer(getEmptyState(), action);
|
||||
|
||||
assert.notProperty(result, 'customizePreferredReactionsModal');
|
||||
});
|
||||
|
@ -76,7 +76,7 @@ describe('preferred reactions duck', () => {
|
|||
const { deselectDraftEmoji } = actions;
|
||||
|
||||
it('is a no-op if the customization modal is not open', () => {
|
||||
const state = getInitialState();
|
||||
const state = getEmptyState();
|
||||
const action = deselectDraftEmoji();
|
||||
const result = reducer(state, action);
|
||||
|
||||
|
@ -167,7 +167,7 @@ describe('preferred reactions duck', () => {
|
|||
const { replaceSelectedDraftEmoji } = actions;
|
||||
|
||||
it('is a no-op if the customization modal is not open', () => {
|
||||
const state = getInitialState();
|
||||
const state = getEmptyState();
|
||||
const action = replaceSelectedDraftEmoji('🦈');
|
||||
const result = reducer(state, action);
|
||||
|
||||
|
@ -350,7 +350,7 @@ describe('preferred reactions duck', () => {
|
|||
};
|
||||
|
||||
it("does nothing if the modal isn't open", () => {
|
||||
const result = reducer(getInitialState(), action);
|
||||
const result = reducer(getEmptyState(), action);
|
||||
|
||||
assert.notProperty(result, 'customizePreferredReactionsModal');
|
||||
});
|
||||
|
@ -404,7 +404,7 @@ describe('preferred reactions duck', () => {
|
|||
};
|
||||
|
||||
it("does nothing if the modal isn't open", () => {
|
||||
const state = getInitialState();
|
||||
const state = getEmptyState();
|
||||
const result = reducer(state, action);
|
||||
|
||||
assert.strictEqual(result, state);
|
||||
|
@ -428,7 +428,7 @@ describe('preferred reactions duck', () => {
|
|||
const { selectDraftEmojiToBeReplaced } = actions;
|
||||
|
||||
it('is a no-op if the customization modal is not open', () => {
|
||||
const state = getInitialState();
|
||||
const state = getEmptyState();
|
||||
const action = selectDraftEmojiToBeReplaced(2);
|
||||
const result = reducer(state, action);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// Copyright 2019-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { omit } from 'lodash';
|
||||
|
@ -86,7 +86,7 @@ const DEFAULT_ADDRESS_TYPE = Proto.DataMessage.Contact.PostalAddress.Type.HOME;
|
|||
export function embeddedContactSelector(
|
||||
contact: EmbeddedContactType,
|
||||
options: {
|
||||
regionCode: string;
|
||||
regionCode?: string;
|
||||
firstNumber?: string;
|
||||
isNumberOnSignal?: boolean;
|
||||
getAbsoluteAttachmentPath: (path: string) => string;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// Copyright 2019-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { isNumber, pick, reject, groupBy, values } from 'lodash';
|
||||
|
@ -23,6 +23,7 @@ import type {
|
|||
import Data from '../sql/Client';
|
||||
import { SignalService as Proto } from '../protobuf';
|
||||
import * as log from '../logging/log';
|
||||
import type { StickersStateType } from '../state/ducks/stickers';
|
||||
|
||||
export type RecentStickerType = Readonly<{
|
||||
stickerId: number;
|
||||
|
@ -31,12 +32,6 @@ export type RecentStickerType = Readonly<{
|
|||
|
||||
export type BlessedType = Pick<StickerPackType, 'key' | 'status'>;
|
||||
|
||||
export type InitialState = {
|
||||
packs: Record<string, StickerPackType>;
|
||||
recentStickers: Array<RecentStickerType>;
|
||||
blessedPacks: Record<string, boolean>;
|
||||
};
|
||||
|
||||
export type DownloadMap = Record<
|
||||
string,
|
||||
{
|
||||
|
@ -85,7 +80,7 @@ const STICKER_PACK_DEFAULTS: StickerPackType = {
|
|||
|
||||
const VALID_PACK_ID_REGEXP = /^[0-9a-f]{32}$/i;
|
||||
|
||||
let initialState: InitialState | undefined;
|
||||
let initialState: StickersStateType | undefined;
|
||||
let packsToDownload: DownloadMap | undefined;
|
||||
const downloadQueue = new Queue({ concurrency: 1, timeout: 1000 * 60 * 2 });
|
||||
|
||||
|
@ -104,6 +99,7 @@ export async function load(): Promise<void> {
|
|||
packs,
|
||||
recentStickers,
|
||||
blessedPacks,
|
||||
installedPack: null,
|
||||
};
|
||||
|
||||
packsToDownload = capturePacksToDownload(packs);
|
||||
|
@ -269,7 +265,7 @@ async function getRecentStickersForRedux(): Promise<Array<RecentStickerType>> {
|
|||
}));
|
||||
}
|
||||
|
||||
export function getInitialState(): InitialState {
|
||||
export function getInitialState(): StickersStateType {
|
||||
strictAssert(initialState !== undefined, 'Stickers not initialized');
|
||||
return initialState;
|
||||
}
|
||||
|
|
|
@ -6401,7 +6401,7 @@
|
|||
{
|
||||
"rule": "jQuery-wrap(",
|
||||
"path": "node_modules/regenerator-runtime/runtime.js",
|
||||
"line": " wrap(innerFn, outerFn, self, tryLocsList)",
|
||||
"line": " wrap(innerFn, outerFn, self, tryLocsList),",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2019-12-11T01:10:06.091Z"
|
||||
},
|
||||
|
@ -7817,13 +7817,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-22T00:52:39.251Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/jobs/helpers/syncHelpers.ts",
|
||||
"line": " await window.ConversationController.load();",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-11-04T16:14:03.477Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/jobs/conversationJobQueue.ts",
|
||||
|
@ -7838,6 +7831,13 @@
|
|||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-11-04T16:14:03.477Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/jobs/helpers/syncHelpers.ts",
|
||||
"line": " await window.ConversationController.load();",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-11-04T16:14:03.477Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "ts/logging/uploadDebugLog.ts",
|
||||
|
@ -8080,4 +8080,4 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-17T21:02:59.414Z"
|
||||
}
|
||||
]
|
||||
]
|
26
yarn.lock
26
yarn.lock
|
@ -933,6 +933,13 @@
|
|||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.9.2":
|
||||
version "7.17.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941"
|
||||
integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/template@^7.1.0", "@babel/template@^7.12.13", "@babel/template@^7.16.0", "@babel/template@^7.4.4":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6"
|
||||
|
@ -12677,13 +12684,12 @@ redux-ts-utils@3.2.2:
|
|||
dependencies:
|
||||
immer "^2.0.0"
|
||||
|
||||
redux@4.0.2, redux@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.2.tgz#597cc660a99f91412e31c96c3da10ed8ace0715d"
|
||||
integrity sha512-oAiFLWYQhbpSvzjcVfgQ90MlZ0u6uDIHFK41Q0/BnCfjEg96SACzwUFwDVUKz/LP/SwJORGaFY8AM5wOB/zf0A==
|
||||
redux@4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104"
|
||||
integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==
|
||||
dependencies:
|
||||
loose-envify "^1.4.0"
|
||||
symbol-observable "^1.2.0"
|
||||
"@babel/runtime" "^7.9.2"
|
||||
|
||||
redux@^3.6.0:
|
||||
version "3.7.2"
|
||||
|
@ -12695,6 +12701,14 @@ redux@^3.6.0:
|
|||
loose-envify "^1.1.0"
|
||||
symbol-observable "^1.0.3"
|
||||
|
||||
redux@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.2.tgz#597cc660a99f91412e31c96c3da10ed8ace0715d"
|
||||
integrity sha512-oAiFLWYQhbpSvzjcVfgQ90MlZ0u6uDIHFK41Q0/BnCfjEg96SACzwUFwDVUKz/LP/SwJORGaFY8AM5wOB/zf0A==
|
||||
dependencies:
|
||||
loose-envify "^1.4.0"
|
||||
symbol-observable "^1.2.0"
|
||||
|
||||
refractor@^2.4.1:
|
||||
version "2.10.0"
|
||||
resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.10.0.tgz#4cc7efc0028a87924a9b31d82d129dec831a287b"
|
||||
|
|
Loading…
Add table
Reference in a new issue