mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-15 20:54:59 +08:00
Consolidate TileShape into TimelineRenderingType (#7843)
This commit is contained in:
parent
ca89d3b96e
commit
5f5bb4a4fe
@ -56,7 +56,7 @@ $left-gutter: 64px;
|
|||||||
font-size: $font-14px;
|
font-size: $font-14px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&[data-shape=thread_list][data-notification]::before {
|
&[data-shape=ThreadsList][data-notification]::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 8px;
|
width: 8px;
|
||||||
@ -67,11 +67,11 @@ $left-gutter: 64px;
|
|||||||
left: auto;
|
left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
&[data-shape=thread_list][data-notification=total]::before {
|
&[data-shape=ThreadsList][data-notification=total]::before {
|
||||||
background-color: $roomtile-default-badge-bg-color;
|
background-color: $roomtile-default-badge-bg-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
&[data-shape=thread_list][data-notification=highlight]::before {
|
&[data-shape=ThreadsList][data-notification=highlight]::before {
|
||||||
background-color: $alert;
|
background-color: $alert;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -797,7 +797,7 @@ $left-gutter: 64px;
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile[data-shape=thread_list] {
|
.mx_EventTile[data-shape=ThreadsList] {
|
||||||
--topOffset: 20px;
|
--topOffset: 20px;
|
||||||
--leftOffset: 46px;
|
--leftOffset: 46px;
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@ import { replaceableComponent } from "../../utils/replaceableComponent";
|
|||||||
import ResizeNotifier from '../../utils/ResizeNotifier';
|
import ResizeNotifier from '../../utils/ResizeNotifier';
|
||||||
import TimelinePanel from "./TimelinePanel";
|
import TimelinePanel from "./TimelinePanel";
|
||||||
import Spinner from "../views/elements/Spinner";
|
import Spinner from "../views/elements/Spinner";
|
||||||
import { TileShape } from '../views/rooms/EventTile';
|
|
||||||
import { Layout } from "../../settings/enums/Layout";
|
import { Layout } from "../../settings/enums/Layout";
|
||||||
import RoomContext, { TimelineRenderingType } from '../../contexts/RoomContext';
|
import RoomContext, { TimelineRenderingType } from '../../contexts/RoomContext';
|
||||||
|
|
||||||
@ -270,7 +269,6 @@ class FilePanel extends React.Component<IProps, IState> {
|
|||||||
timelineSet={this.state.timelineSet}
|
timelineSet={this.state.timelineSet}
|
||||||
showUrlPreview={false}
|
showUrlPreview={false}
|
||||||
onPaginationRequest={this.onPaginationRequest}
|
onPaginationRequest={this.onPaginationRequest}
|
||||||
tileShape={TileShape.FileGrid}
|
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
empty={emptyState}
|
empty={emptyState}
|
||||||
layout={Layout.Group}
|
layout={Layout.Group}
|
||||||
|
@ -29,7 +29,7 @@ import SettingsStore from '../../settings/SettingsStore';
|
|||||||
import RoomContext, { TimelineRenderingType } from "../../contexts/RoomContext";
|
import RoomContext, { TimelineRenderingType } from "../../contexts/RoomContext";
|
||||||
import { Layout } from "../../settings/enums/Layout";
|
import { Layout } from "../../settings/enums/Layout";
|
||||||
import { _t } from "../../languageHandler";
|
import { _t } from "../../languageHandler";
|
||||||
import EventTile, { haveTileForEvent, IReadReceiptProps, TileShape } from "../views/rooms/EventTile";
|
import EventTile, { haveTileForEvent, IReadReceiptProps } from "../views/rooms/EventTile";
|
||||||
import { hasText } from "../../TextForEvent";
|
import { hasText } from "../../TextForEvent";
|
||||||
import IRCTimelineProfileResizer from "../views/elements/IRCTimelineProfileResizer";
|
import IRCTimelineProfileResizer from "../views/elements/IRCTimelineProfileResizer";
|
||||||
import DMRoomMap from "../../utils/DMRoomMap";
|
import DMRoomMap from "../../utils/DMRoomMap";
|
||||||
@ -144,9 +144,6 @@ interface IProps {
|
|||||||
// className for the panel
|
// className for the panel
|
||||||
className: string;
|
className: string;
|
||||||
|
|
||||||
// shape parameter to be passed to EventTiles
|
|
||||||
tileShape?: TileShape;
|
|
||||||
|
|
||||||
// show twelve hour timestamps
|
// show twelve hour timestamps
|
||||||
isTwelveHour?: boolean;
|
isTwelveHour?: boolean;
|
||||||
|
|
||||||
@ -802,7 +799,6 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
|||||||
showUrlPreview={this.props.showUrlPreview}
|
showUrlPreview={this.props.showUrlPreview}
|
||||||
checkUnmounting={this.isUnmounting}
|
checkUnmounting={this.isUnmounting}
|
||||||
eventSendStatus={mxEv.getAssociatedStatus()}
|
eventSendStatus={mxEv.getAssociatedStatus()}
|
||||||
tileShape={this.props.tileShape}
|
|
||||||
isTwelveHour={this.props.isTwelveHour}
|
isTwelveHour={this.props.isTwelveHour}
|
||||||
permalinkCreator={this.props.permalinkCreator}
|
permalinkCreator={this.props.permalinkCreator}
|
||||||
last={last}
|
last={last}
|
||||||
@ -994,7 +990,10 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
|||||||
const style = this.props.hidden ? { display: 'none' } : {};
|
const style = this.props.hidden ? { display: 'none' } : {};
|
||||||
|
|
||||||
let whoIsTyping;
|
let whoIsTyping;
|
||||||
if (this.props.room && !this.props.tileShape && this.state.showTypingNotifications) {
|
if (this.props.room &&
|
||||||
|
this.state.showTypingNotifications &&
|
||||||
|
this.context.timelineRenderingType === TimelineRenderingType.Room
|
||||||
|
) {
|
||||||
whoIsTyping = (<WhoIsTypingTile
|
whoIsTyping = (<WhoIsTypingTile
|
||||||
room={this.props.room}
|
room={this.props.room}
|
||||||
onShown={this.onTypingShown}
|
onShown={this.onTypingShown}
|
||||||
|
@ -23,7 +23,6 @@ import BaseCard from "../views/right_panel/BaseCard";
|
|||||||
import { replaceableComponent } from "../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../utils/replaceableComponent";
|
||||||
import TimelinePanel from "./TimelinePanel";
|
import TimelinePanel from "./TimelinePanel";
|
||||||
import Spinner from "../views/elements/Spinner";
|
import Spinner from "../views/elements/Spinner";
|
||||||
import { TileShape } from "../views/rooms/EventTile";
|
|
||||||
import { Layout } from "../../settings/enums/Layout";
|
import { Layout } from "../../settings/enums/Layout";
|
||||||
import RoomContext, { TimelineRenderingType } from "../../contexts/RoomContext";
|
import RoomContext, { TimelineRenderingType } from "../../contexts/RoomContext";
|
||||||
|
|
||||||
@ -53,7 +52,6 @@ export default class NotificationPanel extends React.PureComponent<IProps> {
|
|||||||
manageReadMarkers={false}
|
manageReadMarkers={false}
|
||||||
timelineSet={timelineSet}
|
timelineSet={timelineSet}
|
||||||
showUrlPreview={false}
|
showUrlPreview={false}
|
||||||
tileShape={TileShape.Notif}
|
|
||||||
empty={emptyState}
|
empty={emptyState}
|
||||||
alwaysShowTimestamps={true}
|
alwaysShowTimestamps={true}
|
||||||
layout={Layout.Group}
|
layout={Layout.Group}
|
||||||
|
@ -36,7 +36,6 @@ import ContextMenu, { ChevronFace, MenuItemRadio, useContextMenu } from './Conte
|
|||||||
import RoomContext, { TimelineRenderingType } from '../../contexts/RoomContext';
|
import RoomContext, { TimelineRenderingType } from '../../contexts/RoomContext';
|
||||||
import TimelinePanel from './TimelinePanel';
|
import TimelinePanel from './TimelinePanel';
|
||||||
import { Layout } from '../../settings/enums/Layout';
|
import { Layout } from '../../settings/enums/Layout';
|
||||||
import { TileShape } from '../views/rooms/EventTile';
|
|
||||||
import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
|
import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
|
||||||
import { useEventEmitter } from '../../hooks/useEventEmitter';
|
import { useEventEmitter } from '../../hooks/useEventEmitter';
|
||||||
|
|
||||||
@ -302,7 +301,6 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
|
|||||||
className="mx_RoomView_messagePanel mx_GroupLayout"
|
className="mx_RoomView_messagePanel mx_GroupLayout"
|
||||||
membersLoaded={true}
|
membersLoaded={true}
|
||||||
permalinkCreator={permalinkCreator}
|
permalinkCreator={permalinkCreator}
|
||||||
tileShape={TileShape.ThreadPanel}
|
|
||||||
disableGrouping={true}
|
disableGrouping={true}
|
||||||
/>
|
/>
|
||||||
) }
|
) }
|
||||||
|
@ -28,7 +28,6 @@ import BaseCard from "../views/right_panel/BaseCard";
|
|||||||
import { RightPanelPhases } from "../../stores/right-panel/RightPanelStorePhases";
|
import { RightPanelPhases } from "../../stores/right-panel/RightPanelStorePhases";
|
||||||
import { replaceableComponent } from "../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../utils/replaceableComponent";
|
||||||
import ResizeNotifier from '../../utils/ResizeNotifier';
|
import ResizeNotifier from '../../utils/ResizeNotifier';
|
||||||
import { TileShape } from '../views/rooms/EventTile';
|
|
||||||
import MessageComposer from '../views/rooms/MessageComposer';
|
import MessageComposer from '../views/rooms/MessageComposer';
|
||||||
import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
|
import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
|
||||||
import { Layout } from '../../settings/enums/Layout';
|
import { Layout } from '../../settings/enums/Layout';
|
||||||
@ -284,7 +283,6 @@ export default class ThreadView extends React.Component<IProps, IState> {
|
|||||||
sendReadReceiptOnLoad={true}
|
sendReadReceiptOnLoad={true}
|
||||||
timelineSet={this.state?.thread?.timelineSet}
|
timelineSet={this.state?.thread?.timelineSet}
|
||||||
showUrlPreview={true}
|
showUrlPreview={true}
|
||||||
tileShape={TileShape.Thread}
|
|
||||||
// ThreadView doesn't support IRC layout at this time
|
// ThreadView doesn't support IRC layout at this time
|
||||||
layout={this.state.layout === Layout.Bubble ? Layout.Bubble : Layout.Group}
|
layout={this.state.layout === Layout.Bubble ? Layout.Bubble : Layout.Group}
|
||||||
hideThreadedMessages={false}
|
hideThreadedMessages={false}
|
||||||
|
@ -39,7 +39,7 @@ import { Action } from '../../dispatcher/actions';
|
|||||||
import { Key } from '../../Keyboard';
|
import { Key } from '../../Keyboard';
|
||||||
import Timer from '../../utils/Timer';
|
import Timer from '../../utils/Timer';
|
||||||
import shouldHideEvent from '../../shouldHideEvent';
|
import shouldHideEvent from '../../shouldHideEvent';
|
||||||
import { haveTileForEvent, TileShape } from "../views/rooms/EventTile";
|
import { haveTileForEvent } from "../views/rooms/EventTile";
|
||||||
import { UIFeature } from "../../settings/UIFeature";
|
import { UIFeature } from "../../settings/UIFeature";
|
||||||
import { replaceableComponent } from "../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../utils/replaceableComponent";
|
||||||
import { arrayFastClone } from "../../utils/arrays";
|
import { arrayFastClone } from "../../utils/arrays";
|
||||||
@ -103,9 +103,6 @@ interface IProps {
|
|||||||
// classname to use for the messagepanel
|
// classname to use for the messagepanel
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|
||||||
// shape property to be passed to EventTiles
|
|
||||||
tileShape?: TileShape;
|
|
||||||
|
|
||||||
// placeholder to use if the timeline is empty
|
// placeholder to use if the timeline is empty
|
||||||
empty?: ReactNode;
|
empty?: ReactNode;
|
||||||
|
|
||||||
@ -1644,7 +1641,6 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
|||||||
this.state.alwaysShowTimestamps
|
this.state.alwaysShowTimestamps
|
||||||
}
|
}
|
||||||
className={this.props.className}
|
className={this.props.className}
|
||||||
tileShape={this.props.tileShape}
|
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
getRelationsForEvent={this.getRelationsForEvent}
|
getRelationsForEvent={this.getRelationsForEvent}
|
||||||
editState={this.props.editState}
|
editState={this.props.editState}
|
||||||
|
@ -18,7 +18,6 @@ import React, { ReactNode } from "react";
|
|||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
|
||||||
import { Playback, PlaybackState } from "../../../audio/Playback";
|
import { Playback, PlaybackState } from "../../../audio/Playback";
|
||||||
import { TileShape } from "../rooms/EventTile";
|
|
||||||
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
|
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
@ -29,7 +28,6 @@ interface IProps {
|
|||||||
playback: Playback;
|
playback: Playback;
|
||||||
|
|
||||||
mediaName?: string;
|
mediaName?: string;
|
||||||
tileShape?: TileShape;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
|
@ -19,16 +19,19 @@ import React, { ReactNode } from "react";
|
|||||||
import PlayPauseButton from "./PlayPauseButton";
|
import PlayPauseButton from "./PlayPauseButton";
|
||||||
import PlaybackClock from "./PlaybackClock";
|
import PlaybackClock from "./PlaybackClock";
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
import { TileShape } from "../rooms/EventTile";
|
|
||||||
import PlaybackWaveform from "./PlaybackWaveform";
|
import PlaybackWaveform from "./PlaybackWaveform";
|
||||||
import AudioPlayerBase from "./AudioPlayerBase";
|
import AudioPlayerBase from "./AudioPlayerBase";
|
||||||
|
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
|
||||||
|
|
||||||
@replaceableComponent("views.audio_messages.RecordingPlayback")
|
@replaceableComponent("views.audio_messages.RecordingPlayback")
|
||||||
export default class RecordingPlayback extends AudioPlayerBase {
|
export default class RecordingPlayback extends AudioPlayerBase {
|
||||||
|
static contextType = RoomContext;
|
||||||
|
public context!: React.ContextType<typeof RoomContext>;
|
||||||
|
|
||||||
private get isWaveformable(): boolean {
|
private get isWaveformable(): boolean {
|
||||||
return this.props.tileShape !== TileShape.Notif
|
return this.context.timelineRenderingType !== TimelineRenderingType.Notification
|
||||||
&& this.props.tileShape !== TileShape.FileGrid
|
&& this.context.timelineRenderingType !== TimelineRenderingType.File
|
||||||
&& this.props.tileShape !== TileShape.Pinned;
|
&& this.context.timelineRenderingType !== TimelineRenderingType.Pinned;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected renderComponent(): ReactNode {
|
protected renderComponent(): ReactNode {
|
||||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import { Relations } from "matrix-js-sdk/src/models/relations";
|
import { Relations } from "matrix-js-sdk/src/models/relations";
|
||||||
|
|
||||||
import { TileShape } from "../rooms/EventTile";
|
|
||||||
import { MediaEventHelper } from "../../../utils/MediaEventHelper";
|
import { MediaEventHelper } from "../../../utils/MediaEventHelper";
|
||||||
import EditorStateTransfer from "../../../utils/EditorStateTransfer";
|
import EditorStateTransfer from "../../../utils/EditorStateTransfer";
|
||||||
import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
|
import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
|
||||||
@ -36,7 +35,6 @@ export interface IBodyProps {
|
|||||||
|
|
||||||
showUrlPreview?: boolean;
|
showUrlPreview?: boolean;
|
||||||
forExport?: boolean;
|
forExport?: boolean;
|
||||||
tileShape: TileShape;
|
|
||||||
maxImageHeight?: number;
|
maxImageHeight?: number;
|
||||||
replacingEventId?: string;
|
replacingEventId?: string;
|
||||||
editState?: EditorStateTransfer;
|
editState?: EditorStateTransfer;
|
||||||
|
@ -28,6 +28,7 @@ import { IBodyProps } from "./IBodyProps";
|
|||||||
import { PlaybackManager } from "../../../audio/PlaybackManager";
|
import { PlaybackManager } from "../../../audio/PlaybackManager";
|
||||||
import { isVoiceMessage } from "../../../utils/EventUtils";
|
import { isVoiceMessage } from "../../../utils/EventUtils";
|
||||||
import { PlaybackQueue } from "../../../audio/PlaybackQueue";
|
import { PlaybackQueue } from "../../../audio/PlaybackQueue";
|
||||||
|
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
error?: Error;
|
error?: Error;
|
||||||
@ -36,6 +37,9 @@ interface IState {
|
|||||||
|
|
||||||
@replaceableComponent("views.messages.MAudioBody")
|
@replaceableComponent("views.messages.MAudioBody")
|
||||||
export default class MAudioBody extends React.PureComponent<IBodyProps, IState> {
|
export default class MAudioBody extends React.PureComponent<IBodyProps, IState> {
|
||||||
|
static contextType = RoomContext;
|
||||||
|
public context!: React.ContextType<typeof RoomContext>;
|
||||||
|
|
||||||
constructor(props: IBodyProps) {
|
constructor(props: IBodyProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
@ -82,6 +86,12 @@ export default class MAudioBody extends React.PureComponent<IBodyProps, IState>
|
|||||||
this.state.playback?.destroy();
|
this.state.playback?.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected get showFileBody(): boolean {
|
||||||
|
return this.context.timelineRenderingType !== TimelineRenderingType.Room &&
|
||||||
|
this.context.timelineRenderingType !== TimelineRenderingType.Pinned &&
|
||||||
|
this.context.timelineRenderingType !== TimelineRenderingType.Search;
|
||||||
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
if (this.state.error) {
|
if (this.state.error) {
|
||||||
return (
|
return (
|
||||||
@ -115,7 +125,7 @@ export default class MAudioBody extends React.PureComponent<IBodyProps, IState>
|
|||||||
return (
|
return (
|
||||||
<span className="mx_MAudioBody">
|
<span className="mx_MAudioBody">
|
||||||
<AudioPlayer playback={this.state.playback} mediaName={this.props.mxEvent.getContent().body} />
|
<AudioPlayer playback={this.state.playback} mediaName={this.props.mxEvent.getContent().body} />
|
||||||
{ this.props.tileShape && <MFileBody {...this.props} showGenericPlaceholder={false} /> }
|
{ this.showFileBody && <MFileBody {...this.props} showGenericPlaceholder={false} /> }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,12 @@ import AccessibleButton from "../elements/AccessibleButton";
|
|||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
import { mediaFromContent } from "../../../customisations/Media";
|
import { mediaFromContent } from "../../../customisations/Media";
|
||||||
import ErrorDialog from "../dialogs/ErrorDialog";
|
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||||
import { TileShape } from "../rooms/EventTile";
|
|
||||||
import { presentableTextForFile } from "../../../utils/FileUtils";
|
import { presentableTextForFile } from "../../../utils/FileUtils";
|
||||||
import { IMediaEventContent } from "../../../customisations/models/IMediaEventContent";
|
import { IMediaEventContent } from "../../../customisations/models/IMediaEventContent";
|
||||||
import { IBodyProps } from "./IBodyProps";
|
import { IBodyProps } from "./IBodyProps";
|
||||||
import { FileDownloader } from "../../../utils/FileDownloader";
|
import { FileDownloader } from "../../../utils/FileDownloader";
|
||||||
import TextWithTooltip from "../elements/TextWithTooltip";
|
import TextWithTooltip from "../elements/TextWithTooltip";
|
||||||
|
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
|
||||||
|
|
||||||
export let DOWNLOAD_ICON_URL; // cached copy of the download.svg asset for the sandboxed iframe later on
|
export let DOWNLOAD_ICON_URL; // cached copy of the download.svg asset for the sandboxed iframe later on
|
||||||
|
|
||||||
@ -108,6 +108,9 @@ interface IState {
|
|||||||
|
|
||||||
@replaceableComponent("views.messages.MFileBody")
|
@replaceableComponent("views.messages.MFileBody")
|
||||||
export default class MFileBody extends React.Component<IProps, IState> {
|
export default class MFileBody extends React.Component<IProps, IState> {
|
||||||
|
static contextType = RoomContext;
|
||||||
|
public context!: React.ContextType<typeof RoomContext>;
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
showGenericPlaceholder: true,
|
showGenericPlaceholder: true,
|
||||||
};
|
};
|
||||||
@ -223,8 +226,15 @@ export default class MFileBody extends React.Component<IProps, IState> {
|
|||||||
</span>;
|
</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const showDownloadLink = (this.props.tileShape || !this.props.showGenericPlaceholder) &&
|
let showDownloadLink = !this.props.showGenericPlaceholder || (
|
||||||
this.props.tileShape !== TileShape.Thread;
|
this.context.timelineRenderingType !== TimelineRenderingType.Room &&
|
||||||
|
this.context.timelineRenderingType !== TimelineRenderingType.Search &&
|
||||||
|
this.context.timelineRenderingType !== TimelineRenderingType.Pinned
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this.context.timelineRenderingType === TimelineRenderingType.Thread) {
|
||||||
|
showDownloadLink = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isEncrypted) {
|
if (isEncrypted) {
|
||||||
if (!this.state.decryptedBlob) {
|
if (!this.state.decryptedBlob) {
|
||||||
@ -334,9 +344,11 @@ export default class MFileBody extends React.Component<IProps, IState> {
|
|||||||
<span className="mx_MFileBody_download_icon" />
|
<span className="mx_MFileBody_download_icon" />
|
||||||
{ _t("Download %(text)s", { text: this.linkText }) }
|
{ _t("Download %(text)s", { text: this.linkText }) }
|
||||||
</a>
|
</a>
|
||||||
{ this.props.tileShape === TileShape.FileGrid && <div className="mx_MImageBody_size">
|
{ this.context.timelineRenderingType === TimelineRenderingType.File && (
|
||||||
{ this.content.info && this.content.info.size ? filesize(this.content.info.size) : "" }
|
<div className="mx_MImageBody_size">
|
||||||
</div> }
|
{ this.content.info && this.content.info.size ? filesize(this.content.info.size) : "" }
|
||||||
|
</div>
|
||||||
|
) }
|
||||||
</div> }
|
</div> }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
@ -26,7 +26,6 @@ import MFileBody from './MFileBody';
|
|||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
|
||||||
import InlineSpinner from '../elements/InlineSpinner';
|
import InlineSpinner from '../elements/InlineSpinner';
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
import { Media, mediaFromContent } from "../../../customisations/Media";
|
import { Media, mediaFromContent } from "../../../customisations/Media";
|
||||||
@ -34,8 +33,9 @@ import { BLURHASH_FIELD } from "../../../ContentMessages";
|
|||||||
import { IMediaEventContent } from '../../../customisations/models/IMediaEventContent';
|
import { IMediaEventContent } from '../../../customisations/models/IMediaEventContent';
|
||||||
import ImageView from '../elements/ImageView';
|
import ImageView from '../elements/ImageView';
|
||||||
import { IBodyProps } from "./IBodyProps";
|
import { IBodyProps } from "./IBodyProps";
|
||||||
import { TileShape } from '../rooms/EventTile';
|
|
||||||
import { ImageSize, suggestedSize as suggestedImageSize } from "../../../settings/enums/ImageSize";
|
import { ImageSize, suggestedSize as suggestedImageSize } from "../../../settings/enums/ImageSize";
|
||||||
|
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||||
|
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
decryptedUrl?: string;
|
decryptedUrl?: string;
|
||||||
@ -55,7 +55,9 @@ interface IState {
|
|||||||
|
|
||||||
@replaceableComponent("views.messages.MImageBody")
|
@replaceableComponent("views.messages.MImageBody")
|
||||||
export default class MImageBody extends React.Component<IBodyProps, IState> {
|
export default class MImageBody extends React.Component<IBodyProps, IState> {
|
||||||
static contextType = MatrixClientContext;
|
static contextType = RoomContext;
|
||||||
|
public context!: React.ContextType<typeof RoomContext>;
|
||||||
|
|
||||||
private unmounted = true;
|
private unmounted = true;
|
||||||
private image = createRef<HTMLImageElement>();
|
private image = createRef<HTMLImageElement>();
|
||||||
private timeout?: number;
|
private timeout?: number;
|
||||||
@ -297,7 +299,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.unmounted = false;
|
this.unmounted = false;
|
||||||
this.context.on('sync', this.onClientSync);
|
MatrixClientPeg.get().on('sync', this.onClientSync);
|
||||||
|
|
||||||
const showImage = this.state.showImage ||
|
const showImage = this.state.showImage ||
|
||||||
localStorage.getItem("mx_ShowImage_" + this.props.mxEvent.getId()) === "true";
|
localStorage.getItem("mx_ShowImage_" + this.props.mxEvent.getId()) === "true";
|
||||||
@ -327,7 +329,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
|
|||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.unmounted = true;
|
this.unmounted = true;
|
||||||
this.context.removeListener('sync', this.onClientSync);
|
MatrixClientPeg.get().removeListener('sync', this.onClientSync);
|
||||||
this.clearBlurhashTimeout();
|
this.clearBlurhashTimeout();
|
||||||
SettingsStore.unwatchSetting(this.sizeWatcher);
|
SettingsStore.unwatchSetting(this.sizeWatcher);
|
||||||
}
|
}
|
||||||
@ -524,9 +526,11 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
|
|||||||
* In the room timeline or the thread context we don't need the download
|
* In the room timeline or the thread context we don't need the download
|
||||||
* link as the message action bar will fullfil that
|
* link as the message action bar will fullfil that
|
||||||
*/
|
*/
|
||||||
const hasMessageActionBar = !this.props.tileShape
|
const hasMessageActionBar = this.context.timelineRenderingType === TimelineRenderingType.Room
|
||||||
|| this.props.tileShape === TileShape.Thread
|
|| this.context.timelineRenderingType === TimelineRenderingType.Pinned
|
||||||
|| this.props.tileShape === TileShape.ThreadPanel;
|
|| this.context.timelineRenderingType === TimelineRenderingType.Search
|
||||||
|
|| this.context.timelineRenderingType === TimelineRenderingType.Thread
|
||||||
|
|| this.context.timelineRenderingType === TimelineRenderingType.ThreadsList;
|
||||||
if (!hasMessageActionBar) {
|
if (!hasMessageActionBar) {
|
||||||
return <MFileBody {...this.props} showGenericPlaceholder={false} />;
|
return <MFileBody {...this.props} showGenericPlaceholder={false} />;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import { IMediaEventContent } from "../../../customisations/models/IMediaEventCo
|
|||||||
import { IBodyProps } from "./IBodyProps";
|
import { IBodyProps } from "./IBodyProps";
|
||||||
import MFileBody from "./MFileBody";
|
import MFileBody from "./MFileBody";
|
||||||
import { ImageSize, suggestedSize as suggestedVideoSize } from "../../../settings/enums/ImageSize";
|
import { ImageSize, suggestedSize as suggestedVideoSize } from "../../../settings/enums/ImageSize";
|
||||||
|
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
decryptedUrl?: string;
|
decryptedUrl?: string;
|
||||||
@ -41,6 +42,9 @@ interface IState {
|
|||||||
|
|
||||||
@replaceableComponent("views.messages.MVideoBody")
|
@replaceableComponent("views.messages.MVideoBody")
|
||||||
export default class MVideoBody extends React.PureComponent<IBodyProps, IState> {
|
export default class MVideoBody extends React.PureComponent<IBodyProps, IState> {
|
||||||
|
static contextType = RoomContext;
|
||||||
|
public context!: React.ContextType<typeof RoomContext>;
|
||||||
|
|
||||||
private videoRef = React.createRef<HTMLVideoElement>();
|
private videoRef = React.createRef<HTMLVideoElement>();
|
||||||
private sizeWatcher: string;
|
private sizeWatcher: string;
|
||||||
|
|
||||||
@ -235,9 +239,15 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
|
|||||||
this.props.onHeightChanged();
|
this.props.onHeightChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected get showFileBody(): boolean {
|
||||||
|
return this.context.timelineRenderingType !== TimelineRenderingType.Room &&
|
||||||
|
this.context.timelineRenderingType !== TimelineRenderingType.Pinned &&
|
||||||
|
this.context.timelineRenderingType !== TimelineRenderingType.Search;
|
||||||
|
}
|
||||||
|
|
||||||
private getFileBody = () => {
|
private getFileBody = () => {
|
||||||
if (this.props.forExport) return null;
|
if (this.props.forExport) return null;
|
||||||
return this.props.tileShape && <MFileBody {...this.props} showGenericPlaceholder={false} />;
|
return this.showFileBody && <MFileBody {...this.props} showGenericPlaceholder={false} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -47,8 +47,8 @@ export default class MVoiceMessageBody extends MAudioBody {
|
|||||||
// At this point we should have a playable state
|
// At this point we should have a playable state
|
||||||
return (
|
return (
|
||||||
<span className="mx_MVoiceMessageBody">
|
<span className="mx_MVoiceMessageBody">
|
||||||
<RecordingPlayback playback={this.state.playback} tileShape={this.props.tileShape} />
|
<RecordingPlayback playback={this.state.playback} />
|
||||||
{ this.props.tileShape && <MFileBody {...this.props} showGenericPlaceholder={false} /> }
|
{ this.showFileBody && <MFileBody {...this.props} showGenericPlaceholder={false} /> }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,6 @@ export default class MessageEvent extends React.Component<IProps> implements IMe
|
|||||||
highlights={this.props.highlights}
|
highlights={this.props.highlights}
|
||||||
highlightLink={this.props.highlightLink}
|
highlightLink={this.props.highlightLink}
|
||||||
showUrlPreview={this.props.showUrlPreview}
|
showUrlPreview={this.props.showUrlPreview}
|
||||||
tileShape={this.props.tileShape}
|
|
||||||
forExport={this.props.forExport}
|
forExport={this.props.forExport}
|
||||||
maxImageHeight={this.props.maxImageHeight}
|
maxImageHeight={this.props.maxImageHeight}
|
||||||
replacingEventId={this.props.replacingEventId}
|
replacingEventId={this.props.replacingEventId}
|
||||||
|
@ -24,7 +24,7 @@ import { getUserNameColorClass } from '../../../utils/FormattingUtils';
|
|||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
import UserIdentifier from '../../../customisations/UserIdentifier';
|
import UserIdentifier from '../../../customisations/UserIdentifier';
|
||||||
import { TileShape } from '../rooms/EventTile';
|
import RoomContext, { TimelineRenderingType } from '../../../contexts/RoomContext';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
|
|
||||||
@ -32,7 +32,6 @@ interface IProps {
|
|||||||
mxEvent: MatrixEvent;
|
mxEvent: MatrixEvent;
|
||||||
onClick?(): void;
|
onClick?(): void;
|
||||||
enableFlair: boolean;
|
enableFlair: boolean;
|
||||||
tileShape?: TileShape;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
@ -121,41 +120,44 @@ export default class SenderProfile extends React.Component<IProps, IState> {
|
|||||||
const displayName = member?.rawDisplayName || mxEvent.getSender() || "";
|
const displayName = member?.rawDisplayName || mxEvent.getSender() || "";
|
||||||
const mxid = member?.userId || mxEvent.getSender() || "";
|
const mxid = member?.userId || mxEvent.getSender() || "";
|
||||||
|
|
||||||
if (msgtype === MsgType.Emote && this.props.tileShape !== TileShape.ThreadPanel) {
|
return <RoomContext.Consumer>
|
||||||
return null; // emote message must include the name so don't duplicate it
|
{ roomContext => {
|
||||||
}
|
if (msgtype === MsgType.Emote &&
|
||||||
|
roomContext.timelineRenderingType !== TimelineRenderingType.ThreadsList
|
||||||
|
) {
|
||||||
|
return null; // emote message must include the name so don't duplicate it
|
||||||
|
}
|
||||||
|
|
||||||
let mxidElement;
|
let mxidElement;
|
||||||
if (disambiguate) {
|
if (disambiguate) {
|
||||||
mxidElement = (
|
mxidElement = (
|
||||||
<span className="mx_SenderProfile_mxid">
|
<span className="mx_SenderProfile_mxid">
|
||||||
{ UserIdentifier.getDisplayUserIdentifier(
|
{ UserIdentifier.getDisplayUserIdentifier(
|
||||||
mxid, { withDisplayName: true, roomId: mxEvent.getRoomId() },
|
mxid, { withDisplayName: true, roomId: mxEvent.getRoomId() },
|
||||||
) }
|
) }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let flair;
|
let flair;
|
||||||
if (this.props.enableFlair) {
|
if (this.props.enableFlair) {
|
||||||
const displayedGroups = this.getDisplayedGroups(
|
const displayedGroups = this.getDisplayedGroups(
|
||||||
this.state.userGroups, this.state.relatedGroups,
|
this.state.userGroups, this.state.relatedGroups,
|
||||||
);
|
);
|
||||||
|
|
||||||
flair = <Flair key='flair'
|
flair = <Flair key='flair' userId={mxEvent.getSender()} groups={displayedGroups} />;
|
||||||
userId={mxEvent.getSender()}
|
}
|
||||||
groups={displayedGroups}
|
|
||||||
/>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SenderProfile" dir="auto" onClick={this.props.onClick}>
|
<div className="mx_SenderProfile" dir="auto" onClick={this.props.onClick}>
|
||||||
<span className={`mx_SenderProfile_displayName ${colorClass}`}>
|
<span className={`mx_SenderProfile_displayName ${colorClass}`}>
|
||||||
{ displayName }
|
{ displayName }
|
||||||
</span>
|
</span>
|
||||||
{ mxidElement }
|
{ mxidElement }
|
||||||
{ flair }
|
{ flair }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
} }
|
||||||
|
</RoomContext.Consumer>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import PinningUtils from "../../../utils/PinningUtils";
|
|||||||
import { useAsyncMemo } from "../../../hooks/useAsyncMemo";
|
import { useAsyncMemo } from "../../../hooks/useAsyncMemo";
|
||||||
import PinnedEventTile from "../rooms/PinnedEventTile";
|
import PinnedEventTile from "../rooms/PinnedEventTile";
|
||||||
import { useRoomState } from "../../../hooks/useRoomState";
|
import { useRoomState } from "../../../hooks/useRoomState";
|
||||||
|
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
room: Room;
|
room: Room;
|
||||||
@ -78,6 +79,7 @@ export const useReadPinnedEvents = (room: Room): Set<string> => {
|
|||||||
|
|
||||||
const PinnedMessagesCard = ({ room, onClose }: IProps) => {
|
const PinnedMessagesCard = ({ room, onClose }: IProps) => {
|
||||||
const cli = useContext(MatrixClientContext);
|
const cli = useContext(MatrixClientContext);
|
||||||
|
const roomContext = useContext(RoomContext);
|
||||||
const canUnpin = useRoomState(room, state => state.mayClientSendStateEvent(EventType.RoomPinnedEvents, cli));
|
const canUnpin = useRoomState(room, state => state.mayClientSendStateEvent(EventType.RoomPinnedEvents, cli));
|
||||||
const pinnedEventIds = usePinnedEvents(room);
|
const pinnedEventIds = usePinnedEvents(room);
|
||||||
const readPinnedEvents = useReadPinnedEvents(room);
|
const readPinnedEvents = useReadPinnedEvents(room);
|
||||||
@ -166,7 +168,12 @@ const PinnedMessagesCard = ({ room, onClose }: IProps) => {
|
|||||||
className="mx_PinnedMessagesCard"
|
className="mx_PinnedMessagesCard"
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
>
|
>
|
||||||
{ content }
|
<RoomContext.Provider value={{
|
||||||
|
...roomContext,
|
||||||
|
timelineRenderingType: TimelineRenderingType.Pinned,
|
||||||
|
}}>
|
||||||
|
{ content }
|
||||||
|
</RoomContext.Provider>
|
||||||
</BaseCard>;
|
</BaseCard>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ import SettingsStore from "../../../settings/SettingsStore";
|
|||||||
import MKeyVerificationConclusion from "../messages/MKeyVerificationConclusion";
|
import MKeyVerificationConclusion from "../messages/MKeyVerificationConclusion";
|
||||||
import { showThread } from '../../../dispatcher/dispatch-actions/threads';
|
import { showThread } from '../../../dispatcher/dispatch-actions/threads';
|
||||||
import { MessagePreviewStore } from '../../../stores/room-list/MessagePreviewStore';
|
import { MessagePreviewStore } from '../../../stores/room-list/MessagePreviewStore';
|
||||||
import { TimelineRenderingType } from "../../../contexts/RoomContext";
|
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
|
||||||
import { MediaEventHelper } from "../../../utils/MediaEventHelper";
|
import { MediaEventHelper } from "../../../utils/MediaEventHelper";
|
||||||
import Toolbar from '../../../accessibility/Toolbar';
|
import Toolbar from '../../../accessibility/Toolbar';
|
||||||
import { RovingAccessibleTooltipButton } from '../../../accessibility/roving/RovingAccessibleTooltipButton';
|
import { RovingAccessibleTooltipButton } from '../../../accessibility/roving/RovingAccessibleTooltipButton';
|
||||||
@ -213,14 +213,6 @@ export interface IReadReceiptProps {
|
|||||||
ts: number;
|
ts: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TileShape {
|
|
||||||
Notif = "notif",
|
|
||||||
FileGrid = "file_grid",
|
|
||||||
Pinned = "pinned",
|
|
||||||
Thread = "thread",
|
|
||||||
ThreadPanel = "thread_list"
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
// the MatrixEvent to show
|
// the MatrixEvent to show
|
||||||
mxEvent: MatrixEvent;
|
mxEvent: MatrixEvent;
|
||||||
@ -281,14 +273,6 @@ interface IProps {
|
|||||||
// that we can tell when it changes.
|
// that we can tell when it changes.
|
||||||
eventSendStatus?: string;
|
eventSendStatus?: string;
|
||||||
|
|
||||||
// the shape of the tile. by default, the layout is intended for the
|
|
||||||
// normal room timeline. alternative values are: "file_list", "file_grid"
|
|
||||||
// and "notif". This could be done by CSS, but it'd be horribly inefficient.
|
|
||||||
// It could also be done by subclassing EventTile, but that'd be quite
|
|
||||||
// boiilerplatey. So just make the necessary render decisions conditional
|
|
||||||
// for now.
|
|
||||||
tileShape?: TileShape;
|
|
||||||
|
|
||||||
forExport?: boolean;
|
forExport?: boolean;
|
||||||
|
|
||||||
// show twelve hour timestamps
|
// show twelve hour timestamps
|
||||||
@ -367,6 +351,7 @@ interface IState {
|
|||||||
threadNotification?: NotificationCountType;
|
threadNotification?: NotificationCountType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MUST be rendered within a RoomContext with a set timelineRenderingType
|
||||||
@replaceableComponent("views.rooms.EventTile")
|
@replaceableComponent("views.rooms.EventTile")
|
||||||
export default class EventTile extends React.Component<IProps, IState> {
|
export default class EventTile extends React.Component<IProps, IState> {
|
||||||
private suppressReadReceiptAnimation: boolean;
|
private suppressReadReceiptAnimation: boolean;
|
||||||
@ -385,13 +370,12 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
layout: Layout.Group,
|
layout: Layout.Group,
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextType = MatrixClientContext;
|
static contextType = RoomContext;
|
||||||
public context!: React.ContextType<typeof MatrixClientContext>;
|
public context!: React.ContextType<typeof RoomContext>;
|
||||||
|
|
||||||
constructor(props: IProps, context: React.ContextType<typeof MatrixClientContext>) {
|
constructor(props: IProps, context: React.ContextType<typeof MatrixClientContext>) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
|
||||||
this.context = context;
|
|
||||||
const thread = this.thread;
|
const thread = this.thread;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
@ -437,12 +421,12 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
if (!this.props.mxEvent) return false;
|
if (!this.props.mxEvent) return false;
|
||||||
|
|
||||||
// Sanity check (should never happen, but we shouldn't explode if it does)
|
// Sanity check (should never happen, but we shouldn't explode if it does)
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
if (!room) return false;
|
if (!room) return false;
|
||||||
|
|
||||||
// Quickly check to see if the event was sent by us. If it wasn't, it won't qualify for
|
// Quickly check to see if the event was sent by us. If it wasn't, it won't qualify for
|
||||||
// special read receipts.
|
// special read receipts.
|
||||||
const myUserId = this.context.getUserId();
|
const myUserId = MatrixClientPeg.get().getUserId();
|
||||||
if (this.props.mxEvent.getSender() !== myUserId) return false;
|
if (this.props.mxEvent.getSender() !== myUserId) return false;
|
||||||
|
|
||||||
// Finally, determine if the type is relevant to the user. This notably excludes state
|
// Finally, determine if the type is relevant to the user. This notably excludes state
|
||||||
@ -473,7 +457,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
// If anyone has read the event besides us, we don't want to show a sent receipt.
|
// If anyone has read the event besides us, we don't want to show a sent receipt.
|
||||||
const receipts = this.props.readReceipts || [];
|
const receipts = this.props.readReceipts || [];
|
||||||
const myUserId = this.context.getUserId();
|
const myUserId = MatrixClientPeg.get().getUserId();
|
||||||
if (receipts.some(r => r.userId !== myUserId)) return false;
|
if (receipts.some(r => r.userId !== myUserId)) return false;
|
||||||
|
|
||||||
// Finally, we should show a receipt.
|
// Finally, we should show a receipt.
|
||||||
@ -501,7 +485,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.suppressReadReceiptAnimation = false;
|
this.suppressReadReceiptAnimation = false;
|
||||||
const client = this.context;
|
const client = MatrixClientPeg.get();
|
||||||
if (!this.props.forExport) {
|
if (!this.props.forExport) {
|
||||||
client.on("deviceVerificationChanged", this.onDeviceVerificationChanged);
|
client.on("deviceVerificationChanged", this.onDeviceVerificationChanged);
|
||||||
client.on("userTrustStatusChanged", this.onUserVerificationChanged);
|
client.on("userTrustStatusChanged", this.onUserVerificationChanged);
|
||||||
@ -526,12 +510,12 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
room?.on(ThreadEvent.New, this.onNewThread);
|
room?.on(ThreadEvent.New, this.onNewThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupNotificationListener = (thread: Thread): void => {
|
private setupNotificationListener = (thread: Thread): void => {
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
const notifications = RoomNotificationStateStore.instance.getThreadsRoomState(room);
|
const notifications = RoomNotificationStateStore.instance.getThreadsRoomState(room);
|
||||||
|
|
||||||
this.threadState = notifications.getThreadRoomState(thread);
|
this.threadState = notifications.getThreadRoomState(thread);
|
||||||
@ -592,7 +576,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
const client = this.context;
|
const client = MatrixClientPeg.get();
|
||||||
client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
|
client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
|
||||||
client.removeListener("userTrustStatusChanged", this.onUserVerificationChanged);
|
client.removeListener("userTrustStatusChanged", this.onUserVerificationChanged);
|
||||||
client.removeListener("Room.receipt", this.onRoomReceipt);
|
client.removeListener("Room.receipt", this.onRoomReceipt);
|
||||||
@ -606,7 +590,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
this.props.mxEvent.off(ThreadEvent.Update, this.updateThread);
|
this.props.mxEvent.off(ThreadEvent.Update, this.updateThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
room?.off(ThreadEvent.New, this.onNewThread);
|
room?.off(ThreadEvent.New, this.onNewThread);
|
||||||
if (this.threadState) {
|
if (this.threadState) {
|
||||||
this.threadState.off(NotificationStateEvents.Update, this.onThreadStateUpdate);
|
this.threadState.off(NotificationStateEvents.Update, this.onThreadStateUpdate);
|
||||||
@ -616,7 +600,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
componentDidUpdate(prevProps: IProps, prevState: IState, snapshot) {
|
componentDidUpdate(prevProps: IProps, prevState: IState, snapshot) {
|
||||||
// If we're not listening for receipts and expect to be, register a listener.
|
// If we're not listening for receipts and expect to be, register a listener.
|
||||||
if (!this.isListeningForReceipts && (this.shouldShowSentReceipt || this.shouldShowSendingReceipt)) {
|
if (!this.isListeningForReceipts && (this.shouldShowSentReceipt || this.shouldShowSendingReceipt)) {
|
||||||
this.context.on("Room.receipt", this.onRoomReceipt);
|
MatrixClientPeg.get().on("Room.receipt", this.onRoomReceipt);
|
||||||
this.isListeningForReceipts = true;
|
this.isListeningForReceipts = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -624,7 +608,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
private onNewThread = (thread: Thread) => {
|
private onNewThread = (thread: Thread) => {
|
||||||
if (thread.id === this.props.mxEvent.getId()) {
|
if (thread.id === this.props.mxEvent.getId()) {
|
||||||
this.updateThread(thread);
|
this.updateThread(thread);
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
room.off(ThreadEvent.New, this.onNewThread);
|
room.off(ThreadEvent.New, this.onNewThread);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -734,7 +718,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
private onRoomReceipt = (ev: MatrixEvent, room: Room): void => {
|
private onRoomReceipt = (ev: MatrixEvent, room: Room): void => {
|
||||||
// ignore events for other rooms
|
// ignore events for other rooms
|
||||||
const tileRoom = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const tileRoom = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
if (room !== tileRoom) return;
|
if (room !== tileRoom) return;
|
||||||
|
|
||||||
if (!this.shouldShowSentReceipt && !this.shouldShowSendingReceipt && !this.isListeningForReceipts) {
|
if (!this.shouldShowSentReceipt && !this.shouldShowSendingReceipt && !this.isListeningForReceipts) {
|
||||||
@ -746,7 +730,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
this.forceUpdate(() => {
|
this.forceUpdate(() => {
|
||||||
// Per elsewhere in this file, we can remove the listener once we will have no further purpose for it.
|
// Per elsewhere in this file, we can remove the listener once we will have no further purpose for it.
|
||||||
if (!this.shouldShowSentReceipt && !this.shouldShowSendingReceipt) {
|
if (!this.shouldShowSentReceipt && !this.shouldShowSendingReceipt) {
|
||||||
this.context.removeListener("Room.receipt", this.onRoomReceipt);
|
MatrixClientPeg.get().removeListener("Room.receipt", this.onRoomReceipt);
|
||||||
this.isListeningForReceipts = false;
|
this.isListeningForReceipts = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -779,9 +763,9 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const encryptionInfo = this.context.getEventEncryptionInfo(mxEvent);
|
const encryptionInfo = MatrixClientPeg.get().getEventEncryptionInfo(mxEvent);
|
||||||
const senderId = mxEvent.getSender();
|
const senderId = mxEvent.getSender();
|
||||||
const userTrust = this.context.checkUserTrust(senderId);
|
const userTrust = MatrixClientPeg.get().checkUserTrust(senderId);
|
||||||
|
|
||||||
if (encryptionInfo.mismatchedSender) {
|
if (encryptionInfo.mismatchedSender) {
|
||||||
// something definitely wrong is going on here
|
// something definitely wrong is going on here
|
||||||
@ -799,7 +783,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventSenderTrust = encryptionInfo.sender && this.context.checkDeviceTrust(
|
const eventSenderTrust = encryptionInfo.sender && MatrixClientPeg.get().checkDeviceTrust(
|
||||||
senderId, encryptionInfo.sender.deviceId,
|
senderId, encryptionInfo.sender.deviceId,
|
||||||
);
|
);
|
||||||
if (!eventSenderTrust) {
|
if (!eventSenderTrust) {
|
||||||
@ -878,14 +862,16 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
private shouldHighlight(): boolean {
|
private shouldHighlight(): boolean {
|
||||||
if (this.props.forExport) return false;
|
if (this.props.forExport) return false;
|
||||||
if (this.props.tileShape === TileShape.Notif) return false;
|
if (this.context.timelineRenderingType === TimelineRenderingType.Notification) return false;
|
||||||
if (this.props.tileShape === TileShape.ThreadPanel) return false;
|
if (this.context.timelineRenderingType === TimelineRenderingType.ThreadsList) return false;
|
||||||
|
|
||||||
const actions = this.context.getPushActionsForEvent(this.props.mxEvent.replacingEvent() || this.props.mxEvent);
|
const actions = MatrixClientPeg.get().getPushActionsForEvent(
|
||||||
|
this.props.mxEvent.replacingEvent() || this.props.mxEvent,
|
||||||
|
);
|
||||||
if (!actions || !actions.tweaks) { return false; }
|
if (!actions || !actions.tweaks) { return false; }
|
||||||
|
|
||||||
// don't show self-highlights from another of our clients
|
// don't show self-highlights from another of our clients
|
||||||
if (this.props.mxEvent.getSender() === this.context.credentials.userId) {
|
if (this.props.mxEvent.getSender() === MatrixClientPeg.get().credentials.userId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1013,7 +999,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
// Cancel any outgoing key request for this event and resend it. If a response
|
// Cancel any outgoing key request for this event and resend it. If a response
|
||||||
// is received for the request with the required keys, the event could be
|
// is received for the request with the required keys, the event could be
|
||||||
// decrypted successfully.
|
// decrypted successfully.
|
||||||
this.context.cancelAndResendEventRoomKeyRequest(this.props.mxEvent);
|
MatrixClientPeg.get().cancelAndResendEventRoomKeyRequest(this.props.mxEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onPermalinkClicked = e => {
|
private onPermalinkClicked = e => {
|
||||||
@ -1054,7 +1040,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.context.isRoomEncrypted(ev.getRoomId())) {
|
if (MatrixClientPeg.get().isRoomEncrypted(ev.getRoomId())) {
|
||||||
// else if room is encrypted
|
// else if room is encrypted
|
||||||
// and event is being encrypted or is not_sent (Unknown Devices/Network Error)
|
// and event is being encrypted or is not_sent (Unknown Devices/Network Error)
|
||||||
if (ev.status === EventStatus.ENCRYPTING) {
|
if (ev.status === EventStatus.ENCRYPTING) {
|
||||||
@ -1169,7 +1155,10 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
const isEncryptionFailure = this.props.mxEvent.isDecryptionFailure();
|
const isEncryptionFailure = this.props.mxEvent.isDecryptionFailure();
|
||||||
|
|
||||||
let isContinuation = this.props.continuation;
|
let isContinuation = this.props.continuation;
|
||||||
if (this.props.tileShape && this.props.layout !== Layout.Bubble) {
|
if (this.context.timelineRenderingType !== TimelineRenderingType.Room &&
|
||||||
|
this.context.timelineRenderingType !== TimelineRenderingType.Search &&
|
||||||
|
this.props.layout !== Layout.Bubble
|
||||||
|
) {
|
||||||
isContinuation = false;
|
isContinuation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1196,7 +1185,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
mx_EventTile_bad: isEncryptionFailure,
|
mx_EventTile_bad: isEncryptionFailure,
|
||||||
mx_EventTile_emote: msgtype === MsgType.Emote,
|
mx_EventTile_emote: msgtype === MsgType.Emote,
|
||||||
mx_EventTile_noSender: this.props.hideSender,
|
mx_EventTile_noSender: this.props.hideSender,
|
||||||
mx_EventTile_clamp: this.props.tileShape === TileShape.ThreadPanel,
|
mx_EventTile_clamp: this.context.timelineRenderingType === TimelineRenderingType.ThreadsList,
|
||||||
mx_EventTile_noBubble: noBubbleEvent,
|
mx_EventTile_noBubble: noBubbleEvent,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1219,7 +1208,9 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
let avatarSize;
|
let avatarSize;
|
||||||
let needsSenderProfile;
|
let needsSenderProfile;
|
||||||
|
|
||||||
if (this.props.tileShape === TileShape.Notif || this.props.tileShape === TileShape.ThreadPanel) {
|
if (this.context.timelineRenderingType === TimelineRenderingType.Notification ||
|
||||||
|
this.context.timelineRenderingType === TimelineRenderingType.ThreadsList
|
||||||
|
) {
|
||||||
avatarSize = 24;
|
avatarSize = 24;
|
||||||
needsSenderProfile = true;
|
needsSenderProfile = true;
|
||||||
} else if (tileHandler === 'messages.RoomCreate' || isBubbleMessage) {
|
} else if (tileHandler === 'messages.RoomCreate' || isBubbleMessage) {
|
||||||
@ -1234,7 +1225,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
avatarSize = 14;
|
avatarSize = 14;
|
||||||
needsSenderProfile = true;
|
needsSenderProfile = true;
|
||||||
} else if (
|
} else if (
|
||||||
(this.props.continuation && this.props.tileShape !== TileShape.FileGrid) ||
|
(this.props.continuation && this.context.timelineRenderingType !== TimelineRenderingType.File) ||
|
||||||
eventType === EventType.CallInvite
|
eventType === EventType.CallInvite
|
||||||
) {
|
) {
|
||||||
// no avatar or sender profile for continuation messages and call tiles
|
// no avatar or sender profile for continuation messages and call tiles
|
||||||
@ -1269,17 +1260,20 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (needsSenderProfile && this.props.hideSender !== true) {
|
if (needsSenderProfile && this.props.hideSender !== true) {
|
||||||
if (!this.props.tileShape || this.props.tileShape === TileShape.Thread) {
|
if (this.context.timelineRenderingType === TimelineRenderingType.Room ||
|
||||||
sender = <SenderProfile onClick={this.onSenderProfileClick}
|
this.context.timelineRenderingType === TimelineRenderingType.Search ||
|
||||||
|
this.context.timelineRenderingType === TimelineRenderingType.Pinned ||
|
||||||
|
this.context.timelineRenderingType === TimelineRenderingType.Thread
|
||||||
|
) {
|
||||||
|
sender = <SenderProfile
|
||||||
|
onClick={this.onSenderProfileClick}
|
||||||
mxEvent={this.props.mxEvent}
|
mxEvent={this.props.mxEvent}
|
||||||
enableFlair={this.props.enableFlair}
|
enableFlair={this.props.enableFlair}
|
||||||
tileShape={this.props.tileShape}
|
|
||||||
/>;
|
/>;
|
||||||
} else {
|
} else {
|
||||||
sender = <SenderProfile
|
sender = <SenderProfile
|
||||||
mxEvent={this.props.mxEvent}
|
mxEvent={this.props.mxEvent}
|
||||||
enableFlair={this.props.enableFlair}
|
enableFlair={this.props.enableFlair}
|
||||||
tileShape={this.props.tileShape}
|
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1303,16 +1297,16 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
|| this.state.hover
|
|| this.state.hover
|
||||||
|| this.state.actionBarFocused);
|
|| this.state.actionBarFocused);
|
||||||
|
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
const thread = room?.findThreadForEvent?.(this.props.mxEvent);
|
const thread = room?.findThreadForEvent?.(this.props.mxEvent);
|
||||||
|
|
||||||
// Thread panel shows the timestamp of the last reply in that thread
|
// Thread panel shows the timestamp of the last reply in that thread
|
||||||
const ts = this.props.tileShape !== TileShape.ThreadPanel
|
const ts = this.context.timelineRenderingType !== TimelineRenderingType.ThreadsList
|
||||||
? this.props.mxEvent.getTs()
|
? this.props.mxEvent.getTs()
|
||||||
: thread?.replyToEvent.getTs();
|
: thread?.replyToEvent.getTs();
|
||||||
|
|
||||||
const messageTimestamp = <MessageTimestamp
|
const messageTimestamp = <MessageTimestamp
|
||||||
showRelative={this.props.tileShape === TileShape.ThreadPanel}
|
showRelative={this.context.timelineRenderingType === TimelineRenderingType.ThreadsList}
|
||||||
showTwelveHour={this.props.isTwelveHour}
|
showTwelveHour={this.props.isTwelveHour}
|
||||||
ts={ts}
|
ts={ts}
|
||||||
/>;
|
/>;
|
||||||
@ -1392,7 +1386,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
msgOption = readAvatars;
|
msgOption = readAvatars;
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderTarget = this.props.tileShape === TileShape.Thread
|
const renderTarget = this.context.timelineRenderingType === TimelineRenderingType.Thread
|
||||||
? RelationType.Thread
|
? RelationType.Thread
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
@ -1412,11 +1406,11 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
/>
|
/>
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const isOwnEvent = this.props.mxEvent?.sender?.userId === this.context.getUserId();
|
const isOwnEvent = this.props.mxEvent?.sender?.userId === MatrixClientPeg.get().getUserId();
|
||||||
|
|
||||||
switch (this.props.tileShape) {
|
switch (this.context.timelineRenderingType) {
|
||||||
case TileShape.Notif: {
|
case TimelineRenderingType.Notification: {
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
return React.createElement(this.props.as || "li", {
|
return React.createElement(this.props.as || "li", {
|
||||||
"className": classes,
|
"className": classes,
|
||||||
"aria-live": ariaLive,
|
"aria-live": ariaLive,
|
||||||
@ -1443,7 +1437,6 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
highlightLink={this.props.highlightLink}
|
highlightLink={this.props.highlightLink}
|
||||||
showUrlPreview={this.props.showUrlPreview}
|
showUrlPreview={this.props.showUrlPreview}
|
||||||
onHeightChanged={this.props.onHeightChanged}
|
onHeightChanged={this.props.onHeightChanged}
|
||||||
tileShape={this.props.tileShape}
|
|
||||||
editState={this.props.editState}
|
editState={this.props.editState}
|
||||||
getRelationsForEvent={this.props.getRelationsForEvent}
|
getRelationsForEvent={this.props.getRelationsForEvent}
|
||||||
isSeeingThroughMessageHiddenForModeration={isSeeingThroughMessageHiddenForModeration}
|
isSeeingThroughMessageHiddenForModeration={isSeeingThroughMessageHiddenForModeration}
|
||||||
@ -1451,8 +1444,8 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
</div>,
|
</div>,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
case TileShape.Thread: {
|
case TimelineRenderingType.Thread: {
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
return React.createElement(this.props.as || "li", {
|
return React.createElement(this.props.as || "li", {
|
||||||
"ref": this.ref,
|
"ref": this.ref,
|
||||||
"className": classes,
|
"className": classes,
|
||||||
@ -1485,7 +1478,6 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
highlightLink={this.props.highlightLink}
|
highlightLink={this.props.highlightLink}
|
||||||
showUrlPreview={this.props.showUrlPreview}
|
showUrlPreview={this.props.showUrlPreview}
|
||||||
onHeightChanged={this.props.onHeightChanged}
|
onHeightChanged={this.props.onHeightChanged}
|
||||||
tileShape={this.props.tileShape}
|
|
||||||
editState={this.props.editState}
|
editState={this.props.editState}
|
||||||
replacingEventId={this.props.replacingEventId}
|
replacingEventId={this.props.replacingEventId}
|
||||||
getRelationsForEvent={this.props.getRelationsForEvent}
|
getRelationsForEvent={this.props.getRelationsForEvent}
|
||||||
@ -1497,7 +1489,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
reactionsRow,
|
reactionsRow,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
case TileShape.ThreadPanel: {
|
case TimelineRenderingType.ThreadsList: {
|
||||||
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers
|
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers
|
||||||
return (
|
return (
|
||||||
React.createElement(this.props.as || "li", {
|
React.createElement(this.props.as || "li", {
|
||||||
@ -1508,7 +1500,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
"aria-atomic": "true",
|
"aria-atomic": "true",
|
||||||
"data-scroll-tokens": scrollToken,
|
"data-scroll-tokens": scrollToken,
|
||||||
"data-layout": this.props.layout,
|
"data-layout": this.props.layout,
|
||||||
"data-shape": this.props.tileShape,
|
"data-shape": this.context.timelineRenderingType,
|
||||||
"data-self": isOwnEvent,
|
"data-self": isOwnEvent,
|
||||||
"data-has-reply": !!replyChain,
|
"data-has-reply": !!replyChain,
|
||||||
"data-notification": this.state.threadNotification,
|
"data-notification": this.state.threadNotification,
|
||||||
@ -1550,7 +1542,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
</>)
|
</>)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case TileShape.FileGrid: {
|
case TimelineRenderingType.File: {
|
||||||
return React.createElement(this.props.as || "li", {
|
return React.createElement(this.props.as || "li", {
|
||||||
"className": classes,
|
"className": classes,
|
||||||
"aria-live": ariaLive,
|
"aria-live": ariaLive,
|
||||||
@ -1563,7 +1555,6 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
highlights={this.props.highlights}
|
highlights={this.props.highlights}
|
||||||
highlightLink={this.props.highlightLink}
|
highlightLink={this.props.highlightLink}
|
||||||
showUrlPreview={this.props.showUrlPreview}
|
showUrlPreview={this.props.showUrlPreview}
|
||||||
tileShape={this.props.tileShape}
|
|
||||||
onHeightChanged={this.props.onHeightChanged}
|
onHeightChanged={this.props.onHeightChanged}
|
||||||
editState={this.props.editState}
|
editState={this.props.editState}
|
||||||
getRelationsForEvent={this.props.getRelationsForEvent}
|
getRelationsForEvent={this.props.getRelationsForEvent}
|
||||||
@ -1584,7 +1575,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: { // Pinned, Room, Search
|
||||||
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers
|
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers
|
||||||
return (
|
return (
|
||||||
React.createElement(this.props.as || "li", {
|
React.createElement(this.props.as || "li", {
|
||||||
|
@ -30,7 +30,6 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
|
|||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import { getUserNameColorClass } from "../../../utils/FormattingUtils";
|
import { getUserNameColorClass } from "../../../utils/FormattingUtils";
|
||||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||||
import { TileShape } from "./EventTile";
|
|
||||||
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
@ -92,7 +91,6 @@ export default class PinnedEventTile extends React.Component<IProps> {
|
|||||||
className="mx_PinnedEventTile_body"
|
className="mx_PinnedEventTile_body"
|
||||||
maxImageHeight={150}
|
maxImageHeight={150}
|
||||||
onHeightChanged={() => {}} // we need to give this, apparently
|
onHeightChanged={() => {}} // we need to give this, apparently
|
||||||
tileShape={TileShape.Pinned}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@ export enum TimelineRenderingType {
|
|||||||
ThreadsList = "ThreadsList",
|
ThreadsList = "ThreadsList",
|
||||||
File = "File",
|
File = "File",
|
||||||
Notification = "Notification",
|
Notification = "Notification",
|
||||||
Search = "Search"
|
Search = "Search",
|
||||||
|
Pinned = "Pinned",
|
||||||
}
|
}
|
||||||
|
|
||||||
const RoomContext = createContext<IRoomState>({
|
const RoomContext = createContext<IRoomState>({
|
||||||
|
Loading…
Reference in New Issue
Block a user