Introduce Service Id Types

Co-authored-by: Scott Nonnenberg <scott@signal.org>
This commit is contained in:
Fedor Indutny
2023-08-10 18:43:33 +02:00
committed by Jamie Kyle
parent 414c0a58d3
commit 366b875fd2
269 changed files with 5832 additions and 5550 deletions

View File

@@ -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,
},
};
}

View File

@@ -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: [],
},
};
}

View File

@@ -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));

View File

@@ -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,
};
}

View File

@@ -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);
}

View File

@@ -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: {

View File

@@ -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 });
}
})
);

View File

@@ -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,
},
},
};

View File

@@ -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: [],
})
);

View File

@@ -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',

View File

@@ -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,

View File

@@ -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 => {

View File

@@ -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

View File

@@ -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);
}
);

View File

@@ -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)
),
});

View File

@@ -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);
}
);

View File

@@ -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;

View File

@@ -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,
}),

View File

@@ -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)
),
}))
);

View File

@@ -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,

View File

@@ -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(

View File

@@ -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
);

View File

@@ -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),
};
};

View File

@@ -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;
}

View File

@@ -333,7 +333,7 @@ function PanelElement({
return (
<SmartPendingInvites
conversationId={conversationId}
ourUuid={window.storage.user.getCheckedUuid().toString()}
ourAci={window.storage.user.getCheckedAci()}
/>
);
}

View File

@@ -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),
};
};

View File

@@ -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 = (