Optimize rendering
This commit is contained in:
parent
81f06e2404
commit
12c78c742f
34 changed files with 702 additions and 444 deletions
|
@ -36,9 +36,6 @@ export const AnnouncementsOnlyGroupBanner = ({
|
|||
onClick={() => {
|
||||
openConversation(admin.id);
|
||||
}}
|
||||
// Required by the component but unecessary for us
|
||||
style={{}}
|
||||
// We don't want these values to show
|
||||
draftPreview=""
|
||||
lastMessage={undefined}
|
||||
lastUpdated={undefined}
|
||||
|
|
|
@ -54,7 +54,7 @@ const createProps = (rows: ReadonlyArray<Row>): PropsType => ({
|
|||
onSelectConversation: action('onSelectConversation'),
|
||||
onClickArchiveButton: action('onClickArchiveButton'),
|
||||
onClickContactCheckbox: action('onClickContactCheckbox'),
|
||||
renderMessageSearchResult: (id: string, style: React.CSSProperties) => (
|
||||
renderMessageSearchResult: (id: string) => (
|
||||
<MessageSearchResult
|
||||
body="Lorem ipsum wow"
|
||||
bodyRanges={[]}
|
||||
|
@ -65,7 +65,6 @@ const createProps = (rows: ReadonlyArray<Row>): PropsType => ({
|
|||
openConversationInternal={action('openConversationInternal')}
|
||||
sentAt={1587358800000}
|
||||
snippet="Lorem <<left>>ipsum<<right>> wow"
|
||||
style={style}
|
||||
to={defaultConversations[1]}
|
||||
/>
|
||||
),
|
||||
|
@ -288,6 +287,7 @@ story.add('Contact checkboxes: disabled', () => (
|
|||
story.add('Conversation: Typing Status', () =>
|
||||
renderConversation({
|
||||
typingContact: {
|
||||
...getDefaultConversation(),
|
||||
name: 'Someone Here',
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { useRef, useEffect, useCallback, CSSProperties } from 'react';
|
||||
import React, { useRef, useEffect, useCallback, ReactNode } from 'react';
|
||||
import { List, ListRowRenderer } from 'react-virtualized';
|
||||
import classNames from 'classnames';
|
||||
import { pick } from 'lodash';
|
||||
|
||||
import { missingCaseError } from '../util/missingCaseError';
|
||||
import { assert } from '../util/assert';
|
||||
|
@ -128,7 +129,7 @@ export type PropsType = {
|
|||
disabledReason: undefined | ContactCheckboxDisabledReason
|
||||
) => void;
|
||||
onSelectConversation: (conversationId: string, messageId?: string) => void;
|
||||
renderMessageSearchResult: (id: string, style: CSSProperties) => JSX.Element;
|
||||
renderMessageSearchResult: (id: string) => JSX.Element;
|
||||
showChooseGroupMembers: () => void;
|
||||
startNewConversationFromPhoneNumber: (e164: string) => void;
|
||||
};
|
||||
|
@ -187,13 +188,12 @@ export const ConversationList: React.FC<PropsType> = ({
|
|||
return <div key={key} style={style} />;
|
||||
}
|
||||
|
||||
let result: ReactNode;
|
||||
switch (row.type) {
|
||||
case RowType.ArchiveButton:
|
||||
return (
|
||||
result = (
|
||||
<button
|
||||
key={key}
|
||||
className="module-conversation-list__item--archive-button"
|
||||
style={style}
|
||||
onClick={onClickArchiveButton}
|
||||
type="button"
|
||||
>
|
||||
|
@ -203,90 +203,108 @@ export const ConversationList: React.FC<PropsType> = ({
|
|||
</span>
|
||||
</button>
|
||||
);
|
||||
break;
|
||||
case RowType.Blank:
|
||||
return <div key={key} style={style} />;
|
||||
result = <></>;
|
||||
break;
|
||||
case RowType.Contact: {
|
||||
const { isClickable = true } = row;
|
||||
return (
|
||||
result = (
|
||||
<ContactListItem
|
||||
{...row.contact}
|
||||
key={key}
|
||||
style={style}
|
||||
onClick={isClickable ? onSelectConversation : undefined}
|
||||
i18n={i18n}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
}
|
||||
case RowType.ContactCheckbox:
|
||||
return (
|
||||
result = (
|
||||
<ContactCheckboxComponent
|
||||
{...row.contact}
|
||||
isChecked={row.isChecked}
|
||||
disabledReason={row.disabledReason}
|
||||
key={key}
|
||||
style={style}
|
||||
onClick={onClickContactCheckbox}
|
||||
i18n={i18n}
|
||||
/>
|
||||
);
|
||||
case RowType.Conversation:
|
||||
return (
|
||||
break;
|
||||
case RowType.Conversation: {
|
||||
const itemProps = pick(row.conversation, [
|
||||
'acceptedMessageRequest',
|
||||
'avatarPath',
|
||||
'color',
|
||||
'draftPreview',
|
||||
'id',
|
||||
'isMe',
|
||||
'isSelected',
|
||||
'lastMessage',
|
||||
'lastUpdated',
|
||||
'markedUnread',
|
||||
'muteExpiresAt',
|
||||
'name',
|
||||
'phoneNumber',
|
||||
'profileName',
|
||||
'sharedGroupNames',
|
||||
'shouldShowDraft',
|
||||
'title',
|
||||
'type',
|
||||
'typingContact',
|
||||
'unblurredAvatarPath',
|
||||
'unreadCount',
|
||||
]);
|
||||
result = (
|
||||
<ConversationListItem
|
||||
{...row.conversation}
|
||||
{...itemProps}
|
||||
key={key}
|
||||
style={style}
|
||||
onClick={onSelectConversation}
|
||||
i18n={i18n}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
}
|
||||
case RowType.CreateNewGroup:
|
||||
return (
|
||||
result = (
|
||||
<CreateNewGroupButton
|
||||
i18n={i18n}
|
||||
key={key}
|
||||
onClick={showChooseGroupMembers}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case RowType.Header:
|
||||
return (
|
||||
<div
|
||||
className="module-conversation-list__item--header"
|
||||
key={key}
|
||||
style={style}
|
||||
>
|
||||
result = (
|
||||
<div className="module-conversation-list__item--header">
|
||||
{i18n(row.i18nKey)}
|
||||
</div>
|
||||
);
|
||||
break;
|
||||
case RowType.MessageSearchResult:
|
||||
return (
|
||||
<React.Fragment key={key}>
|
||||
{renderMessageSearchResult(row.messageId, style)}
|
||||
</React.Fragment>
|
||||
);
|
||||
result = <>{renderMessageSearchResult(row.messageId)}</>;
|
||||
break;
|
||||
case RowType.SearchResultsLoadingFakeHeader:
|
||||
return (
|
||||
<SearchResultsLoadingFakeHeaderComponent key={key} style={style} />
|
||||
);
|
||||
result = <SearchResultsLoadingFakeHeaderComponent />;
|
||||
break;
|
||||
case RowType.SearchResultsLoadingFakeRow:
|
||||
return (
|
||||
<SearchResultsLoadingFakeRowComponent key={key} style={style} />
|
||||
);
|
||||
result = <SearchResultsLoadingFakeRowComponent />;
|
||||
break;
|
||||
case RowType.StartNewConversation:
|
||||
return (
|
||||
result = (
|
||||
<StartNewConversationComponent
|
||||
i18n={i18n}
|
||||
key={key}
|
||||
phoneNumber={row.phoneNumber}
|
||||
onClick={() => {
|
||||
startNewConversationFromPhoneNumber(row.phoneNumber);
|
||||
}}
|
||||
style={style}
|
||||
onClick={startNewConversationFromPhoneNumber}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
default:
|
||||
throw missingCaseError(row);
|
||||
}
|
||||
|
||||
return (
|
||||
<span style={style} key={key}>
|
||||
{result}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
[
|
||||
getRow,
|
||||
|
|
|
@ -98,7 +98,7 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
|||
setChallengeStatus: action('setChallengeStatus'),
|
||||
renderExpiredBuildDialog: () => <div />,
|
||||
renderMainHeader: () => <div />,
|
||||
renderMessageSearchResult: (id: string, style: React.CSSProperties) => (
|
||||
renderMessageSearchResult: (id: string) => (
|
||||
<MessageSearchResult
|
||||
body="Lorem ipsum wow"
|
||||
bodyRanges={[]}
|
||||
|
@ -109,7 +109,6 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
|||
openConversationInternal={action('openConversationInternal')}
|
||||
sentAt={1587358800000}
|
||||
snippet="Lorem <<left>>ipsum<<right>> wow"
|
||||
style={style}
|
||||
to={defaultConversations[1]}
|
||||
/>
|
||||
),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { useEffect, useMemo, CSSProperties } from 'react';
|
||||
import React, { useEffect, useCallback, useMemo } from 'react';
|
||||
import Measure, { MeasuredComponentProps } from 'react-measure';
|
||||
import { isNumber } from 'lodash';
|
||||
|
||||
|
@ -119,7 +119,7 @@ export type PropsType = {
|
|||
// Render Props
|
||||
renderExpiredBuildDialog: () => JSX.Element;
|
||||
renderMainHeader: () => JSX.Element;
|
||||
renderMessageSearchResult: (id: string, style: CSSProperties) => JSX.Element;
|
||||
renderMessageSearchResult: (id: string) => JSX.Element;
|
||||
renderNetworkStatus: () => JSX.Element;
|
||||
renderRelinkDialog: () => JSX.Element;
|
||||
renderUpdateDialog: () => JSX.Element;
|
||||
|
@ -376,6 +376,17 @@ export const LeftPane: React.FC<PropsType> = ({
|
|||
|
||||
const getRow = useMemo(() => helper.getRow.bind(helper), [helper]);
|
||||
|
||||
const onSelectConversation = useCallback(
|
||||
(conversationId: string, messageId?: string) => {
|
||||
openConversationInternal({
|
||||
conversationId,
|
||||
messageId,
|
||||
switchToAssociatedView: true,
|
||||
});
|
||||
},
|
||||
[openConversationInternal]
|
||||
);
|
||||
|
||||
const previousSelectedConversationId = usePrevious(
|
||||
selectedConversationId,
|
||||
selectedConversationId
|
||||
|
@ -458,16 +469,7 @@ export const LeftPane: React.FC<PropsType> = ({
|
|||
throw missingCaseError(disabledReason);
|
||||
}
|
||||
}}
|
||||
onSelectConversation={(
|
||||
conversationId: string,
|
||||
messageId?: string
|
||||
) => {
|
||||
openConversationInternal({
|
||||
conversationId,
|
||||
messageId,
|
||||
switchToAssociatedView: true,
|
||||
});
|
||||
}}
|
||||
onSelectConversation={onSelectConversation}
|
||||
renderMessageSearchResult={renderMessageSearchResult}
|
||||
rowCount={helper.getRowCount()}
|
||||
scrollBehavior={scrollBehavior}
|
||||
|
|
|
@ -271,7 +271,7 @@ type State = {
|
|||
const EXPIRATION_CHECK_MINIMUM = 2000;
|
||||
const EXPIRED_DELAY = 600;
|
||||
|
||||
export class Message extends React.Component<Props, State> {
|
||||
export class Message extends React.PureComponent<Props, State> {
|
||||
public menuTriggerRef: Trigger | undefined;
|
||||
|
||||
public focusRef: React.RefObject<HTMLDivElement> = React.createRef();
|
||||
|
|
|
@ -375,7 +375,6 @@ const renderItem = (id: string) => (
|
|||
i18n={i18n}
|
||||
interactionMode="keyboard"
|
||||
conversationId=""
|
||||
conversationAccepted
|
||||
renderContact={() => '*ContactName*'}
|
||||
renderUniversalTimerNotification={() => (
|
||||
<div>*UniversalTimerNotification*</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { debounce, get, isNumber } from 'lodash';
|
||||
import { debounce, get, isNumber, pick } from 'lodash';
|
||||
import classNames from 'classnames';
|
||||
import React, { CSSProperties, ReactChild, ReactNode } from 'react';
|
||||
import {
|
||||
|
@ -15,12 +15,14 @@ import Measure from 'react-measure';
|
|||
|
||||
import { ScrollDownButton } from './ScrollDownButton';
|
||||
|
||||
import { LocalizerType } from '../../types/Util';
|
||||
import { AssertProps, LocalizerType } from '../../types/Util';
|
||||
import { ConversationType } from '../../state/ducks/conversations';
|
||||
import { assert } from '../../util/assert';
|
||||
import { missingCaseError } from '../../util/missingCaseError';
|
||||
|
||||
import { PropsActions as MessageActionsType } from './Message';
|
||||
import { PropsActions as UnsupportedMessageActionsType } from './UnsupportedMessage';
|
||||
import { PropsActionsType as ChatSessionRefreshedNotificationActionsType } from './ChatSessionRefreshedNotification';
|
||||
import { ErrorBoundary } from './ErrorBoundary';
|
||||
import { PropsActions as SafetyNumberActionsType } from './SafetyNumberNotification';
|
||||
import { Intl } from '../Intl';
|
||||
|
@ -104,7 +106,7 @@ type PropsHousekeepingType = {
|
|||
id: string,
|
||||
conversationId: string,
|
||||
onHeightChange: (messageId: string) => unknown,
|
||||
actions: Record<string, unknown>
|
||||
actions: PropsActionsType
|
||||
) => JSX.Element;
|
||||
renderLastSeenIndicator: (id: string) => JSX.Element;
|
||||
renderHeroRow: (
|
||||
|
@ -117,7 +119,7 @@ type PropsHousekeepingType = {
|
|||
renderTypingBubble: (id: string) => JSX.Element;
|
||||
};
|
||||
|
||||
type PropsActionsType = {
|
||||
export type PropsActionsType = {
|
||||
acknowledgeGroupMemberNameCollisions: (
|
||||
groupNameCollisions: Readonly<GroupNameCollisionsWithIdsByTitle>
|
||||
) => void;
|
||||
|
@ -152,7 +154,9 @@ type PropsActionsType = {
|
|||
unblurAvatar: () => void;
|
||||
updateSharedGroups: () => unknown;
|
||||
} & MessageActionsType &
|
||||
SafetyNumberActionsType;
|
||||
SafetyNumberActionsType &
|
||||
UnsupportedMessageActionsType &
|
||||
ChatSessionRefreshedNotificationActionsType;
|
||||
|
||||
export type PropsType = PropsDataType &
|
||||
PropsHousekeepingType &
|
||||
|
@ -721,6 +725,7 @@ export class Timeline extends React.PureComponent<PropsType, StateType> {
|
|||
);
|
||||
}
|
||||
const messageId = items[itemIndex];
|
||||
|
||||
rowContents = (
|
||||
<div
|
||||
id={messageId}
|
||||
|
@ -730,7 +735,7 @@ export class Timeline extends React.PureComponent<PropsType, StateType> {
|
|||
role="row"
|
||||
>
|
||||
<ErrorBoundary i18n={i18n} showDebugLog={() => window.showDebugLog()}>
|
||||
{renderItem(messageId, id, this.resizeMessage, this.props)}
|
||||
{renderItem(messageId, id, this.resizeMessage, this.getActions())}
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
|
@ -1474,4 +1479,65 @@ export class Timeline extends React.PureComponent<PropsType, StateType> {
|
|||
throw missingCaseError(warning);
|
||||
}
|
||||
}
|
||||
|
||||
private getActions(): PropsActionsType {
|
||||
const unsafe = pick(this.props, [
|
||||
'acknowledgeGroupMemberNameCollisions',
|
||||
'clearChangedMessages',
|
||||
'clearInvitedConversationsForNewlyCreatedGroup',
|
||||
'closeContactSpoofingReview',
|
||||
'setLoadCountdownStart',
|
||||
'setIsNearBottom',
|
||||
'reviewGroupMemberNameCollision',
|
||||
'reviewMessageRequestNameCollision',
|
||||
'learnMoreAboutDeliveryIssue',
|
||||
'loadAndScroll',
|
||||
'loadOlderMessages',
|
||||
'loadNewerMessages',
|
||||
'loadNewestMessages',
|
||||
'markMessageRead',
|
||||
'onBlock',
|
||||
'onBlockAndReportSpam',
|
||||
'onDelete',
|
||||
'onUnblock',
|
||||
'removeMember',
|
||||
'selectMessage',
|
||||
'clearSelectedMessage',
|
||||
'unblurAvatar',
|
||||
'updateSharedGroups',
|
||||
|
||||
'doubleCheckMissingQuoteReference',
|
||||
'onHeightChange',
|
||||
'checkForAccount',
|
||||
'reactToMessage',
|
||||
'replyToMessage',
|
||||
'retrySend',
|
||||
'showForwardMessageModal',
|
||||
'deleteMessage',
|
||||
'deleteMessageForEveryone',
|
||||
'showMessageDetail',
|
||||
'openConversation',
|
||||
'showContactDetail',
|
||||
'showContactModal',
|
||||
'kickOffAttachmentDownload',
|
||||
'markAttachmentAsCorrupted',
|
||||
'showVisualAttachment',
|
||||
'downloadAttachment',
|
||||
'displayTapToViewMessage',
|
||||
'openLink',
|
||||
'scrollToQuotedMessage',
|
||||
'showExpiredIncomingTapToViewToast',
|
||||
'showExpiredOutgoingTapToViewToast',
|
||||
|
||||
'showIdentity',
|
||||
|
||||
'downloadNewVersion',
|
||||
|
||||
'contactSupport',
|
||||
]);
|
||||
|
||||
const safe: AssertProps<PropsActionsType, typeof unsafe> = unsafe;
|
||||
|
||||
return safe;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@ const renderUniversalTimerNotification = () => (
|
|||
|
||||
const getDefaultProps = () => ({
|
||||
conversationId: 'conversation-id',
|
||||
conversationAccepted: true,
|
||||
id: 'asdf',
|
||||
isSelected: false,
|
||||
interactionMode: 'keyboard' as const,
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
import { LocalizerType, ThemeType } from '../../types/Util';
|
||||
|
||||
import { InteractionModeType } from '../../state/ducks/conversations';
|
||||
|
@ -152,7 +154,6 @@ export type TimelineItemType =
|
|||
|
||||
type PropsLocalType = {
|
||||
conversationId: string;
|
||||
conversationAccepted: boolean;
|
||||
item?: TimelineItemType;
|
||||
id: string;
|
||||
isSelected: boolean;
|
||||
|
@ -201,7 +202,7 @@ export class TimelineItem extends React.PureComponent<PropsType> {
|
|||
if (item.type === 'message') {
|
||||
return (
|
||||
<Message
|
||||
{...this.props}
|
||||
{...omit(this.props, ['item'])}
|
||||
{...item.data}
|
||||
i18n={i18n}
|
||||
theme={theme}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { ReactNode, CSSProperties, FunctionComponent } from 'react';
|
||||
import React, { ReactNode, FunctionComponent } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { isBoolean, isNumber } from 'lodash';
|
||||
|
||||
|
@ -37,7 +37,6 @@ type PropsType = {
|
|||
messageStatusIcon?: ReactNode;
|
||||
messageText?: ReactNode;
|
||||
onClick?: () => void;
|
||||
style: CSSProperties;
|
||||
unreadCount?: number;
|
||||
} & Pick<
|
||||
ConversationType,
|
||||
|
@ -77,7 +76,6 @@ export const BaseConversationListItem: FunctionComponent<PropsType> = React.memo
|
|||
phoneNumber,
|
||||
profileName,
|
||||
sharedGroupNames,
|
||||
style,
|
||||
title,
|
||||
unblurredAvatarPath,
|
||||
unreadCount,
|
||||
|
@ -198,7 +196,6 @@ export const BaseConversationListItem: FunctionComponent<PropsType> = React.memo
|
|||
{ [`${BASE_CLASS_NAME}--is-checkbox--disabled`]: disabled }
|
||||
)}
|
||||
data-id={id ? cleanId(id) : undefined}
|
||||
style={style}
|
||||
// `onClick` is will double-fire if we're enabled. We want it to fire when we're
|
||||
// disabled so we can show any "can't add contact" modals, etc. This won't
|
||||
// work for keyboard users, though, because labels are not tabbable.
|
||||
|
@ -219,7 +216,6 @@ export const BaseConversationListItem: FunctionComponent<PropsType> = React.memo
|
|||
data-id={id ? cleanId(id) : undefined}
|
||||
disabled={disabled}
|
||||
onClick={onClick}
|
||||
style={style}
|
||||
type="button"
|
||||
>
|
||||
{contents}
|
||||
|
@ -228,11 +224,7 @@ export const BaseConversationListItem: FunctionComponent<PropsType> = React.memo
|
|||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={commonClassNames}
|
||||
data-id={id ? cleanId(id) : undefined}
|
||||
style={style}
|
||||
>
|
||||
<div className={commonClassNames} data-id={id ? cleanId(id) : undefined}>
|
||||
{contents}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { CSSProperties, FunctionComponent, ReactNode } from 'react';
|
||||
import React, { FunctionComponent, ReactNode } from 'react';
|
||||
|
||||
import { BaseConversationListItem } from './BaseConversationListItem';
|
||||
import { ConversationType } from '../../state/ducks/conversations';
|
||||
|
@ -38,7 +38,6 @@ export type PropsDataType = {
|
|||
|
||||
type PropsHousekeepingType = {
|
||||
i18n: LocalizerType;
|
||||
style: CSSProperties;
|
||||
onClick: (
|
||||
id: string,
|
||||
disabledReason: undefined | ContactCheckboxDisabledReason
|
||||
|
@ -63,7 +62,6 @@ export const ContactCheckbox: FunctionComponent<PropsType> = React.memo(
|
|||
phoneNumber,
|
||||
profileName,
|
||||
sharedGroupNames,
|
||||
style,
|
||||
title,
|
||||
type,
|
||||
unblurredAvatarPath,
|
||||
|
@ -114,7 +112,6 @@ export const ContactCheckbox: FunctionComponent<PropsType> = React.memo(
|
|||
phoneNumber={phoneNumber}
|
||||
profileName={profileName}
|
||||
sharedGroupNames={sharedGroupNames}
|
||||
style={style}
|
||||
title={title}
|
||||
unblurredAvatarPath={unblurredAvatarPath}
|
||||
/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { CSSProperties, FunctionComponent } from 'react';
|
||||
import React, { FunctionComponent } from 'react';
|
||||
|
||||
import { BaseConversationListItem } from './BaseConversationListItem';
|
||||
import { ConversationType } from '../../state/ducks/conversations';
|
||||
|
@ -28,7 +28,6 @@ export type PropsDataType = Pick<
|
|||
|
||||
type PropsHousekeepingType = {
|
||||
i18n: LocalizerType;
|
||||
style: CSSProperties;
|
||||
onClick?: (id: string) => void;
|
||||
};
|
||||
|
||||
|
@ -48,7 +47,6 @@ export const ContactListItem: FunctionComponent<PropsType> = React.memo(
|
|||
phoneNumber,
|
||||
profileName,
|
||||
sharedGroupNames,
|
||||
style,
|
||||
title,
|
||||
type,
|
||||
unblurredAvatarPath,
|
||||
|
@ -85,7 +83,6 @@ export const ContactListItem: FunctionComponent<PropsType> = React.memo(
|
|||
phoneNumber={phoneNumber}
|
||||
profileName={profileName}
|
||||
sharedGroupNames={sharedGroupNames}
|
||||
style={style}
|
||||
title={title}
|
||||
unblurredAvatarPath={unblurredAvatarPath}
|
||||
/>
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
// Copyright 2018-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, {
|
||||
useCallback,
|
||||
CSSProperties,
|
||||
FunctionComponent,
|
||||
ReactNode,
|
||||
} from 'react';
|
||||
import React, { useCallback, FunctionComponent, ReactNode } from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import {
|
||||
|
@ -62,7 +57,6 @@ export type PropsData = Pick<
|
|||
|
||||
type PropsHousekeeping = {
|
||||
i18n: LocalizerType;
|
||||
style: CSSProperties;
|
||||
onClick: (id: string) => void;
|
||||
};
|
||||
|
||||
|
@ -88,7 +82,6 @@ export const ConversationListItem: FunctionComponent<Props> = React.memo(
|
|||
profileName,
|
||||
sharedGroupNames,
|
||||
shouldShowDraft,
|
||||
style,
|
||||
title,
|
||||
type,
|
||||
typingContact,
|
||||
|
@ -197,7 +190,6 @@ export const ConversationListItem: FunctionComponent<Props> = React.memo(
|
|||
phoneNumber={phoneNumber}
|
||||
profileName={profileName}
|
||||
sharedGroupNames={sharedGroupNames}
|
||||
style={style}
|
||||
title={title}
|
||||
unreadCount={unreadCount}
|
||||
unblurredAvatarPath={unblurredAvatarPath}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { CSSProperties, FunctionComponent } from 'react';
|
||||
import React, { FunctionComponent } from 'react';
|
||||
|
||||
import { BaseConversationListItem } from './BaseConversationListItem';
|
||||
import { LocalizerType } from '../../types/Util';
|
||||
|
@ -9,11 +9,10 @@ import { LocalizerType } from '../../types/Util';
|
|||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
onClick: () => void;
|
||||
style: CSSProperties;
|
||||
};
|
||||
|
||||
export const CreateNewGroupButton: FunctionComponent<PropsType> = React.memo(
|
||||
({ i18n, onClick, style }) => {
|
||||
({ i18n, onClick }) => {
|
||||
const title = i18n('createNewGroupButton');
|
||||
|
||||
return (
|
||||
|
@ -26,7 +25,6 @@ export const CreateNewGroupButton: FunctionComponent<PropsType> = React.memo(
|
|||
isSelected={false}
|
||||
onClick={onClick}
|
||||
sharedGroupNames={[]}
|
||||
style={style}
|
||||
title={title}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -55,7 +55,6 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
|||
'isSearchingInConversation',
|
||||
overrideProps.isSearchingInConversation || false
|
||||
),
|
||||
style: {},
|
||||
});
|
||||
|
||||
story.add('Default', () => {
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, {
|
||||
useCallback,
|
||||
CSSProperties,
|
||||
FunctionComponent,
|
||||
ReactNode,
|
||||
} from 'react';
|
||||
import React, { useCallback, FunctionComponent, ReactNode } from 'react';
|
||||
import { escapeRegExp } from 'lodash';
|
||||
|
||||
import { MessageBodyHighlight } from './MessageBodyHighlight';
|
||||
|
@ -59,7 +54,6 @@ type PropsHousekeepingType = {
|
|||
conversationId: string;
|
||||
messageId?: string;
|
||||
}) => void;
|
||||
style: CSSProperties;
|
||||
};
|
||||
|
||||
export type PropsType = PropsDataType & PropsHousekeepingType;
|
||||
|
@ -159,7 +153,6 @@ export const MessageSearchResult: FunctionComponent<PropsType> = React.memo(
|
|||
openConversationInternal,
|
||||
sentAt,
|
||||
snippet,
|
||||
style,
|
||||
to,
|
||||
}) => {
|
||||
const onClickItem = useCallback(() => {
|
||||
|
@ -167,7 +160,7 @@ export const MessageSearchResult: FunctionComponent<PropsType> = React.memo(
|
|||
}, [openConversationInternal, conversationId, id]);
|
||||
|
||||
if (!from || !to) {
|
||||
return <div style={style} />;
|
||||
return <div />;
|
||||
}
|
||||
|
||||
const isNoteToSelf = from.isMe && to.isMe;
|
||||
|
@ -213,7 +206,6 @@ export const MessageSearchResult: FunctionComponent<PropsType> = React.memo(
|
|||
phoneNumber={from.phoneNumber}
|
||||
profileName={from.profileName}
|
||||
sharedGroupNames={from.sharedGroupNames}
|
||||
style={style}
|
||||
title={from.title}
|
||||
unblurredAvatarPath={from.unblurredAvatarPath}
|
||||
/>
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { CSSProperties, FunctionComponent } from 'react';
|
||||
import React, { FunctionComponent } from 'react';
|
||||
|
||||
type PropsType = {
|
||||
style: CSSProperties;
|
||||
};
|
||||
type PropsType = Record<string, never>;
|
||||
|
||||
export const SearchResultsLoadingFakeHeader: FunctionComponent<PropsType> = ({
|
||||
style,
|
||||
}) => <div className="module-SearchResultsLoadingFakeHeader" style={style} />;
|
||||
export const SearchResultsLoadingFakeHeader: FunctionComponent<PropsType> = () => (
|
||||
<div className="module-SearchResultsLoadingFakeHeader" />
|
||||
);
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { CSSProperties, FunctionComponent } from 'react';
|
||||
import React, { FunctionComponent } from 'react';
|
||||
|
||||
type PropsType = {
|
||||
style: CSSProperties;
|
||||
};
|
||||
type PropsType = Record<string, never>;
|
||||
|
||||
export const SearchResultsLoadingFakeRow: FunctionComponent<PropsType> = ({
|
||||
style,
|
||||
}) => (
|
||||
<div className="module-SearchResultsLoadingFakeRow" style={style}>
|
||||
export const SearchResultsLoadingFakeRow: FunctionComponent<PropsType> = () => (
|
||||
<div className="module-SearchResultsLoadingFakeRow">
|
||||
<div className="module-SearchResultsLoadingFakeRow__avatar" />
|
||||
<div className="module-SearchResultsLoadingFakeRow__content">
|
||||
<div className="module-SearchResultsLoadingFakeRow__content__header" />
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { CSSProperties, FunctionComponent } from 'react';
|
||||
import React, { FunctionComponent, useCallback } from 'react';
|
||||
|
||||
import {
|
||||
BaseConversationListItem,
|
||||
|
@ -19,18 +19,21 @@ type PropsData = {
|
|||
|
||||
type PropsHousekeeping = {
|
||||
i18n: LocalizerType;
|
||||
style: CSSProperties;
|
||||
onClick: () => void;
|
||||
onClick: (phoneNumber: string) => void;
|
||||
};
|
||||
|
||||
export type Props = PropsData & PropsHousekeeping;
|
||||
|
||||
export const StartNewConversation: FunctionComponent<Props> = React.memo(
|
||||
({ i18n, onClick, phoneNumber, style }) => {
|
||||
({ i18n, onClick, phoneNumber }) => {
|
||||
const messageText = (
|
||||
<div className={TEXT_CLASS_NAME}>{i18n('startConversation')}</div>
|
||||
);
|
||||
|
||||
const boundOnClick = useCallback(() => {
|
||||
onClick(phoneNumber);
|
||||
}, [onClick, phoneNumber]);
|
||||
|
||||
return (
|
||||
<BaseConversationListItem
|
||||
acceptedMessageRequest={false}
|
||||
|
@ -41,10 +44,9 @@ export const StartNewConversation: FunctionComponent<Props> = React.memo(
|
|||
isMe={false}
|
||||
isSelected={false}
|
||||
messageText={messageText}
|
||||
onClick={onClick}
|
||||
onClick={boundOnClick}
|
||||
phoneNumber={phoneNumber}
|
||||
sharedGroupNames={[]}
|
||||
style={style}
|
||||
title={phoneNumber}
|
||||
/>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue