Migrate most React class components to function components
This commit is contained in:
parent
4c9baaef80
commit
558b5a4a38
23 changed files with 1444 additions and 1775 deletions
|
@ -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" />;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue