Show bubble tile timestamps for bubble layout inside the bubble (#7622)
parent
8ddd677c35
commit
fb49ccce35
|
@ -183,6 +183,10 @@ limitations under the License.
|
|||
}
|
||||
}
|
||||
|
||||
.mx_MessageTimestamp {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
&.mx_CallEvent_narrow {
|
||||
height: unset;
|
||||
width: 290px;
|
||||
|
|
|
@ -22,7 +22,7 @@ limitations under the License.
|
|||
max-width: 75%;
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
grid-template-columns: 24px minmax(0, 1fr) min-content;
|
||||
grid-template-columns: 24px minmax(0, 1fr) min-content min-content;
|
||||
|
||||
&::before, &::after {
|
||||
position: relative;
|
||||
|
@ -57,4 +57,11 @@ limitations under the License.
|
|||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
}
|
||||
|
||||
.mx_MessageTimestamp {
|
||||
grid-column: 4;
|
||||
grid-row: 1 / 3;
|
||||
align-self: center;
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -450,6 +450,14 @@ limitations under the License.
|
|||
}
|
||||
}
|
||||
|
||||
.mx_EventTile.mx_EventTile_bubbleContainer[data-layout=bubble],
|
||||
.mx_EventTile.mx_EventTile_leftAlignedBubble[data-layout=bubble] {
|
||||
.mx_EventTile_line > a {
|
||||
// hide this timestamp as the tile will render its own
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_EventTile.mx_EventTile_bubbleContainer[data-layout=bubble],
|
||||
.mx_EventTile.mx_EventTile_leftAlignedBubble[data-layout=bubble],
|
||||
.mx_EventTile.mx_EventTile_info[data-layout=bubble],
|
||||
|
|
|
@ -33,6 +33,7 @@ const MAX_NON_NARROW_WIDTH = 450 / 70 * 100;
|
|||
interface IProps {
|
||||
mxEvent: MatrixEvent;
|
||||
callEventGrouper: CallEventGrouper;
|
||||
timestamp?: JSX.Element;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
@ -145,6 +146,7 @@ export default class CallEvent extends React.PureComponent<IProps, IState> {
|
|||
>
|
||||
<span> { _t("Accept") } </span>
|
||||
</AccessibleButton>
|
||||
{ this.props.timestamp }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -157,6 +159,7 @@ export default class CallEvent extends React.PureComponent<IProps, IState> {
|
|||
<div className="mx_CallEvent_content">
|
||||
{ _t("Call declined") }
|
||||
{ this.renderCallBackButton(_t("Call back")) }
|
||||
{ this.props.timestamp }
|
||||
</div>
|
||||
);
|
||||
} else if (([CallErrorCode.UserHangup, "user hangup"].includes(hangupReason) || !hangupReason)) {
|
||||
|
@ -174,6 +177,7 @@ export default class CallEvent extends React.PureComponent<IProps, IState> {
|
|||
return (
|
||||
<div className="mx_CallEvent_content">
|
||||
{ text }
|
||||
{ this.props.timestamp }
|
||||
</div>
|
||||
);
|
||||
} else if (hangupReason === CallErrorCode.InviteTimeout) {
|
||||
|
@ -181,6 +185,7 @@ export default class CallEvent extends React.PureComponent<IProps, IState> {
|
|||
<div className="mx_CallEvent_content">
|
||||
{ _t("No answer") }
|
||||
{ this.renderCallBackButton(_t("Call back")) }
|
||||
{ this.props.timestamp }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -215,6 +220,7 @@ export default class CallEvent extends React.PureComponent<IProps, IState> {
|
|||
/>
|
||||
{ _t("Connection failed") }
|
||||
{ this.renderCallBackButton(_t("Retry")) }
|
||||
{ this.props.timestamp }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -222,6 +228,7 @@ export default class CallEvent extends React.PureComponent<IProps, IState> {
|
|||
return (
|
||||
<div className="mx_CallEvent_content">
|
||||
<Clock seconds={this.state.length} />
|
||||
{ this.props.timestamp }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -229,6 +236,7 @@ export default class CallEvent extends React.PureComponent<IProps, IState> {
|
|||
return (
|
||||
<div className="mx_CallEvent_content">
|
||||
{ _t("Connecting") }
|
||||
{ this.props.timestamp }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -237,6 +245,7 @@ export default class CallEvent extends React.PureComponent<IProps, IState> {
|
|||
<div className="mx_CallEvent_content">
|
||||
{ _t("Missed call") }
|
||||
{ this.renderCallBackButton(_t("Call back")) }
|
||||
{ this.props.timestamp }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -244,6 +253,7 @@ export default class CallEvent extends React.PureComponent<IProps, IState> {
|
|||
return (
|
||||
<div className="mx_CallEvent_content">
|
||||
{ _t("The call is in an unknown state!") }
|
||||
{ this.props.timestamp }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -27,11 +27,12 @@ import { objectHasDiff } from "../../../utils/objects";
|
|||
|
||||
interface IProps {
|
||||
mxEvent: MatrixEvent;
|
||||
timestamp?: JSX.Element;
|
||||
}
|
||||
|
||||
const ALGORITHM = "m.megolm.v1.aes-sha2";
|
||||
|
||||
const EncryptionEvent = forwardRef<HTMLDivElement, IProps>(({ mxEvent }, ref) => {
|
||||
const EncryptionEvent = forwardRef<HTMLDivElement, IProps>(({ mxEvent, timestamp }, ref) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const roomId = mxEvent.getRoomId();
|
||||
const isRoomEncrypted = MatrixClientPeg.get().isRoomEncrypted(roomId);
|
||||
|
@ -60,6 +61,7 @@ const EncryptionEvent = forwardRef<HTMLDivElement, IProps>(({ mxEvent }, ref) =>
|
|||
className="mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
title={_t("Encryption enabled")}
|
||||
subtitle={subtitle}
|
||||
timestamp={timestamp}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
@ -68,6 +70,7 @@ const EncryptionEvent = forwardRef<HTMLDivElement, IProps>(({ mxEvent }, ref) =>
|
|||
className="mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
title={_t("Encryption enabled")}
|
||||
subtitle={_t("Ignored attempt to disable encryption")}
|
||||
timestamp={timestamp}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
@ -76,6 +79,7 @@ const EncryptionEvent = forwardRef<HTMLDivElement, IProps>(({ mxEvent }, ref) =>
|
|||
title={_t("Encryption not enabled")}
|
||||
subtitle={_t("The encryption used by this room isn't supported.")}
|
||||
ref={ref}
|
||||
timestamp={timestamp}
|
||||
/>;
|
||||
});
|
||||
|
||||
|
|
|
@ -20,15 +20,23 @@ import classNames from "classnames";
|
|||
interface IProps {
|
||||
className: string;
|
||||
title: string;
|
||||
timestamp?: JSX.Element;
|
||||
subtitle?: ReactNode;
|
||||
children?: ReactChildren;
|
||||
}
|
||||
|
||||
const EventTileBubble = forwardRef<HTMLDivElement, IProps>(({ className, title, subtitle, children }, ref) => {
|
||||
const EventTileBubble = forwardRef<HTMLDivElement, IProps>(({
|
||||
className,
|
||||
title,
|
||||
timestamp,
|
||||
subtitle,
|
||||
children,
|
||||
}, ref) => {
|
||||
return <div className={classNames("mx_EventTileBubble", className)} ref={ref}>
|
||||
<div className="mx_EventTileBubble_title">{ title }</div>
|
||||
{ subtitle && <div className="mx_EventTileBubble_subtitle">{ subtitle }</div> }
|
||||
{ children }
|
||||
{ timestamp }
|
||||
</div>;
|
||||
});
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
|
|||
|
||||
interface IProps {
|
||||
mxEvent: MatrixEvent;
|
||||
timestamp?: JSX.Element;
|
||||
}
|
||||
|
||||
@replaceableComponent("views.messages.MJitsiWidgetEvent")
|
||||
|
@ -54,6 +55,7 @@ export default class MJitsiWidgetEvent extends React.PureComponent<IProps> {
|
|||
return <EventTileBubble
|
||||
className="mx_MJitsiWidgetEvent"
|
||||
title={_t('Video conference ended by %(senderName)s', { senderName })}
|
||||
timestamp={this.props.timestamp}
|
||||
/>;
|
||||
} else if (prevUrl) {
|
||||
// modified
|
||||
|
@ -61,6 +63,7 @@ export default class MJitsiWidgetEvent extends React.PureComponent<IProps> {
|
|||
className="mx_MJitsiWidgetEvent"
|
||||
title={_t('Video conference updated by %(senderName)s', { senderName })}
|
||||
subtitle={joinCopy}
|
||||
timestamp={this.props.timestamp}
|
||||
/>;
|
||||
} else {
|
||||
// assume added
|
||||
|
@ -68,6 +71,7 @@ export default class MJitsiWidgetEvent extends React.PureComponent<IProps> {
|
|||
className="mx_MJitsiWidgetEvent"
|
||||
title={_t("Video conference started by %(senderName)s", { senderName })}
|
||||
subtitle={joinCopy}
|
||||
timestamp={this.props.timestamp}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
|
|||
interface IProps {
|
||||
/* the MatrixEvent to show */
|
||||
mxEvent: MatrixEvent;
|
||||
timestamp?: JSX.Element;
|
||||
}
|
||||
|
||||
@replaceableComponent("views.messages.MKeyVerificationConclusion")
|
||||
|
@ -133,6 +134,7 @@ export default class MKeyVerificationConclusion extends React.Component<IProps>
|
|||
className={classes}
|
||||
title={title}
|
||||
subtitle={userLabelForEventRoom(request.otherUserId, mxEvent.getRoomId())}
|
||||
timestamp={this.props.timestamp}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import RightPanelStore from '../../../stores/right-panel/RightPanelStore';
|
|||
|
||||
interface IProps {
|
||||
mxEvent: MatrixEvent;
|
||||
timestamp?: JSX.Element;
|
||||
}
|
||||
|
||||
@replaceableComponent("views.messages.MKeyVerificationRequest")
|
||||
|
@ -168,6 +169,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
|
|||
className="mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
title={title}
|
||||
subtitle={subtitle}
|
||||
timestamp={this.props.timestamp}
|
||||
>
|
||||
{ stateNode }
|
||||
</EventTileBubble>;
|
||||
|
|
|
@ -29,6 +29,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
|
|||
interface IProps {
|
||||
/* the MatrixEvent to show */
|
||||
mxEvent: MatrixEvent;
|
||||
timestamp?: JSX.Element;
|
||||
}
|
||||
|
||||
@replaceableComponent("views.messages.RoomCreate")
|
||||
|
@ -65,6 +66,7 @@ export default class RoomCreate extends React.Component<IProps> {
|
|||
className="mx_CreateEvent"
|
||||
title={_t("This room is a continuation of another conversation.")}
|
||||
subtitle={link}
|
||||
timestamp={this.props.timestamp}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1273,12 +1273,13 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
? this.props.mxEvent.getTs()
|
||||
: thread?.lastReply().getTs();
|
||||
|
||||
const timestamp = showTimestamp && ts ?
|
||||
<MessageTimestamp
|
||||
showRelative={this.props.tileShape === TileShape.ThreadPanel}
|
||||
showTwelveHour={this.props.isTwelveHour}
|
||||
ts={ts}
|
||||
/> : null;
|
||||
const messageTimestamp = <MessageTimestamp
|
||||
showRelative={this.props.tileShape === TileShape.ThreadPanel}
|
||||
showTwelveHour={this.props.isTwelveHour}
|
||||
ts={ts}
|
||||
/>;
|
||||
|
||||
const timestamp = showTimestamp && ts ? messageTimestamp : null;
|
||||
|
||||
const keyRequestHelpText =
|
||||
<div className="mx_EventTile_keyRequestInfo_tooltip_contents">
|
||||
|
@ -1339,9 +1340,10 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
{ timestamp }
|
||||
</a>;
|
||||
|
||||
const useIRCLayout = this.props.layout == Layout.IRC;
|
||||
const useIRCLayout = this.props.layout === Layout.IRC;
|
||||
const groupTimestamp = !useIRCLayout ? linkedTimestamp : null;
|
||||
const ircTimestamp = useIRCLayout ? linkedTimestamp : null;
|
||||
const bubbleTimestamp = this.props.layout === Layout.Bubble ? messageTimestamp : null;
|
||||
const groupPadlock = !useIRCLayout && !isBubbleMessage && this.renderE2EPadlock();
|
||||
const ircPadlock = useIRCLayout && !isBubbleMessage && this.renderE2EPadlock();
|
||||
|
||||
|
@ -1567,7 +1569,8 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
{ groupTimestamp }
|
||||
{ groupPadlock }
|
||||
{ replyChain }
|
||||
<EventTileType ref={this.tile}
|
||||
<EventTileType
|
||||
ref={this.tile}
|
||||
mxEvent={this.props.mxEvent}
|
||||
forExport={this.props.forExport}
|
||||
replacingEventId={this.props.replacingEventId}
|
||||
|
@ -1580,6 +1583,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
callEventGrouper={this.props.callEventGrouper}
|
||||
getRelationsForEvent={this.props.getRelationsForEvent}
|
||||
isSeeingThroughMessageHiddenForModeration={isSeeingThroughMessageHiddenForModeration}
|
||||
timestamp={bubbleTimestamp}
|
||||
/>
|
||||
{ keyRequestInfo }
|
||||
{ actionBar }
|
||||
|
|
Loading…
Reference in New Issue