Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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