Make thread button always visible (#6903)
Fix https://github.com/vector-im/element-web/issues/18956
This commit is contained in:
parent
34c5a4f8e8
commit
414b20f17e
4 changed files with 64 additions and 32 deletions
|
@ -37,6 +37,7 @@ import TimelinePanel from "./TimelinePanel";
|
||||||
import Spinner from "../views/elements/Spinner";
|
import Spinner from "../views/elements/Spinner";
|
||||||
import { TileShape } from '../views/rooms/EventTile';
|
import { TileShape } from '../views/rooms/EventTile';
|
||||||
import { Layout } from "../../settings/Layout";
|
import { Layout } from "../../settings/Layout";
|
||||||
|
import RoomContext, { TimelineRenderingType } from '../../contexts/RoomContext';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
roomId: string;
|
roomId: string;
|
||||||
|
@ -57,6 +58,7 @@ class FilePanel extends React.Component<IProps, IState> {
|
||||||
// added to the timeline.
|
// added to the timeline.
|
||||||
private decryptingEvents = new Set<string>();
|
private decryptingEvents = new Set<string>();
|
||||||
public noRoom: boolean;
|
public noRoom: boolean;
|
||||||
|
static contextType = RoomContext;
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
timelineSet: null,
|
timelineSet: null,
|
||||||
|
@ -249,38 +251,46 @@ class FilePanel extends React.Component<IProps, IState> {
|
||||||
const isRoomEncrypted = this.noRoom ? false : MatrixClientPeg.get().isRoomEncrypted(this.props.roomId);
|
const isRoomEncrypted = this.noRoom ? false : MatrixClientPeg.get().isRoomEncrypted(this.props.roomId);
|
||||||
|
|
||||||
if (this.state.timelineSet) {
|
if (this.state.timelineSet) {
|
||||||
// console.log("rendering TimelinePanel for timelineSet " + this.state.timelineSet.room.roomId + " " +
|
|
||||||
// "(" + this.state.timelineSet._timelines.join(", ") + ")" + " with key " + this.props.roomId);
|
|
||||||
return (
|
return (
|
||||||
<BaseCard
|
<RoomContext.Provider value={{
|
||||||
className="mx_FilePanel"
|
...this.context,
|
||||||
onClose={this.props.onClose}
|
timelineRenderingType: TimelineRenderingType.File,
|
||||||
previousPhase={RightPanelPhases.RoomSummary}
|
}}>
|
||||||
withoutScrollContainer
|
<BaseCard
|
||||||
>
|
className="mx_FilePanel"
|
||||||
<DesktopBuildsNotice isRoomEncrypted={isRoomEncrypted} kind={WarningKind.Files} />
|
onClose={this.props.onClose}
|
||||||
<TimelinePanel
|
previousPhase={RightPanelPhases.RoomSummary}
|
||||||
manageReadReceipts={false}
|
withoutScrollContainer
|
||||||
manageReadMarkers={false}
|
>
|
||||||
timelineSet={this.state.timelineSet}
|
<DesktopBuildsNotice isRoomEncrypted={isRoomEncrypted} kind={WarningKind.Files} />
|
||||||
showUrlPreview={false}
|
<TimelinePanel
|
||||||
onPaginationRequest={this.onPaginationRequest}
|
manageReadReceipts={false}
|
||||||
tileShape={TileShape.FileGrid}
|
manageReadMarkers={false}
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
timelineSet={this.state.timelineSet}
|
||||||
empty={emptyState}
|
showUrlPreview={false}
|
||||||
layout={Layout.Group}
|
onPaginationRequest={this.onPaginationRequest}
|
||||||
/>
|
tileShape={TileShape.FileGrid}
|
||||||
</BaseCard>
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
|
empty={emptyState}
|
||||||
|
layout={Layout.Group}
|
||||||
|
/>
|
||||||
|
</BaseCard>
|
||||||
|
</RoomContext.Provider>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<BaseCard
|
<RoomContext.Provider value={{
|
||||||
className="mx_FilePanel"
|
...this.context,
|
||||||
onClose={this.props.onClose}
|
timelineRenderingType: TimelineRenderingType.File,
|
||||||
previousPhase={RightPanelPhases.RoomSummary}
|
}}>
|
||||||
>
|
<BaseCard
|
||||||
<Spinner />
|
className="mx_FilePanel"
|
||||||
</BaseCard>
|
onClose={this.props.onClose}
|
||||||
|
previousPhase={RightPanelPhases.RoomSummary}
|
||||||
|
>
|
||||||
|
<Spinner />
|
||||||
|
</BaseCard>
|
||||||
|
</RoomContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import TimelinePanel from "./TimelinePanel";
|
||||||
import Spinner from "../views/elements/Spinner";
|
import Spinner from "../views/elements/Spinner";
|
||||||
import { TileShape } from "../views/rooms/EventTile";
|
import { TileShape } from "../views/rooms/EventTile";
|
||||||
import { Layout } from "../../settings/Layout";
|
import { Layout } from "../../settings/Layout";
|
||||||
|
import RoomContext, { TimelineRenderingType } from "../../contexts/RoomContext";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
onClose(): void;
|
onClose(): void;
|
||||||
|
@ -34,6 +35,7 @@ interface IProps {
|
||||||
*/
|
*/
|
||||||
@replaceableComponent("structures.NotificationPanel")
|
@replaceableComponent("structures.NotificationPanel")
|
||||||
export default class NotificationPanel extends React.PureComponent<IProps> {
|
export default class NotificationPanel extends React.PureComponent<IProps> {
|
||||||
|
static contextType = RoomContext;
|
||||||
render() {
|
render() {
|
||||||
const emptyState = (<div className="mx_RightPanel_empty mx_NotificationPanel_empty">
|
const emptyState = (<div className="mx_RightPanel_empty mx_NotificationPanel_empty">
|
||||||
<h2>{ _t('You’re all caught up') }</h2>
|
<h2>{ _t('You’re all caught up') }</h2>
|
||||||
|
@ -61,8 +63,13 @@ export default class NotificationPanel extends React.PureComponent<IProps> {
|
||||||
content = <Spinner />;
|
content = <Spinner />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <BaseCard className="mx_NotificationPanel" onClose={this.props.onClose} withoutScrollContainer>
|
return <RoomContext.Provider value={{
|
||||||
{ content }
|
...this.context,
|
||||||
</BaseCard>;
|
timelineRenderingType: TimelineRenderingType.Notification,
|
||||||
|
}}>
|
||||||
|
<BaseCard className="mx_NotificationPanel" onClose={this.props.onClose} withoutScrollContainer>
|
||||||
|
{ content }
|
||||||
|
</BaseCard>;
|
||||||
|
</RoomContext.Provider>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,7 +289,7 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
|
||||||
// Like the resend button, the react and reply buttons need to appear before the edit.
|
// Like the resend button, the react and reply buttons need to appear before the edit.
|
||||||
// The only catch is we do the reply button first so that we can make sure the react
|
// The only catch is we do the reply button first so that we can make sure the react
|
||||||
// button is the very first button without having to do length checks for `splice()`.
|
// button is the very first button without having to do length checks for `splice()`.
|
||||||
if (this.context.canReply && this.context.timelineRenderingType === TimelineRenderingType.Room) {
|
if (this.context.canReply && this.context.timelineRenderingType !== TimelineRenderingType.Thread) {
|
||||||
toolbarOpts.splice(0, 0, <>
|
toolbarOpts.splice(0, 0, <>
|
||||||
<RovingAccessibleTooltipButton
|
<RovingAccessibleTooltipButton
|
||||||
className="mx_MessageActionBar_maskButton mx_MessageActionBar_replyButton"
|
className="mx_MessageActionBar_maskButton mx_MessageActionBar_replyButton"
|
||||||
|
@ -325,6 +325,19 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
|
||||||
/>);
|
/>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Show thread icon even for deleted messages, but only within main timeline
|
||||||
|
if (this.context.timelineRenderingType === TimelineRenderingType.Room &&
|
||||||
|
SettingsStore.getValue("feature_thread") &&
|
||||||
|
this.props.mxEvent.getThread() &&
|
||||||
|
!isContentActionable(this.props.mxEvent)
|
||||||
|
) {
|
||||||
|
toolbarOpts.unshift(<RovingAccessibleTooltipButton
|
||||||
|
className="mx_MessageActionBar_maskButton mx_MessageActionBar_threadButton"
|
||||||
|
title={_t("Thread")}
|
||||||
|
onClick={this.onThreadClick}
|
||||||
|
key="thread"
|
||||||
|
/>);
|
||||||
|
}
|
||||||
|
|
||||||
if (allowCancel) {
|
if (allowCancel) {
|
||||||
toolbarOpts.push(cancelSendingButton);
|
toolbarOpts.push(cancelSendingButton);
|
||||||
|
|
|
@ -21,6 +21,8 @@ import { Layout } from "../settings/Layout";
|
||||||
|
|
||||||
export enum TimelineRenderingType {
|
export enum TimelineRenderingType {
|
||||||
Room,
|
Room,
|
||||||
|
File,
|
||||||
|
Notification,
|
||||||
Thread
|
Thread
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue