Group Description: Render newlines, view button in change notification
This commit is contained in:
parent
15678efb4d
commit
3956443f50
6 changed files with 93 additions and 28 deletions
|
@ -9589,6 +9589,10 @@ button.module-image__border-overlay:focus {
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.module-group-v2-change--button-container {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
// Module: GV1 Migration
|
// Module: GV1 Migration
|
||||||
|
|
||||||
.module-group-v1-migration {
|
.module-group-v1-migration {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { Modal } from '../Modal';
|
import { Modal } from '../Modal';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
import { AddNewLines } from './AddNewLines';
|
||||||
|
|
||||||
export type PropsType = {
|
export type PropsType = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
|
@ -37,7 +38,7 @@ export const GroupDescription = ({
|
||||||
onClose={() => setShowFullDescription(false)}
|
onClose={() => setShowFullDescription(false)}
|
||||||
title={title}
|
title={title}
|
||||||
>
|
>
|
||||||
{text}
|
<AddNewLines text={text} />
|
||||||
</Modal>
|
</Modal>
|
||||||
)}
|
)}
|
||||||
<div className="GroupDescription__text" ref={textRef}>
|
<div className="GroupDescription__text" ref={textRef}>
|
||||||
|
|
|
@ -46,10 +46,11 @@ const renderContact: SmartContactRendererType = (conversationId: string) => (
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderChange = (change: GroupV2ChangeType) => (
|
const renderChange = (change: GroupV2ChangeType, groupName?: string) => (
|
||||||
<GroupV2Change
|
<GroupV2Change
|
||||||
AccessControlEnum={AccessControlEnum}
|
AccessControlEnum={AccessControlEnum}
|
||||||
change={change}
|
change={change}
|
||||||
|
groupName={groupName}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
ourConversationId={OUR_ID}
|
ourConversationId={OUR_ID}
|
||||||
renderContact={renderContact}
|
renderContact={renderContact}
|
||||||
|
@ -1360,29 +1361,44 @@ storiesOf('Components/Conversation/GroupV2Change', module)
|
||||||
.add('Description (Change)', () => {
|
.add('Description (Change)', () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{renderChange({
|
{renderChange(
|
||||||
from: OUR_ID,
|
{
|
||||||
details: [
|
from: OUR_ID,
|
||||||
{
|
details: [
|
||||||
type: 'description',
|
{
|
||||||
},
|
type: 'description',
|
||||||
],
|
description:
|
||||||
})}
|
'This is a long description.\n\nWe need a dialog to view it all!',
|
||||||
{renderChange({
|
},
|
||||||
from: ADMIN_A,
|
],
|
||||||
details: [
|
},
|
||||||
{
|
'We do hikes 🌲'
|
||||||
type: 'description',
|
)}
|
||||||
},
|
{renderChange(
|
||||||
],
|
{
|
||||||
})}
|
from: ADMIN_A,
|
||||||
{renderChange({
|
details: [
|
||||||
details: [
|
{
|
||||||
{
|
type: 'description',
|
||||||
type: 'description',
|
description:
|
||||||
},
|
'This is a long description.\n\nWe need a dialog to view it all!',
|
||||||
],
|
},
|
||||||
})}
|
],
|
||||||
|
},
|
||||||
|
'We do hikes 🌲'
|
||||||
|
)}
|
||||||
|
{renderChange(
|
||||||
|
{
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
type: 'description',
|
||||||
|
description:
|
||||||
|
'This is a long description.\n\nWe need a dialog to view it all!',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'We do hikes 🌲'
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import * as React from 'react';
|
import React, { ReactElement, useState } from 'react';
|
||||||
|
|
||||||
import { ReplacementValuesType } from '../../types/I18N';
|
import { ReplacementValuesType } from '../../types/I18N';
|
||||||
import { FullJSXType, Intl } from '../Intl';
|
import { FullJSXType, Intl } from '../Intl';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
|
import { AddNewLines } from './AddNewLines';
|
||||||
|
import { Button, ButtonSize, ButtonVariant } from '../Button';
|
||||||
|
|
||||||
import { GroupV2ChangeType } from '../../groups';
|
import { GroupV2ChangeType, GroupV2DescriptionChangeType } from '../../groups';
|
||||||
|
|
||||||
import { renderChange, SmartContactRendererType } from '../../groupChange';
|
import { renderChange, SmartContactRendererType } from '../../groupChange';
|
||||||
|
import { Modal } from '../Modal';
|
||||||
|
|
||||||
import { AccessControlClass, MemberClass } from '../../textsecure.d';
|
import { AccessControlClass, MemberClass } from '../../textsecure.d';
|
||||||
|
|
||||||
export type PropsDataType = {
|
export type PropsDataType = {
|
||||||
|
groupName?: string;
|
||||||
ourConversationId: string;
|
ourConversationId: string;
|
||||||
change: GroupV2ChangeType;
|
change: GroupV2ChangeType;
|
||||||
AccessControlEnum: typeof AccessControlClass.AccessRequired;
|
AccessControlEnum: typeof AccessControlClass.AccessRequired;
|
||||||
|
@ -35,16 +39,27 @@ function renderStringToIntl(
|
||||||
return <Intl id={id} i18n={i18n} components={components} />;
|
return <Intl id={id} i18n={i18n} components={components} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function GroupV2Change(props: PropsType): React.ReactElement {
|
export function GroupV2Change(props: PropsType): ReactElement {
|
||||||
const {
|
const {
|
||||||
AccessControlEnum,
|
AccessControlEnum,
|
||||||
change,
|
change,
|
||||||
|
groupName,
|
||||||
i18n,
|
i18n,
|
||||||
ourConversationId,
|
ourConversationId,
|
||||||
renderContact,
|
renderContact,
|
||||||
RoleEnum,
|
RoleEnum,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const [
|
||||||
|
isGroupDescriptionDialogOpen,
|
||||||
|
setIsGroupDescriptionDialogOpen,
|
||||||
|
] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const groupDescriptionChange = change.details.find(
|
||||||
|
(item): item is GroupV2DescriptionChangeType =>
|
||||||
|
Boolean(item.type === 'description' && item.description)
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="module-group-v2-change">
|
<div className="module-group-v2-change">
|
||||||
<div className="module-group-v2-change--icon" />
|
<div className="module-group-v2-change--icon" />
|
||||||
|
@ -60,6 +75,27 @@ export function GroupV2Change(props: PropsType): React.ReactElement {
|
||||||
// eslint-disable-next-line react/no-array-index-key
|
// eslint-disable-next-line react/no-array-index-key
|
||||||
<div key={index}>{item}</div>
|
<div key={index}>{item}</div>
|
||||||
))}
|
))}
|
||||||
|
{groupDescriptionChange ? (
|
||||||
|
<div className="module-group-v2-change--button-container">
|
||||||
|
<Button
|
||||||
|
size={ButtonSize.Small}
|
||||||
|
variant={ButtonVariant.SecondaryAffirmative}
|
||||||
|
onClick={() => setIsGroupDescriptionDialogOpen(true)}
|
||||||
|
>
|
||||||
|
{i18n('view')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{groupDescriptionChange && isGroupDescriptionDialogOpen ? (
|
||||||
|
<Modal
|
||||||
|
hasXButton
|
||||||
|
i18n={i18n}
|
||||||
|
title={groupName}
|
||||||
|
onClose={() => setIsGroupDescriptionDialogOpen(false)}
|
||||||
|
>
|
||||||
|
<AddNewLines text={groupDescriptionChange.description} />
|
||||||
|
</Modal>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,6 +181,8 @@ export type GroupV2AdminApprovalRemoveOneChangeType = {
|
||||||
export type GroupV2DescriptionChangeType = {
|
export type GroupV2DescriptionChangeType = {
|
||||||
type: 'description';
|
type: 'description';
|
||||||
removed?: boolean;
|
removed?: boolean;
|
||||||
|
// Adding this field; cannot remove previous field for backwards compatibility
|
||||||
|
description?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type GroupV2ChangeDetailType =
|
export type GroupV2ChangeDetailType =
|
||||||
|
@ -3654,6 +3656,7 @@ function extractDiffs({
|
||||||
details.push({
|
details.push({
|
||||||
type: 'description',
|
type: 'description',
|
||||||
removed: !current.description,
|
removed: !current.description,
|
||||||
|
description: current.description,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -643,7 +643,12 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
throw new Error('change is undefined');
|
throw new Error('change is undefined');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const conversation = this.getConversation();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
groupName: conversation?.isGroupV2()
|
||||||
|
? conversation.get('name')
|
||||||
|
: undefined,
|
||||||
AccessControlEnum: protobuf.AccessControl.AccessRequired,
|
AccessControlEnum: protobuf.AccessControl.AccessRequired,
|
||||||
RoleEnum: protobuf.Member.Role,
|
RoleEnum: protobuf.Member.Role,
|
||||||
ourConversationId,
|
ourConversationId,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue