mirror of
https://github.com/vector-im/element-web.git
synced 2025-12-08 19:01:43 +01:00
Add option to enable read receipt and marker when user interact with UI (#31353)
* feat(room view): add `enableReadReceiptsAndMarkersOnActivity` props For the multiroom module, we display several room views at the same time. In order to avoid all the rooms to send read receipts and markers automatically when we are interacting with the UI, we add `enableReadReceiptsAndMarkersOnActivity`props. When at false, the timeline doesn't listen to user activity to send these receipts. Only when the room is focused, marker and read receipts are updated. * test(room view): add test for `enableReadReceiptsAndMarkersOnActivity` * build(ew-api): update `@element-hq/element-web-module-api` to `v1.9.0`
This commit is contained in:
parent
5607291f1e
commit
242f2deb64
@ -81,7 +81,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.12.5",
|
"@babel/runtime": "^7.12.5",
|
||||||
"@element-hq/element-web-module-api": "1.8.0",
|
"@element-hq/element-web-module-api": "1.9.0",
|
||||||
"@element-hq/web-shared-components": "link:packages/shared-components",
|
"@element-hq/web-shared-components": "link:packages/shared-components",
|
||||||
"@fontsource/fira-code": "^5",
|
"@fontsource/fira-code": "^5",
|
||||||
"@fontsource/inter": "^5",
|
"@fontsource/inter": "^5",
|
||||||
|
|||||||
@ -190,6 +190,13 @@ interface IRoomProps extends RoomViewProps {
|
|||||||
* If true, hide the widgets
|
* If true, hide the widgets
|
||||||
*/
|
*/
|
||||||
hideWidgets?: boolean;
|
hideWidgets?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, enable sending read receipts and markers on user activity in the room view. When the user interacts with the room view, read receipts and markers are sent.
|
||||||
|
* If false, the read receipts and markers are only send when the room view is focused. The user has to focus the room view in order to clear any unreads and to move the unread marker to the bottom of the view.
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
enableReadReceiptsAndMarkersOnActivity?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { MainSplitContentType };
|
export { MainSplitContentType };
|
||||||
@ -418,6 +425,10 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||||||
public static contextType = SDKContext;
|
public static contextType = SDKContext;
|
||||||
declare public context: React.ContextType<typeof SDKContext>;
|
declare public context: React.ContextType<typeof SDKContext>;
|
||||||
|
|
||||||
|
public static readonly defaultProps = {
|
||||||
|
enableReadReceiptsAndMarkersOnActivity: true,
|
||||||
|
};
|
||||||
|
|
||||||
public constructor(props: IRoomProps, context: React.ContextType<typeof SDKContext>) {
|
public constructor(props: IRoomProps, context: React.ContextType<typeof SDKContext>) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
|
||||||
@ -2182,6 +2193,19 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the focus event on the RoomView component.
|
||||||
|
*
|
||||||
|
* Sends read receipts and updates the read marker if the
|
||||||
|
* disableReadReceiptsAndMarkersOnActivity prop is set.
|
||||||
|
*/
|
||||||
|
private onFocus = (): void => {
|
||||||
|
if (this.props.enableReadReceiptsAndMarkersOnActivity) return;
|
||||||
|
|
||||||
|
this.messagePanel?.sendReadReceipts();
|
||||||
|
this.messagePanel?.updateReadMarker();
|
||||||
|
};
|
||||||
|
|
||||||
public render(): ReactNode {
|
public render(): ReactNode {
|
||||||
if (!this.context.client) return null;
|
if (!this.context.client) return null;
|
||||||
const { isRoomEncrypted } = this.state;
|
const { isRoomEncrypted } = this.state;
|
||||||
@ -2539,7 +2563,9 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||||||
timelineSet={this.state.room.getUnfilteredTimelineSet()}
|
timelineSet={this.state.room.getUnfilteredTimelineSet()}
|
||||||
showReadReceipts={this.state.showReadReceipts}
|
showReadReceipts={this.state.showReadReceipts}
|
||||||
manageReadReceipts={!this.state.isPeeking}
|
manageReadReceipts={!this.state.isPeeking}
|
||||||
sendReadReceiptOnLoad={!this.state.wasContextSwitch}
|
sendReadReceiptOnLoad={
|
||||||
|
!this.state.wasContextSwitch && this.props.enableReadReceiptsAndMarkersOnActivity
|
||||||
|
}
|
||||||
manageReadMarkers={!this.state.isPeeking}
|
manageReadMarkers={!this.state.isPeeking}
|
||||||
hidden={hideMessagePanel}
|
hidden={hideMessagePanel}
|
||||||
highlightedEventId={highlightedEventId}
|
highlightedEventId={highlightedEventId}
|
||||||
@ -2556,6 +2582,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||||||
showReactions={true}
|
showReactions={true}
|
||||||
layout={this.state.layout}
|
layout={this.state.layout}
|
||||||
editState={this.state.editState}
|
editState={this.state.editState}
|
||||||
|
enableReadReceiptsAndMarkersOnActivity={this.props.enableReadReceiptsAndMarkersOnActivity}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -2622,7 +2649,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||||||
<Measured sensor={this.roomViewBody} onMeasurement={this.onMeasurement} />
|
<Measured sensor={this.roomViewBody} onMeasurement={this.onMeasurement} />
|
||||||
{auxPanel}
|
{auxPanel}
|
||||||
{pinnedMessageBanner}
|
{pinnedMessageBanner}
|
||||||
<main className={timelineClasses}>
|
<main className={timelineClasses} data-testid="timeline">
|
||||||
<FileDropTarget
|
<FileDropTarget
|
||||||
parent={this.roomView.current}
|
parent={this.roomView.current}
|
||||||
onFileDrop={this.onFileDrop}
|
onFileDrop={this.onFileDrop}
|
||||||
@ -2683,7 +2710,13 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ScopedRoomContextProvider {...this.state} roomViewStore={this.roomViewStore}>
|
<ScopedRoomContextProvider {...this.state} roomViewStore={this.roomViewStore}>
|
||||||
<div className={mainClasses} ref={this.roomView} onKeyDown={this.onReactKeyDown}>
|
<div
|
||||||
|
className={mainClasses}
|
||||||
|
ref={this.roomView}
|
||||||
|
onKeyDown={this.onReactKeyDown}
|
||||||
|
onFocus={this.onFocus}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
{showChatEffects && this.roomView.current && (
|
{showChatEffects && this.roomView.current && (
|
||||||
<EffectsOverlay roomWidth={this.roomView.current.offsetWidth} />
|
<EffectsOverlay roomWidth={this.roomView.current.offsetWidth} />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -139,6 +139,12 @@ interface IProps {
|
|||||||
|
|
||||||
hideThreadedMessages?: boolean;
|
hideThreadedMessages?: boolean;
|
||||||
disableGrouping?: boolean;
|
disableGrouping?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable updating the read receipts and markers on user activity.
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
enableReadReceiptsAndMarkersOnActivity?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
@ -228,6 +234,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
|||||||
sendReadReceiptOnLoad: true,
|
sendReadReceiptOnLoad: true,
|
||||||
hideThreadedMessages: true,
|
hideThreadedMessages: true,
|
||||||
disableGrouping: false,
|
disableGrouping: false,
|
||||||
|
enableReadReceiptsAndMarkersOnActivity: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
private lastRRSentEventId: string | null | undefined = undefined;
|
private lastRRSentEventId: string | null | undefined = undefined;
|
||||||
@ -302,10 +309,10 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
this.props.timelineSet.room?.on(ThreadEvent.Update, this.onThreadUpdate);
|
this.props.timelineSet.room?.on(ThreadEvent.Update, this.onThreadUpdate);
|
||||||
|
|
||||||
if (this.props.manageReadReceipts) {
|
if (this.props.manageReadReceipts && this.props.enableReadReceiptsAndMarkersOnActivity) {
|
||||||
this.updateReadReceiptOnUserActivity();
|
this.updateReadReceiptOnUserActivity();
|
||||||
}
|
}
|
||||||
if (this.props.manageReadMarkers) {
|
if (this.props.manageReadMarkers && this.props.enableReadReceiptsAndMarkersOnActivity) {
|
||||||
this.updateReadMarkerOnUserActivity();
|
this.updateReadMarkerOnUserActivity();
|
||||||
}
|
}
|
||||||
this.initTimeline(this.props);
|
this.initTimeline(this.props);
|
||||||
@ -1028,7 +1035,10 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private sendReadReceipts = async (): Promise<void> => {
|
/**
|
||||||
|
* Sends read receipts and fully read markers as appropriate.
|
||||||
|
*/
|
||||||
|
public sendReadReceipts = async (): Promise<void> => {
|
||||||
if (SettingsStore.getValue("lowBandwidth")) return;
|
if (SettingsStore.getValue("lowBandwidth")) return;
|
||||||
if (!this.messagePanel.current) return;
|
if (!this.messagePanel.current) return;
|
||||||
if (!this.props.manageReadReceipts) return;
|
if (!this.props.manageReadReceipts) return;
|
||||||
@ -1134,9 +1144,12 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the read marker is on the screen, we can now assume we've caught up to the end
|
/**
|
||||||
// of the screen, so move the marker down to the bottom of the screen.
|
* Move the marker to the bottom of the screen.
|
||||||
private updateReadMarker = async (): Promise<void> => {
|
* If the read marker is on the screen, we can now assume we've caught up to the end
|
||||||
|
* of the screen, so move the marker down to the bottom of the screen.
|
||||||
|
*/
|
||||||
|
public updateReadMarker = async (): Promise<void> => {
|
||||||
if (!this.props.manageReadMarkers) return;
|
if (!this.props.manageReadMarkers) return;
|
||||||
if (this.getReadMarkerPosition() === 1) {
|
if (this.getReadMarkerPosition() === 1) {
|
||||||
// the read marker is at an event below the viewport,
|
// the read marker is at an event below the viewport,
|
||||||
|
|||||||
@ -335,6 +335,54 @@ describe("RoomView", () => {
|
|||||||
expect(asFragment()).toMatchSnapshot();
|
expect(asFragment()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("enableReadReceiptsAndMarkersOnActivity", () => {
|
||||||
|
it.each([
|
||||||
|
{
|
||||||
|
enabled: false,
|
||||||
|
testName: "should send read receipts and update read marker on focus when disabled",
|
||||||
|
checkCall: (sendReadReceiptsSpy: jest.Mock, updateReadMarkerSpy: jest.Mock) => {
|
||||||
|
expect(sendReadReceiptsSpy).toHaveBeenCalled();
|
||||||
|
expect(updateReadMarkerSpy).toHaveBeenCalled();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: true,
|
||||||
|
testName: "should not send read receipts and update read marker on focus when enabled",
|
||||||
|
checkCall: (sendReadReceiptsSpy: jest.Mock, updateReadMarkerSpy: jest.Mock) => {
|
||||||
|
expect(sendReadReceiptsSpy).not.toHaveBeenCalled();
|
||||||
|
expect(updateReadMarkerSpy).not.toHaveBeenCalled();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])("$testName", async ({ enabled, checkCall }) => {
|
||||||
|
// Join the room
|
||||||
|
jest.spyOn(room, "getMyMembership").mockReturnValue(KnownMembership.Join);
|
||||||
|
const ref = createRef<RoomView>();
|
||||||
|
await mountRoomView(ref, {
|
||||||
|
enableReadReceiptsAndMarkersOnActivity: enabled,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for the timeline to be rendered
|
||||||
|
await waitFor(() => expect(screen.getByTestId("timeline")).not.toBeNull());
|
||||||
|
|
||||||
|
// Get the RoomView instance and mock the messagePanel methods
|
||||||
|
const instance = ref.current!;
|
||||||
|
const sendReadReceiptsSpy = jest.fn();
|
||||||
|
const updateReadMarkerSpy = jest.fn();
|
||||||
|
// @ts-ignore - accessing private property for testing
|
||||||
|
instance.messagePanel = {
|
||||||
|
sendReadReceipts: sendReadReceiptsSpy,
|
||||||
|
updateReadMarker: updateReadMarkerSpy,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find the main RoomView div and trigger focus
|
||||||
|
const timeline = screen.getByTestId("timeline");
|
||||||
|
fireEvent.focus(timeline);
|
||||||
|
|
||||||
|
// Verify that sendReadReceipts and updateReadMarker were called or not based on the enabled state
|
||||||
|
checkCall(sendReadReceiptsSpy, updateReadMarkerSpy);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("invites", () => {
|
describe("invites", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const member = new RoomMember(room.roomId, cli.getSafeUserId());
|
const member = new RoomMember(room.roomId, cli.getSafeUserId());
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import { Action } from "../../../../src/dispatcher/actions";
|
|||||||
import { SettingLevel } from "../../../../src/settings/SettingLevel";
|
import { SettingLevel } from "../../../../src/settings/SettingLevel";
|
||||||
import MatrixClientBackedController from "../../../../src/settings/controllers/MatrixClientBackedController";
|
import MatrixClientBackedController from "../../../../src/settings/controllers/MatrixClientBackedController";
|
||||||
import { SdkContextClass } from "../../../../src/contexts/SDKContext";
|
import { SdkContextClass } from "../../../../src/contexts/SDKContext";
|
||||||
|
import type Timer from "../../../../src/utils/Timer";
|
||||||
|
|
||||||
// ScrollPanel calls this, but jsdom doesn't mock it for us
|
// ScrollPanel calls this, but jsdom doesn't mock it for us
|
||||||
HTMLDivElement.prototype.scrollBy = () => {};
|
HTMLDivElement.prototype.scrollBy = () => {};
|
||||||
@ -369,6 +370,56 @@ describe("TimelinePanel", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("enableReadReceiptsAndMarkersOnActivity", () => {
|
||||||
|
it.each([
|
||||||
|
{
|
||||||
|
enabled: false,
|
||||||
|
testName: "should not set up activity timers when disabled",
|
||||||
|
checkCall: (readReceiptTimer: Timer | null, readMarkerTimer: Timer | null) => {
|
||||||
|
expect(readReceiptTimer).toBeNull();
|
||||||
|
expect(readMarkerTimer).toBeNull();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: true,
|
||||||
|
testName: "should set up activity timers when enabled",
|
||||||
|
checkCall: (readReceiptTimer: Timer | null, readMarkerTimer: Timer | null) => {
|
||||||
|
expect(readReceiptTimer).toBeTruthy();
|
||||||
|
expect(readMarkerTimer).toBeTruthy();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])("$testName", async ({ enabled, checkCall }) => {
|
||||||
|
const room = mkRoom(client, "roomId");
|
||||||
|
const events = mockEvents(room);
|
||||||
|
const [, timelineSet] = mkTimeline(room, events);
|
||||||
|
|
||||||
|
let timelinePanel: TimelinePanel | null = null;
|
||||||
|
|
||||||
|
render(
|
||||||
|
<TimelinePanel
|
||||||
|
timelineSet={timelineSet}
|
||||||
|
manageReadMarkers={true}
|
||||||
|
manageReadReceipts={true}
|
||||||
|
enableReadReceiptsAndMarkersOnActivity={enabled}
|
||||||
|
ref={(ref) => {
|
||||||
|
timelinePanel = ref;
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
clientAndSDKContextRenderOptions(client, sdkContext),
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => expect(timelinePanel).toBeTruthy());
|
||||||
|
|
||||||
|
// Check if the activity timers were set up
|
||||||
|
// @ts-ignore - accessing private property for testing
|
||||||
|
const readReceiptTimer = timelinePanel!.readReceiptActivityTimer;
|
||||||
|
// @ts-ignore - accessing private property for testing
|
||||||
|
const readMarkerTimer = timelinePanel!.readMarkerActivityTimer;
|
||||||
|
|
||||||
|
checkCall(readReceiptTimer, readMarkerTimer);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("should scroll event into view when props.eventId changes", () => {
|
it("should scroll event into view when props.eventId changes", () => {
|
||||||
const client = MatrixClientPeg.safeGet();
|
const client = MatrixClientPeg.safeGet();
|
||||||
const room = mkRoom(client, "roomId");
|
const room = mkRoom(client, "roomId");
|
||||||
|
|||||||
@ -363,7 +363,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
|
|||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-label="Messages in this room are not end-to-end encrypted"
|
aria-label="Messages in this room are not end-to-end encrypted"
|
||||||
aria-labelledby="_r_jb_"
|
aria-labelledby="_r_o5_"
|
||||||
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
|
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
|
||||||
color="var(--cpd-color-icon-info-primary)"
|
color="var(--cpd-color-icon-info-primary)"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
@ -939,6 +939,7 @@ exports[`RoomView should hide the composer when hideComposer=true 1`] = `
|
|||||||
<DocumentFragment>
|
<DocumentFragment>
|
||||||
<div
|
<div
|
||||||
class="mx_RoomView"
|
class="mx_RoomView"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<canvas
|
<canvas
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -1127,6 +1128,7 @@ exports[`RoomView should hide the composer when hideComposer=true 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<main
|
<main
|
||||||
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
||||||
|
data-testid="timeline"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="mx_AutoHideScrollbar mx_ScrollPanel mx_RoomView_messagePanel"
|
class="mx_AutoHideScrollbar mx_ScrollPanel mx_RoomView_messagePanel"
|
||||||
@ -1166,6 +1168,7 @@ exports[`RoomView should hide the header when hideHeader=true 1`] = `
|
|||||||
<DocumentFragment>
|
<DocumentFragment>
|
||||||
<div
|
<div
|
||||||
class="mx_RoomView"
|
class="mx_RoomView"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<canvas
|
<canvas
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -1189,6 +1192,7 @@ exports[`RoomView should hide the header when hideHeader=true 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<main
|
<main
|
||||||
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
||||||
|
data-testid="timeline"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="mx_AutoHideScrollbar mx_ScrollPanel mx_RoomView_messagePanel"
|
class="mx_AutoHideScrollbar mx_ScrollPanel mx_RoomView_messagePanel"
|
||||||
@ -1435,6 +1439,7 @@ exports[`RoomView should hide the pinned message banner when hidePinnedMessageBa
|
|||||||
<DocumentFragment>
|
<DocumentFragment>
|
||||||
<div
|
<div
|
||||||
class="mx_RoomView"
|
class="mx_RoomView"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<canvas
|
<canvas
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -1623,6 +1628,7 @@ exports[`RoomView should hide the pinned message banner when hidePinnedMessageBa
|
|||||||
</div>
|
</div>
|
||||||
<main
|
<main
|
||||||
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
||||||
|
data-testid="timeline"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="mx_AutoHideScrollbar mx_ScrollPanel mx_RoomView_messagePanel"
|
class="mx_AutoHideScrollbar mx_ScrollPanel mx_RoomView_messagePanel"
|
||||||
@ -1869,6 +1875,7 @@ exports[`RoomView should hide the right panel when hideRightPanel=true 1`] = `
|
|||||||
<DocumentFragment>
|
<DocumentFragment>
|
||||||
<div
|
<div
|
||||||
class="mx_RoomView"
|
class="mx_RoomView"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<canvas
|
<canvas
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -2057,6 +2064,7 @@ exports[`RoomView should hide the right panel when hideRightPanel=true 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<main
|
<main
|
||||||
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
||||||
|
data-testid="timeline"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="mx_AutoHideScrollbar mx_ScrollPanel mx_RoomView_messagePanel"
|
class="mx_AutoHideScrollbar mx_ScrollPanel mx_RoomView_messagePanel"
|
||||||
@ -2303,6 +2311,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
<DocumentFragment>
|
<DocumentFragment>
|
||||||
<div
|
<div
|
||||||
class="mx_RoomView"
|
class="mx_RoomView"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<canvas
|
<canvas
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -2371,7 +2380,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
style="--cpd-icon-button-size: 100%;"
|
style="--cpd-icon-button-size: 100%;"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-labelledby="_r_ab_"
|
aria-labelledby="_r_f5_"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
height="1em"
|
height="1em"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@ -2398,7 +2407,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
style="--cpd-icon-button-size: 100%;"
|
style="--cpd-icon-button-size: 100%;"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-labelledby="_r_ag_"
|
aria-labelledby="_r_fa_"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
height="1em"
|
height="1em"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@ -2413,7 +2422,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-label="Threads"
|
aria-label="Threads"
|
||||||
aria-labelledby="_r_al_"
|
aria-labelledby="_r_ff_"
|
||||||
class="_icon-button_1pz9o_8"
|
class="_icon-button_1pz9o_8"
|
||||||
data-kind="primary"
|
data-kind="primary"
|
||||||
role="button"
|
role="button"
|
||||||
@ -2440,7 +2449,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-label="Room info"
|
aria-label="Room info"
|
||||||
aria-labelledby="_r_aq_"
|
aria-labelledby="_r_fk_"
|
||||||
class="_icon-button_1pz9o_8"
|
class="_icon-button_1pz9o_8"
|
||||||
data-kind="primary"
|
data-kind="primary"
|
||||||
role="button"
|
role="button"
|
||||||
@ -2470,7 +2479,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-label="0 members"
|
aria-label="0 members"
|
||||||
aria-labelledby="_r_av_"
|
aria-labelledby="_r_fp_"
|
||||||
class="mx_AccessibleButton mx_FacePile"
|
class="mx_AccessibleButton mx_FacePile"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@ -2491,6 +2500,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
</div>
|
</div>
|
||||||
<main
|
<main
|
||||||
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
||||||
|
data-testid="timeline"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
aria-label="Room status bar"
|
aria-label="Room status bar"
|
||||||
@ -2515,6 +2525,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
<DocumentFragment>
|
<DocumentFragment>
|
||||||
<div
|
<div
|
||||||
class="mx_RoomView"
|
class="mx_RoomView"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<canvas
|
<canvas
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -2583,7 +2594,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
style="--cpd-icon-button-size: 100%;"
|
style="--cpd-icon-button-size: 100%;"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-labelledby="_r_ab_"
|
aria-labelledby="_r_f5_"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
height="1em"
|
height="1em"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@ -2610,7 +2621,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
style="--cpd-icon-button-size: 100%;"
|
style="--cpd-icon-button-size: 100%;"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-labelledby="_r_ag_"
|
aria-labelledby="_r_fa_"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
height="1em"
|
height="1em"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@ -2625,7 +2636,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-label="Threads"
|
aria-label="Threads"
|
||||||
aria-labelledby="_r_al_"
|
aria-labelledby="_r_ff_"
|
||||||
class="_icon-button_1pz9o_8"
|
class="_icon-button_1pz9o_8"
|
||||||
data-kind="primary"
|
data-kind="primary"
|
||||||
role="button"
|
role="button"
|
||||||
@ -2652,7 +2663,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-label="Room info"
|
aria-label="Room info"
|
||||||
aria-labelledby="_r_aq_"
|
aria-labelledby="_r_fk_"
|
||||||
class="_icon-button_1pz9o_8"
|
class="_icon-button_1pz9o_8"
|
||||||
data-kind="primary"
|
data-kind="primary"
|
||||||
role="button"
|
role="button"
|
||||||
@ -2682,7 +2693,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-label="0 members"
|
aria-label="0 members"
|
||||||
aria-labelledby="_r_av_"
|
aria-labelledby="_r_fp_"
|
||||||
class="mx_AccessibleButton mx_FacePile"
|
class="mx_AccessibleButton mx_FacePile"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@ -2703,6 +2714,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
</div>
|
</div>
|
||||||
<main
|
<main
|
||||||
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
class="mx_RoomView_timeline mx_RoomView_timeline_rr_enabled"
|
||||||
|
data-testid="timeline"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="mx_AutoHideScrollbar mx_ScrollPanel mx_RoomView_messagePanel"
|
class="mx_AutoHideScrollbar mx_ScrollPanel mx_RoomView_messagePanel"
|
||||||
@ -2750,7 +2762,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
|||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-labelledby="_r_be_"
|
aria-labelledby="_r_g8_"
|
||||||
class="mx_E2EIcon mx_E2EIcon_verified mx_MessageComposer_e2eIcon"
|
class="mx_E2EIcon mx_E2EIcon_verified mx_MessageComposer_e2eIcon"
|
||||||
data-testid="e2e-icon"
|
data-testid="e2e-icon"
|
||||||
>
|
>
|
||||||
@ -2977,6 +2989,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
|||||||
<DocumentFragment>
|
<DocumentFragment>
|
||||||
<div
|
<div
|
||||||
class="mx_RoomView mx_RoomView_immersive"
|
class="mx_RoomView mx_RoomView_immersive"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<canvas
|
<canvas
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -3033,7 +3046,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-label="Chat"
|
aria-label="Chat"
|
||||||
aria-labelledby="_r_fd_"
|
aria-labelledby="_r_k7_"
|
||||||
class="_icon-button_1pz9o_8"
|
class="_icon-button_1pz9o_8"
|
||||||
data-kind="primary"
|
data-kind="primary"
|
||||||
role="button"
|
role="button"
|
||||||
@ -3060,7 +3073,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-label="Threads"
|
aria-label="Threads"
|
||||||
aria-labelledby="_r_fi_"
|
aria-labelledby="_r_kc_"
|
||||||
class="_icon-button_1pz9o_8"
|
class="_icon-button_1pz9o_8"
|
||||||
data-kind="primary"
|
data-kind="primary"
|
||||||
role="button"
|
role="button"
|
||||||
@ -3087,7 +3100,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-label="Room info"
|
aria-label="Room info"
|
||||||
aria-labelledby="_r_fn_"
|
aria-labelledby="_r_kh_"
|
||||||
class="_icon-button_1pz9o_8"
|
class="_icon-button_1pz9o_8"
|
||||||
data-kind="primary"
|
data-kind="primary"
|
||||||
role="button"
|
role="button"
|
||||||
@ -3117,7 +3130,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-label="0 members"
|
aria-label="0 members"
|
||||||
aria-labelledby="_r_fs_"
|
aria-labelledby="_r_km_"
|
||||||
class="mx_AccessibleButton mx_FacePile"
|
class="mx_AccessibleButton mx_FacePile"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@ -3191,7 +3204,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
aria-labelledby="_r_g5_"
|
aria-labelledby="_r_kv_"
|
||||||
class="_icon-button_1pz9o_8"
|
class="_icon-button_1pz9o_8"
|
||||||
data-kind="secondary"
|
data-kind="secondary"
|
||||||
data-testid="base-card-close-button"
|
data-testid="base-card-close-button"
|
||||||
@ -3251,7 +3264,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
|||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-label="Messages in this room are not end-to-end encrypted"
|
aria-label="Messages in this room are not end-to-end encrypted"
|
||||||
aria-labelledby="_r_ge_"
|
aria-labelledby="_r_l8_"
|
||||||
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
|
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
|
||||||
color="var(--cpd-color-icon-info-primary)"
|
color="var(--cpd-color-icon-info-primary)"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
|
|||||||
@ -1559,10 +1559,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@element-hq/element-call-embedded/-/element-call-embedded-0.16.1.tgz#28bdbde426051cc2a3228a36e7196e0a254569d3"
|
resolved "https://registry.yarnpkg.com/@element-hq/element-call-embedded/-/element-call-embedded-0.16.1.tgz#28bdbde426051cc2a3228a36e7196e0a254569d3"
|
||||||
integrity sha512-g3v/QFuNy8YVRGrKC5SxjIYvgBh6biOHgejhJT2Jk/yjOOUEuP0y2PBaADm+suPD9BB/Vk1jPxFk2uEIpEzhpA==
|
integrity sha512-g3v/QFuNy8YVRGrKC5SxjIYvgBh6biOHgejhJT2Jk/yjOOUEuP0y2PBaADm+suPD9BB/Vk1jPxFk2uEIpEzhpA==
|
||||||
|
|
||||||
"@element-hq/element-web-module-api@1.8.0":
|
"@element-hq/element-web-module-api@1.9.0", "@element-hq/element-web-module-api@^1.8.0":
|
||||||
version "1.8.0"
|
version "1.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/@element-hq/element-web-module-api/-/element-web-module-api-1.8.0.tgz#95aa4ec22609cf0f4a7f24274473af0645a16f2a"
|
resolved "https://registry.yarnpkg.com/@element-hq/element-web-module-api/-/element-web-module-api-1.9.0.tgz#2e4fcc8809418c8670d4f0576bc4a9a235bc6c50"
|
||||||
integrity sha512-lMiDA9ubP3mZZupIMT8T3wS0riX30rYZj3pFpdP4cfZhkWZa3FJFStokAy5OnaHyENC7Px1cqkBGqilOWewY/A==
|
integrity sha512-Ao/V9w+wysZK4bh61LlKlznF10n2ZbD6KcUI46/zUMttXbmJn3ahvbzhEpwYcD+Cjy3ag5ycxLIIGkKV/fncXg==
|
||||||
|
|
||||||
"@element-hq/element-web-playwright-common@^2.0.0":
|
"@element-hq/element-web-playwright-common@^2.0.0":
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user