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

Fix thread summary layout for narrow right panel timeline #7838

Merged
merged 9 commits into from
Feb 23, 2022
6 changes: 6 additions & 0 deletions res/css/views/right_panel/_TimelineCard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ limitations under the License.
padding-right: 36px;
}

.mx_EventTile:not([data-layout="bubble"]) .mx_ThreadInfo {
margin-left: 36px;
margin-right: 0;
max-width: min(calc(100% - 36px), 600px);
}

.mx_GroupLayout .mx_EventTile > .mx_SenderProfile {
margin-left: 36px;
}
Expand Down
8 changes: 7 additions & 1 deletion res/css/views/rooms/_EventTile.scss
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ $left-gutter: 64px;
.mx_ThreadInfo {
min-width: 267px;
max-width: min(calc(100% - 64px), 600px);
width: auto;
width: fit-content;
height: 40px;
position: relative;
background-color: $system;
Expand Down Expand Up @@ -777,6 +777,12 @@ $left-gutter: 64px;
}
}

.mx_MessagePanel_narrow .mx_ThreadInfo {
min-width: initial;
max-width: initial;
width: initial;
}

.mx_ThreadInfo_content {
text-overflow: ellipsis;
overflow: hidden;
Expand Down
21 changes: 18 additions & 3 deletions src/components/structures/FilePanel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Copyright 2016 OpenMarket Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Copyright 2019 - 2022 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.
Expand All @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import React from 'react';
import React, { createRef } from 'react';
import { Filter } from 'matrix-js-sdk/src/filter';
import { EventTimelineSet, IRoomTimelineData } from "matrix-js-sdk/src/models/event-timeline-set";
import { Direction } from "matrix-js-sdk/src/models/event-timeline";
Expand All @@ -35,6 +35,7 @@ import TimelinePanel from "./TimelinePanel";
import Spinner from "../views/elements/Spinner";
import { Layout } from "../../settings/enums/Layout";
import RoomContext, { TimelineRenderingType } from '../../contexts/RoomContext';
import Measured from '../views/elements/Measured';

interface IProps {
roomId: string;
Expand All @@ -44,21 +45,25 @@ interface IProps {

interface IState {
timelineSet: EventTimelineSet;
narrow: boolean;
}

/*
* Component which shows the filtered file using a TimelinePanel
*/
@replaceableComponent("structures.FilePanel")
class FilePanel extends React.Component<IProps, IState> {
static contextType = RoomContext;

// This is used to track if a decrypted event was a live event and should be
// added to the timeline.
private decryptingEvents = new Set<string>();
public noRoom: boolean;
static contextType = RoomContext;
private card = createRef<HTMLDivElement>();

state = {
timelineSet: null,
narrow: false,
};

private onRoomTimeline = (
Expand Down Expand Up @@ -184,6 +189,10 @@ class FilePanel extends React.Component<IProps, IState> {
}
};

private onMeasurement = (narrow: boolean): void => {
this.setState({ narrow });
};

public async updateTimelineSet(roomId: string): Promise<void> {
const client = MatrixClientPeg.get();
const room = client.getRoom(roomId);
Expand Down Expand Up @@ -256,12 +265,18 @@ class FilePanel extends React.Component<IProps, IState> {
<RoomContext.Provider value={{
...this.context,
timelineRenderingType: TimelineRenderingType.File,
narrow: this.state.narrow,
}}>
<BaseCard
className="mx_FilePanel"
onClose={this.props.onClose}
withoutScrollContainer
ref={this.card}
>
<Measured
sensor={this.card.current}
onMeasurement={this.onMeasurement}
/>
<DesktopBuildsNotice isRoomEncrypted={isRoomEncrypted} kind={WarningKind.Files} />
<TimelinePanel
manageReadReceipts={false}
Expand Down
9 changes: 7 additions & 2 deletions src/components/structures/MessagePanel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2016 - 2021 The Matrix.org Foundation C.I.C.
Copyright 2016 - 2022 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.
Expand All @@ -16,6 +16,7 @@ limitations under the License.

import React, { createRef, KeyboardEvent, ReactNode, SyntheticEvent, TransitionEvent } from 'react';
import ReactDOM from 'react-dom';
import classNames from 'classnames';
import { Room } from 'matrix-js-sdk/src/models/room';
import { EventType } from 'matrix-js-sdk/src/@types/event';
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
Expand Down Expand Up @@ -1012,11 +1013,15 @@ export default class MessagePanel extends React.Component<IProps, IState> {
/>;
}

const classes = classNames(this.props.className, {
"mx_MessagePanel_narrow": this.context.narrow,
});

return (
<ErrorBoundary>
<ScrollPanel
ref={this.scrollPanel}
className={this.props.className}
className={classes}
onScroll={this.props.onScroll}
onUserScroll={this.props.onUserScroll}
onFillRequest={this.props.onFillRequest}
Expand Down
29 changes: 27 additions & 2 deletions src/components/structures/NotificationPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2016, 2019, 2021 The Matrix.org Foundation C.I.C.
Copyright 2016 - 2022 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.
Expand All @@ -25,17 +25,37 @@ import TimelinePanel from "./TimelinePanel";
import Spinner from "../views/elements/Spinner";
import { Layout } from "../../settings/enums/Layout";
import RoomContext, { TimelineRenderingType } from "../../contexts/RoomContext";
import Measured from "../views/elements/Measured";

interface IProps {
onClose(): void;
}

interface IState {
narrow: boolean;
}

/*
* Component which shows the global notification list using a TimelinePanel
*/
@replaceableComponent("structures.NotificationPanel")
export default class NotificationPanel extends React.PureComponent<IProps> {
export default class NotificationPanel extends React.PureComponent<IProps, IState> {
static contextType = RoomContext;

private card = React.createRef<HTMLDivElement>();

constructor(props) {
super(props);

this.state = {
narrow: false,
};
}

private onMeasurement = (narrow: boolean): void => {
this.setState({ narrow });
};

render() {
const emptyState = (<div className="mx_RightPanel_empty mx_NotificationPanel_empty">
<h2>{ _t("You're all caught up") }</h2>
Expand Down Expand Up @@ -65,8 +85,13 @@ export default class NotificationPanel extends React.PureComponent<IProps> {
return <RoomContext.Provider value={{
...this.context,
timelineRenderingType: TimelineRenderingType.Notification,
narrow: this.state.narrow,
}}>
<BaseCard className="mx_NotificationPanel" onClose={this.props.onClose} withoutScrollContainer>
<Measured
sensor={this.card.current}
onMeasurement={this.onMeasurement}
/>
{ content }
</BaseCard>
</RoomContext.Provider>;
Expand Down
16 changes: 14 additions & 2 deletions src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Copyright 2018, 2019 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Copyright 2019 - 2022 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.
Expand Down Expand Up @@ -104,6 +104,7 @@ import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload";
import { JoinRoomPayload } from "../../dispatcher/payloads/JoinRoomPayload";
import { DoAfterSyncPreparedPayload } from '../../dispatcher/payloads/DoAfterSyncPreparedPayload';
import FileDropTarget from './FileDropTarget';
import Measured from '../views/elements/Measured';

const DEBUG = false;
let debuglog = function(msg: string) {};
Expand Down Expand Up @@ -211,6 +212,7 @@ export interface IRoomState {
timelineRenderingType: TimelineRenderingType;
threadId?: string;
liveTimeline?: EventTimeline;
narrow: boolean;
}

@replaceableComponent("structures.RoomView")
Expand All @@ -226,6 +228,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
private roomView = createRef<HTMLElement>();
private searchResultsPanel = createRef<ScrollPanel>();
private messagePanel: TimelinePanel;
private roomViewBody = createRef<HTMLDivElement>();

static contextType = MatrixClientContext;

Expand Down Expand Up @@ -271,6 +274,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
mainSplitContentType: MainSplitContentType.Timeline,
timelineRenderingType: TimelineRenderingType.Room,
liveTimeline: undefined,
narrow: false,
};

this.dispatcherRef = dis.register(this.onAction);
Expand Down Expand Up @@ -1730,6 +1734,10 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
TimelineRenderingType.Room,
);

private onMeasurement = (narrow: boolean): void => {
this.setState({ narrow });
};

render() {
if (!this.state.room) {
const loading = !this.state.matrixClientIsReady || this.state.roomLoading || this.state.peekLoading;
Expand Down Expand Up @@ -2084,6 +2092,10 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {

// Decide what to show in the main split
let mainSplitBody = <React.Fragment>
<Measured
sensor={this.roomViewBody.current}
onMeasurement={this.onMeasurement}
/>
{ auxPanel }
<div className={timelineClasses}>
<FileDropTarget parent={this.roomView.current} onFileDrop={this.onFileDrop} />
Expand Down Expand Up @@ -2148,7 +2160,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
excludedRightPanelPhaseButtons={excludedRightPanelPhaseButtons}
/>
<MainSplit panel={rightPanel} resizeNotifier={this.props.resizeNotifier}>
<div className="mx_RoomView_body" data-layout={this.state.layout}>
<div className="mx_RoomView_body" ref={this.roomViewBody} data-layout={this.state.layout}>
{ mainSplitBody }
</div>
</MainSplit>
Expand Down
23 changes: 16 additions & 7 deletions src/components/structures/ThreadPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2021 The Matrix.org Foundation C.I.C.
Copyright 2021 - 2022 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.
Expand Down Expand Up @@ -37,6 +37,7 @@ import RoomContext, { TimelineRenderingType } from '../../contexts/RoomContext';
import TimelinePanel from './TimelinePanel';
import { Layout } from '../../settings/enums/Layout';
import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
import Measured from '../views/elements/Measured';

async function getThreadTimelineSet(
client: MatrixClient,
Expand Down Expand Up @@ -213,12 +214,14 @@ const EmptyThread: React.FC<EmptyThreadIProps> = ({ filterOption, showAllThreads
const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) => {
const mxClient = useContext(MatrixClientContext);
const roomContext = useContext(RoomContext);
const [filterOption, setFilterOption] = useState<ThreadFilterType>(ThreadFilterType.All);
const ref = useRef<TimelinePanel>();
const timelinePanel = useRef<TimelinePanel>();
const card = useRef<HTMLDivElement>();

const [filterOption, setFilterOption] = useState<ThreadFilterType>(ThreadFilterType.All);
const [room, setRoom] = useState(mxClient.getRoom(roomId));
const [threadCount, setThreadCount] = useState<number>(0);
const [timelineSet, setTimelineSet] = useState<EventTimelineSet | null>(null);
const [narrow, setNarrow] = useState<boolean>(false);

useEffect(() => {
setRoom(mxClient.getRoom(roomId));
Expand Down Expand Up @@ -257,7 +260,7 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
}

function refreshTimeline() {
if (timelineSet) ref.current.refreshTimeline();
if (timelineSet) timelinePanel.current.refreshTimeline();
}

setThreadCount(room.threads.size);
Expand All @@ -278,14 +281,15 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
}, [mxClient, room, filterOption]);

useEffect(() => {
if (timelineSet) ref.current.refreshTimeline();
}, [timelineSet, ref]);
if (timelineSet) timelinePanel.current.refreshTimeline();
}, [timelineSet, timelinePanel]);

return (
<RoomContext.Provider value={{
...roomContext,
timelineRenderingType: TimelineRenderingType.ThreadsList,
showHiddenEventsInTimeline: true,
narrow,
}}>
<BaseCard
header={<ThreadPanelHeader
Expand All @@ -296,10 +300,15 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
className="mx_ThreadPanel"
onClose={onClose}
withoutScrollContainer={true}
ref={card}
>
<Measured
sensor={card.current}
onMeasurement={setNarrow}
/>
{ timelineSet && (
<TimelinePanel
ref={ref}
ref={timelinePanel}
showReadReceipts={false} // No RR support in thread's MVP
manageReadReceipts={false} // No RR support in thread's MVP
manageReadMarkers={false} // No RM support in thread's MVP
Expand Down
Loading