diff --git a/src/components/views/settings/Notifications.tsx b/src/components/views/settings/Notifications.tsx
index ec47cff714..fc86ee0952 100644
--- a/src/components/views/settings/Notifications.tsx
+++ b/src/components/views/settings/Notifications.tsx
@@ -58,6 +58,7 @@ import { Caption } from "../typography/Caption";
 import { SettingsSubsectionHeading } from "./shared/SettingsSubsectionHeading";
 import SettingsSubsection from "./shared/SettingsSubsection";
 import { doesRoomHaveUnreadMessages } from "../../../Unread";
+import SettingsFlag from "../elements/SettingsFlag";
 
 // TODO: this "view" component still has far too much application logic in it,
 // which should be factored out to other files.
@@ -200,6 +201,18 @@ const maximumVectorState = (
     return vectorState;
 };
 
+const NotificationActivitySettings = (): JSX.Element => {
+    return (
+        <div>
+            <SettingsFlag name="Notifications.showbold" level={SettingLevel.DEVICE} />
+            <SettingsFlag name="Notifications.tac_only_notifications" level={SettingLevel.DEVICE} />
+        </div>
+    );
+};
+
+/**
+ * The old, deprecated notifications tab view, only displayed if the user has the labs flag disabled.
+ */
 export default class Notifications extends React.PureComponent<IProps, IState> {
     private settingWatchers: string[];
 
@@ -731,43 +744,10 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
     }
 
     private renderCategory(category: RuleClass): ReactNode {
-        if (category !== RuleClass.VectorOther && this.isInhibited) {
+        if (this.isInhibited) {
             return null; // nothing to show for the section
         }
 
-        let clearNotifsButton: JSX.Element | undefined;
-        if (
-            category === RuleClass.VectorOther &&
-            MatrixClientPeg.safeGet()
-                .getRooms()
-                .some((r) => doesRoomHaveUnreadMessages(r, true))
-        ) {
-            clearNotifsButton = (
-                <AccessibleButton
-                    onClick={this.onClearNotificationsClicked}
-                    disabled={this.state.clearingNotifications}
-                    kind="danger"
-                    className="mx_UserNotifSettings_clearNotifsButton"
-                    data-testid="clear-notifications"
-                >
-                    {_t("notifications|mark_all_read")}
-                </AccessibleButton>
-            );
-        }
-
-        if (category === RuleClass.VectorOther && this.isInhibited) {
-            // only render the utility buttons (if needed)
-            if (clearNotifsButton) {
-                return (
-                    <div className="mx_UserNotifSettings_floatingSection">
-                        <div>{_t("notifications|class_other")}</div>
-                        {clearNotifsButton}
-                    </div>
-                );
-            }
-            return null;
-        }
-
         let keywordComposer: JSX.Element | undefined;
         if (category === RuleClass.VectorMentions) {
             const tags = filterBoolean<string>(this.state.vectorKeywordRuleInfo?.rules.map((r) => r.pattern) || []);
@@ -842,7 +822,6 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
                     <span className="mx_UserNotifSettings_gridColumnLabel">{VectorStateToLabel[VectorState.Loud]}</span>
                     {fieldsetRows}
                 </div>
-                {clearNotifsButton}
                 {keywordComposer}
             </div>
         );
@@ -878,6 +857,25 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
             return <p data-testid="error-message">{_t("settings|notifications|error_loading")}</p>;
         }
 
+        let clearNotifsButton: JSX.Element | undefined;
+        if (
+            MatrixClientPeg.safeGet()
+                .getRooms()
+                .some((r) => doesRoomHaveUnreadMessages(r, true))
+        ) {
+            clearNotifsButton = (
+                <AccessibleButton
+                    onClick={this.onClearNotificationsClicked}
+                    disabled={this.state.clearingNotifications}
+                    kind="danger"
+                    className="mx_UserNotifSettings_clearNotifsButton"
+                    data-testid="clear-notifications"
+                >
+                    {_t("notifications|mark_all_read")}
+                </AccessibleButton>
+            );
+        }
+
         return (
             <>
                 {this.renderTopSection()}
@@ -885,6 +883,8 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
                 {this.renderCategory(RuleClass.VectorMentions)}
                 {this.renderCategory(RuleClass.VectorOther)}
                 {this.renderTargets()}
+                <NotificationActivitySettings />
+                {clearNotifsButton}
             </>
         );
     }
diff --git a/src/components/views/settings/notifications/NotificationSettings2.tsx b/src/components/views/settings/notifications/NotificationSettings2.tsx
index bdc021e486..a15fdd1d8b 100644
--- a/src/components/views/settings/notifications/NotificationSettings2.tsx
+++ b/src/components/views/settings/notifications/NotificationSettings2.tsx
@@ -41,6 +41,7 @@ import { SettingsBanner } from "../shared/SettingsBanner";
 import { SettingsSection } from "../shared/SettingsSection";
 import SettingsSubsection from "../shared/SettingsSubsection";
 import { NotificationPusherSettings } from "./NotificationPusherSettings";
+import SettingsFlag from "../../elements/SettingsFlag";
 
 enum NotificationDefaultLevels {
     AllMessages = "all_messages",
@@ -71,6 +72,9 @@ function useHasUnreadNotifications(): boolean {
     return cli.getRooms().some((room) => room.getUnreadNotificationCount() > 0);
 }
 
+/**
+ * The new notification settings tab view, only displayed if the user has Features.NotificationSettings2 enabled
+ */
 export default function NotificationSettings2(): JSX.Element {
     const cli = useMatrixClientContext();
 
@@ -352,6 +356,9 @@ export default function NotificationSettings2(): JSX.Element {
                         label={_t("notifications|keyword")}
                         placeholder={_t("notifications|keyword_new")}
                     />
+
+                    <SettingsFlag name="Notifications.showbold" level={SettingLevel.DEVICE} />
+                    <SettingsFlag name="Notifications.tac_only_notifications" level={SettingLevel.DEVICE} />
                 </SettingsSubsection>
                 <NotificationPusherSettings />
                 <SettingsSubsection heading={_t("settings|notifications|quick_actions_section")}>
diff --git a/src/components/views/spaces/threads-activity-centre/useUnreadThreadRooms.ts b/src/components/views/spaces/threads-activity-centre/useUnreadThreadRooms.ts
index 72b5380fbd..725fcfd5be 100644
--- a/src/components/views/spaces/threads-activity-centre/useUnreadThreadRooms.ts
+++ b/src/components/views/spaces/threads-activity-centre/useUnreadThreadRooms.ts
@@ -43,13 +43,14 @@ type Result = {
  */
 export function useUnreadThreadRooms(forceComputation: boolean): Result {
     const msc3946ProcessDynamicPredecessor = useSettingValue<boolean>("feature_dynamic_room_predecessors");
+    const settingTACOnlyNotifs = useSettingValue<boolean>("Notifications.tac_only_notifications");
     const mxClient = useMatrixClientContext();
 
     const [result, setResult] = useState<Result>({ greatestNotificationLevel: NotificationLevel.None, rooms: [] });
 
     const doUpdate = useCallback(() => {
-        setResult(computeUnreadThreadRooms(mxClient, msc3946ProcessDynamicPredecessor));
-    }, [mxClient, msc3946ProcessDynamicPredecessor]);
+        setResult(computeUnreadThreadRooms(mxClient, msc3946ProcessDynamicPredecessor, settingTACOnlyNotifs));
+    }, [mxClient, msc3946ProcessDynamicPredecessor, settingTACOnlyNotifs]);
 
     // The exhautive deps lint rule can't compute dependencies here since it's not a plain inline func.
     // We make this as simple as possible so its only dep is doUpdate itself.
@@ -83,7 +84,11 @@ export function useUnreadThreadRooms(forceComputation: boolean): Result {
  * @param mxClient - MatrixClient
  * @param msc3946ProcessDynamicPredecessor
  */
-function computeUnreadThreadRooms(mxClient: MatrixClient, msc3946ProcessDynamicPredecessor: boolean): Result {
+function computeUnreadThreadRooms(
+    mxClient: MatrixClient,
+    msc3946ProcessDynamicPredecessor: boolean,
+    settingTACOnlyNotifs: boolean,
+): Result {
     // Only count visible rooms to not torment the user with notification counts in rooms they can't see.
     // This will include highlights from the previous version of the room internally
     const visibleRooms = mxClient.getVisibleRooms(msc3946ProcessDynamicPredecessor);
@@ -98,7 +103,7 @@ function computeUnreadThreadRooms(mxClient: MatrixClient, msc3946ProcessDynamicP
             const notificationLevel = getThreadNotificationLevel(room);
 
             // If the room has an activity notification or less, we ignore it
-            if (notificationLevel <= NotificationLevel.Activity) {
+            if (settingTACOnlyNotifs && notificationLevel <= NotificationLevel.Activity) {
                 continue;
             }
 
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index e1c6c23ac5..48e6e2f0ae 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -2846,6 +2846,7 @@
         "show_redaction_placeholder": "Show a placeholder for removed messages",
         "show_stickers_button": "Show stickers button",
         "show_typing_notifications": "Show typing notifications",
+        "showbold": "Show all activity in the room list (dots or number of unread messages)",
         "sidebar": {
             "metaspaces_favourites_description": "Group all your favourite rooms and people in one place.",
             "metaspaces_home_all_rooms": "Show all rooms",
@@ -2862,6 +2863,7 @@
             "title": "Sidebar"
         },
         "start_automatically": "Start automatically after system login",
+        "tac_only_notifications": "Only show notifications in the thread activity centre",
         "use_12_hour_format": "Show timestamps in 12 hour format (e.g. 2:30pm)",
         "use_command_enter_send_message": "Use Command + Enter to send a message",
         "use_command_f_search": "Use Command + F to search timeline",
diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx
index 2297437479..6be0a6b46f 100644
--- a/src/settings/Settings.tsx
+++ b/src/settings/Settings.tsx
@@ -1,6 +1,6 @@
 /*
 Copyright 2017 Travis Ralston
-Copyright 2018 - 2023 The Matrix.org Foundation C.I.C.
+Copyright 2018 - 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.
@@ -586,14 +586,23 @@ export const SETTINGS: { [setting: string]: ISetting } = {
         supportedLevels: LEVELS_ROOM_OR_ACCOUNT,
         default: false,
     },
+    // Used to be a feature, name kept for backwards compat
     "feature_hidebold": {
-        isFeature: true,
-        labsGroup: LabGroup.Rooms,
-        configDisablesSetting: true,
         supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
         displayName: _td("labs|hidebold"),
         default: false,
     },
+    "Notifications.showbold": {
+        supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
+        displayName: _td("settings|showbold"),
+        default: false,
+        invertedSettingName: "feature_hidebold",
+    },
+    "Notifications.tac_only_notifications": {
+        supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
+        displayName: _td("settings|tac_only_notifications"),
+        default: true,
+    },
     "feature_ask_to_join": {
         isFeature: true,
         labsGroup: LabGroup.Rooms,
diff --git a/test/components/views/settings/__snapshots__/Notifications-test.tsx.snap b/test/components/views/settings/__snapshots__/Notifications-test.tsx.snap
index bf6c01e50b..25d06ffc23 100644
--- a/test/components/views/settings/__snapshots__/Notifications-test.tsx.snap
+++ b/test/components/views/settings/__snapshots__/Notifications-test.tsx.snap
@@ -35,5 +35,61 @@ exports[`<Notifications /> main notification switches renders only enable notifi
       />
     </div>
   </div>
+  <div>
+    <div
+      class="mx_SettingsFlag"
+    >
+      <label
+        class="mx_SettingsFlag_label"
+        for="mx_SettingsFlag_testid_1"
+      >
+        <span
+          class="mx_SettingsFlag_labelText"
+        >
+          Show all activity in the room list (dots or number of unread messages)
+        </span>
+      </label>
+      <div
+        aria-checked="true"
+        aria-disabled="false"
+        aria-label="Show all activity in the room list (dots or number of unread messages)"
+        class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled"
+        id="mx_SettingsFlag_testid_1"
+        role="switch"
+        tabindex="0"
+      >
+        <div
+          class="mx_ToggleSwitch_ball"
+        />
+      </div>
+    </div>
+    <div
+      class="mx_SettingsFlag"
+    >
+      <label
+        class="mx_SettingsFlag_label"
+        for="mx_SettingsFlag_testid_2"
+      >
+        <span
+          class="mx_SettingsFlag_labelText"
+        >
+          Only show notifications in the thread activity centre
+        </span>
+      </label>
+      <div
+        aria-checked="true"
+        aria-disabled="false"
+        aria-label="Only show notifications in the thread activity centre"
+        class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled"
+        id="mx_SettingsFlag_testid_2"
+        role="switch"
+        tabindex="0"
+      >
+        <div
+          class="mx_ToggleSwitch_ball"
+        />
+      </div>
+    </div>
+  </div>
 </div>
 `;
diff --git a/test/components/views/settings/notifications/__snapshots__/Notifications2-test.tsx.snap b/test/components/views/settings/notifications/__snapshots__/Notifications2-test.tsx.snap
index 08e0d86027..84b9188a7c 100644
--- a/test/components/views/settings/notifications/__snapshots__/Notifications2-test.tsx.snap
+++ b/test/components/views/settings/notifications/__snapshots__/Notifications2-test.tsx.snap
@@ -641,6 +641,60 @@ exports[`<Notifications /> correctly handles the loading/disabled state 1`] = `
                 role="list"
               />
             </div>
+            <div
+              class="mx_SettingsFlag"
+            >
+              <label
+                class="mx_SettingsFlag_label"
+                for="mx_SettingsFlag_QRlYy75nfv5b"
+              >
+                <span
+                  class="mx_SettingsFlag_labelText"
+                >
+                  Show all activity in the room list (dots or number of unread messages)
+                </span>
+              </label>
+              <div
+                aria-checked="true"
+                aria-disabled="false"
+                aria-label="Show all activity in the room list (dots or number of unread messages)"
+                class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled"
+                id="mx_SettingsFlag_QRlYy75nfv5b"
+                role="switch"
+                tabindex="0"
+              >
+                <div
+                  class="mx_ToggleSwitch_ball"
+                />
+              </div>
+            </div>
+            <div
+              class="mx_SettingsFlag"
+            >
+              <label
+                class="mx_SettingsFlag_label"
+                for="mx_SettingsFlag_OEPN1su1JYVt"
+              >
+                <span
+                  class="mx_SettingsFlag_labelText"
+                >
+                  Only show notifications in the thread activity centre
+                </span>
+              </label>
+              <div
+                aria-checked="true"
+                aria-disabled="false"
+                aria-label="Only show notifications in the thread activity centre"
+                class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled"
+                id="mx_SettingsFlag_OEPN1su1JYVt"
+                role="switch"
+                tabindex="0"
+              >
+                <div
+                  class="mx_ToggleSwitch_ball"
+                />
+              </div>
+            </div>
           </div>
         </div>
         <div
@@ -1472,6 +1526,60 @@ exports[`<Notifications /> matches the snapshot 1`] = `
                 </div>
               </div>
             </div>
+            <div
+              class="mx_SettingsFlag"
+            >
+              <label
+                class="mx_SettingsFlag_label"
+                for="mx_SettingsFlag_QRlYy75nfv5b"
+              >
+                <span
+                  class="mx_SettingsFlag_labelText"
+                >
+                  Show all activity in the room list (dots or number of unread messages)
+                </span>
+              </label>
+              <div
+                aria-checked="true"
+                aria-disabled="false"
+                aria-label="Show all activity in the room list (dots or number of unread messages)"
+                class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled"
+                id="mx_SettingsFlag_QRlYy75nfv5b"
+                role="switch"
+                tabindex="0"
+              >
+                <div
+                  class="mx_ToggleSwitch_ball"
+                />
+              </div>
+            </div>
+            <div
+              class="mx_SettingsFlag"
+            >
+              <label
+                class="mx_SettingsFlag_label"
+                for="mx_SettingsFlag_OEPN1su1JYVt"
+              >
+                <span
+                  class="mx_SettingsFlag_labelText"
+                >
+                  Only show notifications in the thread activity centre
+                </span>
+              </label>
+              <div
+                aria-checked="true"
+                aria-disabled="false"
+                aria-label="Only show notifications in the thread activity centre"
+                class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled"
+                id="mx_SettingsFlag_OEPN1su1JYVt"
+                role="switch"
+                tabindex="0"
+              >
+                <div
+                  class="mx_ToggleSwitch_ball"
+                />
+              </div>
+            </div>
           </div>
         </div>
         <div
@@ -1523,11 +1631,11 @@ exports[`<Notifications /> matches the snapshot 1`] = `
                   class="mx_Checkbox mx_Checkbox_hasKind mx_Checkbox_kind_solid"
                 >
                   <input
-                    id="checkbox_QRlYy75nfv"
+                    id="checkbox_OyR5kbu3pE"
                     type="checkbox"
                   />
                   <label
-                    for="checkbox_QRlYy75nfv"
+                    for="checkbox_OyR5kbu3pE"
                   >
                     <div
                       class="mx_Checkbox_background"
diff --git a/test/components/views/spaces/useUnreadThreadRooms-test.tsx b/test/components/views/spaces/useUnreadThreadRooms-test.tsx
index e8c9b97861..d4dc04da96 100644
--- a/test/components/views/spaces/useUnreadThreadRooms-test.tsx
+++ b/test/components/views/spaces/useUnreadThreadRooms-test.tsx
@@ -30,6 +30,7 @@ import { stubClient } from "../../../test-utils";
 import { populateThread } from "../../../test-utils/threads";
 import { NotificationLevel } from "../../../../src/stores/notifications/NotificationLevel";
 import { useUnreadThreadRooms } from "../../../../src/components/views/spaces/threads-activity-centre/useUnreadThreadRooms";
+import SettingsStore from "../../../../src/settings/SettingsStore";
 
 describe("useUnreadThreadRooms", () => {
     let client: MatrixClient;
@@ -43,6 +44,10 @@ describe("useUnreadThreadRooms", () => {
         });
     });
 
+    afterEach(() => {
+        jest.restoreAllMocks();
+    });
+
     it("has no notifications with no rooms", async () => {
         const { result } = renderHook(() => useUnreadThreadRooms(false));
         const { greatestNotificationLevel, rooms } = result.current;
@@ -51,7 +56,7 @@ describe("useUnreadThreadRooms", () => {
         expect(rooms.length).toEqual(0);
     });
 
-    it("an activity notification is ignored", async () => {
+    it("an activity notification is ignored by default", async () => {
         const notifThreadInfo = await populateThread({
             room: room,
             client: client,
@@ -73,6 +78,30 @@ describe("useUnreadThreadRooms", () => {
         expect(rooms.length).toEqual(0);
     });
 
+    it("an activity notification is displayed with the setting enabled", async () => {
+        jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
+
+        const notifThreadInfo = await populateThread({
+            room: room,
+            client: client,
+            authorId: "@foo:bar",
+            participantUserIds: ["@fee:bar"],
+        });
+        room.setThreadUnreadNotificationCount(notifThreadInfo.thread.id, NotificationCountType.Total, 0);
+
+        client.getVisibleRooms = jest.fn().mockReturnValue([room]);
+
+        const wrapper = ({ children }: { children: React.ReactNode }) => (
+            <MatrixClientContext.Provider value={client}>{children}</MatrixClientContext.Provider>
+        );
+
+        const { result } = renderHook(() => useUnreadThreadRooms(true), { wrapper });
+        const { greatestNotificationLevel, rooms } = result.current;
+
+        expect(greatestNotificationLevel).toBe(NotificationLevel.Activity);
+        expect(rooms.length).toEqual(1);
+    });
+
     it("a notification and a highlight summarise to a highlight", async () => {
         const notifThreadInfo = await populateThread({
             room: room,