Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TAC: Release Announcement #12380

Merged
merged 27 commits into from Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
17b5ebe
WIP
florianduros Mar 27, 2024
3ad73e0
Store the release announcements in the account settings
florianduros Mar 28, 2024
75e285c
Update TAC release announcement description
florianduros Mar 28, 2024
76f2a23
Fix settings content comparison
florianduros Mar 28, 2024
caeccb8
Add logging in case of failure
florianduros Mar 28, 2024
3a0d26e
Watch settings changes
florianduros Mar 29, 2024
3cb4220
I add release announcement settings to disable it
florianduros Apr 2, 2024
d8a90ef
Disable release announcement in e2e test
florianduros Apr 2, 2024
ef3ab01
Add release announcement in e2e test
florianduros Apr 2, 2024
ac2156d
Add tests for ReleaseAnnouncementStore.ts
florianduros Apr 3, 2024
a27a95c
Merge branch 'develop' into florianduros/tac/release-announcement
florianduros Apr 3, 2024
c171692
Update compound-web to `3.3.0`
florianduros Apr 3, 2024
009929c
Update TAC tests
florianduros Apr 3, 2024
c06f913
Update Labs tests
florianduros Apr 3, 2024
9ff18d5
Nits
florianduros Apr 3, 2024
f21f541
Add test for ReleaseAnnouncement.tsx
florianduros Apr 3, 2024
5ecabcd
Update `@vector-im/compound-web`
florianduros Apr 4, 2024
4866fd1
Merge branch 'develop' into florianduros/tac/release-announcement
florianduros Apr 4, 2024
c50a415
Add playwright snapshot
florianduros Apr 4, 2024
53be22c
Delete false playwright screenshot
florianduros Apr 4, 2024
2f24cc9
Wait for EW to be displayed after reload
florianduros Apr 4, 2024
0309486
Add screenshot
MidhunSureshR Apr 4, 2024
7953ce0
Clean util file
florianduros Apr 4, 2024
0465e5c
Renaming and comments fixing
florianduros Apr 5, 2024
fc8d80d
Use second store instead of looking in the store.
florianduros Apr 5, 2024
568cb07
Merge branch 'develop' into florianduros/tac/release-announcement
florianduros Apr 5, 2024
8c515e8
Merge branch 'develop' into florianduros/tac/release-announcement
florianduros Apr 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -76,7 +76,7 @@
"@sentry/browser": "^7.0.0",
"@testing-library/react-hooks": "^8.0.1",
"@vector-im/compound-design-tokens": "^1.2.0",
"@vector-im/compound-web": "^3.1.1",
"@vector-im/compound-web": "^3.3.1",
"@zxcvbn-ts/core": "^3.0.4",
"@zxcvbn-ts/language-common": "^3.0.4",
"@zxcvbn-ts/language-en": "^3.0.2",
Expand Down
77 changes: 77 additions & 0 deletions playwright/e2e/release-announcement/index.ts
@@ -0,0 +1,77 @@
/*
*
* Copyright 2024 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* /
*/

import { Page } from "@playwright/test";

import { test as base, expect } from "../../element-web-test";

/**
* Set up for release announcement tests.
*/
export const test = base.extend<{
util: Helpers;
}>({
displayName: "Alice",
botCreateOpts: { displayName: "Other User" },

util: async ({ page, app, bot }, use) => {
await use(new Helpers(page));
},
});

export class Helpers {
constructor(private page: Page) {}

/**
* Get the release announcement with the given name.
* @param name
* @private
*/
private getReleaseAnnouncement(name: string) {
return this.page.getByRole("dialog", { name });
}

/**
* Assert that the release announcement with the given name is visible.
* @param name
*/
async assertReleaseAnnouncementIsVisible(name: string) {
await expect(this.getReleaseAnnouncement(name)).toBeVisible();
await expect(this.page).toMatchScreenshot(`release-announcement-${name}.png`);
}

/**
* Assert that the release announcement with the given name is not visible.
* @param name
*/
assertReleaseAnnouncementIsNotVisible(name: string) {
return expect(this.getReleaseAnnouncement(name)).not.toBeVisible();
}

/**
* Mark the release announcement with the given name as read.
* If the release announcement is not visible, this will throw an error.
* @param name
*/
async markReleaseAnnouncementAsRead(name: string) {
const dialog = this.getReleaseAnnouncement(name);
await dialog.getByRole("button", { name: "Ok" }).click();
}
}

export { expect };
44 changes: 44 additions & 0 deletions playwright/e2e/release-announcement/releaseAnnouncement.spec.ts
@@ -0,0 +1,44 @@
/*
*
* Copyright 2024 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* /
*/

import { test, expect } from "./";

test.describe("Release announcement", () => {
test.use({
config: {
features: {
feature_release_announcement: true,
},
},
labsFlags: ["threadsActivityCentre"],
});

test("should display the release announcement process", 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");

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");
});
});
5 changes: 5 additions & 0 deletions playwright/element-web-test.ts
Expand Up @@ -52,6 +52,11 @@ const CONFIG_JSON: Partial<IConfigOptions> = {

// the location tests want a map style url.
map_style_url: "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx",

features: {
// We don't want to go through the feature announcement during the e2e test
feature_release_announcement: false,
},
};

export type TestOptions = {
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions src/components/structures/ReleaseAnnouncement.tsx
@@ -0,0 +1,54 @@
/*
*
* Copyright 2024 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* /
*/

import React, { ComponentProps, JSX, PropsWithChildren } from "react";
import { ReleaseAnnouncement as ReleaseAnnouncementCompound } from "@vector-im/compound-web";

import { ReleaseAnnouncementStore, Feature } from "../../stores/ReleaseAnnouncementStore";
import { useIsReleaseAnnouncementOpen } from "../../hooks/useIsReleaseAnnouncementOpen";

interface ReleaseAnnouncementProps
extends Omit<ComponentProps<typeof ReleaseAnnouncementCompound>, "open" | "onClick"> {
feature: Feature;
}

/**
* Display a release announcement component around the children
* Wrapper gluing the release announcement compound and the ReleaseAnnouncementStore
* @param feature - the feature to announce, should be listed in {@link Feature}
* @param children
* @param props
* @constructor
*/
export function ReleaseAnnouncement({
feature,
children,
...props
}: PropsWithChildren<ReleaseAnnouncementProps>): JSX.Element {
const enabled = useIsReleaseAnnouncementOpen(feature);

return (
<ReleaseAnnouncementCompound
open={enabled}
onClick={() => ReleaseAnnouncementStore.instance.nextReleaseAnnouncement()}
{...props}
>
{children}
</ReleaseAnnouncementCompound>
);
}
Expand Up @@ -34,6 +34,8 @@ import { NotificationLevel } from "../../../../stores/notifications/Notification
import PosthogTrackers from "../../../../PosthogTrackers";
import { getKeyBindingsManager } from "../../../../KeyBindingsManager";
import { KeyBindingAction } from "../../../../accessibility/KeyboardShortcuts";
import { ReleaseAnnouncement } from "../../../structures/ReleaseAnnouncement";
import { useIsReleaseAnnouncementOpen } from "../../../../hooks/useIsReleaseAnnouncementOpen";

interface ThreadsActivityCentreProps {
/**
Expand All @@ -49,6 +51,7 @@ interface ThreadsActivityCentreProps {
export function ThreadsActivityCentre({ displayButtonLabel }: ThreadsActivityCentreProps): JSX.Element {
const [open, setOpen] = useState(false);
const roomsAndNotifications = useUnreadThreadRooms(open);
const isReleaseAnnouncementOpen = useIsReleaseAnnouncementOpen("threadsActivityCentre");

return (
<div
Expand All @@ -65,41 +68,55 @@ export function ThreadsActivityCentre({ displayButtonLabel }: ThreadsActivityCen
}
}}
>
<Menu
align="end"
open={open}
onOpenChange={(newOpen) => {
// Track only when the Threads Activity Centre is opened
if (newOpen) PosthogTrackers.trackInteraction("WebThreadsActivityCentreButton");

setOpen(newOpen);
}}
side="right"
title={_t("threads_activity_centre|header")}
trigger={
{isReleaseAnnouncementOpen ? (
<ReleaseAnnouncement
feature="threadsActivityCentre"
header={_t("threads_activity_centre|release_announcement_header")}
description={_t("threads_activity_centre|release_announcement_description")}
closeLabel={_t("action|ok")}
>
<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)}
</ReleaseAnnouncement>
) : (
<Menu
align="end"
open={open}
onOpenChange={(newOpen) => {
// Track only when the Threads Activity Centre is opened
if (newOpen) PosthogTrackers.trackInteraction("WebThreadsActivityCentreButton");

setOpen(newOpen);
}}
side="right"
title={_t("threads_activity_centre|header")}
trigger={
<ThreadsActivityCentreButton
displayLabel={displayButtonLabel}
notificationLevel={roomsAndNotifications.greatestNotificationLevel}
/>
))}
{roomsAndNotifications.rooms.length === 0 && (
<div className="mx_ThreadsActivityCentre_emptyCaption">
{_t("threads_activity_centre|no_rooms_with_unreads_threads")}
</div>
)}
</div>
</Menu>
}
>
{/* 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">
{_t("threads_activity_centre|no_rooms_with_unreads_threads")}
</div>
)}
</div>
</Menu>
)}
</div>
);
}
Expand Down
32 changes: 32 additions & 0 deletions src/hooks/useIsReleaseAnnouncementOpen.ts
@@ -0,0 +1,32 @@
/*
*
* Copyright 2024 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* /
*/

import { useTypedEventEmitterState } from "./useEventEmitter";
import { Feature, ReleaseAnnouncementStore } from "../stores/ReleaseAnnouncementStore";

/**
* Return true if the release announcement of the given feature is enabled
* @param feature
*/
export function useIsReleaseAnnouncementOpen(feature: Feature): boolean {
return useTypedEventEmitterState(
ReleaseAnnouncementStore.instance,
"releaseAnnouncementChanged",
() => ReleaseAnnouncementStore.instance.getReleaseAnnouncement() === feature,
);
}
6 changes: 5 additions & 1 deletion src/i18n/strings/en_EN.json
Expand Up @@ -1417,6 +1417,7 @@
"group_spaces": "Spaces",
"group_themes": "Themes",
"group_threads": "Threads",
"group_ui": "User interface",
"group_voip": "Voice & Video",
"group_widgets": "Widgets",
"hidebold": "Hide notification dot (only display counters badges)",
Expand All @@ -1440,6 +1441,7 @@
"oidc_native_flow": "OIDC native authentication",
"oidc_native_flow_description": "⚠ WARNING: Experimental. Use OIDC native authentication when supported by the server.",
"pinning": "Message Pinning",
"release_announcement": "Release announcement",
"render_reaction_images": "Render custom images in reactions",
"render_reaction_images_description": "Sometimes referred to as \"custom emojis\".",
"report_to_moderators": "Report to moderators",
Expand Down Expand Up @@ -3161,7 +3163,9 @@
},
"threads_activity_centre": {
"header": "Threads activity",
"no_rooms_with_unreads_threads": "You don't have rooms with unread threads yet."
"no_rooms_with_unreads_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"
},
"time": {
"about_day_ago": "about a day ago",
Expand Down