From 352f7317f8f50b828dec5f77d585fc545dfc7ad2 Mon Sep 17 00:00:00 2001
From: Jamie B <53781962+JamieB-gu@users.noreply.github.com>
Date: Wed, 25 Mar 2026 18:19:24 +0000
Subject: [PATCH] Refactor `LiveblogNotifications`
We want to expand usage of the notifications button to include
subscribing to football match events. This refactor makes the button
more generic and testable, to facilitate this.
Firstly the component has been renamed to `NotificationsToggle`, so that
it can be reused for both liveblog notifications (new content) and
football notifications (match events such as goals). This component
contains the logic for user events, calling Bridget, and synchronising
UI with the subscription state.
The UI of the button itself is handled in a new, presentational
component called `ToggleButton`, which replaces
`FollowNotificationsButton` and is more suitable for customisation to
the new football design. `FollowNotificationsButton` will soon be
deleted, as its only other usage is in the process of being deprecated
in a separate change.
Wrapping `NotificationsToggle` is a lightweight island component that
dependency-injects the Bridget client. This allows us to use a "live"
implementation of this client in production, and a mock implementation
in tests and stories. As a result, this change also adds a story
containing UI tests that make use of a mock Bridget client.
The type describing the API of the `Notifications` Bridget client has
been simplified to make dependency injection and mocking simpler. A
similar type can be rolled out for the other Bridget clients in a future
change.
---
.../src/components/ArticleMeta.apps.tsx | 50 ++++--
.../LiveblogNotifications.importable.tsx | 117 --------------
.../NotificationsToggle.importable.tsx | 15 ++
.../NotificationsToggle.stories.tsx | 75 +++++++++
.../src/components/NotificationsToggle.tsx | 145 ++++++++++++++++++
.../src/components/ToggleButton.tsx | 86 +++++++++++
dotcom-rendering/src/lib/bridgetApi.ts | 15 +-
7 files changed, 372 insertions(+), 131 deletions(-)
delete mode 100644 dotcom-rendering/src/components/LiveblogNotifications.importable.tsx
create mode 100644 dotcom-rendering/src/components/NotificationsToggle.importable.tsx
create mode 100644 dotcom-rendering/src/components/NotificationsToggle.stories.tsx
create mode 100644 dotcom-rendering/src/components/NotificationsToggle.tsx
create mode 100644 dotcom-rendering/src/components/ToggleButton.tsx
diff --git a/dotcom-rendering/src/components/ArticleMeta.apps.tsx b/dotcom-rendering/src/components/ArticleMeta.apps.tsx
index fe34af72e1e..94d872f168d 100644
--- a/dotcom-rendering/src/components/ArticleMeta.apps.tsx
+++ b/dotcom-rendering/src/components/ArticleMeta.apps.tsx
@@ -23,7 +23,7 @@ import { Dateline } from './Dateline';
import { FollowWrapper } from './FollowWrapper.importable';
import { Island } from './Island';
import { ListenToArticle } from './ListenToArticle.importable';
-import { LiveblogNotifications } from './LiveblogNotifications.importable';
+import { NotificationsToggle } from './NotificationsToggle.importable';
type Props = {
format: ArticleFormat;
@@ -249,9 +249,6 @@ export const ArticleMetaApps = ({
const shouldShowFollowButtons = (layoutOrDesignType: boolean) =>
layoutOrDesignType && !!byline && !isUndefined(soleContributor);
- const shouldShowLiveblogNotifications =
- isLiveBlog && !!pageId && !!headline;
-
const isImmersiveOrAnalysisWithMultipleAuthors =
(isAnalysis || isImmersive) && !!byline && isUndefined(soleContributor);
@@ -311,14 +308,11 @@ export const ArticleMetaApps = ({
/>
)}
- {shouldShowLiveblogNotifications && (
-
-
-
- )}
+
{isCommentable && (
);
};
+
+const LiveblogNotifications = (props: {
+ isLiveBlog: boolean;
+ headline: string | undefined;
+ pageId: string | undefined;
+}) =>
+ props.isLiveBlog && !!props.pageId && !!props.headline ? (
+