Support for creating New Groups
This commit is contained in:
parent
1934120e46
commit
5de4babc0d
56 changed files with 6222 additions and 526 deletions
|
@ -7,20 +7,34 @@ import { LocalizerType } from '../../types/Util';
|
|||
import { Emojify } from './Emojify';
|
||||
|
||||
export type PropsType = {
|
||||
firstName?: string;
|
||||
i18n: LocalizerType;
|
||||
title: string;
|
||||
module?: string;
|
||||
name?: string;
|
||||
phoneNumber?: string;
|
||||
preferFirstName?: boolean;
|
||||
profileName?: string;
|
||||
title: string;
|
||||
};
|
||||
|
||||
export const ContactName = ({ module, title }: PropsType): JSX.Element => {
|
||||
export const ContactName = ({
|
||||
firstName,
|
||||
module,
|
||||
preferFirstName,
|
||||
title,
|
||||
}: PropsType): JSX.Element => {
|
||||
const prefix = module || 'module-contact-name';
|
||||
|
||||
let text: string;
|
||||
if (preferFirstName) {
|
||||
text = firstName || title || '';
|
||||
} else {
|
||||
text = title || '';
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={prefix} dir="auto">
|
||||
<Emojify text={title || ''} />
|
||||
<Emojify text={text} />
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -7,7 +7,6 @@ import { LocalizerType } from '../../types/Util';
|
|||
import { ConversationType } from '../../state/ducks/conversations';
|
||||
import { Intl } from '../Intl';
|
||||
import { ContactName } from './ContactName';
|
||||
import { ModalHost } from '../ModalHost';
|
||||
import { GroupV1MigrationDialog } from '../GroupV1MigrationDialog';
|
||||
|
||||
export type PropsDataType = {
|
||||
|
@ -58,19 +57,17 @@ export function GroupV1Migration(props: PropsType): React.ReactElement {
|
|||
{i18n('GroupV1--Migration--learn-more')}
|
||||
</button>
|
||||
{showingDialog ? (
|
||||
<ModalHost onClose={dismissDialog}>
|
||||
<GroupV1MigrationDialog
|
||||
areWeInvited={areWeInvited}
|
||||
droppedMembers={droppedMembers}
|
||||
hasMigrated
|
||||
i18n={i18n}
|
||||
invitedMembers={invitedMembers}
|
||||
migrate={() =>
|
||||
window.log.warn('GroupV1Migration: Modal called migrate()')
|
||||
}
|
||||
onClose={dismissDialog}
|
||||
/>
|
||||
</ModalHost>
|
||||
<GroupV1MigrationDialog
|
||||
areWeInvited={areWeInvited}
|
||||
droppedMembers={droppedMembers}
|
||||
hasMigrated
|
||||
i18n={i18n}
|
||||
invitedMembers={invitedMembers}
|
||||
migrate={() =>
|
||||
window.log.warn('GroupV1Migration: Modal called migrate()')
|
||||
}
|
||||
onClose={dismissDialog}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020 Signal Messenger, LLC
|
||||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import * as React from 'react';
|
||||
|
@ -211,6 +211,9 @@ const items: Record<string, TimelineItemType> = {
|
|||
|
||||
const actions = () => ({
|
||||
clearChangedMessages: action('clearChangedMessages'),
|
||||
clearInvitedConversationsForNewlyCreatedGroup: action(
|
||||
'clearInvitedConversationsForNewlyCreatedGroup'
|
||||
),
|
||||
setLoadCountdownStart: action('setLoadCountdownStart'),
|
||||
setIsNearBottom: action('setIsNearBottom'),
|
||||
loadAndScroll: action('loadAndScroll'),
|
||||
|
@ -299,6 +302,8 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
|||
oldestUnreadIndex:
|
||||
number('oldestUnreadIndex', overrideProps.oldestUnreadIndex || 0) ||
|
||||
undefined,
|
||||
invitedContactsForNewlyCreatedGroup:
|
||||
overrideProps.invitedContactsForNewlyCreatedGroup || [],
|
||||
|
||||
id: '',
|
||||
renderItem,
|
||||
|
@ -361,3 +366,22 @@ story.add('Without Oldest Message', () => {
|
|||
|
||||
return <Timeline {...props} />;
|
||||
});
|
||||
|
||||
story.add('With invited contacts for a newly-created group', () => {
|
||||
const props = createProps({
|
||||
invitedContactsForNewlyCreatedGroup: [
|
||||
{
|
||||
id: 'abc123',
|
||||
title: 'John Bon Bon Jovi',
|
||||
type: 'direct',
|
||||
},
|
||||
{
|
||||
id: 'def456',
|
||||
title: 'Bon John Bon Jovi',
|
||||
type: 'direct',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return <Timeline {...props} />;
|
||||
});
|
||||
|
|
|
@ -15,9 +15,11 @@ import {
|
|||
import { ScrollDownButton } from './ScrollDownButton';
|
||||
|
||||
import { LocalizerType } from '../../types/Util';
|
||||
import { ConversationType } from '../../state/ducks/conversations';
|
||||
|
||||
import { PropsActions as MessageActionsType } from './Message';
|
||||
import { PropsActions as SafetyNumberActionsType } from './SafetyNumberNotification';
|
||||
import { NewlyCreatedGroupInvitedContactsDialog } from '../NewlyCreatedGroupInvitedContactsDialog';
|
||||
|
||||
const AT_BOTTOM_THRESHOLD = 15;
|
||||
const NEAR_BOTTOM_THRESHOLD = 15;
|
||||
|
@ -48,6 +50,7 @@ type PropsHousekeepingType = {
|
|||
isGroupV1AndDisabled?: boolean;
|
||||
|
||||
selectedMessageId?: string;
|
||||
invitedContactsForNewlyCreatedGroup: Array<ConversationType>;
|
||||
|
||||
i18n: LocalizerType;
|
||||
|
||||
|
@ -68,6 +71,7 @@ type PropsHousekeepingType = {
|
|||
|
||||
type PropsActionsType = {
|
||||
clearChangedMessages: (conversationId: string) => unknown;
|
||||
clearInvitedConversationsForNewlyCreatedGroup: () => void;
|
||||
setLoadCountdownStart: (
|
||||
conversationId: string,
|
||||
loadCountdownStart?: number
|
||||
|
@ -1063,7 +1067,14 @@ export class Timeline extends React.PureComponent<PropsType, StateType> {
|
|||
};
|
||||
|
||||
public render(): JSX.Element | null {
|
||||
const { i18n, id, items, isGroupV1AndDisabled } = this.props;
|
||||
const {
|
||||
clearInvitedConversationsForNewlyCreatedGroup,
|
||||
i18n,
|
||||
id,
|
||||
items,
|
||||
isGroupV1AndDisabled,
|
||||
invitedContactsForNewlyCreatedGroup,
|
||||
} = this.props;
|
||||
const {
|
||||
shouldShowScrollDownButton,
|
||||
areUnreadBelowCurrentPosition,
|
||||
|
@ -1077,60 +1088,70 @@ export class Timeline extends React.PureComponent<PropsType, StateType> {
|
|||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'module-timeline',
|
||||
isGroupV1AndDisabled ? 'module-timeline--disabled' : null
|
||||
)}
|
||||
role="presentation"
|
||||
tabIndex={-1}
|
||||
onBlur={this.handleBlur}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
>
|
||||
<AutoSizer>
|
||||
{({ height, width }) => {
|
||||
if (this.mostRecentWidth && this.mostRecentWidth !== width) {
|
||||
this.resizeFlag = true;
|
||||
<>
|
||||
<div
|
||||
className={classNames(
|
||||
'module-timeline',
|
||||
isGroupV1AndDisabled ? 'module-timeline--disabled' : null
|
||||
)}
|
||||
role="presentation"
|
||||
tabIndex={-1}
|
||||
onBlur={this.handleBlur}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
>
|
||||
<AutoSizer>
|
||||
{({ height, width }) => {
|
||||
if (this.mostRecentWidth && this.mostRecentWidth !== width) {
|
||||
this.resizeFlag = true;
|
||||
|
||||
setTimeout(this.resize, 0);
|
||||
} else if (
|
||||
this.mostRecentHeight &&
|
||||
this.mostRecentHeight !== height
|
||||
) {
|
||||
setTimeout(this.onHeightOnlyChange, 0);
|
||||
}
|
||||
setTimeout(this.resize, 0);
|
||||
} else if (
|
||||
this.mostRecentHeight &&
|
||||
this.mostRecentHeight !== height
|
||||
) {
|
||||
setTimeout(this.onHeightOnlyChange, 0);
|
||||
}
|
||||
|
||||
this.mostRecentWidth = width;
|
||||
this.mostRecentHeight = height;
|
||||
this.mostRecentWidth = width;
|
||||
this.mostRecentHeight = height;
|
||||
|
||||
return (
|
||||
<List
|
||||
deferredMeasurementCache={this.cellSizeCache}
|
||||
height={height}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onScroll={this.onScroll as any}
|
||||
overscanRowCount={10}
|
||||
ref={this.listRef}
|
||||
rowCount={rowCount}
|
||||
rowHeight={this.cellSizeCache.rowHeight}
|
||||
rowRenderer={this.rowRenderer}
|
||||
scrollToAlignment="start"
|
||||
scrollToIndex={scrollToIndex}
|
||||
tabIndex={-1}
|
||||
width={width}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</AutoSizer>
|
||||
{shouldShowScrollDownButton ? (
|
||||
<ScrollDownButton
|
||||
conversationId={id}
|
||||
withNewMessages={areUnreadBelowCurrentPosition}
|
||||
scrollDown={this.onClickScrollDownButton}
|
||||
return (
|
||||
<List
|
||||
deferredMeasurementCache={this.cellSizeCache}
|
||||
height={height}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onScroll={this.onScroll as any}
|
||||
overscanRowCount={10}
|
||||
ref={this.listRef}
|
||||
rowCount={rowCount}
|
||||
rowHeight={this.cellSizeCache.rowHeight}
|
||||
rowRenderer={this.rowRenderer}
|
||||
scrollToAlignment="start"
|
||||
scrollToIndex={scrollToIndex}
|
||||
tabIndex={-1}
|
||||
width={width}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</AutoSizer>
|
||||
{shouldShowScrollDownButton ? (
|
||||
<ScrollDownButton
|
||||
conversationId={id}
|
||||
withNewMessages={areUnreadBelowCurrentPosition}
|
||||
scrollDown={this.onClickScrollDownButton}
|
||||
i18n={i18n}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{Boolean(invitedContactsForNewlyCreatedGroup.length) && (
|
||||
<NewlyCreatedGroupInvitedContactsDialog
|
||||
contacts={invitedContactsForNewlyCreatedGroup}
|
||||
i18n={i18n}
|
||||
onClose={clearInvitedConversationsForNewlyCreatedGroup}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue