Backups: Handle groupV2 notifications
This commit is contained in:
parent
4c4ab306eb
commit
5df8924197
27 changed files with 4563 additions and 301 deletions
|
@ -36,11 +36,13 @@ const contact3: ConversationType = getDefaultConversation({
|
|||
|
||||
const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
||||
areWeInvited: Boolean(overrideProps.areWeInvited),
|
||||
droppedMembers: overrideProps.droppedMembers || [contact3, contact1],
|
||||
droppedMembers: overrideProps.droppedMembers,
|
||||
droppedMemberCount: overrideProps.droppedMemberCount || 0,
|
||||
getPreferredBadge: () => undefined,
|
||||
hasMigrated: Boolean(overrideProps.hasMigrated),
|
||||
i18n,
|
||||
invitedMembers: overrideProps.invitedMembers || [contact2],
|
||||
invitedMembers: overrideProps.invitedMembers,
|
||||
invitedMemberCount: overrideProps.invitedMemberCount || 0,
|
||||
onMigrate: action('onMigrate'),
|
||||
onClose: action('onClose'),
|
||||
theme: ThemeType.light,
|
||||
|
@ -75,23 +77,41 @@ export function MigratedYouAreInvited(): JSX.Element {
|
|||
);
|
||||
}
|
||||
|
||||
export function NotYetMigratedMultipleDroppedAndInvitedMembers(): JSX.Element {
|
||||
export function MigratedMultipleDroppedAndInvitedMember(): JSX.Element {
|
||||
return (
|
||||
<GroupV1MigrationDialog
|
||||
{...createProps({
|
||||
droppedMembers: [contact3, contact1, contact2],
|
||||
invitedMembers: [contact2, contact3, contact1],
|
||||
hasMigrated: true,
|
||||
droppedMembers: [contact1],
|
||||
droppedMemberCount: 1,
|
||||
invitedMembers: [contact2],
|
||||
invitedMemberCount: 1,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function NotYetMigratedNoMembers(): JSX.Element {
|
||||
export function MigratedMultipleDroppedAndInvitedMembers(): JSX.Element {
|
||||
return (
|
||||
<GroupV1MigrationDialog
|
||||
{...createProps({
|
||||
droppedMembers: [],
|
||||
invitedMembers: [],
|
||||
hasMigrated: true,
|
||||
droppedMembers: [contact3, contact1, contact2],
|
||||
droppedMemberCount: 3,
|
||||
invitedMembers: [contact2, contact3, contact1],
|
||||
invitedMemberCount: 3,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function MigratedNoMembers(): JSX.Element {
|
||||
return (
|
||||
<GroupV1MigrationDialog
|
||||
{...createProps({
|
||||
hasMigrated: true,
|
||||
droppedMemberCount: 0,
|
||||
invitedMemberCount: 0,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
|
@ -101,7 +121,65 @@ export function NotYetMigratedJustDroppedMember(): JSX.Element {
|
|||
return (
|
||||
<GroupV1MigrationDialog
|
||||
{...createProps({
|
||||
invitedMembers: [],
|
||||
droppedMembers: [contact1],
|
||||
droppedMemberCount: 1,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function NotYetMigratedJustDroppedMembers(): JSX.Element {
|
||||
return (
|
||||
<GroupV1MigrationDialog
|
||||
{...createProps({
|
||||
droppedMembers: [contact1, contact2],
|
||||
droppedMemberCount: 2,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function NotYetMigratedDropped1(): JSX.Element {
|
||||
return (
|
||||
<GroupV1MigrationDialog
|
||||
{...createProps({
|
||||
droppedMemberCount: 1,
|
||||
invitedMemberCount: 0,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function NotYetMigratedDropped2(): JSX.Element {
|
||||
return (
|
||||
<GroupV1MigrationDialog
|
||||
{...createProps({
|
||||
droppedMemberCount: 2,
|
||||
invitedMemberCount: 0,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function MigratedJustCountIs1(): JSX.Element {
|
||||
return (
|
||||
<GroupV1MigrationDialog
|
||||
{...createProps({
|
||||
hasMigrated: true,
|
||||
droppedMemberCount: 1,
|
||||
invitedMemberCount: 1,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function MigratedJustCountIs2(): JSX.Element {
|
||||
return (
|
||||
<GroupV1MigrationDialog
|
||||
{...createProps({
|
||||
hasMigrated: true,
|
||||
droppedMemberCount: 2,
|
||||
invitedMemberCount: 2,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -11,9 +11,11 @@ import { missingCaseError } from '../util/missingCaseError';
|
|||
|
||||
export type DataPropsType = {
|
||||
readonly areWeInvited: boolean;
|
||||
readonly droppedMembers: Array<ConversationType>;
|
||||
readonly droppedMembers?: Array<ConversationType>;
|
||||
readonly droppedMemberCount: number;
|
||||
readonly hasMigrated: boolean;
|
||||
readonly invitedMembers: Array<ConversationType>;
|
||||
readonly invitedMembers?: Array<ConversationType>;
|
||||
readonly invitedMemberCount: number;
|
||||
readonly getPreferredBadge: PreferredBadgeSelectorType;
|
||||
readonly i18n: LocalizerType;
|
||||
readonly theme: ThemeType;
|
||||
|
@ -30,10 +32,12 @@ export const GroupV1MigrationDialog: React.FunctionComponent<PropsType> =
|
|||
React.memo(function GroupV1MigrationDialogInner({
|
||||
areWeInvited,
|
||||
droppedMembers,
|
||||
droppedMemberCount,
|
||||
getPreferredBadge,
|
||||
hasMigrated,
|
||||
i18n,
|
||||
invitedMembers,
|
||||
invitedMemberCount,
|
||||
theme,
|
||||
onClose,
|
||||
onMigrate,
|
||||
|
@ -88,6 +92,7 @@ export const GroupV1MigrationDialog: React.FunctionComponent<PropsType> =
|
|||
getPreferredBadge,
|
||||
i18n,
|
||||
members: invitedMembers,
|
||||
count: invitedMemberCount,
|
||||
hasMigrated,
|
||||
kind: 'invited',
|
||||
theme,
|
||||
|
@ -96,6 +101,7 @@ export const GroupV1MigrationDialog: React.FunctionComponent<PropsType> =
|
|||
getPreferredBadge,
|
||||
i18n,
|
||||
members: droppedMembers,
|
||||
count: droppedMemberCount,
|
||||
hasMigrated,
|
||||
kind: 'dropped',
|
||||
theme,
|
||||
|
@ -110,21 +116,50 @@ function renderMembers({
|
|||
getPreferredBadge,
|
||||
i18n,
|
||||
members,
|
||||
count,
|
||||
hasMigrated,
|
||||
kind,
|
||||
theme,
|
||||
}: Readonly<{
|
||||
getPreferredBadge: PreferredBadgeSelectorType;
|
||||
i18n: LocalizerType;
|
||||
members: Array<ConversationType>;
|
||||
members?: Array<ConversationType>;
|
||||
count: number;
|
||||
hasMigrated: boolean;
|
||||
kind: 'invited' | 'dropped';
|
||||
theme: ThemeType;
|
||||
}>): React.ReactNode {
|
||||
if (!members.length) {
|
||||
if (count === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!members) {
|
||||
if (kind === 'invited') {
|
||||
return (
|
||||
<GroupDialog.Paragraph>
|
||||
{i18n('icu:GroupV1--Migration--info--invited--count', { count })}
|
||||
</GroupDialog.Paragraph>
|
||||
);
|
||||
}
|
||||
if (hasMigrated) {
|
||||
return (
|
||||
<GroupDialog.Paragraph>
|
||||
{i18n('icu:GroupV1--Migration--info--removed--after--count', {
|
||||
count,
|
||||
})}
|
||||
</GroupDialog.Paragraph>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<GroupDialog.Paragraph>
|
||||
{i18n('icu:GroupV1--Migration--info--removed--before--count', {
|
||||
count,
|
||||
})}
|
||||
</GroupDialog.Paragraph>
|
||||
);
|
||||
}
|
||||
|
||||
let text: string;
|
||||
switch (kind) {
|
||||
case 'invited':
|
||||
|
@ -137,13 +172,13 @@ function renderMembers({
|
|||
if (hasMigrated) {
|
||||
text =
|
||||
members.length === 1
|
||||
? i18n('icu:GroupV1--Migration--info--removed--before--one')
|
||||
: i18n('icu:GroupV1--Migration--info--removed--before--many');
|
||||
? i18n('icu:GroupV1--Migration--info--removed--after--one')
|
||||
: i18n('icu:GroupV1--Migration--info--removed--after--many');
|
||||
} else {
|
||||
text =
|
||||
members.length === 1
|
||||
? i18n('icu:GroupV1--Migration--info--removed--after--one')
|
||||
: i18n('icu:GroupV1--Migration--info--removed--after--many');
|
||||
? i18n('icu:GroupV1--Migration--info--removed--before--one')
|
||||
: i18n('icu:GroupV1--Migration--info--removed--before--many');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -33,9 +33,11 @@ export default {
|
|||
areWeInvited: false,
|
||||
conversationId: '123',
|
||||
droppedMembers: [contact1],
|
||||
droppedMemberCount: 1,
|
||||
getPreferredBadge: () => undefined,
|
||||
i18n,
|
||||
invitedMembers: [contact2],
|
||||
invitedMemberCount: 1,
|
||||
theme: ThemeType.light,
|
||||
},
|
||||
} satisfies Meta<PropsType>;
|
||||
|
@ -55,7 +57,9 @@ export function MultipleDroppedAndInvitedMembers(args: PropsType): JSX.Element {
|
|||
<GroupV1Migration
|
||||
{...args}
|
||||
invitedMembers={[contact1, contact2]}
|
||||
invitedMemberCount={3}
|
||||
droppedMembers={[contact1, contact2]}
|
||||
droppedMemberCount={3}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -65,7 +69,9 @@ export function JustInvitedMembers(args: PropsType): JSX.Element {
|
|||
<GroupV1Migration
|
||||
{...args}
|
||||
invitedMembers={[contact1, contact1, contact2, contact2]}
|
||||
invitedMemberCount={4}
|
||||
droppedMembers={[]}
|
||||
droppedMemberCount={0}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -75,11 +81,45 @@ export function JustDroppedMembers(args: PropsType): JSX.Element {
|
|||
<GroupV1Migration
|
||||
{...args}
|
||||
invitedMembers={[]}
|
||||
invitedMemberCount={0}
|
||||
droppedMembers={[contact1, contact1, contact2, contact2]}
|
||||
droppedMemberCount={4}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function NoDroppedOrInvitedMembers(args: PropsType): JSX.Element {
|
||||
return <GroupV1Migration {...args} invitedMembers={[]} droppedMembers={[]} />;
|
||||
return (
|
||||
<GroupV1Migration
|
||||
{...args}
|
||||
invitedMembers={[]}
|
||||
invitedMemberCount={0}
|
||||
droppedMembers={[]}
|
||||
droppedMemberCount={0}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function NoArraysCountIsZero(args: PropsType): JSX.Element {
|
||||
return (
|
||||
<GroupV1Migration
|
||||
{...args}
|
||||
invitedMembers={undefined}
|
||||
invitedMemberCount={0}
|
||||
droppedMembers={undefined}
|
||||
droppedMemberCount={0}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function NoArraysWithCount(args: PropsType): JSX.Element {
|
||||
return (
|
||||
<GroupV1Migration
|
||||
{...args}
|
||||
invitedMembers={undefined}
|
||||
invitedMemberCount={4}
|
||||
droppedMembers={undefined}
|
||||
droppedMemberCount={2}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -16,8 +16,10 @@ import * as log from '../../logging/log';
|
|||
export type PropsDataType = {
|
||||
areWeInvited: boolean;
|
||||
conversationId: string;
|
||||
droppedMembers: Array<ConversationType>;
|
||||
invitedMembers: Array<ConversationType>;
|
||||
droppedMembers?: Array<ConversationType>;
|
||||
invitedMembers?: Array<ConversationType>;
|
||||
droppedMemberCount: number;
|
||||
invitedMemberCount: number;
|
||||
};
|
||||
|
||||
export type PropsHousekeepingType = {
|
||||
|
@ -32,9 +34,11 @@ export function GroupV1Migration(props: PropsType): React.ReactElement {
|
|||
const {
|
||||
areWeInvited,
|
||||
droppedMembers,
|
||||
droppedMemberCount,
|
||||
getPreferredBadge,
|
||||
i18n,
|
||||
invitedMembers,
|
||||
invitedMemberCount,
|
||||
theme,
|
||||
} = props;
|
||||
const [showingDialog, setShowingDialog] = React.useState(false);
|
||||
|
@ -55,12 +59,23 @@ export function GroupV1Migration(props: PropsType): React.ReactElement {
|
|||
<>
|
||||
<p>{i18n('icu:GroupV1--Migration--was-upgraded')}</p>
|
||||
<p>
|
||||
{' '}
|
||||
{areWeInvited ? (
|
||||
i18n('icu:GroupV1--Migration--invited--you')
|
||||
) : (
|
||||
<>
|
||||
{renderUsers(invitedMembers, i18n, 'invited')}
|
||||
{renderUsers(droppedMembers, i18n, 'removed')}
|
||||
{renderUsers({
|
||||
members: invitedMembers,
|
||||
count: invitedMemberCount,
|
||||
i18n,
|
||||
kind: 'invited',
|
||||
})}
|
||||
{renderUsers({
|
||||
members: droppedMembers,
|
||||
count: droppedMemberCount,
|
||||
i18n,
|
||||
kind: 'removed',
|
||||
})}
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
|
@ -80,10 +95,12 @@ export function GroupV1Migration(props: PropsType): React.ReactElement {
|
|||
<GroupV1MigrationDialog
|
||||
areWeInvited={areWeInvited}
|
||||
droppedMembers={droppedMembers}
|
||||
droppedMemberCount={droppedMemberCount}
|
||||
getPreferredBadge={getPreferredBadge}
|
||||
hasMigrated
|
||||
i18n={i18n}
|
||||
invitedMembers={invitedMembers}
|
||||
invitedMemberCount={invitedMemberCount}
|
||||
onMigrate={() => log.warn('GroupV1Migration: Modal called migrate()')}
|
||||
onClose={dismissDialog}
|
||||
theme={theme}
|
||||
|
@ -93,16 +110,22 @@ export function GroupV1Migration(props: PropsType): React.ReactElement {
|
|||
);
|
||||
}
|
||||
|
||||
function renderUsers(
|
||||
members: Array<ConversationType>,
|
||||
i18n: LocalizerType,
|
||||
kind: 'invited' | 'removed'
|
||||
): React.ReactElement | null {
|
||||
if (!members || members.length === 0) {
|
||||
function renderUsers({
|
||||
members,
|
||||
count,
|
||||
i18n,
|
||||
kind,
|
||||
}: {
|
||||
members?: Array<ConversationType>;
|
||||
count: number;
|
||||
i18n: LocalizerType;
|
||||
kind: 'invited' | 'removed';
|
||||
}): React.ReactElement | null {
|
||||
if (count === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (members.length === 1) {
|
||||
if (members && count === 1) {
|
||||
const contact = <ContactName title={members[0].title} />;
|
||||
return (
|
||||
<p>
|
||||
|
@ -124,18 +147,16 @@ function renderUsers(
|
|||
);
|
||||
}
|
||||
|
||||
const count = members.length;
|
||||
|
||||
return (
|
||||
<p>
|
||||
{kind === 'invited' && members.length > 1 && (
|
||||
{kind === 'invited' && (
|
||||
<Intl
|
||||
i18n={i18n}
|
||||
id="icu:GroupV1--Migration--invited--many"
|
||||
components={{ count }}
|
||||
/>
|
||||
)}
|
||||
{kind === 'removed' && members.length > 1 && (
|
||||
{kind === 'removed' && (
|
||||
<Intl
|
||||
i18n={i18n}
|
||||
id="icu:GroupV1--Migration--removed--many"
|
||||
|
|
|
@ -14,16 +14,31 @@ import type { SmartContactRendererType } from '../../groupChange';
|
|||
import type { PropsType } from './GroupV2Change';
|
||||
import { GroupV2Change } from './GroupV2Change';
|
||||
|
||||
// Note: this should be kept up to date with backup_groupv2_notifications_test.ts, to
|
||||
// maintain the comprehensive set of GroupV2 notifications we need to handle
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
const OUR_ACI = generateAci();
|
||||
const OUR_PNI = generatePni();
|
||||
const CONTACT_A = generateAci();
|
||||
const CONTACT_A_PNI = generatePni();
|
||||
const CONTACT_B = generateAci();
|
||||
const CONTACT_C = generateAci();
|
||||
const ADMIN_A = generateAci();
|
||||
const INVITEE_A = generateAci();
|
||||
|
||||
const contactMap = {
|
||||
[OUR_ACI]: 'YOU',
|
||||
[OUR_PNI]: 'YOU',
|
||||
[CONTACT_A]: 'CONTACT_A',
|
||||
[CONTACT_A_PNI]: 'CONTACT_A',
|
||||
[CONTACT_B]: 'CONTACT_B',
|
||||
[CONTACT_C]: 'CONTACT_C',
|
||||
[ADMIN_A]: 'ADMIN_A',
|
||||
[INVITEE_A]: 'INVITEE_A',
|
||||
};
|
||||
|
||||
const AccessControlEnum = Proto.AccessControl.AccessRequired;
|
||||
const RoleEnum = Proto.Member.Role;
|
||||
|
||||
|
@ -31,10 +46,17 @@ const renderContact: SmartContactRendererType<JSX.Element> = (
|
|||
conversationId: string
|
||||
) => (
|
||||
<React.Fragment key={conversationId}>
|
||||
{`Conversation(${conversationId})`}
|
||||
{contactMap[conversationId] || 'UNKNOWN'}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
function checkServiceIdEquivalence(
|
||||
left: ServiceIdString | undefined,
|
||||
right: ServiceIdString | undefined
|
||||
): boolean {
|
||||
return Boolean(left && right && contactMap[left] === contactMap[right]);
|
||||
}
|
||||
|
||||
const renderChange = (
|
||||
change: GroupV2ChangeType,
|
||||
{
|
||||
|
@ -57,6 +79,7 @@ const renderChange = (
|
|||
blockGroupLinkRequests={action('blockGroupLinkRequests')}
|
||||
conversationId="some-conversation-id"
|
||||
change={change}
|
||||
checkServiceIdEquivalence={checkServiceIdEquivalence}
|
||||
groupBannedMemberships={groupBannedMemberships}
|
||||
groupMemberships={groupMemberships}
|
||||
groupName={groupName}
|
||||
|
@ -603,6 +626,24 @@ export function MemberAddFromInvited(): JSX.Element {
|
|||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: OUR_PNI,
|
||||
details: [
|
||||
{
|
||||
type: 'member-add-from-invite',
|
||||
aci: OUR_ACI,
|
||||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: CONTACT_A_PNI,
|
||||
details: [
|
||||
{
|
||||
type: 'member-add-from-invite',
|
||||
aci: CONTACT_A,
|
||||
},
|
||||
],
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -923,6 +964,15 @@ export function PendingAddMany(): JSX.Element {
|
|||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: OUR_ACI,
|
||||
details: [
|
||||
{
|
||||
type: 'pending-add-many',
|
||||
count: 1,
|
||||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: CONTACT_A,
|
||||
details: [
|
||||
|
@ -932,11 +982,28 @@ export function PendingAddMany(): JSX.Element {
|
|||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: CONTACT_A,
|
||||
details: [
|
||||
{
|
||||
type: 'pending-add-many',
|
||||
count: 1,
|
||||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
details: [
|
||||
{
|
||||
type: 'pending-add-many',
|
||||
count: 5,
|
||||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
details: [
|
||||
{
|
||||
type: 'pending-add-many',
|
||||
count: 5,
|
||||
count: 1,
|
||||
},
|
||||
],
|
||||
})}
|
||||
|
@ -1100,6 +1167,16 @@ export function PendingRemoveMany(): JSX.Element {
|
|||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: OUR_ACI,
|
||||
details: [
|
||||
{
|
||||
type: 'pending-remove-many',
|
||||
count: 1,
|
||||
inviter: OUR_ACI,
|
||||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: ADMIN_A,
|
||||
details: [
|
||||
|
@ -1110,11 +1187,30 @@ export function PendingRemoveMany(): JSX.Element {
|
|||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: ADMIN_A,
|
||||
details: [
|
||||
{
|
||||
type: 'pending-remove-many',
|
||||
count: 1,
|
||||
inviter: OUR_ACI,
|
||||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
details: [
|
||||
{
|
||||
type: 'pending-remove-many',
|
||||
count: 5,
|
||||
inviter: OUR_ACI,
|
||||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
details: [
|
||||
{
|
||||
type: 'pending-remove-many',
|
||||
count: 5,
|
||||
count: 1,
|
||||
inviter: OUR_ACI,
|
||||
},
|
||||
],
|
||||
|
@ -1129,6 +1225,16 @@ export function PendingRemoveMany(): JSX.Element {
|
|||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: OUR_ACI,
|
||||
details: [
|
||||
{
|
||||
type: 'pending-remove-many',
|
||||
count: 1,
|
||||
inviter: CONTACT_A,
|
||||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: ADMIN_A,
|
||||
details: [
|
||||
|
@ -1139,6 +1245,16 @@ export function PendingRemoveMany(): JSX.Element {
|
|||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: ADMIN_A,
|
||||
details: [
|
||||
{
|
||||
type: 'pending-remove-many',
|
||||
count: 1,
|
||||
inviter: CONTACT_A,
|
||||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
details: [
|
||||
{
|
||||
|
@ -1148,6 +1264,15 @@ export function PendingRemoveMany(): JSX.Element {
|
|||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
details: [
|
||||
{
|
||||
type: 'pending-remove-many',
|
||||
count: 1,
|
||||
inviter: CONTACT_A,
|
||||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: OUR_ACI,
|
||||
details: [
|
||||
|
@ -1157,6 +1282,15 @@ export function PendingRemoveMany(): JSX.Element {
|
|||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: OUR_ACI,
|
||||
details: [
|
||||
{
|
||||
type: 'pending-remove-many',
|
||||
count: 1,
|
||||
},
|
||||
],
|
||||
})}
|
||||
|
||||
{renderChange({
|
||||
from: CONTACT_A,
|
||||
|
@ -1167,6 +1301,15 @@ export function PendingRemoveMany(): JSX.Element {
|
|||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: CONTACT_A,
|
||||
details: [
|
||||
{
|
||||
type: 'pending-remove-many',
|
||||
count: 1,
|
||||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
details: [
|
||||
{
|
||||
|
@ -1175,6 +1318,14 @@ export function PendingRemoveMany(): JSX.Element {
|
|||
},
|
||||
],
|
||||
})}
|
||||
{renderChange({
|
||||
details: [
|
||||
{
|
||||
type: 'pending-remove-many',
|
||||
count: 1,
|
||||
},
|
||||
],
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1183,6 +1334,7 @@ export function AdminApprovalAdd(): JSX.Element {
|
|||
return (
|
||||
<>
|
||||
{renderChange({
|
||||
from: OUR_ACI,
|
||||
details: [
|
||||
{
|
||||
type: 'admin-approval-add-one',
|
||||
|
@ -1191,6 +1343,7 @@ export function AdminApprovalAdd(): JSX.Element {
|
|||
],
|
||||
})}
|
||||
{renderChange({
|
||||
from: CONTACT_A,
|
||||
details: [
|
||||
{
|
||||
type: 'admin-approval-add-one',
|
||||
|
@ -1332,6 +1485,21 @@ export function AdminApprovalBounce(): JSX.Element {
|
|||
|
||||
{ groupBannedMemberships: [CONTACT_A] }
|
||||
)}
|
||||
Open request
|
||||
{renderChange(
|
||||
{
|
||||
from: CONTACT_A,
|
||||
details: [
|
||||
{
|
||||
type: 'admin-approval-bounce',
|
||||
aci: CONTACT_A,
|
||||
times: 4,
|
||||
isApprovalPending: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{ groupBannedMemberships: [] }
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -29,16 +29,16 @@ import { ConfirmationDialog } from '../ConfirmationDialog';
|
|||
|
||||
export type PropsDataType = {
|
||||
areWeAdmin: boolean;
|
||||
change: GroupV2ChangeType;
|
||||
conversationId: string;
|
||||
groupBannedMemberships?: ReadonlyArray<ServiceIdString>;
|
||||
groupMemberships?: ReadonlyArray<{
|
||||
aci: AciString;
|
||||
isAdmin: boolean;
|
||||
}>;
|
||||
groupBannedMemberships?: ReadonlyArray<ServiceIdString>;
|
||||
groupName?: string;
|
||||
ourAci: AciString | undefined;
|
||||
ourPni: PniString | undefined;
|
||||
change: GroupV2ChangeType;
|
||||
};
|
||||
|
||||
export type PropsActionsType = {
|
||||
|
@ -49,6 +49,10 @@ export type PropsActionsType = {
|
|||
};
|
||||
|
||||
export type PropsHousekeepingType = {
|
||||
checkServiceIdEquivalence(
|
||||
left: ServiceIdString | undefined,
|
||||
right: ServiceIdString | undefined
|
||||
): boolean;
|
||||
i18n: LocalizerType;
|
||||
renderContact: SmartContactRendererType<JSX.Element>;
|
||||
};
|
||||
|
@ -293,6 +297,7 @@ export function GroupV2Change(props: PropsType): ReactElement {
|
|||
areWeAdmin,
|
||||
blockGroupLinkRequests,
|
||||
change,
|
||||
checkServiceIdEquivalence,
|
||||
conversationId,
|
||||
groupBannedMemberships,
|
||||
groupMemberships,
|
||||
|
@ -306,6 +311,7 @@ export function GroupV2Change(props: PropsType): ReactElement {
|
|||
return (
|
||||
<>
|
||||
{renderChange<JSX.Element>(change, {
|
||||
checkServiceIdEquivalence,
|
||||
i18n,
|
||||
ourAci,
|
||||
ourPni,
|
||||
|
|
|
@ -361,6 +361,7 @@ const renderItem = ({
|
|||
isNextItemCallingNotification={false}
|
||||
theme={ThemeType.light}
|
||||
platform="darwin"
|
||||
checkServiceIdEquivalence={() => false}
|
||||
containerElementRef={containerElementRef}
|
||||
containerWidthBreakpoint={containerWidthBreakpoint}
|
||||
conversationId=""
|
||||
|
|
|
@ -69,6 +69,7 @@ const getDefaultProps = () => ({
|
|||
toggleSelectMessage: action('toggleSelectMessage'),
|
||||
reactToMessage: action('reactToMessage'),
|
||||
checkForAccount: action('checkForAccount'),
|
||||
checkServiceIdEquivalence: () => false,
|
||||
clearTargetedMessage: action('clearTargetedMessage'),
|
||||
setMessageToEdit: action('setMessageToEdit'),
|
||||
setQuoteByMessageId: action('setQuoteByMessageId'),
|
||||
|
|
|
@ -61,6 +61,7 @@ import {
|
|||
type MessageRequestResponseNotificationData,
|
||||
} from './MessageRequestResponseNotification';
|
||||
import type { MessageRequestState } from './MessageRequestActionsConfirmation';
|
||||
import type { ServiceIdString } from '../../types/ServiceId';
|
||||
|
||||
type CallHistoryType = {
|
||||
type: 'callHistory';
|
||||
|
@ -172,6 +173,10 @@ export type TimelineItemType = (
|
|||
) & { timestamp: number };
|
||||
|
||||
type PropsLocalType = {
|
||||
checkServiceIdEquivalence(
|
||||
left: ServiceIdString | undefined,
|
||||
right: ServiceIdString | undefined
|
||||
): boolean;
|
||||
containerElementRef: RefObject<HTMLElement>;
|
||||
conversationId: string;
|
||||
item?: TimelineItemType;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue