Moves panel header into the panel component
This commit is contained in:
parent
0b885d5feb
commit
7d0f94c654
8 changed files with 158 additions and 87 deletions
|
@ -36,24 +36,6 @@
|
||||||
background-color: $color-gray-95;
|
background-color: $color-gray-95;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel {
|
|
||||||
height: calc(100% - #{$header-height} - var(--title-bar-drag-area-height));
|
|
||||||
inset-inline-start: 0;
|
|
||||||
overflow-y: overlay;
|
|
||||||
position: absolute;
|
|
||||||
top: calc(#{$header-height} + var(--title-bar-drag-area-height));
|
|
||||||
width: 100%;
|
|
||||||
z-index: $z-index-base;
|
|
||||||
|
|
||||||
@include light-theme() {
|
|
||||||
background-color: $color-white;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include dark-theme() {
|
|
||||||
background-color: $color-gray-95;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
.panel {
|
||||||
&:not(.main) {
|
&:not(.main) {
|
||||||
&:dir(ltr) {
|
&:dir(ltr) {
|
||||||
|
|
|
@ -197,7 +197,6 @@
|
||||||
height: $icon-size;
|
height: $icon-size;
|
||||||
margin-inline-end: var(--button-spacing);
|
margin-inline-end: var(--button-spacing);
|
||||||
min-width: $icon-size;
|
min-width: $icon-size;
|
||||||
opacity: 0;
|
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
transition: margin-inline-end 200ms ease-out, opacity 200ms ease-out,
|
transition: margin-inline-end 200ms ease-out, opacity 200ms ease-out,
|
||||||
background 100ms ease-out;
|
background 100ms ease-out;
|
||||||
|
@ -207,10 +206,6 @@
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
&--show {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--show-disabled {
|
&--show-disabled {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
99
stylesheets/components/ConversationPanel.scss
Normal file
99
stylesheets/components/ConversationPanel.scss
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
// Copyright 2023 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
.ConversationPanel {
|
||||||
|
height: 100%;
|
||||||
|
inset-inline-start: 0;
|
||||||
|
overflow-y: overlay;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: $z-index-base;
|
||||||
|
|
||||||
|
@include light-theme() {
|
||||||
|
background-color: $color-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include dark-theme() {
|
||||||
|
background-color: $color-gray-95;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
padding-top: var(--title-bar-drag-area-height);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
height: calc(#{$header-height} + var(--title-bar-drag-area-height));
|
||||||
|
|
||||||
|
@include light-theme {
|
||||||
|
color: $color-gray-90;
|
||||||
|
background-color: $color-white;
|
||||||
|
}
|
||||||
|
@include dark-theme {
|
||||||
|
color: $color-gray-02;
|
||||||
|
background-color: $color-gray-95;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
@include font-body-1-bold;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
&__in-contacts-icon {
|
||||||
|
margin-inline-start: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__back-button {
|
||||||
|
border: none;
|
||||||
|
display: inline-block;
|
||||||
|
height: 20px;
|
||||||
|
margin-inline: 24px 6px;
|
||||||
|
min-width: 20px;
|
||||||
|
opacity: 0;
|
||||||
|
opacity: 1;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
width: 20px;
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include light-theme {
|
||||||
|
@include color-svg(
|
||||||
|
'../images/icons/v3/chevron/chevron-left.svg',
|
||||||
|
$color-gray-90
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@include dark-theme {
|
||||||
|
@include color-svg(
|
||||||
|
'../images/icons/v3/chevron/chevron-left.svg',
|
||||||
|
$color-gray-02
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@include keyboard-mode {
|
||||||
|
&:focus {
|
||||||
|
background-color: $color-ultramarine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@include dark-keyboard-mode {
|
||||||
|
&:focus {
|
||||||
|
background-color: $color-ultramarine-light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,10 +9,21 @@
|
||||||
&__pane {
|
&__pane {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: calc(100% - #{$header-height} - var(--title-bar-drag-area-height));
|
||||||
overflow: initial;
|
inset-inline-start: 0;
|
||||||
|
overflow-y: overlay;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
top: calc(#{$header-height} + var(--title-bar-drag-area-height));
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
z-index: $z-index-base;
|
||||||
|
|
||||||
|
@include light-theme() {
|
||||||
|
background-color: $color-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include dark-theme() {
|
||||||
|
background-color: $color-gray-95;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__timeline {
|
&__timeline {
|
||||||
|
@ -44,4 +55,7 @@
|
||||||
margin-inline: 16px;
|
margin-inline: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
@import './components/ConversationHeader.scss';
|
@import './components/ConversationHeader.scss';
|
||||||
@import './components/ConversationHero.scss';
|
@import './components/ConversationHero.scss';
|
||||||
@import './components/ConversationMergeNotification.scss';
|
@import './components/ConversationMergeNotification.scss';
|
||||||
|
@import './components/ConversationPanel.scss';
|
||||||
@import './components/ConversationView.scss';
|
@import './components/ConversationView.scss';
|
||||||
@import './components/CustomColorEditor.scss';
|
@import './components/CustomColorEditor.scss';
|
||||||
@import './components/CustomizingPreferredReactionsModal.scss';
|
@import './components/CustomizingPreferredReactionsModal.scss';
|
||||||
|
|
|
@ -51,11 +51,10 @@ export enum OutgoingCallButtonStyle {
|
||||||
export type PropsDataType = {
|
export type PropsDataType = {
|
||||||
badge?: BadgeType;
|
badge?: BadgeType;
|
||||||
cannotLeaveBecauseYouAreLastAdmin: boolean;
|
cannotLeaveBecauseYouAreLastAdmin: boolean;
|
||||||
conversationTitle?: string;
|
hasPanelShowing?: boolean;
|
||||||
hasStories?: HasStories;
|
hasStories?: HasStories;
|
||||||
isMissingMandatoryProfileSharing?: boolean;
|
isMissingMandatoryProfileSharing?: boolean;
|
||||||
outgoingCallButtonStyle: OutgoingCallButtonStyle;
|
outgoingCallButtonStyle: OutgoingCallButtonStyle;
|
||||||
showBackButton?: boolean;
|
|
||||||
isSMSOnly?: boolean;
|
isSMSOnly?: boolean;
|
||||||
isSignalConversation?: boolean;
|
isSignalConversation?: boolean;
|
||||||
theme: ThemeType;
|
theme: ThemeType;
|
||||||
|
@ -161,23 +160,6 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderBackButton(): ReactNode {
|
|
||||||
const { i18n, popPanelForConversation, showBackButton } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={popPanelForConversation}
|
|
||||||
className={classNames(
|
|
||||||
'module-ConversationHeader__back-icon',
|
|
||||||
showBackButton ? 'module-ConversationHeader__back-icon--show' : null
|
|
||||||
)}
|
|
||||||
disabled={!showBackButton}
|
|
||||||
aria-label={i18n('icu:goBack')}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private renderHeaderInfoTitle(): ReactNode {
|
private renderHeaderInfoTitle(): ReactNode {
|
||||||
const { name, title, type, i18n, isMe } = this.props;
|
const { name, title, type, i18n, isMe } = this.props;
|
||||||
|
|
||||||
|
@ -304,7 +286,7 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderMoreButton(triggerId: string): ReactNode {
|
private renderMoreButton(triggerId: string): ReactNode {
|
||||||
const { i18n, showBackButton } = this.props;
|
const { i18n } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenuTrigger id={triggerId} ref={this.menuTriggerRef}>
|
<ContextMenuTrigger id={triggerId} ref={this.menuTriggerRef}>
|
||||||
|
@ -313,10 +295,8 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
onClick={this.showMenuBound}
|
onClick={this.showMenuBound}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'module-ConversationHeader__button',
|
'module-ConversationHeader__button',
|
||||||
'module-ConversationHeader__button--more',
|
'module-ConversationHeader__button--more'
|
||||||
showBackButton ? null : 'module-ConversationHeader__button--show'
|
|
||||||
)}
|
)}
|
||||||
disabled={showBackButton}
|
|
||||||
aria-label={i18n('icu:moreInfo')}
|
aria-label={i18n('icu:moreInfo')}
|
||||||
/>
|
/>
|
||||||
</ContextMenuTrigger>
|
</ContextMenuTrigger>
|
||||||
|
@ -324,7 +304,7 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderSearchButton(): ReactNode {
|
private renderSearchButton(): ReactNode {
|
||||||
const { i18n, id, searchInConversation, showBackButton } = this.props;
|
const { i18n, id, searchInConversation } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
@ -332,10 +312,8 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
onClick={() => searchInConversation(id)}
|
onClick={() => searchInConversation(id)}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'module-ConversationHeader__button',
|
'module-ConversationHeader__button',
|
||||||
'module-ConversationHeader__button--search',
|
'module-ConversationHeader__button--search'
|
||||||
showBackButton ? null : 'module-ConversationHeader__button--show'
|
|
||||||
)}
|
)}
|
||||||
disabled={showBackButton}
|
|
||||||
aria-label={i18n('icu:search')}
|
aria-label={i18n('icu:search')}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -700,20 +678,7 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderHeader(): ReactNode {
|
private renderHeader(): ReactNode {
|
||||||
const { conversationTitle, groupVersion, pushPanelForConversation, type } =
|
const { groupVersion, pushPanelForConversation, type } = this.props;
|
||||||
this.props;
|
|
||||||
|
|
||||||
if (conversationTitle !== undefined) {
|
|
||||||
return (
|
|
||||||
<div className="module-ConversationHeader__header">
|
|
||||||
<div className="module-ConversationHeader__header__info">
|
|
||||||
<div className="module-ConversationHeader__header__info__title">
|
|
||||||
{conversationTitle}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let onClick: undefined | (() => void);
|
let onClick: undefined | (() => void);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -775,6 +740,7 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
announcementsOnly,
|
announcementsOnly,
|
||||||
areWeAdmin,
|
areWeAdmin,
|
||||||
expireTimer,
|
expireTimer,
|
||||||
|
hasPanelShowing,
|
||||||
i18n,
|
i18n,
|
||||||
id,
|
id,
|
||||||
isSMSOnly,
|
isSMSOnly,
|
||||||
|
@ -783,8 +749,12 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
onOutgoingVideoCallInConversation,
|
onOutgoingVideoCallInConversation,
|
||||||
outgoingCallButtonStyle,
|
outgoingCallButtonStyle,
|
||||||
setDisappearingMessages,
|
setDisappearingMessages,
|
||||||
showBackButton,
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
if (hasPanelShowing) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { isNarrow, modalState } = this.state;
|
const { isNarrow, modalState } = this.state;
|
||||||
const triggerId = `conversation-${id}`;
|
const triggerId = `conversation-${id}`;
|
||||||
|
|
||||||
|
@ -829,7 +799,6 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
})}
|
})}
|
||||||
ref={measureRef}
|
ref={measureRef}
|
||||||
>
|
>
|
||||||
{this.renderBackButton()}
|
|
||||||
{this.renderHeader()}
|
{this.renderHeader()}
|
||||||
{!isSMSOnly && !isSignalConversation && (
|
{!isSMSOnly && !isSignalConversation && (
|
||||||
<OutgoingCallButtons
|
<OutgoingCallButtons
|
||||||
|
@ -845,7 +814,6 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
||||||
onOutgoingVideoCallInConversation
|
onOutgoingVideoCallInConversation
|
||||||
}
|
}
|
||||||
outgoingCallButtonStyle={outgoingCallButtonStyle}
|
outgoingCallButtonStyle={outgoingCallButtonStyle}
|
||||||
showBackButton={showBackButton}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.renderSearchButton()}
|
{this.renderSearchButton()}
|
||||||
|
@ -868,7 +836,6 @@ function OutgoingCallButtons({
|
||||||
onOutgoingAudioCallInConversation,
|
onOutgoingAudioCallInConversation,
|
||||||
onOutgoingVideoCallInConversation,
|
onOutgoingVideoCallInConversation,
|
||||||
outgoingCallButtonStyle,
|
outgoingCallButtonStyle,
|
||||||
showBackButton,
|
|
||||||
}: { isNarrow: boolean } & Pick<
|
}: { isNarrow: boolean } & Pick<
|
||||||
PropsType,
|
PropsType,
|
||||||
| 'announcementsOnly'
|
| 'announcementsOnly'
|
||||||
|
@ -878,7 +845,6 @@ function OutgoingCallButtons({
|
||||||
| 'onOutgoingAudioCallInConversation'
|
| 'onOutgoingAudioCallInConversation'
|
||||||
| 'onOutgoingVideoCallInConversation'
|
| 'onOutgoingVideoCallInConversation'
|
||||||
| 'outgoingCallButtonStyle'
|
| 'outgoingCallButtonStyle'
|
||||||
| 'showBackButton'
|
|
||||||
>): JSX.Element | null {
|
>): JSX.Element | null {
|
||||||
const videoButton = (
|
const videoButton = (
|
||||||
<button
|
<button
|
||||||
|
@ -886,12 +852,10 @@ function OutgoingCallButtons({
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'module-ConversationHeader__button',
|
'module-ConversationHeader__button',
|
||||||
'module-ConversationHeader__button--video',
|
'module-ConversationHeader__button--video',
|
||||||
showBackButton ? null : 'module-ConversationHeader__button--show',
|
announcementsOnly && !areWeAdmin
|
||||||
!showBackButton && announcementsOnly && !areWeAdmin
|
|
||||||
? 'module-ConversationHeader__button--show-disabled'
|
? 'module-ConversationHeader__button--show-disabled'
|
||||||
: undefined
|
: undefined
|
||||||
)}
|
)}
|
||||||
disabled={showBackButton}
|
|
||||||
onClick={() => onOutgoingVideoCallInConversation(id)}
|
onClick={() => onOutgoingVideoCallInConversation(id)}
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
|
@ -917,10 +881,8 @@ function OutgoingCallButtons({
|
||||||
onClick={() => onOutgoingAudioCallInConversation(id)}
|
onClick={() => onOutgoingAudioCallInConversation(id)}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'module-ConversationHeader__button',
|
'module-ConversationHeader__button',
|
||||||
'module-ConversationHeader__button--audio',
|
'module-ConversationHeader__button--audio'
|
||||||
showBackButton ? null : 'module-ConversationHeader__button--show'
|
|
||||||
)}
|
)}
|
||||||
disabled={showBackButton}
|
|
||||||
aria-label={i18n('icu:makeOutgoingCall')}
|
aria-label={i18n('icu:makeOutgoingCall')}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -932,9 +894,10 @@ function OutgoingCallButtons({
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'module-ConversationHeader__button',
|
'module-ConversationHeader__button',
|
||||||
'module-ConversationHeader__button--join-call',
|
'module-ConversationHeader__button--join-call',
|
||||||
showBackButton ? null : 'module-ConversationHeader__button--show'
|
announcementsOnly && !areWeAdmin
|
||||||
|
? 'module-ConversationHeader__button--show-disabled'
|
||||||
|
: undefined
|
||||||
)}
|
)}
|
||||||
disabled={showBackButton}
|
|
||||||
onClick={() => onOutgoingVideoCallInConversation(id)}
|
onClick={() => onOutgoingVideoCallInConversation(id)}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
|
|
|
@ -14,7 +14,6 @@ import { getPreferredBadgeSelector } from '../selectors/badges';
|
||||||
import {
|
import {
|
||||||
getConversationByUuidSelector,
|
getConversationByUuidSelector,
|
||||||
getConversationSelector,
|
getConversationSelector,
|
||||||
getConversationTitle,
|
|
||||||
isMissingRequiredProfileSharing,
|
isMissingRequiredProfileSharing,
|
||||||
} from '../selectors/conversations';
|
} from '../selectors/conversations';
|
||||||
import { CallMode } from '../../types/Calling';
|
import { CallMode } from '../../types/Calling';
|
||||||
|
@ -88,9 +87,8 @@ export function SmartConversationHeader({ id }: OwnProps): JSX.Element {
|
||||||
|
|
||||||
const badgeSelector = useSelector(getPreferredBadgeSelector);
|
const badgeSelector = useSelector(getPreferredBadgeSelector);
|
||||||
const badge = badgeSelector(conversation.badges);
|
const badge = badgeSelector(conversation.badges);
|
||||||
const conversationTitle = useSelector(getConversationTitle);
|
|
||||||
const i18n = useSelector(getIntl);
|
const i18n = useSelector(getIntl);
|
||||||
const showBackButton = useSelector<StateType, boolean>(
|
const hasPanelShowing = useSelector<StateType, boolean>(
|
||||||
state => state.conversations.targetedConversationPanels.length > 0
|
state => state.conversations.targetedConversationPanels.length > 0
|
||||||
);
|
);
|
||||||
const outgoingCallButtonStyle = useSelector<
|
const outgoingCallButtonStyle = useSelector<
|
||||||
|
@ -155,8 +153,8 @@ export function SmartConversationHeader({ id }: OwnProps): JSX.Element {
|
||||||
])}
|
])}
|
||||||
badge={badge}
|
badge={badge}
|
||||||
cannotLeaveBecauseYouAreLastAdmin={cannotLeaveBecauseYouAreLastAdmin}
|
cannotLeaveBecauseYouAreLastAdmin={cannotLeaveBecauseYouAreLastAdmin}
|
||||||
conversationTitle={conversationTitle}
|
|
||||||
destroyMessages={destroyMessages}
|
destroyMessages={destroyMessages}
|
||||||
|
hasPanelShowing={hasPanelShowing}
|
||||||
hasStories={hasStories}
|
hasStories={hasStories}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
id={id}
|
id={id}
|
||||||
|
@ -178,7 +176,6 @@ export function SmartConversationHeader({ id }: OwnProps): JSX.Element {
|
||||||
setDisappearingMessages={setDisappearingMessages}
|
setDisappearingMessages={setDisappearingMessages}
|
||||||
setMuteExpiration={setMuteExpiration}
|
setMuteExpiration={setMuteExpiration}
|
||||||
setPinned={setPinned}
|
setPinned={setPinned}
|
||||||
showBackButton={showBackButton}
|
|
||||||
theme={theme}
|
theme={theme}
|
||||||
toggleSelectMode={toggleSelectMode}
|
toggleSelectMode={toggleSelectMode}
|
||||||
viewUserStories={viewUserStories}
|
viewUserStories={viewUserStories}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { SmartMessageDetail } from './MessageDetail';
|
||||||
import { SmartPendingInvites } from './PendingInvites';
|
import { SmartPendingInvites } from './PendingInvites';
|
||||||
import { SmartStickerManager } from './StickerManager';
|
import { SmartStickerManager } from './StickerManager';
|
||||||
import { getIntl } from '../selectors/user';
|
import { getIntl } from '../selectors/user';
|
||||||
import { getTopPanel } from '../selectors/conversations';
|
import { getConversationTitle, getTopPanel } from '../selectors/conversations';
|
||||||
import { useConversationsActions } from '../ducks/conversations';
|
import { useConversationsActions } from '../ducks/conversations';
|
||||||
import { focusableSelectors } from '../../util/focusableSelectors';
|
import { focusableSelectors } from '../../util/focusableSelectors';
|
||||||
|
|
||||||
|
@ -30,10 +30,12 @@ export function ConversationPanel({
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
}): JSX.Element | null {
|
}): JSX.Element | null {
|
||||||
const i18n = useSelector(getIntl);
|
const i18n = useSelector(getIntl);
|
||||||
const { startConversation } = useConversationsActions();
|
const { popPanelForConversation, startConversation } =
|
||||||
|
useConversationsActions();
|
||||||
const topPanel = useSelector<StateType, PanelRenderType | undefined>(
|
const topPanel = useSelector<StateType, PanelRenderType | undefined>(
|
||||||
getTopPanel
|
getTopPanel
|
||||||
);
|
);
|
||||||
|
const conversationTitle = useSelector(getConversationTitle);
|
||||||
|
|
||||||
const selectors = useMemo(() => focusableSelectors.join(','), []);
|
const selectors = useMemo(() => focusableSelectors.join(','), []);
|
||||||
const panelRef = useRef<HTMLDivElement | null>(null);
|
const panelRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
@ -109,7 +111,25 @@ export function ConversationPanel({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames('panel', panelClassName)} ref={panelRef}>
|
<div
|
||||||
|
className={classNames('ConversationPanel', 'panel', panelClassName)}
|
||||||
|
ref={panelRef}
|
||||||
|
>
|
||||||
|
<div className="ConversationPanel__header">
|
||||||
|
<button
|
||||||
|
aria-label={i18n('icu:goBack')}
|
||||||
|
className="ConversationPanel__header__back-button"
|
||||||
|
onClick={popPanelForConversation}
|
||||||
|
type="button"
|
||||||
|
/>
|
||||||
|
{conversationTitle && (
|
||||||
|
<div className="ConversationPanel__header__info">
|
||||||
|
<div className="ConversationPanel__header__info__title">
|
||||||
|
{conversationTitle}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
{panelChild}
|
{panelChild}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue