Remove release announcement on thread activity centre (#29892)

* Remove release announcement on thread activity centre

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2025-05-07 14:26:32 +01:00 committed by GitHub
parent d553be6316
commit e427b71040
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 102 additions and 236 deletions

View File

@ -15,20 +15,34 @@ test.describe("Release announcement", () => {
feature_release_announcement: true,
},
},
labsFlags: ["threadsActivityCentre"],
room: async ({ app, user }, use) => {
const roomId = await app.client.createRoom({
name: "Test room",
});
await app.viewRoomById(roomId);
await use({ roomId });
},
});
test("should display the release announcement process", { tag: "@screenshot" }, async ({ page, app, util }) => {
// The TAC release announcement should be displayed
await util.assertReleaseAnnouncementIsVisible("Threads Activity Centre");
// Hide the release announcement
await util.markReleaseAnnouncementAsRead("Threads Activity Centre");
await util.assertReleaseAnnouncementIsNotVisible("Threads Activity Centre");
test(
"should display the pinned messages release announcement",
{ tag: "@screenshot" },
async ({ page, app, room, util }) => {
await app.toggleRoomInfoPanel();
await page.reload();
// Wait for EW to load
await expect(page.getByRole("navigation", { name: "Spaces" })).toBeVisible();
// Check that once the release announcement has been marked as viewed, it does not appear again
await util.assertReleaseAnnouncementIsNotVisible("Threads Activity Centre");
});
const name = "All new pinned messages";
// The release announcement should be displayed
await util.assertReleaseAnnouncementIsVisible(name);
// Hide the release announcement
await util.markReleaseAnnouncementAsRead(name);
await util.assertReleaseAnnouncementIsNotVisible(name);
await page.reload();
await app.toggleRoomInfoPanel();
await expect(page.getByRole("menuitem", { name: "Pinned messages" })).toBeVisible();
// Check that once the release announcement has been marked as viewed, it does not appear again
await util.assertReleaseAnnouncementIsNotVisible(name);
},
);
});

View File

@ -19,7 +19,6 @@ test.describe("Threads Activity Centre", { tag: "@no-firefox" }, () => {
test.use({
displayName: "Alice",
botCreateOpts: { displayName: "Other User" },
labsFlags: ["threadsActivityCentre"],
});
test(

View File

@ -24,10 +24,7 @@ import { type NotificationLevel } from "../../../../stores/notifications/Notific
import PosthogTrackers from "../../../../PosthogTrackers";
import { getKeyBindingsManager } from "../../../../KeyBindingsManager";
import { KeyBindingAction } from "../../../../accessibility/KeyboardShortcuts";
import { ReleaseAnnouncement } from "../../../structures/ReleaseAnnouncement";
import { useIsReleaseAnnouncementOpen } from "../../../../hooks/useIsReleaseAnnouncementOpen";
import { useSettingValue } from "../../../../hooks/useSettings";
import { ReleaseAnnouncementStore } from "../../../../stores/ReleaseAnnouncementStore";
interface ThreadsActivityCentreProps {
/**
@ -43,7 +40,6 @@ interface ThreadsActivityCentreProps {
export function ThreadsActivityCentre({ displayButtonLabel }: ThreadsActivityCentreProps): JSX.Element {
const [open, setOpen] = useState(false);
const roomsAndNotifications = useUnreadThreadRooms(open);
const isReleaseAnnouncementOpen = useIsReleaseAnnouncementOpen("threadsActivityCentre");
const settingTACOnlyNotifs = useSettingValue("Notifications.tac_only_notifications");
const emptyCaption = settingTACOnlyNotifs
@ -65,59 +61,39 @@ export function ThreadsActivityCentre({ displayButtonLabel }: ThreadsActivityCen
}
}}
>
{isReleaseAnnouncementOpen ? (
<ReleaseAnnouncement
feature="threadsActivityCentre"
header={_t("threads_activity_centre|release_announcement_header")}
description={_t("threads_activity_centre|release_announcement_description")}
closeLabel={_t("action|ok")}
>
<Menu
align="start"
side="top"
open={open}
onOpenChange={(newOpen) => {
// Track only when the Threads Activity Centre is opened
if (newOpen) PosthogTrackers.trackInteraction("WebThreadsActivityCentreButton");
setOpen(newOpen);
}}
title={_t("threads_activity_centre|header")}
trigger={
<ThreadsActivityCentreButton
disableTooltip={true}
displayLabel={displayButtonLabel}
notificationLevel={roomsAndNotifications.greatestNotificationLevel}
onClick={async () => {
// Open the TAC after the release announcement closing
setOpen(true);
await ReleaseAnnouncementStore.instance.nextReleaseAnnouncement();
}}
/>
</ReleaseAnnouncement>
) : (
<Menu
align="start"
side="top"
open={open}
onOpenChange={(newOpen) => {
// Track only when the Threads Activity Centre is opened
if (newOpen) PosthogTrackers.trackInteraction("WebThreadsActivityCentreButton");
setOpen(newOpen);
}}
title={_t("threads_activity_centre|header")}
trigger={
<ThreadsActivityCentreButton
displayLabel={displayButtonLabel}
notificationLevel={roomsAndNotifications.greatestNotificationLevel}
}
>
{/* Make the content of the pop-up scrollable */}
<div className="mx_ThreadsActivityCentre_rows">
{roomsAndNotifications.rooms.map(({ room, notificationLevel }) => (
<ThreadsActivityCentreRow
key={room.roomId}
room={room}
notificationLevel={notificationLevel}
onClick={() => setOpen(false)}
/>
}
>
{/* Make the content of the pop-up scrollable */}
<div className="mx_ThreadsActivityCentre_rows">
{roomsAndNotifications.rooms.map(({ room, notificationLevel }) => (
<ThreadsActivityCentreRow
key={room.roomId}
room={room}
notificationLevel={notificationLevel}
onClick={() => setOpen(false)}
/>
))}
{roomsAndNotifications.rooms.length === 0 && (
<div className="mx_ThreadsActivityCentre_emptyCaption">{emptyCaption}</div>
)}
</div>
</Menu>
)}
))}
{roomsAndNotifications.rooms.length === 0 && (
<div className="mx_ThreadsActivityCentre_emptyCaption">{emptyCaption}</div>
)}
</div>
</Menu>
</div>
);
}

View File

@ -3292,9 +3292,7 @@
"threads_activity_centre": {
"header": "Threads activity",
"no_rooms_with_threads_notifs": "You don't have rooms with thread notifications yet.",
"no_rooms_with_unread_threads": "You don't have rooms with unread threads yet.",
"release_announcement_description": "Threads notifications have moved, find them here from now on.",
"release_announcement_header": "Threads Activity Centre"
"no_rooms_with_unread_threads": "You don't have rooms with unread threads yet."
},
"time": {
"about_day_ago": "about a day ago",

View File

@ -17,7 +17,7 @@ import { Features } from "../settings/Settings";
/**
* The features are shown in the array order.
*/
const FEATURES = ["threadsActivityCentre", "pinningMessageList"] as const;
const FEATURES = ["pinningMessageList"] as const;
/**
* All the features that can be shown in the release announcements.
*/

View File

@ -23,7 +23,7 @@ describe("ReleaseAnnouncement", () => {
function renderReleaseAnnouncement() {
return render(
<ReleaseAnnouncement
feature="threadsActivityCentre"
feature="pinningMessageList"
header="header"
description="description"
closeLabel="close"

View File

@ -31,6 +31,8 @@ import { tagRoom } from "../../../../../src/utils/room/tagRoom";
import { DefaultTagID } from "../../../../../src/stores/room-list/models";
import { Action } from "../../../../../src/dispatcher/actions";
import { ReportRoomDialog } from "../../../../../src/components/views/dialogs/ReportRoomDialog.tsx";
import SettingsStore from "../../../../../src/settings/SettingsStore.ts";
import { SettingLevel } from "../../../../../src/settings/SettingLevel.ts";
jest.mock("../../../../../src/utils/room/tagRoom");
@ -78,6 +80,8 @@ describe("<RoomSummaryCard />", () => {
jest.clearAllMocks();
DMRoomMap.makeShared(mockClient);
SettingsStore.setValue("releaseAnnouncementData", null, SettingLevel.DEVICE, { pinningMessageList: true });
mockClient.getRoom.mockReturnValue(room);
jest.spyOn(room, "isElementVideoRoom").mockRestore();
jest.spyOn(room, "isCallRoom").mockRestore();

View File

@ -8,7 +8,6 @@ exports[`<SpacePanel /> should show all activated MetaSpaces in the correct orde
>
<div
class="mx_UserMenu"
data-floating-ui-inert=""
>
<div
aria-expanded="false"
@ -43,7 +42,6 @@ exports[`<SpacePanel /> should show all activated MetaSpaces in the correct orde
<ul
aria-label="Spaces"
class="mx_AutoHideScrollbar mx_SpaceTreeLevel"
data-floating-ui-inert=""
data-rbd-droppable-context-id="0"
data-rbd-droppable-id="top-level-spaces"
role="tree"
@ -231,17 +229,18 @@ exports[`<SpacePanel /> should show all activated MetaSpaces in the correct orde
class="mx_ThreadsActivityCentre_container"
>
<button
aria-controls="«r12»"
aria-describedby="«r12»"
aria-expanded="true"
aria-haspopup="dialog"
aria-disabled="false"
aria-expanded="false"
aria-haspopup="menu"
aria-label="Threads"
aria-labelledby="«r14»"
aria-labelledby="«r12»"
class="_icon-button_m2erp_8 mx_ThreadsActivityCentreButton"
data-floating-ui-inert=""
data-state="closed"
id="radix-«r10»"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_zr2a0_17"
@ -261,37 +260,11 @@ exports[`<SpacePanel /> should show all activated MetaSpaces in the correct orde
</svg>
</div>
</button>
<span
aria-hidden="true"
data-floating-ui-inert=""
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
tabindex="-1"
/>
<span
data-floating-ui-focus-guard=""
data-type="outside"
role="button"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
tabindex="0"
/>
<span
aria-owns="«r19»"
data-floating-ui-inert=""
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
/>
<span
data-floating-ui-focus-guard=""
data-type="outside"
role="button"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
tabindex="0"
/>
</div>
<div
aria-expanded="false"
aria-label="Quick settings"
class="mx_AccessibleButton mx_QuickSettingsButton"
data-floating-ui-inert=""
role="button"
tabindex="0"
/>

View File

@ -2,7 +2,7 @@
exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] = `
<div
aria-labelledby="radix-«r33»"
aria-labelledby="radix-«r2f»"
aria-orientation="vertical"
class="_menu_19sse_8"
data-align="start"
@ -11,14 +11,14 @@ exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] =
data-side="top"
data-state="open"
dir="ltr"
id="radix-«r34»"
id="radix-«r2g»"
role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;"
tabindex="-1"
>
<h3
class="_typography_6v6n8_153 _font-body-sm-semibold_6v6n8_36 _menu-title_1sgvx_8 _title_19sse_74"
id="«r3b»"
id="«r2n»"
>
Threads activity
</h3>
@ -145,15 +145,15 @@ exports[`ThreadsActivityCentre should close the release announcement when the TA
class="mx_ThreadsActivityCentre_container"
>
<button
aria-controls="radix-«r1d»"
aria-controls="radix-«rp»"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="Threads"
aria-labelledby="«r1e»"
aria-labelledby="«rq»"
class="_icon-button_m2erp_8 mx_ThreadsActivityCentreButton"
data-state="open"
id="radix-«r1c»"
id="radix-«ro»"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
@ -183,7 +183,7 @@ exports[`ThreadsActivityCentre should close the release announcement when the TA
aria-hidden="true"
data-aria-hidden="true"
data-floating-ui-portal=""
id="«r1i»"
id="«ru»"
>
<div
class="_tooltip_6ode6_8 _invisible_6ode6_21"
@ -204,7 +204,7 @@ exports[`ThreadsActivityCentre should close the release announcement when the TA
stroke="none"
/>
<clippath
id="«r1j»"
id="«rv»"
>
<rect
height="10"
@ -215,7 +215,7 @@ exports[`ThreadsActivityCentre should close the release announcement when the TA
</clippath>
</svg>
<span
id="«r1e»"
id="«rq»"
>
Threads
</span>
@ -227,7 +227,7 @@ exports[`ThreadsActivityCentre should close the release announcement when the TA
style="position: fixed; left: 0px; top: 0px; transform: translate(0px, -8px); min-width: max-content; --radix-popper-transform-origin: 0% 0px; --radix-popper-available-width: 0px; --radix-popper-available-height: -8px; --radix-popper-anchor-width: 0px; --radix-popper-anchor-height: 0px;"
>
<div
aria-labelledby="radix-«r1c»"
aria-labelledby="radix-«ro»"
aria-orientation="vertical"
class="_menu_19sse_8"
data-align="start"
@ -236,14 +236,14 @@ exports[`ThreadsActivityCentre should close the release announcement when the TA
data-side="top"
data-state="open"
dir="ltr"
id="radix-«r1d»"
id="radix-«rp»"
role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;"
tabindex="-1"
>
<h3
class="_typography_6v6n8_153 _font-body-sm-semibold_6v6n8_36 _menu-title_1sgvx_8 _title_19sse_74"
id="«r1k»"
id="«r10»"
>
Threads activity
</h3>
@ -270,7 +270,7 @@ exports[`ThreadsActivityCentre should close the release announcement when the TA
exports[`ThreadsActivityCentre should match snapshot when empty 1`] = `
<div
aria-labelledby="radix-«r3n»"
aria-labelledby="radix-«r33»"
aria-orientation="vertical"
class="_menu_19sse_8"
data-align="start"
@ -279,14 +279,14 @@ exports[`ThreadsActivityCentre should match snapshot when empty 1`] = `
data-side="top"
data-state="open"
dir="ltr"
id="radix-«r3o»"
id="radix-«r34»"
role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;"
tabindex="-1"
>
<h3
class="_typography_6v6n8_153 _font-body-sm-semibold_6v6n8_36 _menu-title_1sgvx_8 _title_19sse_74"
id="«r3v»"
id="«r3b»"
>
Threads activity
</h3>
@ -304,7 +304,7 @@ exports[`ThreadsActivityCentre should match snapshot when empty 1`] = `
exports[`ThreadsActivityCentre should order the room with the same notification level by most recent 1`] = `
<div
aria-labelledby="radix-«r40»"
aria-labelledby="radix-«r3c»"
aria-orientation="vertical"
class="_menu_19sse_8"
data-align="start"
@ -313,14 +313,14 @@ exports[`ThreadsActivityCentre should order the room with the same notification
data-side="top"
data-state="open"
dir="ltr"
id="radix-«r41»"
id="radix-«r3d»"
role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;"
tabindex="-1"
>
<h3
class="_typography_6v6n8_153 _font-body-sm-semibold_6v6n8_36 _menu-title_1sgvx_8 _title_19sse_74"
id="«r48»"
id="«r3k»"
>
Threads activity
</h3>
@ -482,17 +482,18 @@ exports[`ThreadsActivityCentre should render the release announcement 1`] = `
class="mx_ThreadsActivityCentre_container"
>
<button
aria-controls="«ra»"
aria-describedby="«ra»"
aria-expanded="true"
aria-haspopup="dialog"
aria-disabled="false"
aria-expanded="false"
aria-haspopup="menu"
aria-label="Threads"
aria-labelledby="«rc»"
aria-labelledby="«ra»"
class="_icon-button_m2erp_8 mx_ThreadsActivityCentreButton"
data-floating-ui-inert=""
data-state="closed"
id="radix-«r8»"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_zr2a0_17"
@ -512,37 +513,11 @@ exports[`ThreadsActivityCentre should render the release announcement 1`] = `
</svg>
</div>
</button>
<span
aria-hidden="true"
data-floating-ui-inert=""
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
tabindex="-1"
/>
<span
data-floating-ui-focus-guard=""
data-type="outside"
role="button"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
tabindex="0"
/>
<span
aria-owns="«rh»"
data-floating-ui-inert=""
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
/>
<span
data-floating-ui-focus-guard=""
data-type="outside"
role="button"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
tabindex="0"
/>
</div>
</div>
<div
data-floating-ui-inert=""
data-floating-ui-portal=""
id="«rg»"
id="«re»"
>
<div
class="_tooltip_6ode6_8 _invisible_6ode6_21"
@ -563,7 +538,7 @@ exports[`ThreadsActivityCentre should render the release announcement 1`] = `
stroke="none"
/>
<clippath
id="«ri»"
id="«rf»"
>
<rect
height="10"
@ -574,85 +549,11 @@ exports[`ThreadsActivityCentre should render the release announcement 1`] = `
</clippath>
</svg>
<span
id="«rc»"
id="«ra»"
>
Threads
</span>
</div>
</div>
<div
data-floating-ui-portal=""
id="«rh»"
>
<span
data-floating-ui-focus-guard=""
data-type="inside"
role="button"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
tabindex="0"
/>
<div
aria-describedby="«r9»"
aria-labelledby="«r8»"
class="_content_3xq91_8"
data-floating-ui-focusable=""
id="«ra»"
role="dialog"
style="position: absolute; left: 0px; top: 0px; transform: translate(0px, 0px);"
tabindex="-1"
>
<svg
aria-hidden="true"
class="_arrow_3xq91_53"
height="20"
style="position: absolute; pointer-events: none; right: calc(100% - 0px); transform: rotate(90deg);"
viewBox="0 0 20 20"
width="20"
>
<path
d="M0,0 H20 L10,12 Q10,12 10,12 Z"
stroke="none"
/>
<clippath
id="«rj»"
>
<rect
height="20"
width="20"
x="0"
y="0"
/>
</clippath>
</svg>
<h3
class="_typography_6v6n8_153 _font-body-lg-semibold_6v6n8_74 _header_3xq91_37"
id="«r8»"
>
Threads Activity Centre
</h3>
<span
class="_typography_6v6n8_153 _font-body-sm-regular_6v6n8_31 _description_3xq91_43"
id="«r9»"
>
Threads notifications have moved, find them here from now on.
</span>
<button
class="_button_vczzf_8 _button_3xq91_48"
data-kind="secondary"
data-size="sm"
role="button"
tabindex="0"
>
OK
</button>
</div>
<span
data-floating-ui-focus-guard=""
data-type="inside"
role="button"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
tabindex="0"
/>
</div>
</body>
`;

View File

@ -85,7 +85,8 @@ describe("ReleaseAnnouncementStore", () => {
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBeNull();
});
it("should return the next feature when the next release announcement is called", async () => {
// We only have a single release announcement currently
it.skip("should return the next feature when the next release announcement is called", async () => {
// Sanity check
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBe("threadsActivityCentre");
@ -109,12 +110,12 @@ describe("ReleaseAnnouncementStore", () => {
it("should listen to release announcement data changes in the store", async () => {
const secondStore = new ReleaseAnnouncementStore();
expect(secondStore.getReleaseAnnouncement()).toBe("threadsActivityCentre");
expect(secondStore.getReleaseAnnouncement()).toBe("pinningMessageList");
const promise = listenReleaseAnnouncementChanged();
await secondStore.nextReleaseAnnouncement();
expect(await promise).toBe("pinningMessageList");
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBe("pinningMessageList");
expect(await promise).toBe(null);
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBe(null);
});
});