UI fixes for conversation details screen
This commit is contained in:
parent
ddebbf8121
commit
267ae80442
9 changed files with 134 additions and 51 deletions
|
@ -487,13 +487,15 @@ export class ConversationHeader extends React.Component<PropsType> {
|
|||
private renderHeader(): JSX.Element {
|
||||
const {
|
||||
conversationTitle,
|
||||
groupVersion,
|
||||
id,
|
||||
isMe,
|
||||
onShowContactModal,
|
||||
onShowConversationDetails,
|
||||
type,
|
||||
} = this.props;
|
||||
|
||||
if (conversationTitle) {
|
||||
if (conversationTitle !== undefined) {
|
||||
return (
|
||||
<div className="module-conversation-header__title-flex">
|
||||
<div className="module-conversation-header__title">
|
||||
|
@ -503,6 +505,35 @@ export class ConversationHeader extends React.Component<PropsType> {
|
|||
);
|
||||
}
|
||||
|
||||
const hasGV2AdminEnabled =
|
||||
groupVersion === 2 &&
|
||||
window.Signal.RemoteConfig.isEnabled('desktop.gv2Admin');
|
||||
|
||||
if (type === 'group' && hasGV2AdminEnabled) {
|
||||
const onHeaderClick = () => onShowConversationDetails();
|
||||
const onKeyDown = (e: React.KeyboardEvent): void => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
onShowConversationDetails();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="module-conversation-header__title-flex module-conversation-header__title-clickable"
|
||||
onClick={onHeaderClick}
|
||||
onKeyDown={onKeyDown}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
>
|
||||
{this.renderAvatar()}
|
||||
{this.renderTitle()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (type === 'group' || isMe) {
|
||||
return (
|
||||
<div className="module-conversation-header__title-flex">
|
||||
|
|
|
@ -37,7 +37,11 @@ export const ConversationDetailsActions: React.ComponentType<Props> = ({
|
|||
icon="leave"
|
||||
/>
|
||||
}
|
||||
label={i18n('ConversationDetailsActions--leave-group')}
|
||||
label={
|
||||
<div className="module-conversation-details__leave-group">
|
||||
{i18n('ConversationDetailsActions--leave-group')}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
<PanelRow
|
||||
onClick={() => setConfirmingBlock(true)}
|
||||
|
@ -47,7 +51,11 @@ export const ConversationDetailsActions: React.ComponentType<Props> = ({
|
|||
icon="block"
|
||||
/>
|
||||
}
|
||||
label={i18n('ConversationDetailsActions--block-group')}
|
||||
label={
|
||||
<div className="module-conversation-details__block-group">
|
||||
{i18n('ConversationDetailsActions--block-group')}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</PanelSection>
|
||||
|
||||
|
|
|
@ -45,16 +45,32 @@ const createProps = (overrideProps: Partial<Props>): Props => ({
|
|||
memberships: overrideProps.memberships || [],
|
||||
});
|
||||
|
||||
story.add('Basic', () => {
|
||||
const memberships = createMemberships(10);
|
||||
story.add('Few', () => {
|
||||
const memberships = createMemberships(3);
|
||||
|
||||
const props = createProps({ memberships });
|
||||
|
||||
return <ConversationDetailsMembershipList {...props} />;
|
||||
});
|
||||
|
||||
story.add('Few', () => {
|
||||
const memberships = createMemberships(3);
|
||||
story.add('Limit', () => {
|
||||
const memberships = createMemberships(5);
|
||||
|
||||
const props = createProps({ memberships });
|
||||
|
||||
return <ConversationDetailsMembershipList {...props} />;
|
||||
});
|
||||
|
||||
story.add('Limit +1', () => {
|
||||
const memberships = createMemberships(6);
|
||||
|
||||
const props = createProps({ memberships });
|
||||
|
||||
return <ConversationDetailsMembershipList {...props} />;
|
||||
});
|
||||
|
||||
story.add('Limit +2', () => {
|
||||
const memberships = createMemberships(7);
|
||||
|
||||
const props = createProps({ memberships });
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ export type Props = {
|
|||
i18n: LocalizerType;
|
||||
};
|
||||
|
||||
const INITIAL_MEMBER_COUNT = 5;
|
||||
const MAX_MEMBER_COUNT = 5;
|
||||
|
||||
export const ConversationDetailsMembershipList: React.ComponentType<Props> = ({
|
||||
memberships,
|
||||
|
@ -33,44 +33,47 @@ export const ConversationDetailsMembershipList: React.ComponentType<Props> = ({
|
|||
}) => {
|
||||
const [showAllMembers, setShowAllMembers] = React.useState<boolean>(false);
|
||||
|
||||
const shouldHideRestMembers = memberships.length - MAX_MEMBER_COUNT > 1;
|
||||
const membersToShow =
|
||||
shouldHideRestMembers && !showAllMembers
|
||||
? MAX_MEMBER_COUNT
|
||||
: memberships.length;
|
||||
|
||||
return (
|
||||
<PanelSection
|
||||
title={i18n('ConversationDetailsMembershipList--title', [
|
||||
memberships.length.toString(),
|
||||
])}
|
||||
>
|
||||
{memberships
|
||||
.slice(0, showAllMembers ? undefined : INITIAL_MEMBER_COUNT)
|
||||
.map(({ isAdmin, member }) => (
|
||||
<PanelRow
|
||||
key={member.id}
|
||||
onClick={() => showContactModal(member.id)}
|
||||
icon={
|
||||
<Avatar
|
||||
conversationType="direct"
|
||||
i18n={i18n}
|
||||
size={32}
|
||||
{...member}
|
||||
/>
|
||||
}
|
||||
label={member.title}
|
||||
right={isAdmin ? i18n('GroupV2--admin') : ''}
|
||||
/>
|
||||
))}
|
||||
{showAllMembers === false &&
|
||||
memberships.length > INITIAL_MEMBER_COUNT && (
|
||||
<PanelRow
|
||||
className="module-conversation-details-membership-list--show-all"
|
||||
icon={
|
||||
<ConversationDetailsIcon
|
||||
ariaLabel={i18n('ConversationDetailsMembershipList--show-all')}
|
||||
icon="down"
|
||||
/>
|
||||
}
|
||||
onClick={() => setShowAllMembers(true)}
|
||||
label={i18n('ConversationDetailsMembershipList--show-all')}
|
||||
/>
|
||||
)}
|
||||
{memberships.slice(0, membersToShow).map(({ isAdmin, member }) => (
|
||||
<PanelRow
|
||||
key={member.id}
|
||||
onClick={() => showContactModal(member.id)}
|
||||
icon={
|
||||
<Avatar
|
||||
conversationType="direct"
|
||||
i18n={i18n}
|
||||
size={32}
|
||||
{...member}
|
||||
/>
|
||||
}
|
||||
label={member.title}
|
||||
right={isAdmin ? i18n('GroupV2--admin') : ''}
|
||||
/>
|
||||
))}
|
||||
{showAllMembers === false && shouldHideRestMembers && (
|
||||
<PanelRow
|
||||
className="module-conversation-details-membership-list--show-all"
|
||||
icon={
|
||||
<ConversationDetailsIcon
|
||||
ariaLabel={i18n('ConversationDetailsMembershipList--show-all')}
|
||||
icon="down"
|
||||
/>
|
||||
}
|
||||
onClick={() => setShowAllMembers(true)}
|
||||
label={i18n('ConversationDetailsMembershipList--show-all')}
|
||||
/>
|
||||
)}
|
||||
</PanelSection>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
|
|||
icon: boolean('with icon', overrideProps.icon !== undefined) ? (
|
||||
<ConversationDetailsIcon ariaLabel="timer" icon="timer" />
|
||||
) : null,
|
||||
label: text('label', overrideProps.label || ''),
|
||||
label: text('label', (overrideProps.label as string) || ''),
|
||||
info: text('info', overrideProps.info || ''),
|
||||
right: text('right', (overrideProps.right as string) || ''),
|
||||
actions: boolean('with action', overrideProps.actions !== undefined) ? (
|
||||
|
|
|
@ -9,7 +9,7 @@ export type Props = {
|
|||
alwaysShowActions?: boolean;
|
||||
className?: string;
|
||||
icon?: React.ReactNode;
|
||||
label: string;
|
||||
label: string | React.ReactNode;
|
||||
info?: string;
|
||||
right?: string | React.ReactNode;
|
||||
actions?: React.ReactNode;
|
||||
|
@ -30,15 +30,15 @@ export const PanelRow: React.ComponentType<Props> = ({
|
|||
}) => {
|
||||
const content = (
|
||||
<>
|
||||
{icon && <div className={bem('icon')}>{icon}</div>}
|
||||
{icon !== undefined ? <div className={bem('icon')}>{icon}</div> : null}
|
||||
<div className={bem('label')}>
|
||||
<div>{label}</div>
|
||||
{info && <div className={bem('info')}>{info}</div>}
|
||||
{info !== undefined ? <div className={bem('info')}>{info}</div> : null}
|
||||
</div>
|
||||
{right && <div className={bem('right')}>{right}</div>}
|
||||
{actions && (
|
||||
{right !== undefined ? <div className={bem('right')}>{right}</div> : null}
|
||||
{actions !== undefined ? (
|
||||
<div className={alwaysShowActions ? '' : bem('actions')}>{actions}</div>
|
||||
)}
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue