Introduce Service Id Types
Co-authored-by: Scott Nonnenberg <scott@signal.org>
This commit is contained in:

committed by
Jamie Kyle

parent
414c0a58d3
commit
366b875fd2
@@ -9,8 +9,8 @@ import * as log from '../../logging/log';
|
||||
|
||||
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||
import type { StateType as RootStateType } from '../reducer';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import { getUuidsForE164s } from '../../util/getUuidsForE164s';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
import { getServiceIdsForE164s } from '../../util/getServiceIdsForE164s';
|
||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||
|
||||
import type { NoopActionType } from './noop';
|
||||
@@ -18,7 +18,7 @@ import type { NoopActionType } from './noop';
|
||||
// State
|
||||
|
||||
export type AccountsStateType = ReadonlyDeep<{
|
||||
accounts: Record<string, UUIDStringType | undefined>;
|
||||
accounts: Record<string, ServiceIdString | undefined>;
|
||||
}>;
|
||||
|
||||
// Actions
|
||||
@@ -27,7 +27,7 @@ type AccountUpdateActionType = ReadonlyDeep<{
|
||||
type: 'accounts/UPDATE';
|
||||
payload: {
|
||||
phoneNumber: string;
|
||||
uuid?: UUIDStringType;
|
||||
serviceId?: ServiceIdString;
|
||||
};
|
||||
}>;
|
||||
|
||||
@@ -64,13 +64,13 @@ function checkForAccount(
|
||||
const conversation = window.ConversationController.get(phoneNumber);
|
||||
if (conversation && conversation.get('uuid')) {
|
||||
log.info(`checkForAccount: found ${phoneNumber} in existing contacts`);
|
||||
const uuid = conversation.get('uuid');
|
||||
const serviceId = conversation.get('uuid');
|
||||
|
||||
dispatch({
|
||||
type: 'accounts/UPDATE',
|
||||
payload: {
|
||||
phoneNumber,
|
||||
uuid,
|
||||
serviceId,
|
||||
},
|
||||
});
|
||||
return;
|
||||
@@ -89,11 +89,11 @@ function checkForAccount(
|
||||
return;
|
||||
}
|
||||
|
||||
let uuid: UUIDStringType | undefined;
|
||||
let serviceId: ServiceIdString | undefined;
|
||||
|
||||
log.info(`checkForAccount: looking ${phoneNumber} up on server`);
|
||||
try {
|
||||
const uuidLookup = await getUuidsForE164s(server, [phoneNumber]);
|
||||
const uuidLookup = await getServiceIdsForE164s(server, [phoneNumber]);
|
||||
const maybePair = uuidLookup.get(phoneNumber);
|
||||
|
||||
if (maybePair) {
|
||||
@@ -104,7 +104,7 @@ function checkForAccount(
|
||||
e164: phoneNumber,
|
||||
reason: 'checkForAccount',
|
||||
});
|
||||
uuid = maybeMerged.get('uuid');
|
||||
serviceId = maybeMerged.get('uuid');
|
||||
}
|
||||
} catch (error) {
|
||||
log.error('checkForAccount:', Errors.toLogFormat(error));
|
||||
@@ -114,7 +114,7 @@ function checkForAccount(
|
||||
type: 'accounts/UPDATE',
|
||||
payload: {
|
||||
phoneNumber,
|
||||
uuid,
|
||||
serviceId,
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -138,13 +138,13 @@ export function reducer(
|
||||
|
||||
if (action.type === 'accounts/UPDATE') {
|
||||
const { payload } = action;
|
||||
const { phoneNumber, uuid } = payload;
|
||||
const { phoneNumber, serviceId } = payload;
|
||||
|
||||
return {
|
||||
...state,
|
||||
accounts: {
|
||||
...state.accounts,
|
||||
[phoneNumber]: uuid,
|
||||
[phoneNumber]: serviceId,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@ import { requestCameraPermissions } from '../../util/callingPermissions';
|
||||
import { isGroupCallOutboundRingEnabled } from '../../util/isGroupCallOutboundRingEnabled';
|
||||
import { sleep } from '../../util/sleep';
|
||||
import { LatestQueue } from '../../util/LatestQueue';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { AciString } from '../../types/ServiceId';
|
||||
import type {
|
||||
ConversationChangedActionType,
|
||||
ConversationRemovedActionType,
|
||||
@@ -60,8 +60,8 @@ import { isAnybodyElseInGroupCall } from './callingHelpers';
|
||||
// State
|
||||
|
||||
export type GroupCallPeekInfoType = ReadonlyDeep<{
|
||||
uuids: Array<UUIDStringType>;
|
||||
creatorUuid?: UUIDStringType;
|
||||
acis: Array<AciString>;
|
||||
creatorAci?: AciString;
|
||||
eraId?: string;
|
||||
maxDevices: number;
|
||||
deviceCount: number;
|
||||
@@ -69,7 +69,7 @@ export type GroupCallPeekInfoType = ReadonlyDeep<{
|
||||
|
||||
// eslint-disable-next-line local-rules/type-alias-readonlydeep
|
||||
export type GroupCallParticipantInfoType = {
|
||||
uuid: UUIDStringType;
|
||||
aci: AciString;
|
||||
demuxId: number;
|
||||
hasRemoteAudio: boolean;
|
||||
hasRemoteVideo: boolean;
|
||||
@@ -94,11 +94,11 @@ export type DirectCallStateType = {
|
||||
type GroupCallRingStateType = ReadonlyDeep<
|
||||
| {
|
||||
ringId?: undefined;
|
||||
ringerUuid?: undefined;
|
||||
ringerAci?: undefined;
|
||||
}
|
||||
| {
|
||||
ringId: bigint;
|
||||
ringerUuid: UUIDStringType;
|
||||
ringerAci: AciString;
|
||||
}
|
||||
>;
|
||||
|
||||
@@ -125,7 +125,7 @@ export type ActiveCallStateType = {
|
||||
pip: boolean;
|
||||
presentingSource?: PresentedSource;
|
||||
presentingSourcesAvailable?: Array<PresentableSource>;
|
||||
safetyNumberChangedUuids: Array<UUIDStringType>;
|
||||
safetyNumberChangedAcis: Array<AciString>;
|
||||
settingsDialogOpen: boolean;
|
||||
showNeedsScreenRecordingPermissionsWarning?: boolean;
|
||||
showParticipantsList: boolean;
|
||||
@@ -181,7 +181,7 @@ type GroupCallStateChangeArgumentType = {
|
||||
// eslint-disable-next-line local-rules/type-alias-readonlydeep
|
||||
type GroupCallStateChangeActionPayloadType =
|
||||
GroupCallStateChangeArgumentType & {
|
||||
ourUuid: UUIDStringType;
|
||||
ourAci: AciString;
|
||||
};
|
||||
|
||||
type HangUpActionPayloadType = ReadonlyDeep<{
|
||||
@@ -189,7 +189,7 @@ type HangUpActionPayloadType = ReadonlyDeep<{
|
||||
}>;
|
||||
|
||||
type KeyChangedType = ReadonlyDeep<{
|
||||
uuid: UUIDStringType;
|
||||
aci: AciString;
|
||||
}>;
|
||||
|
||||
export type KeyChangeOkType = ReadonlyDeep<{
|
||||
@@ -204,7 +204,7 @@ export type IncomingDirectCallType = ReadonlyDeep<{
|
||||
type IncomingGroupCallType = ReadonlyDeep<{
|
||||
conversationId: string;
|
||||
ringId: bigint;
|
||||
ringerUuid: UUIDStringType;
|
||||
ringerAci: AciString;
|
||||
}>;
|
||||
|
||||
type PeekNotConnectedGroupCallType = ReadonlyDeep<{
|
||||
@@ -296,7 +296,7 @@ const getGroupCallRingState = (
|
||||
): GroupCallRingStateType =>
|
||||
call?.ringId === undefined
|
||||
? {}
|
||||
: { ringId: call.ringId, ringerUuid: call.ringerUuid };
|
||||
: { ringId: call.ringId, ringerAci: call.ringerAci };
|
||||
|
||||
// We might call this function many times in rapid succession (for example, if lots of
|
||||
// people are joining and leaving at once). We want to make sure to update eventually
|
||||
@@ -501,7 +501,7 @@ type IncomingGroupCallActionType = ReadonlyDeep<{
|
||||
type KeyChangedActionType = {
|
||||
type: 'calling/MARK_CALL_UNTRUSTED';
|
||||
payload: {
|
||||
safetyNumberChangedUuids: Array<UUIDStringType>;
|
||||
safetyNumberChangedAcis: Array<AciString>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -864,14 +864,14 @@ function groupCallStateChange(
|
||||
didSomeoneStartPresenting = false;
|
||||
}
|
||||
|
||||
const { ourACI: ourUuid } = getState().user;
|
||||
strictAssert(ourUuid, 'groupCallStateChange failed to fetch our uuid');
|
||||
const { ourAci } = getState().user;
|
||||
strictAssert(ourAci, 'groupCallStateChange failed to fetch our ACI');
|
||||
|
||||
dispatch({
|
||||
type: GROUP_CALL_STATE_CHANGE,
|
||||
payload: {
|
||||
...payload,
|
||||
ourUuid,
|
||||
ourAci,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -928,23 +928,23 @@ function keyChanged(
|
||||
}
|
||||
|
||||
if (activeCall.callMode === CallMode.Group) {
|
||||
const uuidsChanged = new Set(activeCallState.safetyNumberChangedUuids);
|
||||
const acisChanged = new Set(activeCallState.safetyNumberChangedAcis);
|
||||
|
||||
// Iterate over each participant to ensure that the uuid passed in
|
||||
// matches one of the participants in the group call.
|
||||
activeCall.remoteParticipants.forEach(participant => {
|
||||
if (participant.uuid === payload.uuid) {
|
||||
uuidsChanged.add(participant.uuid);
|
||||
if (participant.aci === payload.aci) {
|
||||
acisChanged.add(participant.aci);
|
||||
}
|
||||
});
|
||||
|
||||
const safetyNumberChangedUuids = Array.from(uuidsChanged);
|
||||
const safetyNumberChangedAcis = Array.from(acisChanged);
|
||||
|
||||
if (safetyNumberChangedUuids.length) {
|
||||
if (safetyNumberChangedAcis.length) {
|
||||
dispatch({
|
||||
type: MARK_CALL_UNTRUSTED,
|
||||
payload: {
|
||||
safetyNumberChangedUuids,
|
||||
safetyNumberChangedAcis,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1244,14 +1244,14 @@ function onOutgoingVideoCallInConversation(
|
||||
);
|
||||
|
||||
// technically not necessary, but isAnybodyElseInGroupCall requires it
|
||||
const ourUuid = window.storage.user.getCheckedUuid().toString();
|
||||
const ourAci = window.storage.user.getCheckedAci();
|
||||
|
||||
const isOngoingGroupCall =
|
||||
call &&
|
||||
ourUuid &&
|
||||
ourAci &&
|
||||
call.callMode === CallMode.Group &&
|
||||
call.peekInfo &&
|
||||
isAnybodyElseInGroupCall(call.peekInfo, ourUuid);
|
||||
isAnybodyElseInGroupCall(call.peekInfo, ourAci);
|
||||
|
||||
if (!isOngoingGroupCall) {
|
||||
dispatch({
|
||||
@@ -1583,7 +1583,7 @@ export function reducer(
|
||||
joinState: action.payload.joinState,
|
||||
peekInfo: action.payload.peekInfo ||
|
||||
existingCall?.peekInfo || {
|
||||
uuids: action.payload.remoteParticipants.map(({ uuid }) => uuid),
|
||||
acis: action.payload.remoteParticipants.map(({ aci }) => aci),
|
||||
maxDevices: Infinity,
|
||||
deviceCount: action.payload.remoteParticipants.length,
|
||||
},
|
||||
@@ -1593,7 +1593,7 @@ export function reducer(
|
||||
outgoingRing =
|
||||
isGroupCallOutboundRingEnabled() &&
|
||||
!ringState.ringId &&
|
||||
!call.peekInfo?.uuids.length &&
|
||||
!call.peekInfo?.acis.length &&
|
||||
!call.remoteParticipants.length &&
|
||||
!action.payload.isConversationTooBigToRing;
|
||||
break;
|
||||
@@ -1615,7 +1615,7 @@ export function reducer(
|
||||
localAudioLevel: 0,
|
||||
viewMode: CallViewMode.Grid,
|
||||
pip: false,
|
||||
safetyNumberChangedUuids: [],
|
||||
safetyNumberChangedAcis: [],
|
||||
settingsDialogOpen: false,
|
||||
showParticipantsList: false,
|
||||
outgoingRing,
|
||||
@@ -1643,7 +1643,7 @@ export function reducer(
|
||||
localAudioLevel: 0,
|
||||
viewMode: CallViewMode.Grid,
|
||||
pip: false,
|
||||
safetyNumberChangedUuids: [],
|
||||
safetyNumberChangedAcis: [],
|
||||
settingsDialogOpen: false,
|
||||
showParticipantsList: false,
|
||||
outgoingRing: true,
|
||||
@@ -1666,7 +1666,7 @@ export function reducer(
|
||||
localAudioLevel: 0,
|
||||
viewMode: CallViewMode.Grid,
|
||||
pip: false,
|
||||
safetyNumberChangedUuids: [],
|
||||
safetyNumberChangedAcis: [],
|
||||
settingsDialogOpen: false,
|
||||
showParticipantsList: false,
|
||||
outgoingRing: false,
|
||||
@@ -1706,7 +1706,7 @@ export function reducer(
|
||||
...state,
|
||||
callsByConversation: {
|
||||
...callsByConversation,
|
||||
[conversationId]: omit(groupCall, ['ringId', 'ringerUuid']),
|
||||
[conversationId]: omit(groupCall, ['ringId', 'ringerAci']),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1755,12 +1755,12 @@ export function reducer(
|
||||
}
|
||||
|
||||
if (action.type === INCOMING_GROUP_CALL) {
|
||||
const { conversationId, ringId, ringerUuid } = action.payload;
|
||||
const { conversationId, ringId, ringerAci } = action.payload;
|
||||
|
||||
let groupCall: GroupCallStateType;
|
||||
const existingGroupCall = getGroupCall(conversationId, state);
|
||||
if (existingGroupCall) {
|
||||
if (existingGroupCall.ringerUuid) {
|
||||
if (existingGroupCall.ringerAci) {
|
||||
log.info('Group call was already ringing');
|
||||
return state;
|
||||
}
|
||||
@@ -1772,7 +1772,7 @@ export function reducer(
|
||||
groupCall = {
|
||||
...existingGroupCall,
|
||||
ringId,
|
||||
ringerUuid,
|
||||
ringerAci,
|
||||
};
|
||||
} else {
|
||||
groupCall = {
|
||||
@@ -1781,13 +1781,13 @@ export function reducer(
|
||||
connectionState: GroupCallConnectionState.NotConnected,
|
||||
joinState: GroupCallJoinState.NotJoined,
|
||||
peekInfo: {
|
||||
uuids: [],
|
||||
acis: [],
|
||||
maxDevices: Infinity,
|
||||
deviceCount: 0,
|
||||
},
|
||||
remoteParticipants: [],
|
||||
ringId,
|
||||
ringerUuid,
|
||||
ringerAci,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1820,7 +1820,7 @@ export function reducer(
|
||||
localAudioLevel: 0,
|
||||
viewMode: CallViewMode.Grid,
|
||||
pip: false,
|
||||
safetyNumberChangedUuids: [],
|
||||
safetyNumberChangedAcis: [],
|
||||
settingsDialogOpen: false,
|
||||
showParticipantsList: false,
|
||||
outgoingRing: true,
|
||||
@@ -1929,7 +1929,7 @@ export function reducer(
|
||||
hasLocalAudio,
|
||||
hasLocalVideo,
|
||||
joinState,
|
||||
ourUuid,
|
||||
ourAci,
|
||||
peekInfo,
|
||||
remoteParticipants,
|
||||
} = action.payload;
|
||||
@@ -1939,7 +1939,7 @@ export function reducer(
|
||||
|
||||
const newPeekInfo = peekInfo ||
|
||||
existingCall?.peekInfo || {
|
||||
uuids: remoteParticipants.map(({ uuid }) => uuid),
|
||||
acis: remoteParticipants.map(({ aci }) => aci),
|
||||
maxDevices: Infinity,
|
||||
deviceCount: remoteParticipants.length,
|
||||
};
|
||||
@@ -1962,7 +1962,7 @@ export function reducer(
|
||||
newActiveCallState &&
|
||||
newActiveCallState.outgoingRing &&
|
||||
newActiveCallState.conversationId === conversationId &&
|
||||
isAnybodyElseInGroupCall(newPeekInfo, ourUuid)
|
||||
isAnybodyElseInGroupCall(newPeekInfo, ourAci)
|
||||
) {
|
||||
newActiveCallState = {
|
||||
...newActiveCallState,
|
||||
@@ -2007,7 +2007,7 @@ export function reducer(
|
||||
connectionState: GroupCallConnectionState.NotConnected,
|
||||
joinState: GroupCallJoinState.NotJoined,
|
||||
peekInfo: {
|
||||
uuids: [],
|
||||
acis: [],
|
||||
maxDevices: Infinity,
|
||||
deviceCount: 0,
|
||||
},
|
||||
@@ -2351,14 +2351,14 @@ export function reducer(
|
||||
return state;
|
||||
}
|
||||
|
||||
const { safetyNumberChangedUuids } = action.payload;
|
||||
const { safetyNumberChangedAcis } = action.payload;
|
||||
|
||||
return {
|
||||
...state,
|
||||
activeCallState: {
|
||||
...activeCallState,
|
||||
pip: false,
|
||||
safetyNumberChangedUuids,
|
||||
safetyNumberChangedAcis,
|
||||
settingsDialogOpen: false,
|
||||
showParticipantsList: false,
|
||||
},
|
||||
@@ -2376,7 +2376,7 @@ export function reducer(
|
||||
...state,
|
||||
activeCallState: {
|
||||
...activeCallState,
|
||||
safetyNumberChangedUuids: [],
|
||||
safetyNumberChangedAcis: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ import {
|
||||
CallState,
|
||||
GroupCallConnectionState,
|
||||
} from '../../types/Calling';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { AciString } from '../../types/ServiceId';
|
||||
import { missingCaseError } from '../../util/missingCaseError';
|
||||
import type {
|
||||
DirectCallStateType,
|
||||
@@ -22,7 +22,7 @@ import type {
|
||||
// support it for direct calls.
|
||||
export const getIncomingCall = (
|
||||
callsByConversation: Readonly<CallsByConversationType>,
|
||||
ourUuid: UUIDStringType
|
||||
ourAci: AciString
|
||||
): undefined | DirectCallStateType | GroupCallStateType =>
|
||||
Object.values(callsByConversation).find(call => {
|
||||
switch (call.callMode) {
|
||||
@@ -30,9 +30,9 @@ export const getIncomingCall = (
|
||||
return call.isIncoming && call.callState === CallState.Ringing;
|
||||
case CallMode.Group:
|
||||
return (
|
||||
call.ringerUuid &&
|
||||
call.ringerAci &&
|
||||
call.connectionState === GroupCallConnectionState.NotConnected &&
|
||||
isAnybodyElseInGroupCall(call.peekInfo, ourUuid)
|
||||
isAnybodyElseInGroupCall(call.peekInfo, ourAci)
|
||||
);
|
||||
default:
|
||||
throw missingCaseError(call);
|
||||
@@ -40,6 +40,6 @@ export const getIncomingCall = (
|
||||
});
|
||||
|
||||
export const isAnybodyElseInGroupCall = (
|
||||
peekInfo: undefined | Readonly<Pick<GroupCallPeekInfoType, 'uuids'>>,
|
||||
ourUuid: UUIDStringType
|
||||
): boolean => Boolean(peekInfo?.uuids.some(id => id !== ourUuid));
|
||||
peekInfo: undefined | Readonly<Pick<GroupCallPeekInfoType, 'acis'>>,
|
||||
ourAci: AciString
|
||||
): boolean => Boolean(peekInfo?.acis.some(id => id !== ourAci));
|
||||
|
@@ -2,9 +2,9 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import { debounce, isEqual } from 'lodash';
|
||||
import type { ThunkAction, ThunkDispatch } from 'redux-thunk';
|
||||
import { v4 as generateUuid } from 'uuid';
|
||||
|
||||
import type { ReadonlyDeep } from 'type-fest';
|
||||
import type {
|
||||
@@ -27,7 +27,6 @@ import type {
|
||||
import type { NoopActionType } from './noop';
|
||||
import type { ShowToastActionType } from './toast';
|
||||
import type { StateType as RootStateType } from '../reducer';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import * as log from '../../logging/log';
|
||||
import * as Errors from '../../types/errors';
|
||||
import * as LinkPreview from '../../types/LinkPreview';
|
||||
@@ -42,7 +41,6 @@ import { SHOW_TOAST } from './toast';
|
||||
import type { AnyToast } from '../../types/Toast';
|
||||
import { ToastType } from '../../types/Toast';
|
||||
import { SafetyNumberChangeSource } from '../../components/SafetyNumberChangeDialog';
|
||||
import { UUID } from '../../types/UUID';
|
||||
import { assignWithNoUnnecessaryAllocation } from '../../util/assignWithNoUnnecessaryAllocation';
|
||||
import { blockSendUntilConversationsAreVerified } from '../../util/blockSendUntilConversationsAreVerified';
|
||||
import { clearConversationDraftAttachments } from '../../util/clearConversationDraftAttachments';
|
||||
@@ -105,7 +103,7 @@ type ComposerStateByConversationType = {
|
||||
isDisabled: boolean;
|
||||
linkPreviewLoading: boolean;
|
||||
linkPreviewResult?: LinkPreviewType;
|
||||
messageCompositionId: UUIDStringType;
|
||||
messageCompositionId: string;
|
||||
quotedMessage?: Pick<MessageAttributesType, 'conversationId' | 'quote'>;
|
||||
sendCounter: number;
|
||||
shouldSendHighQualityAttachments?: boolean;
|
||||
@@ -128,7 +126,7 @@ function getEmptyComposerState(): ComposerStateByConversationType {
|
||||
focusCounter: 0,
|
||||
isDisabled: false,
|
||||
linkPreviewLoading: false,
|
||||
messageCompositionId: UUID.generate().toString(),
|
||||
messageCompositionId: generateUuid(),
|
||||
sendCounter: 0,
|
||||
};
|
||||
}
|
||||
|
@@ -63,7 +63,14 @@ import type {
|
||||
} from '../../types/BodyRange';
|
||||
import { CallMode } from '../../types/Calling';
|
||||
import type { MediaItemType } from '../../types/MediaItem';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { StoryDistributionIdString } from '../../types/StoryDistributionId';
|
||||
import { normalizeStoryDistributionId } from '../../types/StoryDistributionId';
|
||||
import type {
|
||||
ServiceIdString,
|
||||
AciString,
|
||||
PniString,
|
||||
} from '../../types/ServiceId';
|
||||
import { isAciString } from '../../types/ServiceId';
|
||||
import { MY_STORY_ID, StorySendMode } from '../../types/Stories';
|
||||
import * as Errors from '../../types/errors';
|
||||
import {
|
||||
@@ -76,7 +83,7 @@ import type { GroupNameCollisionsWithIdsByTitle } from '../../util/groupMemberNa
|
||||
import { ContactSpoofingType } from '../../util/contactSpoofing';
|
||||
import { writeProfile } from '../../services/writeProfile';
|
||||
import {
|
||||
getConversationUuidsStoppingSend,
|
||||
getConversationServiceIdsStoppingSend,
|
||||
getConversationIdsStoppedForVerification,
|
||||
getConversationSelector,
|
||||
getMe,
|
||||
@@ -139,7 +146,6 @@ import { isNotNil } from '../../util/isNotNil';
|
||||
import { PanelType } from '../../types/Panels';
|
||||
import { startConversation } from '../../util/startConversation';
|
||||
import { getMessageSentTimestamp } from '../../util/getMessageSentTimestamp';
|
||||
import { UUIDKind } from '../../types/UUID';
|
||||
import { removeLinkPreview } from '../../services/LinkPreview';
|
||||
import type {
|
||||
ReplaceAttachmentsActionType,
|
||||
@@ -213,8 +219,8 @@ export type DraftPreviewType = ReadonlyDeep<{
|
||||
export type ConversationType = ReadonlyDeep<
|
||||
{
|
||||
id: string;
|
||||
uuid?: UUIDStringType;
|
||||
pni?: UUIDStringType;
|
||||
uuid?: ServiceIdString;
|
||||
pni?: PniString;
|
||||
e164?: string;
|
||||
name?: string;
|
||||
systemGivenName?: string;
|
||||
@@ -268,17 +274,17 @@ export type ConversationType = ReadonlyDeep<
|
||||
announcementsOnlyReady?: boolean;
|
||||
expireTimer?: DurationInSeconds;
|
||||
memberships?: ReadonlyArray<{
|
||||
uuid: UUIDStringType;
|
||||
uuid: AciString;
|
||||
isAdmin: boolean;
|
||||
}>;
|
||||
pendingMemberships?: ReadonlyArray<{
|
||||
uuid: UUIDStringType;
|
||||
addedByUserId?: UUIDStringType;
|
||||
uuid: ServiceIdString;
|
||||
addedByUserId?: AciString;
|
||||
}>;
|
||||
pendingApprovalMemberships?: ReadonlyArray<{
|
||||
uuid: UUIDStringType;
|
||||
uuid: AciString;
|
||||
}>;
|
||||
bannedMemberships?: ReadonlyArray<UUIDStringType>;
|
||||
bannedMemberships?: ReadonlyArray<ServiceIdString>;
|
||||
muteExpiresAt?: number;
|
||||
dontNotifyForMentionsIfMuted?: boolean;
|
||||
isMe: boolean;
|
||||
@@ -407,15 +413,18 @@ type ComposerGroupCreationState = ReadonlyDeep<{
|
||||
}>;
|
||||
|
||||
type DistributionVerificationData = ReadonlyDeep<{
|
||||
uuidsNeedingVerification: Array<UUIDStringType>;
|
||||
serviceIdsNeedingVerification: Array<ServiceIdString>;
|
||||
}>;
|
||||
|
||||
export type ConversationVerificationData = ReadonlyDeep<
|
||||
| {
|
||||
type: ConversationVerificationState.PendingVerification;
|
||||
uuidsNeedingVerification: ReadonlyArray<UUIDStringType>;
|
||||
serviceIdsNeedingVerification: ReadonlyArray<ServiceIdString>;
|
||||
|
||||
byDistributionId?: Record<string, DistributionVerificationData>;
|
||||
byDistributionId?: Record<
|
||||
StoryDistributionIdString,
|
||||
DistributionVerificationData
|
||||
>;
|
||||
}
|
||||
| {
|
||||
type: ConversationVerificationState.VerificationCancelled;
|
||||
@@ -462,7 +471,7 @@ type ContactSpoofingReviewStateType = ReadonlyDeep<
|
||||
// eslint-disable-next-line local-rules/type-alias-readonlydeep -- FIXME
|
||||
export type ConversationsStateType = Readonly<{
|
||||
preJoinConversation?: PreJoinConversationType;
|
||||
invitedUuidsForNewlyCreatedGroup?: ReadonlyArray<string>;
|
||||
invitedServiceIdsForNewlyCreatedGroup?: ReadonlyArray<ServiceIdString>;
|
||||
conversationLookup: ConversationLookupType;
|
||||
conversationsByE164: ConversationLookupType;
|
||||
conversationsByUuid: ConversationLookupType;
|
||||
@@ -568,7 +577,7 @@ type ClearGroupCreationErrorActionType = ReadonlyDeep<{
|
||||
type: 'CLEAR_GROUP_CREATION_ERROR';
|
||||
}>;
|
||||
type ClearInvitedUuidsForNewlyCreatedGroupActionType = ReadonlyDeep<{
|
||||
type: 'CLEAR_INVITED_UUIDS_FOR_NEWLY_CREATED_GROUP';
|
||||
type: 'CLEAR_INVITED_SERVICE_IDS_FOR_NEWLY_CREATED_GROUP';
|
||||
}>;
|
||||
type ClearVerificationDataByConversationActionType = ReadonlyDeep<{
|
||||
type: typeof CLEAR_CONVERSATIONS_PENDING_VERIFICATION;
|
||||
@@ -680,7 +689,7 @@ type CreateGroupPendingActionType = ReadonlyDeep<{
|
||||
type CreateGroupFulfilledActionType = ReadonlyDeep<{
|
||||
type: 'CREATE_GROUP_FULFILLED';
|
||||
payload: {
|
||||
invitedUuids: ReadonlyArray<UUIDStringType>;
|
||||
invitedServiceIds: ReadonlyArray<ServiceIdString>;
|
||||
};
|
||||
}>;
|
||||
type CreateGroupRejectedActionType = ReadonlyDeep<{
|
||||
@@ -715,8 +724,8 @@ type ConversationStoppedByMissingVerificationActionType = ReadonlyDeep<{
|
||||
type: typeof CONVERSATION_STOPPED_BY_MISSING_VERIFICATION;
|
||||
payload: {
|
||||
conversationId: string;
|
||||
distributionId?: string;
|
||||
untrustedUuids: ReadonlyArray<UUIDStringType>;
|
||||
distributionId?: StoryDistributionIdString;
|
||||
untrustedServiceIds: ReadonlyArray<ServiceIdString>;
|
||||
};
|
||||
}>;
|
||||
// eslint-disable-next-line local-rules/type-alias-readonlydeep -- FIXME
|
||||
@@ -1235,14 +1244,14 @@ function acknowledgeGroupMemberNameCollisions(
|
||||
}
|
||||
function blockGroupLinkRequests(
|
||||
conversationId: string,
|
||||
uuid: UUIDStringType
|
||||
serviceId: ServiceIdString
|
||||
): NoopActionType {
|
||||
const conversation = window.ConversationController.get(conversationId);
|
||||
if (!conversation) {
|
||||
throw new Error('blockGroupLinkRequests: Conversation not found!');
|
||||
}
|
||||
|
||||
void conversation.blockGroupLinkRequests(uuid);
|
||||
void conversation.blockGroupLinkRequests(serviceId);
|
||||
|
||||
return {
|
||||
type: 'NOOP',
|
||||
@@ -2116,7 +2125,7 @@ function kickOffAttachmentDownload(
|
||||
if (didUpdateValues) {
|
||||
drop(
|
||||
window.Signal.Data.saveMessage(message.attributes, {
|
||||
ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(),
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -2379,21 +2388,21 @@ function verifyConversationsStoppingSend(): ThunkAction<
|
||||
> {
|
||||
return async (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const uuidsStoppingSend = getConversationUuidsStoppingSend(state);
|
||||
const serviceIdsStoppingSend = getConversationServiceIdsStoppingSend(state);
|
||||
const conversationIdsBlocked =
|
||||
getConversationIdsStoppedForVerification(state);
|
||||
log.info(
|
||||
`verifyConversationsStoppingSend: Starting with ${conversationIdsBlocked.length} blocked ` +
|
||||
`conversations and ${uuidsStoppingSend.length} conversations to verify.`
|
||||
`conversations and ${serviceIdsStoppingSend.length} conversations to verify.`
|
||||
);
|
||||
|
||||
// Mark conversations as approved/verified as appropriate
|
||||
const promises: Array<Promise<unknown>> = [];
|
||||
uuidsStoppingSend.forEach(async uuid => {
|
||||
const conversation = window.ConversationController.get(uuid);
|
||||
serviceIdsStoppingSend.forEach(async serviceId => {
|
||||
const conversation = window.ConversationController.get(serviceId);
|
||||
if (!conversation) {
|
||||
log.warn(
|
||||
`verifyConversationsStoppingSend: Cannot verify missing converastion for uuid ${uuid}`
|
||||
`verifyConversationsStoppingSend: Cannot verify missing conversation for serviceId ${serviceId}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -2568,7 +2577,7 @@ function createGroup(
|
||||
dispatch({
|
||||
type: 'CREATE_GROUP_FULFILLED',
|
||||
payload: {
|
||||
invitedUuids: (conversation.get('pendingMembersV2') || []).map(
|
||||
invitedServiceIds: (conversation.get('pendingMembersV2') || []).map(
|
||||
member => member.uuid
|
||||
),
|
||||
},
|
||||
@@ -2693,11 +2702,11 @@ function getProfilesForConversation(conversationId: string): NoopActionType {
|
||||
|
||||
function conversationStoppedByMissingVerification(payload: {
|
||||
conversationId: string;
|
||||
distributionId?: string;
|
||||
untrustedUuids: ReadonlyArray<UUIDStringType>;
|
||||
distributionId?: StoryDistributionIdString;
|
||||
untrustedServiceIds: ReadonlyArray<ServiceIdString>;
|
||||
}): ConversationStoppedByMissingVerificationActionType {
|
||||
// Fetching profiles to ensure that we have their latest identity key in storage
|
||||
payload.untrustedUuids.forEach(uuid => {
|
||||
payload.untrustedServiceIds.forEach(uuid => {
|
||||
const conversation = window.ConversationController.get(uuid);
|
||||
if (!conversation) {
|
||||
log.error(
|
||||
@@ -3081,14 +3090,18 @@ function approvePendingMembershipFromGroupV2(
|
||||
);
|
||||
}
|
||||
|
||||
const uuid = pendingMember.getCheckedUuid(
|
||||
const serviceId = pendingMember.getCheckedServiceId(
|
||||
`approvePendingMembershipFromGroupV2/${logId}`
|
||||
);
|
||||
|
||||
if (
|
||||
isGroupV2(conversation.attributes) &&
|
||||
isMemberRequestingToJoin(conversation.attributes, uuid)
|
||||
isMemberRequestingToJoin(conversation.attributes, serviceId)
|
||||
) {
|
||||
strictAssert(
|
||||
isAciString(serviceId),
|
||||
'Member requesting to join must have ACI'
|
||||
);
|
||||
await modifyGroupV2({
|
||||
conversation,
|
||||
usingCredentialsFrom: [pendingMember],
|
||||
@@ -3096,9 +3109,9 @@ function approvePendingMembershipFromGroupV2(
|
||||
// This user's pending state may have changed in the time between the user's
|
||||
// button press and when we get here. It's especially important to check here
|
||||
// in conflict/retry cases.
|
||||
if (!isMemberRequestingToJoin(conversation.attributes, uuid)) {
|
||||
if (!isMemberRequestingToJoin(conversation.attributes, serviceId)) {
|
||||
log.warn(
|
||||
`approvePendingMembershipFromGroupV2/${logId}: ${uuid} is not requesting ` +
|
||||
`approvePendingMembershipFromGroupV2/${logId}: ${serviceId} is not requesting ` +
|
||||
'to join the group. Returning early.'
|
||||
);
|
||||
return undefined;
|
||||
@@ -3106,7 +3119,7 @@ function approvePendingMembershipFromGroupV2(
|
||||
|
||||
return buildPromotePendingAdminApprovalMemberChange({
|
||||
group: conversation.attributes,
|
||||
uuid,
|
||||
aci: serviceId,
|
||||
});
|
||||
},
|
||||
name: 'approvePendingMembershipFromGroupV2',
|
||||
@@ -3138,16 +3151,16 @@ function revokePendingMembershipsFromGroupV2(
|
||||
|
||||
// Only pending memberships can be revoked for multiple members at once
|
||||
if (memberIds.length > 1) {
|
||||
const uuids = memberIds.map(id => {
|
||||
const uuid = window.ConversationController.get(id)?.getUuid();
|
||||
strictAssert(uuid, `UUID does not exist for ${id}`);
|
||||
return uuid;
|
||||
const serviceIds = memberIds.map(id => {
|
||||
const serviceId = window.ConversationController.get(id)?.getServiceId();
|
||||
strictAssert(serviceId, `serviceId does not exist for ${id}`);
|
||||
return serviceId;
|
||||
});
|
||||
await conversation.modifyGroupV2({
|
||||
name: 'removePendingMember',
|
||||
usingCredentialsFrom: [],
|
||||
createGroupChange: () =>
|
||||
removePendingMember(conversation.attributes, uuids),
|
||||
removePendingMember(conversation.attributes, serviceIds),
|
||||
extraConversationsForSend: memberIds,
|
||||
});
|
||||
return;
|
||||
@@ -3163,24 +3176,28 @@ function revokePendingMembershipsFromGroupV2(
|
||||
);
|
||||
}
|
||||
|
||||
const uuid = pendingMember.getCheckedUuid(
|
||||
const serviceId = pendingMember.getCheckedServiceId(
|
||||
'revokePendingMembershipsFromGroupV2'
|
||||
);
|
||||
|
||||
if (isMemberRequestingToJoin(conversation.attributes, uuid)) {
|
||||
if (isMemberRequestingToJoin(conversation.attributes, serviceId)) {
|
||||
strictAssert(
|
||||
isAciString(serviceId),
|
||||
'Member requesting to join must have ACI'
|
||||
);
|
||||
await conversation.modifyGroupV2({
|
||||
name: 'denyPendingApprovalRequest',
|
||||
usingCredentialsFrom: [],
|
||||
createGroupChange: () =>
|
||||
denyPendingApprovalRequest(conversation.attributes, uuid),
|
||||
denyPendingApprovalRequest(conversation.attributes, serviceId),
|
||||
extraConversationsForSend: [memberId],
|
||||
});
|
||||
} else if (conversation.isMemberPending(uuid)) {
|
||||
} else if (conversation.isMemberPending(serviceId)) {
|
||||
await conversation.modifyGroupV2({
|
||||
name: 'removePendingMember',
|
||||
usingCredentialsFrom: [],
|
||||
createGroupChange: () =>
|
||||
removePendingMember(conversation.attributes, [uuid]),
|
||||
removePendingMember(conversation.attributes, [serviceId]),
|
||||
extraConversationsForSend: [memberId],
|
||||
});
|
||||
}
|
||||
@@ -3485,7 +3502,7 @@ export function saveAttachmentFromMessage(
|
||||
}
|
||||
|
||||
function clearInvitedUuidsForNewlyCreatedGroup(): ClearInvitedUuidsForNewlyCreatedGroupActionType {
|
||||
return { type: 'CLEAR_INVITED_UUIDS_FOR_NEWLY_CREATED_GROUP' };
|
||||
return { type: 'CLEAR_INVITED_SERVICE_IDS_FOR_NEWLY_CREATED_GROUP' };
|
||||
}
|
||||
function clearGroupCreationError(): ClearGroupCreationErrorActionType {
|
||||
return { type: 'CLEAR_GROUP_CREATION_ERROR' };
|
||||
@@ -4017,10 +4034,10 @@ function onConversationOpened(
|
||||
);
|
||||
drop(conversation.throttledFetchSMSOnlyUUID());
|
||||
|
||||
const ourUuid = window.textsecure.storage.user.getUuid(UUIDKind.ACI);
|
||||
const ourAci = window.textsecure.storage.user.getAci();
|
||||
if (
|
||||
!isGroup(conversation.attributes) ||
|
||||
(ourUuid && conversation.hasMember(ourUuid))
|
||||
(ourAci && conversation.hasMember(ourAci))
|
||||
) {
|
||||
strictAssert(
|
||||
conversation.throttledGetProfiles !== undefined,
|
||||
@@ -4236,12 +4253,12 @@ function getVerificationDataForConversation({
|
||||
conversationId,
|
||||
distributionId,
|
||||
state,
|
||||
untrustedUuids,
|
||||
untrustedServiceIds,
|
||||
}: {
|
||||
conversationId: string;
|
||||
distributionId?: string;
|
||||
distributionId?: StoryDistributionIdString;
|
||||
state: Readonly<VerificationDataByConversation>;
|
||||
untrustedUuids: ReadonlyArray<UUIDStringType>;
|
||||
untrustedServiceIds: ReadonlyArray<ServiceIdString>;
|
||||
}): VerificationDataByConversation {
|
||||
const existing = getOwn(state, conversationId);
|
||||
|
||||
@@ -4252,12 +4269,14 @@ function getVerificationDataForConversation({
|
||||
return {
|
||||
[conversationId]: {
|
||||
type: ConversationVerificationState.PendingVerification as const,
|
||||
uuidsNeedingVerification: distributionId ? [] : untrustedUuids,
|
||||
serviceIdsNeedingVerification: distributionId
|
||||
? []
|
||||
: untrustedServiceIds,
|
||||
...(distributionId
|
||||
? {
|
||||
byDistributionId: {
|
||||
[distributionId]: {
|
||||
uuidsNeedingVerification: untrustedUuids,
|
||||
serviceIdsNeedingVerification: untrustedServiceIds,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -4267,24 +4286,23 @@ function getVerificationDataForConversation({
|
||||
}
|
||||
|
||||
const existingUuids = distributionId
|
||||
? existing.byDistributionId?.[distributionId]?.uuidsNeedingVerification
|
||||
: existing.uuidsNeedingVerification;
|
||||
? existing.byDistributionId?.[distributionId]?.serviceIdsNeedingVerification
|
||||
: existing.serviceIdsNeedingVerification;
|
||||
|
||||
const uuidsNeedingVerification: ReadonlyArray<UUIDStringType> = Array.from(
|
||||
new Set([...(existingUuids || []), ...untrustedUuids])
|
||||
);
|
||||
const serviceIdsNeedingVerification: ReadonlyArray<ServiceIdString> =
|
||||
Array.from(new Set([...(existingUuids || []), ...untrustedServiceIds]));
|
||||
|
||||
return {
|
||||
[conversationId]: {
|
||||
...existing,
|
||||
type: ConversationVerificationState.PendingVerification as const,
|
||||
...(distributionId ? undefined : { uuidsNeedingVerification }),
|
||||
...(distributionId ? undefined : { serviceIdsNeedingVerification }),
|
||||
...(distributionId
|
||||
? {
|
||||
byDistributionId: {
|
||||
...existing.byDistributionId,
|
||||
[distributionId]: {
|
||||
uuidsNeedingVerification,
|
||||
serviceIdsNeedingVerification,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -4340,7 +4358,7 @@ function visitListsInVerificationData(
|
||||
|
||||
const listCount = Object.keys(updatedByDistributionId).length;
|
||||
if (
|
||||
conversationData.uuidsNeedingVerification.length === 0 &&
|
||||
conversationData.serviceIdsNeedingVerification.length === 0 &&
|
||||
listCount === 0
|
||||
) {
|
||||
result = omit(result, [conversationId]);
|
||||
@@ -4461,8 +4479,8 @@ export function reducer(
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === 'CLEAR_INVITED_UUIDS_FOR_NEWLY_CREATED_GROUP') {
|
||||
return omit(state, 'invitedUuidsForNewlyCreatedGroup');
|
||||
if (action.type === 'CLEAR_INVITED_SERVICE_IDS_FOR_NEWLY_CREATED_GROUP') {
|
||||
return omit(state, 'invitedServiceIdsForNewlyCreatedGroup');
|
||||
}
|
||||
|
||||
if (action.type === 'CLEAR_GROUP_CREATION_ERROR') {
|
||||
@@ -4706,7 +4724,7 @@ export function reducer(
|
||||
// the work.
|
||||
return {
|
||||
...state,
|
||||
invitedUuidsForNewlyCreatedGroup: action.payload.invitedUuids,
|
||||
invitedServiceIdsForNewlyCreatedGroup: action.payload.invitedServiceIds,
|
||||
};
|
||||
}
|
||||
if (action.type === 'CREATE_GROUP_REJECTED') {
|
||||
@@ -4788,16 +4806,17 @@ export function reducer(
|
||||
state.verificationDataByConversation,
|
||||
(id, data): DistributionVerificationData | undefined => {
|
||||
if (listId === id) {
|
||||
const uuidsNeedingVerification = data.uuidsNeedingVerification.filter(
|
||||
uuid => !removedUuids.has(uuid)
|
||||
);
|
||||
const serviceIdsNeedingVerification =
|
||||
data.serviceIdsNeedingVerification.filter(
|
||||
uuid => !removedUuids.has(uuid)
|
||||
);
|
||||
|
||||
if (!uuidsNeedingVerification.length) {
|
||||
if (!serviceIdsNeedingVerification.length) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
...data,
|
||||
uuidsNeedingVerification,
|
||||
serviceIdsNeedingVerification,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4844,17 +4863,18 @@ export function reducer(
|
||||
state.verificationDataByConversation,
|
||||
(id, data): DistributionVerificationData | undefined => {
|
||||
if (MY_STORY_ID === id) {
|
||||
const uuidsNeedingVerification = data.uuidsNeedingVerification.filter(
|
||||
uuid => !removedUuids.has(uuid)
|
||||
);
|
||||
const serviceIdsNeedingVerification =
|
||||
data.serviceIdsNeedingVerification.filter(
|
||||
uuid => !removedUuids.has(uuid)
|
||||
);
|
||||
|
||||
if (!uuidsNeedingVerification.length) {
|
||||
if (!serviceIdsNeedingVerification.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
...data,
|
||||
uuidsNeedingVerification,
|
||||
serviceIdsNeedingVerification,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4872,24 +4892,25 @@ export function reducer(
|
||||
};
|
||||
}
|
||||
if (action.type === VIEWERS_CHANGED) {
|
||||
const { listId, memberUuids } = action.payload;
|
||||
const newUuids = new Set(memberUuids);
|
||||
const { listId, memberServiceIds } = action.payload;
|
||||
const newUuids = new Set(memberServiceIds);
|
||||
|
||||
const nextVerificationData = visitListsInVerificationData(
|
||||
state.verificationDataByConversation,
|
||||
(id, data): DistributionVerificationData | undefined => {
|
||||
if (listId === id) {
|
||||
const uuidsNeedingVerification = data.uuidsNeedingVerification.filter(
|
||||
uuid => newUuids.has(uuid)
|
||||
);
|
||||
const serviceIdsNeedingVerification =
|
||||
data.serviceIdsNeedingVerification.filter(uuid =>
|
||||
newUuids.has(uuid)
|
||||
);
|
||||
|
||||
if (!uuidsNeedingVerification.length) {
|
||||
if (!serviceIdsNeedingVerification.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
...data,
|
||||
uuidsNeedingVerification,
|
||||
serviceIdsNeedingVerification,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4908,13 +4929,14 @@ export function reducer(
|
||||
}
|
||||
|
||||
if (action.type === CONVERSATION_STOPPED_BY_MISSING_VERIFICATION) {
|
||||
const { conversationId, distributionId, untrustedUuids } = action.payload;
|
||||
const { conversationId, distributionId, untrustedServiceIds } =
|
||||
action.payload;
|
||||
|
||||
const nextVerificationData = getVerificationDataForConversation({
|
||||
conversationId,
|
||||
distributionId,
|
||||
state: state.verificationDataByConversation,
|
||||
untrustedUuids,
|
||||
untrustedServiceIds,
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -4935,7 +4957,7 @@ export function reducer(
|
||||
const nextConversation = getVerificationDataForConversation({
|
||||
state: verificationDataByConversation,
|
||||
conversationId,
|
||||
untrustedUuids: conversationData.uuids,
|
||||
untrustedServiceIds: conversationData.serviceIds,
|
||||
});
|
||||
Object.assign(verificationDataByConversation, nextConversation);
|
||||
|
||||
@@ -4947,9 +4969,12 @@ export function reducer(
|
||||
([distributionId, distributionData]) => {
|
||||
const nextDistribution = getVerificationDataForConversation({
|
||||
state: verificationDataByConversation,
|
||||
distributionId,
|
||||
distributionId: normalizeStoryDistributionId(
|
||||
distributionId,
|
||||
'ducks/conversations'
|
||||
),
|
||||
conversationId,
|
||||
untrustedUuids: distributionData.uuids,
|
||||
untrustedServiceIds: distributionData.serviceIds,
|
||||
});
|
||||
Object.assign(verificationDataByConversation, nextDistribution);
|
||||
}
|
||||
|
@@ -17,7 +17,6 @@ import type { MessagePropsType } from '../selectors/message';
|
||||
import type { RecipientsByConversation } from './stories';
|
||||
import type { SafetyNumberChangeSource } from '../../components/SafetyNumberChangeDialog';
|
||||
import type { StateType as RootStateType } from '../reducer';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import * as Errors from '../../types/errors';
|
||||
import * as SingleServePromise from '../../services/singleServePromise';
|
||||
import * as Stickers from '../../types/Stickers';
|
||||
@@ -58,7 +57,7 @@ export type ForwardMessagesPropsType = ReadonlyDeep<{
|
||||
onForward?: () => void;
|
||||
}>;
|
||||
export type SafetyNumberChangedBlockingDataType = ReadonlyDeep<{
|
||||
promiseUuid: UUIDStringType;
|
||||
promiseUuid: SingleServePromise.SingleServePromiseIdString;
|
||||
source?: SafetyNumberChangeSource;
|
||||
}>;
|
||||
export type FormattingWarningDataType = ReadonlyDeep<{
|
||||
@@ -112,8 +111,10 @@ const HIDE_CONTACT_MODAL = 'globalModals/HIDE_CONTACT_MODAL';
|
||||
const SHOW_CONTACT_MODAL = 'globalModals/SHOW_CONTACT_MODAL';
|
||||
const HIDE_WHATS_NEW_MODAL = 'globalModals/HIDE_WHATS_NEW_MODAL_MODAL';
|
||||
const SHOW_WHATS_NEW_MODAL = 'globalModals/SHOW_WHATS_NEW_MODAL_MODAL';
|
||||
const HIDE_UUID_NOT_FOUND_MODAL = 'globalModals/HIDE_UUID_NOT_FOUND_MODAL';
|
||||
const SHOW_UUID_NOT_FOUND_MODAL = 'globalModals/SHOW_UUID_NOT_FOUND_MODAL';
|
||||
const HIDE_SERVICE_ID_NOT_FOUND_MODAL =
|
||||
'globalModals/HIDE_SERVICE_ID_NOT_FOUND_MODAL';
|
||||
const SHOW_SERVICE_ID_NOT_FOUND_MODAL =
|
||||
'globalModals/SHOW_SERVICE_ID_NOT_FOUND_MODAL';
|
||||
const SHOW_STORIES_SETTINGS = 'globalModals/SHOW_STORIES_SETTINGS';
|
||||
const HIDE_STORIES_SETTINGS = 'globalModals/HIDE_STORIES_SETTINGS';
|
||||
const TOGGLE_DELETE_MESSAGES_MODAL =
|
||||
@@ -186,11 +187,11 @@ type ShowWhatsNewModalActionType = ReadonlyDeep<{
|
||||
}>;
|
||||
|
||||
type HideUserNotFoundModalActionType = ReadonlyDeep<{
|
||||
type: typeof HIDE_UUID_NOT_FOUND_MODAL;
|
||||
type: typeof HIDE_SERVICE_ID_NOT_FOUND_MODAL;
|
||||
}>;
|
||||
|
||||
export type ShowUserNotFoundModalActionType = ReadonlyDeep<{
|
||||
type: typeof SHOW_UUID_NOT_FOUND_MODAL;
|
||||
type: typeof SHOW_SERVICE_ID_NOT_FOUND_MODAL;
|
||||
payload: UserNotFoundModalStateType;
|
||||
}>;
|
||||
|
||||
@@ -445,7 +446,7 @@ function showWhatsNewModal(): ShowWhatsNewModalActionType {
|
||||
|
||||
function hideUserNotFoundModal(): HideUserNotFoundModalActionType {
|
||||
return {
|
||||
type: HIDE_UUID_NOT_FOUND_MODAL,
|
||||
type: HIDE_SERVICE_ID_NOT_FOUND_MODAL,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -453,7 +454,7 @@ function showUserNotFoundModal(
|
||||
payload: UserNotFoundModalStateType
|
||||
): ShowUserNotFoundModalActionType {
|
||||
return {
|
||||
type: SHOW_UUID_NOT_FOUND_MODAL,
|
||||
type: SHOW_SERVICE_ID_NOT_FOUND_MODAL,
|
||||
payload,
|
||||
};
|
||||
}
|
||||
@@ -904,14 +905,14 @@ export function reducer(
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === HIDE_UUID_NOT_FOUND_MODAL) {
|
||||
if (action.type === HIDE_SERVICE_ID_NOT_FOUND_MODAL) {
|
||||
return {
|
||||
...state,
|
||||
userNotFoundModalState: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === SHOW_UUID_NOT_FOUND_MODAL) {
|
||||
if (action.type === SHOW_SERVICE_ID_NOT_FOUND_MODAL) {
|
||||
return {
|
||||
...state,
|
||||
userNotFoundModalState: {
|
||||
|
@@ -82,7 +82,7 @@ function loadMediaItems(
|
||||
const DEFAULT_MEDIA_FETCH_COUNT = 50;
|
||||
const DEFAULT_DOCUMENTS_FETCH_COUNT = 150;
|
||||
|
||||
const ourUuid = window.textsecure.storage.user.getCheckedUuid().toString();
|
||||
const ourAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const rawMedia = await dataInterface.getMessagesWithVisualMediaAttachments(
|
||||
conversationId,
|
||||
@@ -107,7 +107,7 @@ function loadMediaItems(
|
||||
const upgradedMsgAttributes = await upgradeMessageSchema(message);
|
||||
model.set(upgradedMsgAttributes);
|
||||
|
||||
await dataInterface.saveMessage(upgradedMsgAttributes, { ourUuid });
|
||||
await dataInterface.saveMessage(upgradedMsgAttributes, { ourAci });
|
||||
}
|
||||
})
|
||||
);
|
||||
|
@@ -19,7 +19,8 @@ import type { NoopActionType } from './noop';
|
||||
import type { StateType as RootStateType } from '../reducer';
|
||||
import type { StoryViewTargetType, StoryViewType } from '../../types/Stories';
|
||||
import type { SyncType } from '../../jobs/helpers/syncHelpers';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { StoryDistributionIdString } from '../../types/StoryDistributionId';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
import * as log from '../../logging/log';
|
||||
import { TARGETED_CONVERSATION_CHANGED } from './conversations';
|
||||
import { SIGNAL_ACI } from '../../types/SignalConversation';
|
||||
@@ -125,12 +126,12 @@ export type AddStoryData = ReadonlyDeep<
|
||||
export type RecipientsByConversation = Record<
|
||||
string, // conversationId
|
||||
{
|
||||
uuids: Array<UUIDStringType>;
|
||||
serviceIds: Array<ServiceIdString>;
|
||||
|
||||
byDistributionId?: Record<
|
||||
string, // distributionId
|
||||
StoryDistributionIdString,
|
||||
{
|
||||
uuids: Array<UUIDStringType>;
|
||||
serviceIds: Array<ServiceIdString>;
|
||||
}
|
||||
>;
|
||||
}
|
||||
@@ -180,8 +181,8 @@ type ListMembersVerified = ReadonlyDeep<{
|
||||
type: typeof LIST_MEMBERS_VERIFIED;
|
||||
payload: {
|
||||
conversationId: string;
|
||||
distributionId: string | undefined;
|
||||
uuids: Array<UUIDStringType>;
|
||||
distributionId: StoryDistributionIdString | undefined;
|
||||
serviceIds: Array<ServiceIdString>;
|
||||
};
|
||||
}>;
|
||||
|
||||
@@ -415,7 +416,7 @@ function markStoryRead(
|
||||
message.set(markViewed(message.attributes, storyReadDate));
|
||||
drop(
|
||||
dataInterface.saveMessage(message.attributes, {
|
||||
ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(),
|
||||
ourAci: window.textsecure.storage.user.getCheckedAci(),
|
||||
})
|
||||
);
|
||||
|
||||
@@ -620,7 +621,7 @@ function replyToStory(
|
||||
}
|
||||
|
||||
function sendStoryMessage(
|
||||
listIds: Array<UUIDStringType>,
|
||||
listIds: Array<StoryDistributionIdString>,
|
||||
conversationIds: Array<string>,
|
||||
attachment: AttachmentType,
|
||||
bodyRanges: DraftBodyRanges | undefined
|
||||
@@ -740,11 +741,11 @@ function markStoriesTabViewed(): MarkStoriesTabViewedActionType {
|
||||
function verifyStoryListMembers({
|
||||
conversationId,
|
||||
distributionId,
|
||||
uuids,
|
||||
serviceIds,
|
||||
}: {
|
||||
conversationId: string;
|
||||
distributionId: string | undefined;
|
||||
uuids: Array<UUIDStringType>;
|
||||
distributionId: StoryDistributionIdString | undefined;
|
||||
serviceIds: Array<ServiceIdString>;
|
||||
}): ThunkAction<void, RootStateType, unknown, ListMembersVerified> {
|
||||
return async (dispatch, getState) => {
|
||||
const { stories } = getState();
|
||||
@@ -754,20 +755,20 @@ function verifyStoryListMembers({
|
||||
return;
|
||||
}
|
||||
|
||||
if (!uuids.length) {
|
||||
if (!serviceIds.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This will fetch the latest identity key for these contacts, which will ensure that
|
||||
// the later verified/trusted checks will flag that change.
|
||||
await doVerifyStoryListMembers(uuids);
|
||||
await doVerifyStoryListMembers(serviceIds);
|
||||
|
||||
dispatch({
|
||||
type: LIST_MEMBERS_VERIFIED,
|
||||
payload: {
|
||||
conversationId,
|
||||
distributionId,
|
||||
uuids,
|
||||
serviceIds,
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -826,12 +827,12 @@ const getSelectedStoryDataForConversationId = (
|
||||
const state = getState();
|
||||
const { stories } = state.stories;
|
||||
|
||||
const ourUuid = window.storage.user.getCheckedUuid().toString();
|
||||
const ourAci = window.storage.user.getCheckedAci();
|
||||
const storiesByConversationId = stories.filter(
|
||||
item =>
|
||||
item.conversationId === conversationId &&
|
||||
!item.deletedForEveryone &&
|
||||
(!onlyFromSelf || item.sourceUuid === ourUuid)
|
||||
(!onlyFromSelf || item.sourceUuid === ourAci)
|
||||
);
|
||||
|
||||
// Find the index of the storyId provided, or if none provided then find the
|
||||
@@ -1782,16 +1783,17 @@ export function reducer(
|
||||
|
||||
if (action.type === LIST_MEMBERS_VERIFIED) {
|
||||
const { sendStoryModalData } = state;
|
||||
const { conversationId, distributionId, uuids } = action.payload;
|
||||
const { conversationId, distributionId, serviceIds } = action.payload;
|
||||
|
||||
const existing =
|
||||
sendStoryModalData && getOwn(sendStoryModalData, conversationId);
|
||||
|
||||
if (distributionId) {
|
||||
const existingUuids = existing?.byDistributionId?.[distributionId]?.uuids;
|
||||
const existingServiceIds =
|
||||
existing?.byDistributionId?.[distributionId]?.serviceIds;
|
||||
|
||||
const finalUuids = Array.from(
|
||||
new Set([...(existingUuids || []), ...uuids])
|
||||
const finalServiceIds = Array.from(
|
||||
new Set([...(existingServiceIds || []), ...serviceIds])
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -1800,11 +1802,11 @@ export function reducer(
|
||||
...sendStoryModalData,
|
||||
[conversationId]: {
|
||||
...existing,
|
||||
uuids: existing?.uuids || [],
|
||||
serviceIds: existing?.serviceIds || [],
|
||||
byDistributionId: {
|
||||
...existing?.byDistributionId,
|
||||
[distributionId]: {
|
||||
uuids: finalUuids,
|
||||
serviceIds: finalServiceIds,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1812,8 +1814,8 @@ export function reducer(
|
||||
};
|
||||
}
|
||||
|
||||
const finalUuids = Array.from(
|
||||
new Set([...(existing?.uuids || []), ...uuids])
|
||||
const finalServiceIds = Array.from(
|
||||
new Set([...(existing?.serviceIds || []), ...serviceIds])
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -1822,7 +1824,7 @@ export function reducer(
|
||||
...sendStoryModalData,
|
||||
[conversationId]: {
|
||||
...existing,
|
||||
uuids: finalUuids,
|
||||
serviceIds: finalServiceIds,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@@ -7,11 +7,12 @@ import type { ThunkAction } from 'redux-thunk';
|
||||
import type { ReadonlyDeep } from 'type-fest';
|
||||
import type { StateType as RootStateType } from '../reducer';
|
||||
import type { StoryDistributionWithMembersType } from '../../sql/Interface';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { StoryDistributionIdString } from '../../types/StoryDistributionId';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
import * as log from '../../logging/log';
|
||||
import dataInterface from '../../sql/Client';
|
||||
import { MY_STORY_ID } from '../../types/Stories';
|
||||
import { UUID } from '../../types/UUID';
|
||||
import { generateStoryDistributionId } from '../../types/StoryDistributionId';
|
||||
import { deleteStoryForEveryone } from '../../util/deleteStoryForEveryone';
|
||||
import { replaceIndex } from '../../util/replaceIndex';
|
||||
import { storageServiceUploadJob } from '../../services/storage';
|
||||
@@ -21,12 +22,12 @@ import { useBoundActions } from '../../hooks/useBoundActions';
|
||||
// State
|
||||
|
||||
export type StoryDistributionListDataType = ReadonlyDeep<{
|
||||
id: UUIDStringType;
|
||||
id: StoryDistributionIdString;
|
||||
deletedAtTimestamp?: number;
|
||||
name: string;
|
||||
allowsReplies: boolean;
|
||||
isBlockList: boolean;
|
||||
memberUuids: Array<UUIDStringType>;
|
||||
memberServiceIds: Array<ServiceIdString>;
|
||||
}>;
|
||||
|
||||
export type StoryDistributionListStateType = ReadonlyDeep<{
|
||||
@@ -67,13 +68,13 @@ type DeleteListActionType = ReadonlyDeep<{
|
||||
|
||||
type HideMyStoriesFromActionType = ReadonlyDeep<{
|
||||
type: typeof HIDE_MY_STORIES_FROM;
|
||||
payload: Array<UUIDStringType>;
|
||||
payload: Array<ServiceIdString>;
|
||||
}>;
|
||||
|
||||
type ModifyDistributionListType = ReadonlyDeep<
|
||||
Omit<StoryDistributionListDataType, 'memberUuids'> & {
|
||||
membersToAdd: Array<UUIDStringType>;
|
||||
membersToRemove: Array<UUIDStringType>;
|
||||
Omit<StoryDistributionListDataType, 'memberServiceIds'> & {
|
||||
membersToAdd: Array<ServiceIdString>;
|
||||
membersToRemove: Array<ServiceIdString>;
|
||||
}
|
||||
>;
|
||||
|
||||
@@ -90,7 +91,7 @@ type ViewersChangedActionType = ReadonlyDeep<{
|
||||
type: typeof VIEWERS_CHANGED;
|
||||
payload: {
|
||||
listId: string;
|
||||
memberUuids: Array<UUIDStringType>;
|
||||
memberServiceIds: Array<ServiceIdString>;
|
||||
};
|
||||
}>;
|
||||
|
||||
@@ -155,11 +156,11 @@ function allowsRepliesChanged(
|
||||
|
||||
function createDistributionList(
|
||||
name: string,
|
||||
memberUuids: Array<UUIDStringType>,
|
||||
memberServiceIds: Array<ServiceIdString>,
|
||||
storageServiceDistributionListRecord?: StoryDistributionWithMembersType,
|
||||
shouldSave = true
|
||||
): ThunkAction<
|
||||
Promise<UUIDStringType>,
|
||||
Promise<StoryDistributionIdString>,
|
||||
RootStateType,
|
||||
string,
|
||||
CreateListActionType
|
||||
@@ -167,9 +168,9 @@ function createDistributionList(
|
||||
return async dispatch => {
|
||||
const storyDistribution: StoryDistributionWithMembersType = {
|
||||
allowsReplies: true,
|
||||
id: UUID.generate().toString(),
|
||||
id: generateStoryDistributionId(),
|
||||
isBlockList: false,
|
||||
members: memberUuids,
|
||||
members: memberServiceIds,
|
||||
name,
|
||||
senderKeyInfo: undefined,
|
||||
storageNeedsSync: true,
|
||||
@@ -191,7 +192,7 @@ function createDistributionList(
|
||||
deletedAtTimestamp: storyDistribution.deletedAtTimestamp,
|
||||
id: storyDistribution.id,
|
||||
isBlockList: Boolean(storyDistribution.isBlockList),
|
||||
memberUuids,
|
||||
memberServiceIds,
|
||||
name: storyDistribution.name,
|
||||
},
|
||||
});
|
||||
@@ -262,7 +263,7 @@ function modifyDistributionList(
|
||||
}
|
||||
|
||||
function hideMyStoriesFrom(
|
||||
memberUuids: Array<UUIDStringType>
|
||||
memberServiceIds: Array<ServiceIdString>
|
||||
): ThunkAction<void, RootStateType, null, HideMyStoriesFromActionType> {
|
||||
return async dispatch => {
|
||||
const myStories = await dataInterface.getStoryDistributionWithMembers(
|
||||
@@ -276,7 +277,7 @@ function hideMyStoriesFrom(
|
||||
return;
|
||||
}
|
||||
|
||||
const toAdd = new Set<UUIDStringType>(memberUuids);
|
||||
const toAdd = new Set<ServiceIdString>(memberServiceIds);
|
||||
|
||||
await dataInterface.modifyStoryDistributionWithMembers(
|
||||
{
|
||||
@@ -296,17 +297,17 @@ function hideMyStoriesFrom(
|
||||
|
||||
dispatch({
|
||||
type: HIDE_MY_STORIES_FROM,
|
||||
payload: memberUuids,
|
||||
payload: memberServiceIds,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function removeMembersFromDistributionList(
|
||||
listId: string,
|
||||
memberUuids: Array<UUIDStringType>
|
||||
memberServiceIds: Array<ServiceIdString>
|
||||
): ThunkAction<void, RootStateType, null, ModifyListActionType> {
|
||||
return async dispatch => {
|
||||
if (!memberUuids.length) {
|
||||
if (!memberServiceIds.length) {
|
||||
log.warn(
|
||||
'storyDistributionLists.removeMembersFromDistributionList cannot remove a member without uuid',
|
||||
listId
|
||||
@@ -325,8 +326,8 @@ function removeMembersFromDistributionList(
|
||||
return;
|
||||
}
|
||||
|
||||
let toAdd: Array<UUIDStringType> = [];
|
||||
let toRemove: Array<UUIDStringType> = memberUuids;
|
||||
let toAdd: Array<ServiceIdString> = [];
|
||||
let toRemove: Array<ServiceIdString> = memberServiceIds;
|
||||
let { isBlockList } = storyDistribution;
|
||||
|
||||
// My Story is set to 'All Signal Connections' or is already an exclude list
|
||||
@@ -335,7 +336,7 @@ function removeMembersFromDistributionList(
|
||||
(storyDistribution.members.length === 0 || isBlockList)
|
||||
) {
|
||||
isBlockList = true;
|
||||
toAdd = memberUuids;
|
||||
toAdd = memberServiceIds;
|
||||
toRemove = [];
|
||||
|
||||
// The user has now configured My Stories
|
||||
@@ -358,7 +359,7 @@ function removeMembersFromDistributionList(
|
||||
'storyDistributionLists.removeMembersFromDistributionList: removed',
|
||||
{
|
||||
listId,
|
||||
memberUuids,
|
||||
memberServiceIds,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -421,7 +422,7 @@ function setMyStoriesToAllSignalConnections(): ThunkAction<
|
||||
|
||||
function updateStoryViewers(
|
||||
listId: string,
|
||||
memberUuids: Array<UUIDStringType>
|
||||
memberServiceIds: Array<ServiceIdString>
|
||||
): ThunkAction<void, RootStateType, null, ViewersChangedActionType> {
|
||||
return async dispatch => {
|
||||
const storyDistribution =
|
||||
@@ -435,17 +436,17 @@ function updateStoryViewers(
|
||||
return;
|
||||
}
|
||||
|
||||
const existingUuids = new Set<UUIDStringType>(storyDistribution.members);
|
||||
const toAdd: Array<UUIDStringType> = [];
|
||||
const existingUuids = new Set<ServiceIdString>(storyDistribution.members);
|
||||
const toAdd: Array<ServiceIdString> = [];
|
||||
|
||||
memberUuids.forEach(uuid => {
|
||||
memberServiceIds.forEach(uuid => {
|
||||
if (!existingUuids.has(uuid)) {
|
||||
toAdd.push(uuid);
|
||||
}
|
||||
});
|
||||
|
||||
const updatedUuids = new Set<UUIDStringType>(memberUuids);
|
||||
const toRemove: Array<UUIDStringType> = [];
|
||||
const updatedUuids = new Set<ServiceIdString>(memberServiceIds);
|
||||
const toRemove: Array<ServiceIdString> = [];
|
||||
|
||||
storyDistribution.members.forEach(uuid => {
|
||||
if (!updatedUuids.has(uuid)) {
|
||||
@@ -475,14 +476,14 @@ function updateStoryViewers(
|
||||
type: VIEWERS_CHANGED,
|
||||
payload: {
|
||||
listId,
|
||||
memberUuids,
|
||||
memberServiceIds,
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function removeMemberFromAllDistributionLists(
|
||||
member: UUIDStringType
|
||||
member: ServiceIdString
|
||||
): ThunkAction<void, RootStateType, null, ModifyListActionType> {
|
||||
return async dispatch => {
|
||||
const logId = `removeMemberFromAllDistributionLists(${member})`;
|
||||
@@ -558,17 +559,17 @@ export function reducer(
|
||||
);
|
||||
if (listIndex >= 0) {
|
||||
const existingDistributionList = state.distributionLists[listIndex];
|
||||
const memberUuids = new Set<UUIDStringType>(
|
||||
existingDistributionList.memberUuids
|
||||
const memberServiceIds = new Set<ServiceIdString>(
|
||||
existingDistributionList.memberServiceIds
|
||||
);
|
||||
membersToAdd.forEach(uuid => memberUuids.add(uuid));
|
||||
membersToRemove.forEach(uuid => memberUuids.delete(uuid));
|
||||
membersToAdd.forEach(uuid => memberServiceIds.add(uuid));
|
||||
membersToRemove.forEach(uuid => memberServiceIds.delete(uuid));
|
||||
|
||||
return {
|
||||
distributionLists: replaceIndex(state.distributionLists, listIndex, {
|
||||
...existingDistributionList,
|
||||
...distributionListDetails,
|
||||
memberUuids: Array.from(memberUuids),
|
||||
memberServiceIds: Array.from(memberServiceIds),
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -578,7 +579,7 @@ export function reducer(
|
||||
...state.distributionLists,
|
||||
{
|
||||
...distributionListDetails,
|
||||
memberUuids: membersToAdd,
|
||||
memberServiceIds: membersToAdd,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -596,7 +597,7 @@ export function reducer(
|
||||
action.payload.listId,
|
||||
() => ({
|
||||
deletedAtTimestamp: action.payload.deletedAtTimestamp,
|
||||
memberUuids: [],
|
||||
memberServiceIds: [],
|
||||
name: '',
|
||||
})
|
||||
);
|
||||
@@ -610,7 +611,7 @@ export function reducer(
|
||||
MY_STORY_ID,
|
||||
() => ({
|
||||
isBlockList: true,
|
||||
memberUuids: action.payload,
|
||||
memberServiceIds: action.payload,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -635,7 +636,7 @@ export function reducer(
|
||||
action.payload.listId,
|
||||
() => ({
|
||||
isBlockList: false,
|
||||
memberUuids: Array.from(new Set(action.payload.memberUuids)),
|
||||
memberServiceIds: Array.from(new Set(action.payload.memberServiceIds)),
|
||||
})
|
||||
);
|
||||
|
||||
@@ -648,7 +649,7 @@ export function reducer(
|
||||
MY_STORY_ID,
|
||||
() => ({
|
||||
isBlockList: true,
|
||||
memberUuids: [],
|
||||
memberServiceIds: [],
|
||||
})
|
||||
);
|
||||
|
||||
|
@@ -8,7 +8,7 @@ import type { LocaleMessagesType } from '../../types/I18N';
|
||||
import type { LocalizerType } from '../../types/Util';
|
||||
import type { MenuOptionsType } from '../../types/menu';
|
||||
import type { NoopActionType } from './noop';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { AciString, PniString } from '../../types/ServiceId';
|
||||
import OS from '../../util/os/osMain';
|
||||
import { ThemeType } from '../../types/Util';
|
||||
|
||||
@@ -24,11 +24,11 @@ export type UserStateType = Readonly<{
|
||||
localeMessages: LocaleMessagesType;
|
||||
menuOptions: MenuOptionsType;
|
||||
osName: 'linux' | 'macos' | 'windows' | undefined;
|
||||
ourACI: UUIDStringType | undefined;
|
||||
ourAci: AciString | undefined;
|
||||
ourConversationId: string | undefined;
|
||||
ourDeviceId: number | undefined;
|
||||
ourNumber: string | undefined;
|
||||
ourPNI: UUIDStringType | undefined;
|
||||
ourPni: PniString | undefined;
|
||||
platform: string;
|
||||
regionCode: string | undefined;
|
||||
stickersPath: string;
|
||||
@@ -44,8 +44,8 @@ type UserChangedActionType = ReadonlyDeep<{
|
||||
payload: {
|
||||
ourConversationId?: string;
|
||||
ourDeviceId?: number;
|
||||
ourACI?: UUIDStringType;
|
||||
ourPNI?: UUIDStringType;
|
||||
ourAci?: AciString;
|
||||
ourPni?: PniString;
|
||||
ourNumber?: string;
|
||||
regionCode?: string;
|
||||
interactionMode?: 'mouse' | 'keyboard';
|
||||
@@ -70,8 +70,8 @@ function userChanged(attributes: {
|
||||
ourConversationId?: string;
|
||||
ourDeviceId?: number;
|
||||
ourNumber?: string;
|
||||
ourACI?: UUIDStringType;
|
||||
ourPNI?: UUIDStringType;
|
||||
ourAci?: AciString;
|
||||
ourPni?: PniString;
|
||||
regionCode?: string;
|
||||
theme?: ThemeType;
|
||||
isMainWindowMaximized?: boolean;
|
||||
@@ -132,11 +132,11 @@ export function getEmptyState(): UserStateType {
|
||||
platform: 'unknown',
|
||||
},
|
||||
osName,
|
||||
ourACI: undefined,
|
||||
ourAci: undefined,
|
||||
ourConversationId: 'missing',
|
||||
ourDeviceId: 0,
|
||||
ourNumber: 'missing',
|
||||
ourPNI: undefined,
|
||||
ourPni: undefined,
|
||||
platform: 'missing',
|
||||
regionCode: 'missing',
|
||||
stickersPath: 'missing',
|
||||
|
@@ -35,7 +35,6 @@ 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 { UUIDKind } from '../types/UUID';
|
||||
import { getEmojiReducerState as emojis } from '../util/loadRecentEmojis';
|
||||
import { getInitialState as stickers } from '../types/Stickers';
|
||||
import { getThemeType } from '../util/getThemeType';
|
||||
@@ -65,12 +64,8 @@ export function getInitialState({
|
||||
conversation.format()
|
||||
);
|
||||
const ourNumber = window.textsecure.storage.user.getNumber();
|
||||
const ourACI = window.textsecure.storage.user
|
||||
.getUuid(UUIDKind.ACI)
|
||||
?.toString();
|
||||
const ourPNI = window.textsecure.storage.user
|
||||
.getUuid(UUIDKind.PNI)
|
||||
?.toString();
|
||||
const ourAci = window.textsecure.storage.user.getAci();
|
||||
const ourPni = window.textsecure.storage.user.getPni();
|
||||
const ourConversationId =
|
||||
window.ConversationController.getOurConversationId();
|
||||
const ourDeviceId = window.textsecure.storage.user.getDeviceId();
|
||||
@@ -145,11 +140,11 @@ export function getInitialState({
|
||||
localeMessages: window.i18n.getLocaleMessages(),
|
||||
menuOptions,
|
||||
osName,
|
||||
ourACI,
|
||||
ourAci,
|
||||
ourConversationId,
|
||||
ourDeviceId,
|
||||
ourNumber,
|
||||
ourPNI,
|
||||
ourPni,
|
||||
platform: window.platform,
|
||||
regionCode: window.storage.get('regionCode'),
|
||||
stickersPath: window.BasePaths.stickers,
|
||||
|
@@ -5,14 +5,14 @@ import { createSelector } from 'reselect';
|
||||
|
||||
import type { StateType } from '../reducer';
|
||||
import type { AccountsStateType } from '../ducks/accounts';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
|
||||
export const getAccounts = (state: StateType): AccountsStateType =>
|
||||
state.accounts;
|
||||
|
||||
export type AccountSelectorType = (
|
||||
identifier?: string
|
||||
) => UUIDStringType | undefined;
|
||||
) => ServiceIdString | undefined;
|
||||
export const getAccountSelector = createSelector(
|
||||
getAccounts,
|
||||
(accounts: AccountsStateType): AccountSelectorType => {
|
||||
|
@@ -28,7 +28,7 @@ import { getMessageIdForLogging } from '../../util/idForLogging';
|
||||
import * as Attachment from '../../types/Attachment';
|
||||
import type { ActiveAudioPlayerStateType } from '../ducks/audioPlayer';
|
||||
import { isPlayed } from '../../types/Attachment';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
|
||||
export type VoiceNoteForPlayback = {
|
||||
id: string;
|
||||
@@ -36,7 +36,7 @@ export type VoiceNoteForPlayback = {
|
||||
url: string | undefined;
|
||||
type: 'incoming' | 'outgoing';
|
||||
source: string | undefined;
|
||||
sourceUuid: UUIDStringType | undefined;
|
||||
sourceUuid: ServiceIdString | undefined;
|
||||
isPlayed: boolean;
|
||||
messageIdForLogging: string;
|
||||
timestamp: number;
|
||||
@@ -58,12 +58,12 @@ export const selectVoiceNoteTitle = createSelector(
|
||||
getUserConversationId,
|
||||
getConversationSelector,
|
||||
getIntl,
|
||||
(ourNumber, ourACI, ourConversationId, conversationSelector, i18n) => {
|
||||
(ourNumber, ourAci, ourConversationId, conversationSelector, i18n) => {
|
||||
return (
|
||||
message: Pick<MessageAttributesType, 'type' | 'source' | 'sourceUuid'>
|
||||
) => {
|
||||
const source = getSource(message, ourNumber);
|
||||
const sourceUuid = getSourceUuid(message, ourACI);
|
||||
const sourceUuid = getSourceUuid(message, ourAci);
|
||||
|
||||
const conversation =
|
||||
!source && !sourceUuid
|
||||
|
@@ -15,7 +15,7 @@ import { getIncomingCall as getIncomingCallHelper } from '../ducks/callingHelper
|
||||
import { getUserACI } from './user';
|
||||
import { getOwn } from '../../util/getOwn';
|
||||
import { CallViewMode } from '../../types/Calling';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { AciString } from '../../types/ServiceId';
|
||||
|
||||
export type CallStateType = DirectCallStateType | GroupCallStateType;
|
||||
|
||||
@@ -70,13 +70,13 @@ export const getIncomingCall = createSelector(
|
||||
getUserACI,
|
||||
(
|
||||
callsByConversation: CallsByConversationType,
|
||||
ourUuid: UUIDStringType | undefined
|
||||
ourAci: AciString | undefined
|
||||
): undefined | DirectCallStateType | GroupCallStateType => {
|
||||
if (!ourUuid) {
|
||||
if (!ourAci) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getIncomingCallHelper(callsByConversation, ourUuid);
|
||||
return getIncomingCallHelper(callsByConversation, ourAci);
|
||||
}
|
||||
);
|
||||
|
||||
|
@@ -6,6 +6,7 @@
|
||||
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import { normalizeStoryDistributionId } from '../../types/StoryDistributionId';
|
||||
import type { ContactsByStory } from '../../components/SafetyNumberChangeDialog';
|
||||
import type { ConversationVerificationData } from '../ducks/conversations';
|
||||
import type { StoryDistributionListDataType } from '../ducks/storyDistributionLists';
|
||||
@@ -41,22 +42,22 @@ export const getByDistributionListConversationsStoppingSend = createSelector(
|
||||
return;
|
||||
}
|
||||
|
||||
const conversationUuids = new Set(
|
||||
conversationData.uuidsNeedingVerification
|
||||
const conversationServiceIds = new Set(
|
||||
conversationData.serviceIdsNeedingVerification
|
||||
);
|
||||
|
||||
if (conversationData.byDistributionId) {
|
||||
Object.entries(conversationData.byDistributionId).forEach(
|
||||
([distributionId, distributionData]) => {
|
||||
if (distributionData.uuidsNeedingVerification.length === 0) {
|
||||
if (distributionData.serviceIdsNeedingVerification.length === 0) {
|
||||
return;
|
||||
}
|
||||
const currentDistribution =
|
||||
distributionListSelector(distributionId);
|
||||
|
||||
if (!currentDistribution) {
|
||||
distributionData.uuidsNeedingVerification.forEach(uuid => {
|
||||
conversationUuids.add(uuid);
|
||||
distributionData.serviceIdsNeedingVerification.forEach(uuid => {
|
||||
conversationServiceIds.add(uuid);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -64,18 +65,21 @@ export const getByDistributionListConversationsStoppingSend = createSelector(
|
||||
conversations.push({
|
||||
story: {
|
||||
conversationId,
|
||||
distributionId,
|
||||
distributionId: normalizeStoryDistributionId(
|
||||
distributionId,
|
||||
'conversations-extra'
|
||||
),
|
||||
name: currentDistribution.name,
|
||||
},
|
||||
contacts: distributionData.uuidsNeedingVerification.map(uuid =>
|
||||
conversationSelector(uuid)
|
||||
contacts: distributionData.serviceIdsNeedingVerification.map(
|
||||
uuid => conversationSelector(uuid)
|
||||
),
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (conversationUuids.size) {
|
||||
if (conversationServiceIds.size) {
|
||||
const currentConversation = conversationSelector(conversationId);
|
||||
conversations.push({
|
||||
story: isGroup(currentConversation)
|
||||
@@ -84,7 +88,7 @@ export const getByDistributionListConversationsStoppingSend = createSelector(
|
||||
name: currentConversation.title,
|
||||
}
|
||||
: undefined,
|
||||
contacts: Array.from(conversationUuids).map(uuid =>
|
||||
contacts: Array.from(conversationServiceIds).map(uuid =>
|
||||
conversationSelector(uuid)
|
||||
),
|
||||
});
|
||||
|
@@ -37,7 +37,7 @@ import {
|
||||
import type { ContactNameColorType } from '../../types/Colors';
|
||||
import { ContactNameColors } from '../../types/Colors';
|
||||
import type { AvatarDataType } from '../../types/Avatar';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
import { isInSystemContacts } from '../../util/isInSystemContacts';
|
||||
import { isSignalConnection } from '../../util/getSignalConnections';
|
||||
import { sortByTitle } from '../../util/sortByTitle';
|
||||
@@ -871,7 +871,7 @@ export const getConversationByIdSelector = createSelector(
|
||||
export const getConversationByUuidSelector = createSelector(
|
||||
getConversationsByUuid,
|
||||
conversationsByUuid =>
|
||||
(uuid: UUIDStringType): undefined | ConversationType =>
|
||||
(uuid: ServiceIdString): undefined | ConversationType =>
|
||||
getOwn(conversationsByUuid, uuid)
|
||||
);
|
||||
|
||||
@@ -1042,9 +1042,9 @@ export const getInvitedContactsForNewlyCreatedGroup = createSelector(
|
||||
getConversations,
|
||||
(
|
||||
conversationLookup,
|
||||
{ invitedUuidsForNewlyCreatedGroup = [] }
|
||||
{ invitedServiceIdsForNewlyCreatedGroup = [] }
|
||||
): Array<ConversationType> =>
|
||||
deconstructLookup(conversationLookup, invitedUuidsForNewlyCreatedGroup)
|
||||
deconstructLookup(conversationLookup, invitedServiceIdsForNewlyCreatedGroup)
|
||||
);
|
||||
|
||||
export const getConversationsWithCustomColorSelector = createSelector(
|
||||
@@ -1127,20 +1127,20 @@ export const getConversationIdsStoppedForVerification = createSelector(
|
||||
Object.keys(verificationDataByConversation)
|
||||
);
|
||||
|
||||
export const getConversationUuidsStoppingSend = createSelector(
|
||||
export const getConversationServiceIdsStoppingSend = createSelector(
|
||||
getConversationVerificationData,
|
||||
(pendingData): Array<string> => {
|
||||
const result = new Set<string>();
|
||||
(pendingData): Array<ServiceIdString> => {
|
||||
const result = new Set<ServiceIdString>();
|
||||
Object.values(pendingData).forEach(item => {
|
||||
if (item.type === ConversationVerificationState.PendingVerification) {
|
||||
item.uuidsNeedingVerification.forEach(conversationId => {
|
||||
result.add(conversationId);
|
||||
item.serviceIdsNeedingVerification.forEach(serviceId => {
|
||||
result.add(serviceId);
|
||||
});
|
||||
|
||||
if (item.byDistributionId) {
|
||||
Object.values(item.byDistributionId).forEach(distribution => {
|
||||
distribution.uuidsNeedingVerification.forEach(conversationId => {
|
||||
result.add(conversationId);
|
||||
distribution.serviceIdsNeedingVerification.forEach(serviceId => {
|
||||
result.add(serviceId);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1152,12 +1152,14 @@ export const getConversationUuidsStoppingSend = createSelector(
|
||||
|
||||
export const getConversationsStoppingSend = createSelector(
|
||||
getConversationSelector,
|
||||
getConversationUuidsStoppingSend,
|
||||
getConversationServiceIdsStoppingSend,
|
||||
(
|
||||
conversationSelector: GetConversationByIdType,
|
||||
uuids: ReadonlyArray<string>
|
||||
serviceIds: ReadonlyArray<ServiceIdString>
|
||||
): Array<ConversationType> => {
|
||||
const conversations = uuids.map(uuid => conversationSelector(uuid));
|
||||
const conversations = serviceIds.map(serviceId =>
|
||||
conversationSelector(serviceId)
|
||||
);
|
||||
return sortByTitle(conversations);
|
||||
}
|
||||
);
|
||||
|
@@ -14,7 +14,7 @@ import type {
|
||||
ConversationColorType,
|
||||
CustomColorType,
|
||||
} from '../../types/Colors';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { AciString } from '../../types/ServiceId';
|
||||
import { DEFAULT_CONVERSATION_COLOR } from '../../types/Colors';
|
||||
import { getPreferredReactionEmoji as getPreferredReactionEmojiFromStoredValue } from '../../reactions/preferredReactionEmoji';
|
||||
import { isBeta } from '../../util/version';
|
||||
@@ -60,7 +60,7 @@ const isRemoteConfigBucketEnabled = (
|
||||
config: Readonly<ConfigMapType>,
|
||||
name: ConfigKeyType,
|
||||
e164: string | undefined,
|
||||
uuid: UUIDStringType | undefined
|
||||
uuid: AciString | undefined
|
||||
): boolean => {
|
||||
const flagValue = config[name]?.value;
|
||||
return innerIsBucketValueEnabled(name, flagValue, e164, uuid);
|
||||
@@ -140,7 +140,7 @@ export const getStoriesEnabled = createSelector(
|
||||
state: ItemsStateType,
|
||||
remoteConfig: ConfigMapType,
|
||||
e164: string | undefined,
|
||||
aci: UUIDStringType | undefined
|
||||
aci: AciString | undefined
|
||||
): boolean => {
|
||||
if (state.hasStoriesDisabled) {
|
||||
return false;
|
||||
|
@@ -42,7 +42,11 @@ import type { PropsType as ProfileChangeNotificationPropsType } from '../../comp
|
||||
import type { QuotedAttachmentType } from '../../components/conversation/Quote';
|
||||
|
||||
import { getDomain, isStickerPack } from '../../types/LinkPreview';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type {
|
||||
AciString,
|
||||
PniString,
|
||||
ServiceIdString,
|
||||
} from '../../types/ServiceId';
|
||||
|
||||
import type { EmbeddedContactType } from '../../types/EmbeddedContact';
|
||||
import { embeddedContactSelector } from '../../types/EmbeddedContact';
|
||||
@@ -82,9 +86,9 @@ import {
|
||||
getIntl,
|
||||
getRegionCode,
|
||||
getUserACI,
|
||||
getUserPNI,
|
||||
getUserConversationId,
|
||||
getUserNumber,
|
||||
getUserPNI,
|
||||
} from './user';
|
||||
|
||||
import type {
|
||||
@@ -161,8 +165,8 @@ export type GetPropsForBubbleOptions = Readonly<{
|
||||
conversationSelector: GetConversationByIdType;
|
||||
ourConversationId?: string;
|
||||
ourNumber?: string;
|
||||
ourACI?: UUIDStringType;
|
||||
ourPNI?: UUIDStringType;
|
||||
ourAci: AciString | undefined;
|
||||
ourPni: PniString | undefined;
|
||||
targetedMessageId?: string;
|
||||
targetedMessageCounter?: number;
|
||||
selectedMessageIds: ReadonlyArray<string> | undefined;
|
||||
@@ -214,8 +218,8 @@ export function getSourceDevice(
|
||||
|
||||
export function getSourceUuid(
|
||||
message: Pick<MessageAttributesType, 'type' | 'sourceUuid'>,
|
||||
ourACI: string | undefined
|
||||
): string | undefined {
|
||||
ourAci: AciString | undefined
|
||||
): ServiceIdString | undefined {
|
||||
if (isIncoming(message)) {
|
||||
return message.sourceUuid;
|
||||
}
|
||||
@@ -225,16 +229,12 @@ export function getSourceUuid(
|
||||
);
|
||||
}
|
||||
|
||||
return ourACI;
|
||||
return ourAci;
|
||||
}
|
||||
|
||||
export type GetContactOptions = Pick<
|
||||
GetPropsForBubbleOptions,
|
||||
| 'conversationSelector'
|
||||
| 'ourConversationId'
|
||||
| 'ourNumber'
|
||||
| 'ourACI'
|
||||
| 'ourPNI'
|
||||
'conversationSelector' | 'ourConversationId' | 'ourNumber' | 'ourAci'
|
||||
>;
|
||||
|
||||
export function getContactId(
|
||||
@@ -243,11 +243,11 @@ export function getContactId(
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
ourNumber,
|
||||
ourACI,
|
||||
ourAci,
|
||||
}: GetContactOptions
|
||||
): string | undefined {
|
||||
const source = getSource(message, ourNumber);
|
||||
const sourceUuid = getSourceUuid(message, ourACI);
|
||||
const sourceUuid = getSourceUuid(message, ourAci);
|
||||
|
||||
if (!source && !sourceUuid) {
|
||||
return ourConversationId;
|
||||
@@ -264,11 +264,11 @@ export function getContact(
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
ourNumber,
|
||||
ourACI,
|
||||
ourAci,
|
||||
}: GetContactOptions
|
||||
): ConversationType {
|
||||
const source = getSource(message, ourNumber);
|
||||
const sourceUuid = getSourceUuid(message, ourACI);
|
||||
const sourceUuid = getSourceUuid(message, ourAci);
|
||||
|
||||
if (!source && !sourceUuid) {
|
||||
return conversationSelector(ourConversationId);
|
||||
@@ -578,8 +578,8 @@ export type GetPropsForMessageOptions = Pick<
|
||||
GetPropsForBubbleOptions,
|
||||
| 'conversationSelector'
|
||||
| 'ourConversationId'
|
||||
| 'ourACI'
|
||||
| 'ourPNI'
|
||||
| 'ourAci'
|
||||
| 'ourPni'
|
||||
| 'ourNumber'
|
||||
| 'targetedMessageId'
|
||||
| 'targetedMessageCounter'
|
||||
@@ -675,7 +675,7 @@ export const getPropsForMessage = (
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
ourNumber,
|
||||
ourACI,
|
||||
ourAci,
|
||||
regionCode,
|
||||
targetedMessageId,
|
||||
targetedMessageCounter,
|
||||
@@ -706,7 +706,7 @@ export const getPropsForMessage = (
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
ourNumber,
|
||||
ourACI,
|
||||
ourAci,
|
||||
});
|
||||
const contactNameColor = contactNameColorSelector(conversationId, authorId);
|
||||
|
||||
@@ -788,8 +788,8 @@ export const getMessagePropsSelector = createSelector(
|
||||
(
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
ourACI,
|
||||
ourPNI,
|
||||
ourAci,
|
||||
ourPni,
|
||||
ourNumber,
|
||||
regionCode,
|
||||
accountSelector,
|
||||
@@ -804,8 +804,8 @@ export const getMessagePropsSelector = createSelector(
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
ourNumber,
|
||||
ourACI,
|
||||
ourPNI,
|
||||
ourAci,
|
||||
ourPni,
|
||||
regionCode,
|
||||
targetedMessageCounter: targetedMessage?.counter,
|
||||
targetedMessageId: targetedMessage?.id,
|
||||
@@ -1008,7 +1008,7 @@ export function isGroupV2Change(message: MessageWithUIFieldsType): boolean {
|
||||
|
||||
function getPropsForGroupV2Change(
|
||||
message: MessageWithUIFieldsType,
|
||||
{ conversationSelector, ourACI, ourPNI }: GetPropsForBubbleOptions
|
||||
{ conversationSelector, ourAci, ourPni }: GetPropsForBubbleOptions
|
||||
): GroupsV2Props {
|
||||
const change = message.groupV2Change;
|
||||
|
||||
@@ -1024,8 +1024,8 @@ function getPropsForGroupV2Change(
|
||||
groupName: conversation?.type === 'group' ? conversation?.name : undefined,
|
||||
groupMemberships: conversation.memberships,
|
||||
groupBannedMemberships: conversation.bannedMemberships,
|
||||
ourACI,
|
||||
ourPNI,
|
||||
ourAci,
|
||||
ourPni,
|
||||
change,
|
||||
};
|
||||
}
|
||||
@@ -1611,7 +1611,7 @@ export function getMessagePropStatus(
|
||||
export function getPropsForEmbeddedContact(
|
||||
message: MessageWithUIFieldsType,
|
||||
regionCode: string | undefined,
|
||||
accountSelector: (identifier?: string) => UUIDStringType | undefined
|
||||
accountSelector: (identifier?: string) => ServiceIdString | undefined
|
||||
): EmbeddedContactType | undefined {
|
||||
const contacts = message.contact;
|
||||
if (!contacts || !contacts.length) {
|
||||
@@ -1911,8 +1911,8 @@ export const getMessageDetails = createSelector(
|
||||
i18n,
|
||||
regionCode,
|
||||
message,
|
||||
ourACI,
|
||||
ourPNI,
|
||||
ourAci,
|
||||
ourPni,
|
||||
ourConversationId,
|
||||
ourNumber,
|
||||
selectedMessageIds
|
||||
@@ -1943,7 +1943,7 @@ export const getMessageDetails = createSelector(
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
ourNumber,
|
||||
ourACI,
|
||||
ourAci,
|
||||
}),
|
||||
].filter(isNotNil);
|
||||
} else if (!isEmpty(sendStateByConversationId)) {
|
||||
@@ -1985,15 +1985,15 @@ export const getMessageDetails = createSelector(
|
||||
// If an error has a specific number it's associated with, we'll show it next to
|
||||
// that contact. Otherwise, it will be a standalone entry.
|
||||
const errors = allErrors.filter(error =>
|
||||
Boolean(error.identifier || error.number)
|
||||
Boolean(error.serviceId || error.number)
|
||||
);
|
||||
const errorsGroupedById = groupBy(allErrors, error => {
|
||||
const identifier = error.identifier || error.number;
|
||||
if (!identifier) {
|
||||
const serviceId = error.serviceId || error.number;
|
||||
if (!serviceId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return window.ConversationController.getConversationId(identifier);
|
||||
return window.ConversationController.getConversationId(serviceId);
|
||||
});
|
||||
|
||||
const hasUnidentifiedDeliveryIndicators = window.storage.get(
|
||||
@@ -2045,10 +2045,10 @@ export const getMessageDetails = createSelector(
|
||||
accountSelector,
|
||||
contactNameColorSelector,
|
||||
conversationSelector,
|
||||
ourACI,
|
||||
ourAci,
|
||||
ourPni,
|
||||
ourConversationId,
|
||||
ourNumber,
|
||||
ourPNI,
|
||||
regionCode,
|
||||
selectedMessageIds,
|
||||
}),
|
||||
|
@@ -31,6 +31,8 @@ export const getDistributionListsWithMembers = createSelector(
|
||||
): Array<StoryDistributionListWithMembersDataType> =>
|
||||
distributionLists.map(list => ({
|
||||
...list,
|
||||
members: list.memberUuids.map(uuid => conversationSelector(uuid)),
|
||||
members: list.memberServiceIds.map(serviceId =>
|
||||
conversationSelector(serviceId)
|
||||
),
|
||||
}))
|
||||
);
|
||||
|
@@ -42,8 +42,8 @@ export const getTimelineItem = (
|
||||
const conversationSelector = getConversationSelector(state);
|
||||
const regionCode = getRegionCode(state);
|
||||
const ourNumber = getUserNumber(state);
|
||||
const ourACI = getUserACI(state);
|
||||
const ourPNI = getUserPNI(state);
|
||||
const ourAci = getUserACI(state);
|
||||
const ourPni = getUserPNI(state);
|
||||
const ourConversationId = getUserConversationId(state);
|
||||
const callSelector = getCallSelector(state);
|
||||
const callHistorySelector = getCallHistorySelector(state);
|
||||
@@ -56,8 +56,8 @@ export const getTimelineItem = (
|
||||
conversationSelector,
|
||||
ourConversationId,
|
||||
ourNumber,
|
||||
ourACI,
|
||||
ourPNI,
|
||||
ourAci,
|
||||
ourPni,
|
||||
regionCode,
|
||||
targetedMessageId: targetedMessage?.id,
|
||||
targetedMessageCounter: targetedMessage?.counter,
|
||||
|
@@ -4,7 +4,7 @@
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import type { LocalizerType, ThemeType } from '../../types/Util';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { AciString, PniString } from '../../types/ServiceId';
|
||||
import type { LocaleMessagesType } from '../../types/I18N';
|
||||
import type { MenuOptionsType } from '../../types/menu';
|
||||
|
||||
@@ -37,12 +37,12 @@ export const getUserConversationId = createSelector(
|
||||
|
||||
export const getUserACI = createSelector(
|
||||
getUser,
|
||||
(state: UserStateType): UUIDStringType | undefined => state.ourACI
|
||||
(state: UserStateType): AciString | undefined => state.ourAci
|
||||
);
|
||||
|
||||
export const getUserPNI = createSelector(
|
||||
getUser,
|
||||
(state: UserStateType): UUIDStringType | undefined => state.ourPNI
|
||||
(state: UserStateType): PniString | undefined => state.ourPni
|
||||
);
|
||||
|
||||
export const getIntl = createSelector(
|
||||
|
@@ -17,7 +17,7 @@ import type {
|
||||
ActiveCallType,
|
||||
GroupCallRemoteParticipantType,
|
||||
} from '../../types/Calling';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { AciString } from '../../types/ServiceId';
|
||||
import { CallMode, CallState } from '../../types/Calling';
|
||||
import type { StateType } from '../reducer';
|
||||
import { missingCaseError } from '../../util/missingCaseError';
|
||||
@@ -127,14 +127,14 @@ const mapStateToActiveCallProp = (
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const conversationSelectorByUuid = memoize<
|
||||
(uuid: UUIDStringType) => undefined | ConversationType
|
||||
>(uuid => {
|
||||
const convoForUuid = window.ConversationController.lookupOrCreate({
|
||||
uuid,
|
||||
const conversationSelectorByAci = memoize<
|
||||
(aci: AciString) => undefined | ConversationType
|
||||
>(aci => {
|
||||
const convoForAci = window.ConversationController.lookupOrCreate({
|
||||
uuid: aci,
|
||||
reason: 'CallManager.mapStateToActiveCallProp',
|
||||
});
|
||||
return convoForUuid ? conversationSelector(convoForUuid.id) : undefined;
|
||||
return convoForAci ? conversationSelector(convoForAci.id) : undefined;
|
||||
});
|
||||
|
||||
const baseResult = {
|
||||
@@ -194,7 +194,7 @@ const mapStateToActiveCallProp = (
|
||||
peekInfo = {
|
||||
deviceCount: 0,
|
||||
maxDevices: Infinity,
|
||||
uuids: [],
|
||||
acis: [],
|
||||
},
|
||||
} = call;
|
||||
|
||||
@@ -213,8 +213,8 @@ const mapStateToActiveCallProp = (
|
||||
for (let i = 0; i < call.remoteParticipants.length; i += 1) {
|
||||
const remoteParticipant = call.remoteParticipants[i];
|
||||
|
||||
const remoteConversation = conversationSelectorByUuid(
|
||||
remoteParticipant.uuid
|
||||
const remoteConversation = conversationSelectorByAci(
|
||||
remoteParticipant.aci
|
||||
);
|
||||
if (!remoteConversation) {
|
||||
log.error('Remote participant has no corresponding conversation');
|
||||
@@ -235,12 +235,12 @@ const mapStateToActiveCallProp = (
|
||||
|
||||
for (
|
||||
let i = 0;
|
||||
i < activeCallState.safetyNumberChangedUuids.length;
|
||||
i < activeCallState.safetyNumberChangedAcis.length;
|
||||
i += 1
|
||||
) {
|
||||
const uuid = activeCallState.safetyNumberChangedUuids[i];
|
||||
const aci = activeCallState.safetyNumberChangedAcis[i];
|
||||
|
||||
const remoteConversation = conversationSelectorByUuid(uuid);
|
||||
const remoteConversation = conversationSelectorByAci(aci);
|
||||
if (!remoteConversation) {
|
||||
log.error('Remote participant has no corresponding conversation');
|
||||
continue;
|
||||
@@ -249,12 +249,11 @@ const mapStateToActiveCallProp = (
|
||||
conversationsWithSafetyNumberChanges.push(remoteConversation);
|
||||
}
|
||||
|
||||
for (let i = 0; i < peekInfo.uuids.length; i += 1) {
|
||||
const peekedParticipantUuid = peekInfo.uuids[i];
|
||||
for (let i = 0; i < peekInfo.acis.length; i += 1) {
|
||||
const peekedParticipantAci = peekInfo.acis[i];
|
||||
|
||||
const peekedConversation = conversationSelectorByUuid(
|
||||
peekedParticipantUuid
|
||||
);
|
||||
const peekedConversation =
|
||||
conversationSelectorByAci(peekedParticipantAci);
|
||||
if (!peekedConversation) {
|
||||
log.error('Remote participant has no corresponding conversation');
|
||||
continue;
|
||||
@@ -303,13 +302,13 @@ const mapStateToIncomingCallProp = (state: StateType) => {
|
||||
isVideoCall: call.isVideoCall,
|
||||
};
|
||||
case CallMode.Group: {
|
||||
if (!call.ringerUuid) {
|
||||
if (!call.ringerAci) {
|
||||
log.error('The incoming group call has no ring state');
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const conversationSelector = getConversationSelector(state);
|
||||
const ringer = conversationSelector(call.ringerUuid);
|
||||
const ringer = conversationSelector(call.ringerAci);
|
||||
const otherMembersRung = (conversation.sortedGroupMembers ?? []).filter(
|
||||
c => c.id !== ringer.id && !c.isMe
|
||||
);
|
||||
|
@@ -6,7 +6,7 @@ import { connect } from 'react-redux';
|
||||
import type { StateType } from '../reducer';
|
||||
import { mapDispatchToProps } from '../actions';
|
||||
import { strictAssert } from '../../util/assert';
|
||||
import { lookupConversationWithoutUuid } from '../../util/lookupConversationWithoutUuid';
|
||||
import { lookupConversationWithoutServiceId } from '../../util/lookupConversationWithoutServiceId';
|
||||
|
||||
import type { StatePropsType } from '../../components/conversation/conversation-details/AddGroupMembersModal/ChooseGroupMembersModal';
|
||||
import { ChooseGroupMembersModal } from '../../components/conversation/conversation-details/AddGroupMembersModal/ChooseGroupMembersModal';
|
||||
@@ -55,7 +55,7 @@ const mapStateToProps = (
|
||||
i18n: getIntl(state),
|
||||
theme: getTheme(state),
|
||||
selectedContacts,
|
||||
lookupConversationWithoutUuid,
|
||||
lookupConversationWithoutServiceId,
|
||||
isUsernamesEnabled: getUsernamesEnabled(state),
|
||||
};
|
||||
};
|
||||
|
@@ -45,8 +45,8 @@ const getOutgoingCallButtonStyle = (
|
||||
state: StateType
|
||||
): OutgoingCallButtonStyle => {
|
||||
const { calling } = state;
|
||||
const ourACI = getUserACI(state);
|
||||
strictAssert(ourACI, 'getOutgoingCallButtonStyle missing our uuid');
|
||||
const ourAci = getUserACI(state);
|
||||
strictAssert(ourAci, 'getOutgoingCallButtonStyle missing our uuid');
|
||||
|
||||
if (getActiveCall(calling)) {
|
||||
return OutgoingCallButtonStyle.None;
|
||||
@@ -62,7 +62,7 @@ const getOutgoingCallButtonStyle = (
|
||||
const call = getOwn(calling.callsByConversation, conversation.id);
|
||||
if (
|
||||
call?.callMode === CallMode.Group &&
|
||||
isAnybodyElseInGroupCall(call.peekInfo, ourACI)
|
||||
isAnybodyElseInGroupCall(call.peekInfo, ourAci)
|
||||
) {
|
||||
return OutgoingCallButtonStyle.Join;
|
||||
}
|
||||
|
@@ -333,7 +333,7 @@ function PanelElement({
|
||||
return (
|
||||
<SmartPendingInvites
|
||||
conversationId={conversationId}
|
||||
ourUuid={window.storage.user.getCheckedUuid().toString()}
|
||||
ourAci={window.storage.user.getCheckedAci()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ import { DialogExpiredBuild } from '../../components/DialogExpiredBuild';
|
||||
import type { PropsType as DialogExpiredBuildPropsType } from '../../components/DialogExpiredBuild';
|
||||
import type { StateType } from '../reducer';
|
||||
import { missingCaseError } from '../../util/missingCaseError';
|
||||
import { lookupConversationWithoutUuid } from '../../util/lookupConversationWithoutUuid';
|
||||
import { lookupConversationWithoutServiceId } from '../../util/lookupConversationWithoutServiceId';
|
||||
import { isDone as isRegistrationDone } from '../../util/registration';
|
||||
|
||||
import { ComposerStep, OneTimeModalState } from '../ducks/conversationsEnums';
|
||||
@@ -246,7 +246,7 @@ const mapStateToProps = (state: StateType) => {
|
||||
renderCrashReportDialog,
|
||||
renderExpiredBuildDialog,
|
||||
renderUnsupportedOSDialog,
|
||||
lookupConversationWithoutUuid,
|
||||
lookupConversationWithoutServiceId,
|
||||
theme: getTheme(state),
|
||||
};
|
||||
};
|
||||
|
@@ -15,11 +15,11 @@ import {
|
||||
} from '../selectors/conversations';
|
||||
import { getGroupMemberships } from '../../util/getGroupMemberships';
|
||||
import { assertDev } from '../../util/assert';
|
||||
import type { UUIDStringType } from '../../types/UUID';
|
||||
import type { AciString } from '../../types/ServiceId';
|
||||
|
||||
export type SmartPendingInvitesProps = {
|
||||
conversationId: string;
|
||||
ourUuid: UUIDStringType;
|
||||
ourAci: AciString;
|
||||
};
|
||||
|
||||
const mapStateToProps = (
|
||||
|
Reference in New Issue
Block a user