Migrate most React class components to function components

This commit is contained in:
Jamie Kyle 2023-04-12 16:17:56 -07:00 committed by GitHub
parent 4c9baaef80
commit 558b5a4a38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 1444 additions and 1775 deletions

View file

@ -32,146 +32,152 @@ type PropsHousekeeping = {
export type Props = PropsData & PropsHousekeeping;
export class GroupNotification extends React.Component<Props> {
public renderChange(
change: Change,
from: ConversationType
): JSX.Element | string | null | undefined {
const { contacts, type, newName } = change;
const { i18n } = this.props;
function GroupNotificationChange({
change,
from,
i18n,
}: {
change: Change;
from: ConversationType;
i18n: LocalizerType;
}): JSX.Element | null {
const { contacts, type, newName } = change;
const otherPeople: Array<JSX.Element> = compact(
(contacts || []).map(contact => {
if (contact.isMe) {
return null;
}
const otherPeople: Array<JSX.Element> = compact(
(contacts || []).map(contact => {
if (contact.isMe) {
return null;
}
return (
<span
key={`external-${contact.id}`}
className="module-group-notification__contact"
>
<ContactName title={contact.title} />
</span>
);
})
);
const otherPeopleWithCommas: Array<JSX.Element | string> = compact(
flatten(
otherPeople.map((person, index) => [index > 0 ? ', ' : null, person])
)
);
const contactsIncludesMe = (contacts || []).length !== otherPeople.length;
return (
<span
key={`external-${contact.id}`}
className="module-group-notification__contact"
>
<ContactName title={contact.title} />
</span>
);
})
);
const otherPeopleWithCommas: Array<JSX.Element | string> = compact(
flatten(
otherPeople.map((person, index) => [index > 0 ? ', ' : null, person])
)
);
const contactsIncludesMe = (contacts || []).length !== otherPeople.length;
switch (type) {
case 'name':
return (
<Intl
i18n={i18n}
id="icu:titleIsNow"
components={{ name: newName || '' }}
/>
);
case 'avatar':
return <Intl i18n={i18n} id="icu:updatedGroupAvatar" />;
case 'add':
if (!contacts || !contacts.length) {
throw new Error('Group update is missing contacts');
}
switch (type) {
case 'name':
return (
<Intl
i18n={i18n}
id="icu:titleIsNow"
components={{ name: newName || '' }}
/>
);
case 'avatar':
return <Intl i18n={i18n} id="icu:updatedGroupAvatar" />;
case 'add':
if (!contacts || !contacts.length) {
throw new Error('Group update is missing contacts');
}
return (
<>
{otherPeople.length > 0 && (
<>
{otherPeople.length === 1 ? (
<Intl
i18n={i18n}
id="icu:joinedTheGroup"
components={{ name: otherPeopleWithCommas }}
/>
) : (
<Intl
i18n={i18n}
id="icu:multipleJoinedTheGroup"
components={{ names: otherPeopleWithCommas }}
/>
)}
</>
)}
{contactsIncludesMe && (
<div className="module-group-notification__change">
<Intl i18n={i18n} id="icu:youJoinedTheGroup" />
</div>
)}
</>
);
case 'remove':
if (from && from.isMe) {
return i18n('icu:youLeftTheGroup');
}
if (!contacts || !contacts.length) {
throw new Error('Group update is missing contacts');
}
return contacts.length > 1 ? (
<Intl
id="icu:multipleLeftTheGroup"
i18n={i18n}
components={{ name: otherPeopleWithCommas }}
/>
) : (
<Intl
id="icu:leftTheGroup"
i18n={i18n}
components={{ name: otherPeopleWithCommas }}
/>
);
case 'general':
return;
default:
throw missingCaseError(type);
}
}
public override render(): JSX.Element {
const { changes: rawChanges, i18n, from } = this.props;
// This check is just to be extra careful, and can probably be removed.
const changes: Array<Change> = Array.isArray(rawChanges) ? rawChanges : [];
// Leave messages are always from the person leaving, so we omit the fromLabel if
// the change is a 'leave.'
const firstChange: undefined | Change = changes[0];
const isLeftOnly = changes.length === 1 && firstChange?.type === 'remove';
const fromLabel = from.isMe ? (
<Intl i18n={i18n} id="icu:youUpdatedTheGroup" />
) : (
<Intl
i18n={i18n}
id="icu:updatedTheGroup"
components={{ name: <ContactName title={from.title} /> }}
/>
);
let contents: ReactNode;
if (isLeftOnly) {
contents = this.renderChange(firstChange, from);
} else {
contents = (
return (
<>
<p>{fromLabel}</p>
{changes.map((change, i) => (
// eslint-disable-next-line react/no-array-index-key
<p key={i} className="module-group-notification__change">
{this.renderChange(change, from)}
</p>
))}
{otherPeople.length > 0 && (
<>
{otherPeople.length === 1 ? (
<Intl
i18n={i18n}
id="icu:joinedTheGroup"
components={{ name: otherPeopleWithCommas }}
/>
) : (
<Intl
i18n={i18n}
id="icu:multipleJoinedTheGroup"
components={{ names: otherPeopleWithCommas }}
/>
)}
</>
)}
{contactsIncludesMe && (
<div className="module-group-notification__change">
<Intl i18n={i18n} id="icu:youJoinedTheGroup" />
</div>
)}
</>
);
}
case 'remove':
if (from && from.isMe) {
return <>{i18n('icu:youLeftTheGroup')}</>;
}
return <SystemMessage contents={contents} icon="group" />;
if (!contacts || !contacts.length) {
throw new Error('Group update is missing contacts');
}
return contacts.length > 1 ? (
<Intl
id="icu:multipleLeftTheGroup"
i18n={i18n}
components={{ name: otherPeopleWithCommas }}
/>
) : (
<Intl
id="icu:leftTheGroup"
i18n={i18n}
components={{ name: otherPeopleWithCommas }}
/>
);
case 'general':
return null;
default:
throw missingCaseError(type);
}
}
export function GroupNotification({
changes: rawChanges,
i18n,
from,
}: Props): JSX.Element {
// This check is just to be extra careful, and can probably be removed.
const changes: Array<Change> = Array.isArray(rawChanges) ? rawChanges : [];
// Leave messages are always from the person leaving, so we omit the fromLabel if
// the change is a 'leave.'
const firstChange: undefined | Change = changes[0];
const isLeftOnly = changes.length === 1 && firstChange?.type === 'remove';
const fromLabel = from.isMe ? (
<Intl i18n={i18n} id="icu:youUpdatedTheGroup" />
) : (
<Intl
i18n={i18n}
id="icu:updatedTheGroup"
components={{ name: <ContactName title={from.title} /> }}
/>
);
let contents: ReactNode;
if (isLeftOnly) {
contents = (
<GroupNotificationChange change={firstChange} from={from} i18n={i18n} />
);
} else {
contents = (
<>
<p>{fromLabel}</p>
{changes.map((change, i) => (
// eslint-disable-next-line react/no-array-index-key
<p key={i} className="module-group-notification__change">
<GroupNotificationChange change={change} from={from} i18n={i18n} />
</p>
))}
</>
);
}
return <SystemMessage contents={contents} icon="group" />;
}