Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Only show core navigation elements (call/chat/notification/info) when a widget is maximised #7114

Merged
merged 95 commits into from
Nov 29, 2021
Merged
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
0a6c20c
add maximise widget functionality
toger5 Nov 8, 2021
a9a2c41
fix linter issues
toger5 Nov 8, 2021
cb4ae5f
fix style lint issues
toger5 Nov 8, 2021
e68c8f1
Update src/components/structures/RoomView.tsx
toger5 Nov 9, 2021
8608c59
fix typo
toger5 Nov 9, 2021
bb543a2
typo
toger5 Nov 9, 2021
4cc316d
Remove caps "AND "
toger5 Nov 10, 2021
4a3b48d
fix spelling
toger5 Nov 10, 2021
5d14783
improove readibility for continue in for
toger5 Nov 10, 2021
74f9b93
review fixes
toger5 Nov 10, 2021
cfbdf40
reuse already added icons
toger5 Nov 10, 2021
ffb0af8
more container comment fixes
toger5 Nov 10, 2021
1155ae9
fix app options button
toger5 Nov 10, 2021
cd9d193
remove error message
toger5 Nov 10, 2021
a76e7ec
fix issue not beeing able to maximise
toger5 Nov 10, 2021
04e0b42
remove maxmimisedDrawer
toger5 Nov 10, 2021
21b9549
fix centering and overflow of appDrawer
toger5 Nov 10, 2021
38f8cfe
fix hover label "Minimise widget"->"Close"
toger5 Nov 11, 2021
4aa18f7
right panel chat timeline
toger5 Nov 10, 2021
0df2b82
automatically switch to TimelineCard on maximise
toger5 Nov 10, 2021
bddb05f
fix style and compile errors
toger5 Nov 10, 2021
2ffd836
fix highlighting and labels
toger5 Nov 11, 2021
c3a6409
rename timelinePanel-> timelineCard
toger5 Nov 11, 2021
6fb6e6d
simplify previous phase access
toger5 Nov 11, 2021
98adc21
close right panel chat if no widget is maximised
toger5 Nov 11, 2021
7d8879f
fix linter
toger5 Nov 11, 2021
1fac898
only show core elements if a widget is maximised
toger5 Nov 11, 2021
1bff7f0
hide timeline card button
toger5 Nov 11, 2021
0831b60
review fixes
toger5 Nov 11, 2021
fdf7b9f
add jest test for WidgetLayoutStore
toger5 Nov 12, 2021
afef1d0
Merge branch 'develop' into toger5/maximised_widgets
toger5 Nov 12, 2021
b06490e
change accent-color
toger5 Nov 12, 2021
b3c6526
another try
toger5 Nov 12, 2021
03ec030
Merge branch 'develop' into toger5/maximised_widgets
toger5 Nov 12, 2021
a23931b
I think I have it now...(accent related commit)
toger5 Nov 12, 2021
0bcb881
fix room state always overriding user settings
toger5 Nov 15, 2021
b1ef33b
fix container border width
toger5 Nov 15, 2021
ba4d09c
change icons, change border width
toger5 Nov 15, 2021
26d5cd1
Merge branch 'toger5/widget_container_border_width' into toger5/maxim…
toger5 Nov 15, 2021
2a8bba6
use $container-border-width where needed
toger5 Nov 15, 2021
6f3a1c0
fix style lint
toger5 Nov 15, 2021
fa35b44
add !important for widget card AppTileFullWidth
toger5 Nov 15, 2021
7f0c5d6
fix bug where a widget can be open twice
toger5 Nov 15, 2021
a8d2e5e
review fixes
toger5 Nov 15, 2021
3743b74
fix awkward ternary stack
toger5 Nov 15, 2021
c6e9c82
Merge branch 'develop' into toger5/maximised_widgets
toger5 Nov 15, 2021
704ddc8
remove the now deprecated collapse button url after merge
toger5 Nov 15, 2021
0b9a544
Merge branch 'toger5/maximised_widgets' into toger5/maximised_widgets…
toger5 Nov 16, 2021
ad183fb
fix styling and move TimelineCard to the views
toger5 Nov 16, 2021
d3218f3
Merge branch 'develop' into toger5/maximised_widgets_rightPanel_timeline
toger5 Nov 16, 2021
6e1f1fe
clean up TimelinCard class
toger5 Nov 16, 2021
585ffa8
fix maximised state being loaded correctly
toger5 Nov 16, 2021
583d754
enable Read Receipts and sendReadReceiptOnLoad for timelineCard
toger5 Nov 17, 2021
d782c06
Merge branch 'develop' into toger5/maximised_widgets_rightPanel_timeline
toger5 Nov 17, 2021
f8c1388
Merge branch 'toger5/maximised_widgets_rightPanel_timeline' into toge…
toger5 Nov 17, 2021
d66a411
Update src/components/structures/RightPanel.tsx
toger5 Nov 17, 2021
6aa2e9b
fix position of dispatcher
toger5 Nov 17, 2021
596af16
fix header styles (make them prettier and simpler)
toger5 Nov 17, 2021
90e331f
fix up event tile
toger5 Nov 17, 2021
8dfa940
rename RightPanelPhases.TimelineCard -> Timeline
toger5 Nov 17, 2021
89b6266
Merge remote-tracking branch 'origin/toger5/maximised_widgets_rightPa…
toger5 Nov 17, 2021
304e788
fix style
toger5 Nov 17, 2021
d6ad1ae
code cleanup for previous phase logic
toger5 Nov 17, 2021
658eb7e
Merge branch 'toger5/maximised_widgets_rightPanel_timeline' into toge…
toger5 Nov 17, 2021
65c752d
remove artifacts from the previousPhase logic.
toger5 Nov 17, 2021
756630e
Merge branch 'toger5/maximised_widgets_rightPanel_timeline' into toge…
toger5 Nov 17, 2021
5a3cf2b
remove unecassary imports
toger5 Nov 17, 2021
d6e80f1
Merge branch 'toger5/maximised_widgets_rightPanel_timeline' into toge…
toger5 Nov 17, 2021
20ff205
Merge branch 'develop' into toger5/maximised_widgets_rightPanel_timeline
toger5 Nov 18, 2021
3acb7a3
fix settings layout path
toger5 Nov 18, 2021
786cff8
timeline panel header fixups
toger5 Nov 18, 2021
842150c
only enable new back button behaviour if feature enabled
toger5 Nov 18, 2021
23e9fb3
Merge branch 'toger5/maximised_widgets_rightPanel_timeline' into toge…
toger5 Nov 18, 2021
f8ae27e
prevent double timeline
toger5 Nov 18, 2021
6e4bcf0
Merge branch 'toger5/maximised_widgets_rightPanel_timeline' into toge…
toger5 Nov 18, 2021
03262fe
coreElementOnly -> excludedRighPanelPhaseButtons
toger5 Nov 19, 2021
77b9c03
disable RR's
toger5 Nov 19, 2021
d097136
remove unread indicator fragments HeaderButton
toger5 Nov 19, 2021
1e3b157
dont go to room info when widget gets closed
toger5 Nov 19, 2021
7999cdf
styling stuff
toger5 Nov 19, 2021
92d8895
solve "never show two timelines" more properly
toger5 Nov 19, 2021
d5a0652
hello linter ;)
toger5 Nov 19, 2021
10f4143
fix typo(s)
toger5 Nov 19, 2021
1bf0704
Update src/components/structures/RoomView.tsx
toger5 Nov 19, 2021
f03de71
Update src/components/structures/RoomView.tsx
toger5 Nov 19, 2021
bd0d989
Merge branch 'develop' into toger5/maximised_widgets_rightPanel_timeline
toger5 Nov 22, 2021
e881053
Merge branch 'toger5/maximised_widgets_rightPanel_timeline' into toge…
toger5 Nov 22, 2021
4f4b185
remove unused var (showNewMessages)
toger5 Nov 22, 2021
9251b03
add comment about RR's
toger5 Nov 22, 2021
7ea9f54
Merge branch 'toger5/maximised_widgets_rightPanel_timeline' into toge…
toger5 Nov 22, 2021
d21dc8f
fix feature flag check
toger5 Nov 24, 2021
bfdb6d1
remove viewInRoom button if a widget is maximised
toger5 Nov 29, 2021
c2f854b
Merge branch 'toger5/maximised_widgets_rightPanel_timeline' into toge…
toger5 Nov 29, 2021
0bd570d
Merge branch 'develop' into toger5/maximised_widgets_only_core_nav
toger5 Nov 29, 2021
c5e23f0
Fix tricky way to still get two timelines
toger5 Nov 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions res/css/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@
@import "./views/right_panel/_PinnedMessagesCard.scss";
@import "./views/right_panel/_RoomSummaryCard.scss";
@import "./views/right_panel/_ThreadPanel.scss";
@import "./views/right_panel/_TimelineCard.scss";
@import "./views/right_panel/_UserInfo.scss";
@import "./views/right_panel/_VerificationPanel.scss";
@import "./views/right_panel/_WidgetCard.scss";
Expand Down
7 changes: 7 additions & 0 deletions res/css/structures/_RightPanel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ $pulse-color: $alert;
}
}

.mx_RightPanel_timelineCardButton {
&::before {
mask-image: url('$(res)/img/element-icons/feedback.svg');
mask-position: center;
}
}

@keyframes mx_RightPanel_indicator_pulse {
0% {
transform: scale(0.95);
Expand Down
35 changes: 35 additions & 0 deletions res/css/views/right_panel/_TimelineCard.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Copyright 2021 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

.mx_TimelineCard {
.mx_TimelineCard__header {
margin-left: 6px;

span:first-of-type {
font-weight: 600;
font-size: 15px;
line-height: 18px;
color: $secondary-content;
}
}
.mx_BaseCard_header {
margin: 5px 0 9px 0;
.mx_BaseCard_close {
margin: 8px;
right: 0;
}
}
}
9 changes: 8 additions & 1 deletion src/components/structures/RightPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import SpaceStore from "../../stores/spaces/SpaceStore";
import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
import { E2EStatus } from '../../utils/ShieldUtils';
import { dispatchShowThreadsPanelEvent } from '../../dispatcher/dispatch-actions/threads';
import TimelineCard from '../views/right_panel/TimelineCard';

interface IProps {
room?: Room; // if showing panels for a given room, this is set
Expand Down Expand Up @@ -334,7 +335,13 @@ export default class RightPanel extends React.Component<IProps, IState> {
panel = <PinnedMessagesCard room={this.props.room} onClose={this.onClose} />;
}
break;

case RightPanelPhases.Timeline:
if (!SettingsStore.getValue("feature_maximised_widgets")) break;
panel = <TimelineCard
room={this.props.room}
resizeNotifier={this.props.resizeNotifier}
onClose={this.onClose} />;
break;
case RightPanelPhases.FilePanel:
panel = <FilePanel roomId={roomId} resizeNotifier={this.props.resizeNotifier} onClose={this.onClose} />;
break;
Expand Down
19 changes: 18 additions & 1 deletion src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ import { dispatchShowThreadEvent } from '../../dispatcher/dispatch-actions/threa
import { fetchInitialEvent } from "../../utils/EventUtils";
import { ComposerType } from "../../dispatcher/payloads/ComposerInsertPayload";
import AppsDrawer from '../views/rooms/AppsDrawer';
import { SetRightPanelPhasePayload } from '../../dispatcher/payloads/SetRightPanelPhasePayload';
import { RightPanelPhases } from '../../stores/RightPanelStorePhases';

const DEBUG = false;
let debuglog = function(msg: string) {};
Expand Down Expand Up @@ -327,6 +329,13 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {

private onWidgetLayoutChange = () => {
if (!this.state.room) return;
if (WidgetLayoutStore.instance.hasMaximisedWidget(this.state.room)) {
// Show chat in right panel when a widget is maximised
dis.dispatch<SetRightPanelPhasePayload>({
action: Action.SetRightPanelPhase,
phase: RightPanelPhases.Timeline,
});
}
this.checkWidgets(this.state.room);
};

Expand Down Expand Up @@ -2089,7 +2098,14 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
/>);
}

const showRightPanel = this.state.room && this.state.showRightPanel;
let showRightPanel = this.state.room && this.state.showRightPanel;
// This is a hack to hide the chat. This should not be necassary once the right panel
// phase is stored per room.
if (RightPanelStore.getSharedInstance().roomPanelPhase === RightPanelPhases.Timeline
&& this.state.mainSplitContentType === MainSplitContentType.Timeline ) {
// Two timelines are shown prevent this by hiding the right panel
showRightPanel = false;
}
const rightPanel = showRightPanel
? <RightPanel
room={this.state.room}
Expand Down Expand Up @@ -2158,6 +2174,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
onAppsClick={this.state.hasPinnedWidgets ? this.onAppsClick : null}
appsShown={this.state.showApps}
onCallPlaced={this.onCallPlaced}
coreElementsOnly={this.state.mainSplitContentType === MainSplitContentType.MaximisedWidget}
/>
<MainSplit panel={rightPanel} resizeNotifier={this.props.resizeNotifier}>
<div className="mx_RoomView_body">
Expand Down
18 changes: 16 additions & 2 deletions src/components/structures/ThreadView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ import ContentMessages from '../../ContentMessages';
import UploadBar from './UploadBar';
import { _t } from '../../languageHandler';
import ThreadListContextMenu from '../views/context_menus/ThreadListContextMenu';
import RightPanelStore from '../../stores/RightPanelStore';
import SettingsStore from '../../settings/SettingsStore';

interface IProps {
room: Room;
Expand Down Expand Up @@ -203,6 +205,18 @@ export default class ThreadView extends React.Component<IProps, IState> {
event_id: this.state.thread?.id,
};

let previousPhase = RightPanelStore.getSharedInstance().previousPhase;
if (SettingsStore.getValue("feature_maximised_widgets")) {
previousPhase = RightPanelPhases.ThreadPanel;
}
// Make sure the previous Phase is always one of the two: Timeline or ThreadPanel
if (![RightPanelPhases.ThreadPanel, RightPanelPhases.Timeline].includes(previousPhase)) {
previousPhase = RightPanelPhases.ThreadPanel;
}
const previousPhaseLabels = {};
previousPhaseLabels[RightPanelPhases.ThreadPanel] = _t("All threads");
previousPhaseLabels[RightPanelPhases.Timeline] = _t("Chat");

return (
<RoomContext.Provider value={{
...this.context,
Expand All @@ -213,8 +227,8 @@ export default class ThreadView extends React.Component<IProps, IState> {
<BaseCard
className="mx_ThreadView mx_ThreadPanel"
onClose={this.props.onClose}
previousPhase={RightPanelPhases.ThreadPanel}
previousPhaseLabel={_t("All threads")}
previousPhase={previousPhase}
previousPhaseLabel={previousPhaseLabels[previousPhase]}
withoutScrollContainer={true}
header={this.renderThreadViewHeader()}
>
Expand Down
7 changes: 2 additions & 5 deletions src/components/structures/TimelinePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -475,10 +475,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
};

private onMessageListScroll = e => {
if (this.props.onScroll) {
this.props.onScroll(e);
}

this.props.onScroll?.(e);
if (this.props.manageReadMarkers) {
this.doManageReadMarkers();
}
Expand Down Expand Up @@ -593,7 +590,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
this.setState<null>(updatedState, () => {
this.messagePanel.current.updateTimelineMinHeight();
if (callRMUpdated) {
this.props.onReadMarkerUpdated();
this.props.onReadMarkerUpdated?.();
}
});
});
Expand Down
8 changes: 8 additions & 0 deletions src/components/views/elements/AppTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ interface IState {
}

import { logger } from "matrix-js-sdk/src/logger";
import { RightPanelPhases } from '../../../stores/RightPanelStorePhases';
import { Action } from '../../../dispatcher/actions';
import RightPanelStore from '../../../stores/RightPanelStore';

@replaceableComponent("views.elements.AppTile")
export default class AppTile extends React.Component<IProps, IState> {
Expand Down Expand Up @@ -406,6 +409,11 @@ export default class AppTile extends React.Component<IProps, IState> {
? Container.Right
: Container.Center;
WidgetLayoutStore.instance.moveToContainer(this.props.room, this.props.app, targetContainer);
if (targetContainer === Container.Right
&& RightPanelStore.getSharedInstance().visibleRoomPanelPhase === RightPanelPhases.Timeline) {
// If the widget gets closed also close the RightPanel chat.
dis.dispatch({ action: Action.SetRightPanelPhase, phase: RightPanelPhases.RoomSummary });
}
};

private onContextMenuClick = (): void => {
Expand Down
35 changes: 32 additions & 3 deletions src/components/views/right_panel/RoomHeaderButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,28 @@ const PinnedMessagesHeaderButton = ({ room, isHighlighted, onClick }) => {
</HeaderButton>;
};

const TimelineCardHeaderButton = ({ room, isHighlighted, showNewMessage, onClick }) => {
if (!SettingsStore.getValue("feature_maximised_widgets")) return null;

let unreadIndicator;
if (/*pinnedEvents.some(id => !readPinnedEvents.has(id)*/ showNewMessage) {
unreadIndicator = <div className="mx_RightPanel_pinnedMessagesButton_unreadIndicator" />;
}

return <HeaderButton
name="timelineCardButton"
title={_t("Chat")}
isHighlighted={isHighlighted}
onClick={onClick}
analytics={["Right Panel", "Timeline Panel Button", "click"]}
>
{ unreadIndicator }
</HeaderButton>;
};

interface IProps {
room?: Room;
coreElementsOnly?: boolean;
}

@replaceableComponent("views.right_panel.RoomHeaderButtons")
Expand Down Expand Up @@ -122,6 +142,9 @@ export default class RoomHeaderButtons extends HeaderButtons<IProps> {
// This toggles for us, if needed
this.setPhase(RightPanelPhases.PinnedMessages);
};
private onTimelineCardClicked = () => {
this.setPhase(RightPanelPhases.Timeline);
};

private onThreadsPanelClicked = () => {
if (RoomHeaderButtons.THREAD_PHASES.includes(this.state.phase)) {
Expand All @@ -136,12 +159,18 @@ export default class RoomHeaderButtons extends HeaderButtons<IProps> {

public renderButtons() {
return <>
<PinnedMessagesHeaderButton
{ !this.props.coreElementsOnly && <PinnedMessagesHeaderButton
room={this.props.room}
isHighlighted={this.isPhase(RightPanelPhases.PinnedMessages)}
onClick={this.onPinnedMessagesClicked}
/>
{ SettingsStore.getValue("feature_thread") && <HeaderButton
/> }
{ this.props.coreElementsOnly && <TimelineCardHeaderButton
jryans marked this conversation as resolved.
Show resolved Hide resolved
room={this.props.room}
isHighlighted={this.isPhase(RightPanelPhases.Timeline)}
showNewMessage={false}
onClick={this.onTimelineCardClicked}
/> }
{ (!this.props.coreElementsOnly && SettingsStore.getValue("feature_thread")) && <HeaderButton
name="threadsButton"
title={_t("Threads")}
onClick={this.onThreadsPanelClicked}
Expand Down
103 changes: 103 additions & 0 deletions src/components/views/right_panel/TimelineCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
Copyright 2021 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from 'react';
import { MatrixEvent, Room } from 'matrix-js-sdk/src';
import { Thread } from 'matrix-js-sdk/src/models/thread';

import BaseCard from "./BaseCard";

import ResizeNotifier from '../../../utils/ResizeNotifier';
import MessageComposer from '../rooms/MessageComposer';
import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks';
import { Layout } from '../../../settings/enums/Layout';
import TimelinePanel from '../../structures/TimelinePanel';
import { E2EStatus } from '../../../utils/ShieldUtils';
import EditorStateTransfer from '../../../utils/EditorStateTransfer';
import RoomContext from '../../../contexts/RoomContext';

import { _t } from '../../../languageHandler';
import { replaceableComponent } from '../../../utils/replaceableComponent';

interface IProps {
room: Room;
onClose: () => void;
resizeNotifier: ResizeNotifier;
permalinkCreator?: RoomPermalinkCreator;
e2eStatus?: E2EStatus;
initialEvent?: MatrixEvent;
initialEventHighlighted?: boolean;
}
interface IState {
thread?: Thread;
editState?: EditorStateTransfer;
replyToEvent?: MatrixEvent;
}

@replaceableComponent("structures.TimelineCard")
export default class TimelineCard extends React.Component<IProps, IState> {
static contextType = RoomContext;

constructor(props: IProps) {
super(props);
this.state = {};
}

private renderTimelineCardHeader = (): JSX.Element => {
return <div className="mx_TimelineCard__header">
<span>{ _t("Chat") }</span>
</div>;
};

public render(): JSX.Element {
return (
<BaseCard
className="mx_ThreadPanel mx_TimelineCard"
onClose={this.props.onClose}
withoutScrollContainer={true}
header={this.renderTimelineCardHeader()}
>
<TimelinePanel
showReadReceipts={true}
manageReadReceipts={true}
manageReadMarkers={false} // No RM support in the TimelineCard
sendReadReceiptOnLoad={true}
timelineSet={this.props.room.getUnfilteredTimelineSet()}
showUrlPreview={true}
layout={Layout.Group}
hideThreadedMessages={false}
hidden={false}
showReactions={true}
className="mx_RoomView_messagePanel mx_GroupLayout"
permalinkCreator={this.props.permalinkCreator}
membersLoaded={true}
editState={this.state.editState}
eventId={this.props.initialEvent?.getId()}
resizeNotifier={this.props.resizeNotifier}
/>

<MessageComposer
room={this.props.room}
resizeNotifier={this.props.resizeNotifier}
replyToEvent={this.state.replyToEvent}
permalinkCreator={this.props.permalinkCreator}
e2eStatus={this.props.e2eStatus}
compact={true}
/>
</BaseCard>
);
}
}
7 changes: 2 additions & 5 deletions src/components/views/rooms/EventTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -619,11 +619,8 @@ export default class EventTile extends React.Component<IProps, IState> {
<div
className="mx_ThreadInfo"
onClick={() => {
dispatchShowThreadEvent(
this.props.mxEvent,
);
}}
>
dispatchShowThreadEvent(this.props.mxEvent);
}}>
<span className="mx_ThreadInfo_threads-amount">
{ _t("%(count)s reply", {
count: this.thread.length,
Expand Down
Loading