Streamlined system messages
This commit is contained in:
parent
1973224adb
commit
2b08cbfdfe
57 changed files with 864 additions and 937 deletions
|
@ -2,6 +2,8 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { ReactElement, useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { get } from 'lodash';
|
||||
|
||||
import { ReplacementValuesType } from '../../types/I18N';
|
||||
import { FullJSXType, Intl } from '../Intl';
|
||||
|
@ -9,7 +11,7 @@ import { LocalizerType } from '../../types/Util';
|
|||
import { GroupDescriptionText } from '../GroupDescriptionText';
|
||||
import { Button, ButtonSize, ButtonVariant } from '../Button';
|
||||
|
||||
import { GroupV2ChangeType, GroupV2DescriptionChangeType } from '../../groups';
|
||||
import { GroupV2ChangeType, GroupV2ChangeDetailType } from '../../groups';
|
||||
|
||||
import { renderChange, SmartContactRendererType } from '../../groupChange';
|
||||
import { Modal } from '../Modal';
|
||||
|
@ -35,53 +37,141 @@ function renderStringToIntl(
|
|||
return <Intl id={id} i18n={i18n} components={components} />;
|
||||
}
|
||||
|
||||
export function GroupV2Change(props: PropsType): ReactElement {
|
||||
const { change, groupName, i18n, ourConversationId, renderContact } = props;
|
||||
type GroupIconType =
|
||||
| 'group'
|
||||
| 'group-access'
|
||||
| 'group-add'
|
||||
| 'group-approved'
|
||||
| 'group-avatar'
|
||||
| 'group-decline'
|
||||
| 'group-edit'
|
||||
| 'group-leave'
|
||||
| 'group-remove';
|
||||
|
||||
const [
|
||||
isGroupDescriptionDialogOpen,
|
||||
setIsGroupDescriptionDialogOpen,
|
||||
] = useState<boolean>(false);
|
||||
const changeToIconMap = new Map<string, GroupIconType>([
|
||||
['access-attributes', 'group-access'],
|
||||
['access-invite-link', 'group-access'],
|
||||
['access-members', 'group-access'],
|
||||
['admin-approval-add-one', 'group-add'],
|
||||
['admin-approval-remove-one', 'group-decline'],
|
||||
['announcements-only', 'group-access'],
|
||||
['avatar', 'group-avatar'],
|
||||
['description', 'group-edit'],
|
||||
['group-link-add', 'group-access'],
|
||||
['group-link-remove', 'group-access'],
|
||||
['group-link-reset', 'group-access'],
|
||||
['member-add', 'group-add'],
|
||||
['member-add-from-admin-approval', 'group-approved'],
|
||||
['member-add-from-invite', 'group-add'],
|
||||
['member-add-from-link', 'group-add'],
|
||||
['member-privilege', 'group-access'],
|
||||
['member-remove', 'group-remove'],
|
||||
['pending-add-many', 'group-add'],
|
||||
['pending-add-one', 'group-add'],
|
||||
['pending-remove-many', 'group-decline'],
|
||||
['pending-remove-one', 'group-decline'],
|
||||
['title', 'group-edit'],
|
||||
]);
|
||||
|
||||
const newGroupDescription = change.details.find(
|
||||
(item): item is GroupV2DescriptionChangeType =>
|
||||
Boolean(item.type === 'description' && item.description)
|
||||
)?.description;
|
||||
function getIcon(
|
||||
detail: GroupV2ChangeDetailType,
|
||||
fromId?: string
|
||||
): GroupIconType {
|
||||
const changeType = detail.type;
|
||||
let possibleIcon = changeToIconMap.get(changeType);
|
||||
const isSameId = fromId === get(detail, 'conversationId', null);
|
||||
if (isSameId) {
|
||||
if (changeType === 'member-remove') {
|
||||
possibleIcon = 'group-leave';
|
||||
}
|
||||
if (changeType === 'member-add-from-invite') {
|
||||
possibleIcon = 'group-approved';
|
||||
}
|
||||
}
|
||||
return possibleIcon || 'group';
|
||||
}
|
||||
|
||||
function GroupV2Detail({
|
||||
detail,
|
||||
i18n,
|
||||
fromId,
|
||||
onButtonClick,
|
||||
text,
|
||||
}: {
|
||||
detail: GroupV2ChangeDetailType;
|
||||
i18n: LocalizerType;
|
||||
fromId?: string;
|
||||
onButtonClick: (x: string) => unknown;
|
||||
text: FullJSXType;
|
||||
}): JSX.Element {
|
||||
const icon = getIcon(detail, fromId);
|
||||
|
||||
const newGroupDescription =
|
||||
detail.type === 'description' && get(detail, 'description');
|
||||
|
||||
return (
|
||||
<div className="module-group-v2-change">
|
||||
<div className="module-group-v2-change--icon" />
|
||||
{renderChange(change, {
|
||||
i18n,
|
||||
ourConversationId,
|
||||
renderContact,
|
||||
renderString: renderStringToIntl,
|
||||
}).map((item: FullJSXType, index: number) => (
|
||||
// Difficult to find a unique key for this type
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
<div key={index}>{item}</div>
|
||||
))}
|
||||
<div
|
||||
className={classNames('SystemMessage', {
|
||||
'SystemMessage--multiline': Boolean(newGroupDescription),
|
||||
})}
|
||||
>
|
||||
<div className="SystemMessage__line">
|
||||
<div className={`SystemMessage__icon SystemMessage__icon--${icon}`} />
|
||||
<div className="SystemMessage__text">{text}</div>
|
||||
</div>
|
||||
{newGroupDescription ? (
|
||||
<div className="module-group-v2-change--button-container">
|
||||
<div className="SystemMessage__line">
|
||||
<Button
|
||||
onClick={() => onButtonClick(newGroupDescription)}
|
||||
size={ButtonSize.Small}
|
||||
variant={ButtonVariant.SecondaryAffirmative}
|
||||
onClick={() => setIsGroupDescriptionDialogOpen(true)}
|
||||
variant={ButtonVariant.SystemMessage}
|
||||
>
|
||||
{i18n('view')}
|
||||
</Button>
|
||||
</div>
|
||||
) : null}
|
||||
{newGroupDescription && isGroupDescriptionDialogOpen ? (
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function GroupV2Change(props: PropsType): ReactElement {
|
||||
const { change, groupName, i18n, ourConversationId, renderContact } = props;
|
||||
|
||||
const [groupDescription, setGroupDescription] = useState<
|
||||
string | undefined
|
||||
>();
|
||||
|
||||
return (
|
||||
<>
|
||||
{renderChange(change, {
|
||||
i18n,
|
||||
ourConversationId,
|
||||
renderContact,
|
||||
renderString: renderStringToIntl,
|
||||
}).map((text: FullJSXType, index: number) => (
|
||||
<GroupV2Detail
|
||||
detail={change.details[index]}
|
||||
fromId={change.from}
|
||||
i18n={i18n}
|
||||
// Difficult to find a unique key for this type
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
key={index}
|
||||
onButtonClick={nextGroupDescription =>
|
||||
setGroupDescription(nextGroupDescription)
|
||||
}
|
||||
text={text}
|
||||
/>
|
||||
))}
|
||||
{groupDescription ? (
|
||||
<Modal
|
||||
hasXButton
|
||||
i18n={i18n}
|
||||
title={groupName}
|
||||
onClose={() => setIsGroupDescriptionDialogOpen(false)}
|
||||
onClose={() => setGroupDescription(undefined)}
|
||||
>
|
||||
<GroupDescriptionText text={newGroupDescription} />
|
||||
<GroupDescriptionText text={groupDescription} />
|
||||
</Modal>
|
||||
) : null}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue