Remove NoOneHere disabled reason. (#30524)

* Remove NoOneHere disabled reason.
This was used to prohibit starting calls if the user is alone in the room.
Since there are currently issues with the user count calculation this can disable the button even when not appropriate.

On top of that, there is a reason to start a call if the room was just created and the user is still waiting for the others to join the room to then join the call.

Signed-off-by: Timo K <toger5@hotmail.de>

* some ci fixes

Signed-off-by: Timo K <toger5@hotmail.de>

* fix test snapshots

Signed-off-by: Timo K <toger5@hotmail.de>

* fix test to expect enabled call buttons

* Update snapshot for unit-tests/components/views/rooms/RoomHeader/RoomHeader-test.tsx

---------

Signed-off-by: Timo K <toger5@hotmail.de>
Co-authored-by: fkwp <github-fkwp@w4ve.de>
This commit is contained in:
Timo
2025-08-12 10:07:59 +00:00
committed by GitHub
co-authored by fkwp
parent 76be5ccc9e
commit 789dba7b3d
6 changed files with 24 additions and 114 deletions
@@ -1449,8 +1449,8 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</div>
</button>
<button
aria-disabled="true"
aria-label="There's no one here to call"
aria-disabled="false"
aria-label="Video call"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1459,7 +1459,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%; --cpd-color-icon-tertiary: var(--cpd-color-icon-disabled);"
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="«r2c»"
@@ -1476,8 +1476,8 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</div>
</button>
<button
aria-disabled="true"
aria-label="There's no one here to call"
aria-disabled="false"
aria-label="Voice call"
aria-labelledby="«r2h»"
class="_icon-button_1pz9o_8"
data-kind="primary"
@@ -1487,7 +1487,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%; --cpd-color-icon-tertiary: var(--cpd-color-icon-disabled);"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
@@ -1661,8 +1661,8 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</div>
</button>
<button
aria-disabled="true"
aria-label="There's no one here to call"
aria-disabled="false"
aria-label="Video call"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1671,7 +1671,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%; --cpd-color-icon-tertiary: var(--cpd-color-icon-disabled);"
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="«r2c»"
@@ -1688,8 +1688,8 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</div>
</button>
<button
aria-disabled="true"
aria-label="There's no one here to call"
aria-disabled="false"
aria-label="Voice call"
aria-labelledby="«r2h»"
class="_icon-button_1pz9o_8"
data-kind="primary"
@@ -1699,7 +1699,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%; --cpd-color-icon-tertiary: var(--cpd-color-icon-disabled);"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
@@ -26,7 +26,6 @@ import {
getAllByLabelText,
getByLabelText,
getByText,
queryAllByLabelText,
queryByLabelText,
render,
type RenderOptions,
@@ -327,14 +326,6 @@ describe("RoomHeader", () => {
SdkConfig.reset();
});
it("you can't call if you're alone", () => {
mockRoomMembers(room, 1);
const { container } = render(<RoomHeader room={room} />, getWrapper());
for (const button of getAllByLabelText(container, "There's no one here to call")) {
expect(button).toHaveAttribute("aria-disabled", "true");
}
});
it("you can call when you're two in the room", async () => {
const user = userEvent.setup();
mockRoomMembers(room, 2);
@@ -489,71 +480,6 @@ describe("RoomHeader", () => {
}
});
it("can't call if you have no friends and cannot invite friends", () => {
mockRoomMembers(room, 1);
const { container } = render(<RoomHeader room={room} />, getWrapper());
for (const button of getAllByLabelText(container, "There's no one here to call")) {
expect(button).toHaveAttribute("aria-disabled", "true");
}
});
it("can call if you have no friends but can invite friends", () => {
mockRoomMembers(room, 1);
// go through all the different `canInvite` and `getJoinRule` combinations
// check where we can't do anything but can upgrade
jest.spyOn(room.currentState, "maySendStateEvent").mockReturnValue(true);
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Invite);
jest.spyOn(room, "canInvite").mockReturnValue(false);
SdkConfig.add({
element_call: {
guest_spa_url: "https://guest_spa_url.com",
},
});
const { container: containerNoInviteNotPublicCanUpgradeAccess } = render(
<RoomHeader room={room} />,
getWrapper(),
);
expect(
queryAllByLabelText(containerNoInviteNotPublicCanUpgradeAccess, "There's no one here to call"),
).toHaveLength(0);
// dont allow upgrading anymore and go through the other combinations
jest.spyOn(room.currentState, "maySendStateEvent").mockReturnValue(false);
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Invite);
jest.spyOn(room, "canInvite").mockReturnValue(false);
SdkConfig.add({
element_call: {
guest_spa_url: "https://guest_spa_url.com",
},
});
const { container: containerNoInviteNotPublic } = render(<RoomHeader room={room} />, getWrapper());
expect(queryAllByLabelText(containerNoInviteNotPublic, "There's no one here to call")).toHaveLength(2);
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Knock);
jest.spyOn(room, "canInvite").mockReturnValue(false);
const { container: containerNoInvitePublic } = render(<RoomHeader room={room} />, getWrapper());
expect(queryAllByLabelText(containerNoInvitePublic, "There's no one here to call")).toHaveLength(2);
jest.spyOn(room, "canInvite").mockReturnValue(true);
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Invite);
const { container: containerInviteNotPublic } = render(<RoomHeader room={room} />, getWrapper());
expect(queryAllByLabelText(containerInviteNotPublic, "There's no one here to call")).toHaveLength(2);
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Knock);
jest.spyOn(room, "canInvite").mockReturnValue(true);
const { container: containerInvitePublic } = render(<RoomHeader room={room} />, getWrapper());
expect(queryAllByLabelText(containerInvitePublic, "There's no one here to call")).toHaveLength(0);
// Clear guest_spa_url
SdkConfig.reset();
// last we can allow everything but without guest_spa_url nothing will work
const { container: containerAllAllowedButNoGuestSpaUrl } = render(<RoomHeader room={room} />, getWrapper());
expect(
queryAllByLabelText(containerAllAllowedButNoGuestSpaUrl, "There's no one here to call"),
).toHaveLength(2);
});
it("calls using legacy or jitsi", async () => {
const user = userEvent.setup();
mockRoomMembers(room, 2);
@@ -43,8 +43,8 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
</div>
</button>
<button
aria-disabled="true"
aria-label="There's no one here to call"
aria-disabled="false"
aria-label="Video call"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -53,10 +53,10 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%; --cpd-color-icon-tertiary: var(--cpd-color-icon-disabled);"
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="«r1do»"
aria-labelledby="«r14k»"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -70,9 +70,9 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
</div>
</button>
<button
aria-disabled="true"
aria-label="There's no one here to call"
aria-labelledby="«r1dt»"
aria-disabled="false"
aria-label="Voice call"
aria-labelledby="«r14p»"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -81,7 +81,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%; --cpd-color-icon-tertiary: var(--cpd-color-icon-disabled);"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
@@ -98,7 +98,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
</button>
<button
aria-label="Threads"
aria-labelledby="«r1e2»"
aria-labelledby="«r14u»"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -125,7 +125,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
</button>
<button
aria-label="Room info"
aria-labelledby="«r1e7»"
aria-labelledby="«r153»"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"