Repository: gitify-app/gitify
Pull request #1344 (2024-07-08 18:14:09)

feat: align filters by using legend component


Patch:
diff --git a/src/__mocks__/state-mocks.ts b/src/__mocks__/state-mocks.ts
index 68278bc8..5226657c 100644
--- a/src/__mocks__/state-mocks.ts
+++ b/src/__mocks__/state-mocks.ts
@@ -84,6 +84,7 @@ export const mockSettings: SettingsState = {
   showAccountHostname: false,
   delayNotificationState: false,
   showPills: true,
+  showNumber: true,
   keyboardShortcut: true,
   groupBy: GroupBy.REPOSITORY,
   filterReasons: [],
diff --git a/src/components/NotificationRow.tsx b/src/components/NotificationRow.tsx
index bfcead59..5f635e21 100644
--- a/src/components/NotificationRow.tsx
+++ b/src/components/NotificationRow.tsx
@@ -71,6 +71,13 @@ export const NotificationRow: FC<INotificationRow> = ({
     notification.subject.type,
   ]);
 
+  const notificationNumber = notification.subject?.number
+    ? `#${notification.subject.number}`
+    : '';
+
+  const notificationTitle =
+    `${notification.subject.title} ${notificationNumber}`.trim();
+
   const groupByDate = settings.groupBy === 'DATE';
 
   return (
@@ -102,9 +109,18 @@ export const NotificationRow: FC<INotificationRow> = ({
         <div
           className="mb-1 truncate text-sm"
           role="main"
-          title={notification.subject.title}
+          title={notificationTitle}
         >
           {notification.subject.title}
+          <span
+            className={cn(
+              'text-xxs ml-1',
+              Opacity.READ,
+              !settings.showNumber && 'hidden',
+            )}
+          >
+            {notificationNumber}
+          </span>
         </div>
 
         <NotificationFooter notification={notification} />
diff --git a/src/components/settings/AppearanceSettings.tsx b/src/components/settings/AppearanceSettings.tsx
index 1d0da8e5..ae0b959b 100644
--- a/src/components/settings/AppearanceSettings.tsx
+++ b/src/components/settings/AppearanceSettings.tsx
@@ -1,6 +1,7 @@
 import {
   CheckIcon,
   CommentIcon,
+  GitPullRequestIcon,
   IssueClosedIcon,
   MilestoneIcon,
   PaintbrushIcon,
@@ -99,6 +100,41 @@ export const AppearanceSettings: FC = () => {
           </div>
         }
       />
+      <Checkbox
+        name="showNumber"
+        label="Show number"
+        checked={settings.detailedNotifications && settings.showNumber}
+        onChange={(evt) =>
+          settings.detailedNotifications &&
+          updateSetting('showNumber', evt.target.checked)
+        }
+        disabled={!settings.detailedNotifications}
+        tooltip={
+          <div>
+            <div>Show GitHub number for:</div>
+            <div className="pl-6">
+              <ul className="list-disc">
+                <li>
+                  <CommentIcon size={Size.MEDIUM} className="pr-1" />
+                  Discussion
+                </li>
+                <li>
+                  <IssueClosedIcon size={Size.MEDIUM} className="pr-1" />
+                  Issue
+                </li>
+                <li>
+                  <GitPullRequestIcon size={Size.MEDIUM} className="pr-1" />
+                  Pull Request
+                </li>
+              </ul>
+            </div>
+            <div className="pt-3 text-orange-600">
+              ⚠️ This setting requires <strong>Detailed Notifications</strong> to
+              be enabled.
+            </div>
+          </div>
+        }
+      />
       <Checkbox
         name="showAccountHostname"
         label="Show account hostname"
diff --git a/src/context/App.tsx b/src/context/App.tsx
index 05ac5594..36ea4742 100644
--- a/src/context/App.tsx
+++ b/src/context/App.tsx
@@ -67,6 +67,7 @@ export const defaultSettings: SettingsState = {
   showAccountHostname: false,
   delayNotificationState: false,
   showPills: true,
+  showNumber: true,
   keyboardShortcut: true,
   groupBy: GroupBy.REPOSITORY,
   ...defaultFilters,
diff --git a/src/routes/Filters.tsx b/src/routes/Filters.tsx
index 295044fd..83a05569 100644
--- a/src/routes/Filters.tsx
+++ b/src/routes/Filters.tsx
@@ -6,6 +6,7 @@ import {
 import { type FC, useContext } from 'react';
 import { Header } from '../components/Header';
 import { Checkbox } from '../components/fields/Checkbox';
+import { Legend } from '../components/settings/Legend';
 import { AppContext } from '../context/App';
 import { BUTTON_CLASS_NAME } from '../styles/gitify';
 import { Size } from '../types';
@@ -36,10 +37,7 @@ export const FiltersRoute: FC = () => {
       <Header fetchOnBack={true}>Filters</Header>
       <div className="flex-grow overflow-x-auto px-8">
         <fieldset className="mb-3">
-          <legend id="notifications" className="mb-1 mt-2 font-semibold">
-            <FeedPersonIcon className="mr-2" />
-            Users
-          </legend>
+          <Legend icon={FeedPersonIcon}>Users</Legend>
           <Checkbox
             name="hideBots"
             label="Hide notifications from Bot accounts"
@@ -65,10 +63,7 @@ export const FiltersRoute: FC = () => {
         </fieldset>
 
         <fieldset className="mb-3">
-          <legend id="appearance" className="mb-1 mt-2 font-semibold">
-            <NoteIcon className="mr-2" />
-            Reason
-          </legend>
+          <Legend icon={NoteIcon}>Reason</Legend>
           <span className="text-xs italic">
             Note: if no reasons are selected, all notifications will be shown.
           </span>
diff --git a/src/types.ts b/src/types.ts
index 6fe2d25c..f60c03f7 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -63,6 +63,7 @@ interface AppearanceSettingsState {
   detailedNotifications: boolean;
   showAccountHostname: boolean;
   showPills: boolean;
+  showNumber: boolean;
 }
 
 interface NotificationSettingsState {
diff --git a/src/typesGitHub.ts b/src/typesGitHub.ts
index 2fed9d32..39e56723 100644
--- a/src/typesGitHub.ts
+++ b/src/typesGitHub.ts
@@ -261,6 +261,7 @@ interface GitHubSubject {
 
 // This is not in the GitHub API, but we add it to the type to make it easier to work with
 export interface GitifySubject {
+  number?: number;
   state?: StateType;
   user?: SubjectUser;
   reviews?: GitifyPullRequestReview[];
@@ -494,6 +495,7 @@ export interface GraphQLSearch<T> {
 }
 
 export interface Discussion {
+  number: number;
   title: string;
   stateReason: DiscussionStateType;
   isAnswered: boolean;
diff --git a/src/utils/api/__mocks__/response-mocks.ts b/src/utils/api/__mocks__/response-mocks.ts
index 74097fb3..714635ab 100644
--- a/src/utils/api/__mocks__/response-mocks.ts
+++ b/src/utils/api/__mocks__/response-mocks.ts
@@ -419,6 +419,7 @@ export const mockGraphQLResponse: GraphQLSearch<Discussion> = {
     search: {
       nodes: [
         {
+          number: 123,
           title: '1.16.0',
           isAnswered: false,
           stateReason: 'OPEN',
diff --git a/src/utils/api/graphql/discussions.ts b/src/utils/api/graphql/discussions.ts
index b5ce239a..93ec4c91 100644
--- a/src/utils/api/graphql/discussions.ts
+++ b/src/utils/api/graphql/discussions.ts
@@ -31,6 +31,7 @@ export const QUERY_SEARCH_DISCUSSIONS = gql`
     search(query: $queryStatement, type: DISCUSSION, first: $firstDiscussions) {
       nodes {
         ... on Discussion {
+          number
           title
           stateReason
           isAnswered
diff --git a/src/utils/notifications.ts b/src/utils/notifications.ts
index 801530d3..44ffcc0e 100644
--- a/src/utils/notifications.ts
+++ b/src/utils/notifications.ts
@@ -103,7 +103,7 @@ export const raiseNativeNotification = (notifications: Notification[]) => {
 };
 
 export const raiseSoundNotification = () => {
-  const audio = new Audio('assets/sounds/clearly.mp3');
+  const audio = new Audio('../../assets/sounds/clearly.mp3');
   audio.volume = 0.2;
   audio.play();
 };
diff --git a/src/utils/subject.ts b/src/utils/subject.ts
index ba0c7853..a4063c0a 100644
--- a/src/utils/subject.ts
+++ b/src/utils/subject.ts
@@ -183,6 +183,7 @@ async function getGitifySubjectForDiscussion(
   }
 
   return {
+    number: discussion.number,
     state: discussionState,
     user: discussionUser,
     comments: discussion.comments.totalCount,
@@ -226,6 +227,7 @@ async function getGitifySubjectForIssue(
   }
 
   return {
+    number: issue.number,
     state: issue.state_reason ?? issue.state,
     user: {
       login: issueCommentUser?.login ?? issue.user.login,
@@ -272,6 +274,7 @@ async function getGitifySubjectForPullRequest(
   const linkedIssues = parseLinkedIssuesFromPr(pr);
 
   return {
+    number: pr.number,
     state: prState,
     user: {
       login: prCommentUser?.login ?? pr.user.login,


Test patch:
diff --git a/src/components/NotificationRow.test.tsx b/src/components/NotificationRow.test.tsx
index bb781f14..15a6abb5 100644
--- a/src/components/NotificationRow.test.tsx
+++ b/src/components/NotificationRow.test.tsx
@@ -61,6 +61,26 @@ describe('components/NotificationRow.tsx', () => {
     expect(tree).toMatchSnapshot();
   });
 
+  it('should render itself & its children - hide numbers', async () => {
+    jest
+      .spyOn(global.Date, 'now')
+      .mockImplementation(() => new Date('2024').valueOf());
+
+    const props = {
+      notification: mockSingleNotification,
+      account: mockGitHubCloudAccount,
+    };
+
+    const tree = render(
+      <AppContext.Provider
+        value={{ settings: { ...mockSettings, showNumber: false } }}
+      >
+        <NotificationRow {...props} />
+      </AppContext.Provider>,
+    );
+    expect(tree).toMatchSnapshot();
+  });
+
   describe('notification interactions', () => {
     it('should open a notification in the browser - click', () => {
       const removeNotificationFromState = jest.fn();
diff --git a/src/components/__snapshots__/AccountNotifications.test.tsx.snap b/src/components/__snapshots__/AccountNotifications.test.tsx.snap
index 9250db70..cec4888c 100644
--- a/src/components/__snapshots__/AccountNotifications.test.tsx.snap
+++ b/src/components/__snapshots__/AccountNotifications.test.tsx.snap
@@ -121,6 +121,9 @@ exports[`components/AccountNotifications.tsx should render itself (github.com wi
             title="I am a robot and this is a test!"
           >
             I am a robot and this is a test!
+            <span
+              class="text-xxs ml-1 opacity-50"
+            />
           </div>
           <div
             class="flex flex-wrap items-center gap-1 text-xs capitalize opacity-80"
@@ -317,6 +320,9 @@ exports[`components/AccountNotifications.tsx should render itself (github.com wi
             title="Improve the UI"
           >
             Improve the UI
+            <span
+              class="text-xxs ml-1 opacity-50"
+            />
           </div>
           <div
             class="flex flex-wrap items-center gap-1 text-xs capitalize opacity-80"
@@ -539,6 +545,9 @@ exports[`components/AccountNotifications.tsx should render itself (github.com wi
           title="I am a robot and this is a test!"
         >
           I am a robot and this is a test!
+          <span
+            class="text-xxs ml-1 opacity-50"
+          />
         </div>
         <div
           class="flex flex-wrap items-center gap-1 text-xs capitalize opacity-80"
@@ -735,6 +744,9 @@ exports[`components/AccountNotifications.tsx should render itself (github.com wi
           title="Improve the UI"
         >
           Improve the UI
+          <span
+            class="text-xxs ml-1 opacity-50"
+          />
         </div>
         <div
           class="flex flex-wrap items-center gap-1 text-xs capitalize opacity-80"
diff --git a/src/components/__snapshots__/NotificationRow.test.tsx.snap b/src/components/__snapshots__/NotificationRow.test.tsx.snap
index 30e7c1cd..c30e3a4b 100644
--- a/src/components/__snapshots__/NotificationRow.test.tsx.snap
+++ b/src/components/__snapshots__/NotificationRow.test.tsx.snap
@@ -58,6 +58,9 @@ exports[`components/NotificationRow.tsx should render itself & its children - gr
             title="I am a robot and this is a test!"
           >
             I am a robot and this is a test!
+            <span
+              class="text-xxs ml-1 opacity-50"
+            />
           </div>
           <div
             class="flex flex-wrap items-center gap-1 text-xs capitalize opacity-80"
@@ -257,6 +260,9 @@ exports[`components/NotificationRow.tsx should render itself & its children - gr
           title="I am a robot and this is a test!"
         >
           I am a robot and this is a test!
+          <span
+            class="text-xxs ml-1 opacity-50"
+          />
         </div>
         <div
           class="flex flex-wrap items-center gap-1 text-xs capitalize opacity-80"
@@ -496,6 +502,436 @@ exports[`components/NotificationRow.tsx should render itself & its children - gr
             title="I am a robot and this is a test!"
           >
             I am a robot and this is a test!
+            <span
+              class="text-xxs ml-1 opacity-50"
+            />
+          </div>
+          <div
+            class="flex flex-wrap items-center gap-1 text-xs capitalize opacity-80"
+          >
+            <button
+              class="flex-shrink-0"
+              title="View User Profile"
+              type="button"
+            >
+              <img
+                alt="gitify-app's avatar"
+                class="rounded-full object-cover size-4"
+                src="https://avatars.githubusercontent.com/u/133795385?s=200&v=4"
+              />
+            </button>
+            <div
+              title="You're watching the repository."
+            >
+              Updated
+            </div>
+            <div
+              title="gitify-app updated 7 years ago"
+            >
+              7 years ago
+            </div>
+            <div
+              class="flex"
+            >
+              <button
+                class="flex gap-1 items-center m-0.5 rounded-full bg-gray-100 px-1 text-xxs hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700"
+                title="octocat approved these changes"
+                type="button"
+              >
+                <svg
+                  aria-label="octocat approved these changes"
+                  class="text-green-500"
+                  fill="currentColor"
+                  focusable="false"
+                  height="12"
+                  role="img"
+                  style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+                  viewBox="0 0 16 16"
+                  width="12"
+                >
+                  <path
+                    d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"
+                  />
+                </svg>
+                1
+              </button>
+              <button
+                class="flex gap-1 items-center m-0.5 rounded-full bg-gray-100 px-1 text-xxs hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700"
+                title="gitify-app requested changes"
+                type="button"
+              >
+                <svg
+                  aria-label="gitify-app requested changes"
+                  class="text-red-500"
+                  fill="currentColor"
+                  focusable="false"
+                  height="12"
+                  role="img"
+                  style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+                  viewBox="0 0 16 16"
+                  width="12"
+                >
+                  <path
+                    d="M1 1.75C1 .784 1.784 0 2.75 0h7.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073ZM8 3.25a.75.75 0 0 1 .75.75v1.5h1.5a.75.75 0 0 1 0 1.5h-1.5v1.5a.75.75 0 0 1-1.5 0V7h-1.5a.75.75 0 0 1 0-1.5h1.5V4A.75.75 0 0 1 8 3.25Zm-3 8a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Z"
+                  />
+                </svg>
+                1
+              </button>
+            </div>
+          </div>
+        </div>
+        <div
+          class="flex items-center justify-center gap-2 opacity-0 transition-opacity group-hover:opacity-80"
+        >
+          <button
+            class="h-full hover:text-green-500 focus:outline-none"
+            title="Mark as Done"
+            type="button"
+          >
+            <svg
+              aria-label="Mark as Done"
+              class="octicon octicon-check"
+              fill="currentColor"
+              focusable="false"
+              height="16"
+              role="img"
+              style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+              viewBox="0 0 16 16"
+              width="16"
+            >
+              <path
+                d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"
+              />
+            </svg>
+          </button>
+          <button
+            class="h-full hover:text-green-500 focus:outline-none"
+            title="Mark as Read"
+            type="button"
+          >
+            <svg
+              aria-label="Mark as Read"
+              class="octicon octicon-read"
+              fill="currentColor"
+              focusable="false"
+              height="14"
+              role="img"
+              style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+              viewBox="0 0 16 16"
+              width="14"
+            >
+              <path
+                d="M7.115.65a1.752 1.752 0 0 1 1.77 0l6.25 3.663c.536.314.865.889.865 1.51v6.427A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25V5.823c0-.621.33-1.196.865-1.51Zm1.011 1.293a.252.252 0 0 0-.252 0l-5.72 3.353L6.468 7.76a2.748 2.748 0 0 1 3.066 0l4.312-2.464-5.719-3.353ZM13.15 12.5 8.772 9.06a1.25 1.25 0 0 0-1.544 0L2.85 12.5Zm1.35-5.85-3.687 2.106 3.687 2.897ZM5.187 8.756 1.5 6.65v5.003Z"
+              />
+            </svg>
+          </button>
+          <button
+            class="h-full hover:text-green-500 focus:outline-none"
+            title="Unsubscribe from Thread"
+            type="button"
+          >
+            <svg
+              aria-label="Unsubscribe from Thread"
+              class="octicon octicon-bell-slash"
+              fill="currentColor"
+              focusable="false"
+              height="14"
+              role="img"
+              style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+              viewBox="0 0 16 16"
+              width="14"
+            >
+              <path
+                d="m4.182 4.31.016.011 10.104 7.316.013.01 1.375.996a.75.75 0 1 1-.88 1.214L13.626 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947V5.305L.31 3.357a.75.75 0 1 1 .88-1.214Zm7.373 7.19L4.5 6.391v1.556c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01c0 .005.002.009.005.012l.006.004.007.001ZM8 1.5c-.997 0-1.895.416-2.534 1.086A.75.75 0 1 1 4.38 1.55 5 5 0 0 1 13 5v2.373a.75.75 0 0 1-1.5 0V5A3.5 3.5 0 0 0 8 1.5ZM8 16a2 2 0 0 1-1.985-1.75c-.017-.137.097-.25.235-.25h3.5c.138 0 .252.113.235.25A2 2 0 0 1 8 16Z"
+              />
+            </svg>
+          </button>
+        </div>
+      </div>
+    </div>
+  </body>,
+  "container": <div>
+    <div
+      class="group flex border-b border-gray-100 bg-white px-3 py-2 hover:bg-gray-100 dark:border-gray-darker dark:bg-gray-dark dark:text-white dark:hover:bg-gray-darker"
+      id="138661096"
+    >
+      <div
+        class="mr-3 flex items-center justify-center text-green-500"
+        title="Open Issue"
+      >
+        <svg
+          aria-label="Issue"
+          class="octicon octicon-issue-opened"
+          fill="currentColor"
+          focusable="false"
+          height="16"
+          role="img"
+          style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+          viewBox="0 0 16 16"
+          width="16"
+        >
+          <path
+            d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"
+          />
+          <path
+            d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"
+          />
+        </svg>
+      </div>
+      <div
+        class="flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap cursor-pointer"
+      >
+        <div
+          class="mb-1 truncate text-sm"
+          role="main"
+          title="I am a robot and this is a test!"
+        >
+          I am a robot and this is a test!
+          <span
+            class="text-xxs ml-1 opacity-50"
+          />
+        </div>
+        <div
+          class="flex flex-wrap items-center gap-1 text-xs capitalize opacity-80"
+        >
+          <button
+            class="flex-shrink-0"
+            title="View User Profile"
+            type="button"
+          >
+            <img
+              alt="gitify-app's avatar"
+              class="rounded-full object-cover size-4"
+              src="https://avatars.githubusercontent.com/u/133795385?s=200&v=4"
+            />
+          </button>
+          <div
+            title="You're watching the repository."
+          >
+            Updated
+          </div>
+          <div
+            title="gitify-app updated 7 years ago"
+          >
+            7 years ago
+          </div>
+          <div
+            class="flex"
+          >
+            <button
+              class="flex gap-1 items-center m-0.5 rounded-full bg-gray-100 px-1 text-xxs hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700"
+              title="octocat approved these changes"
+              type="button"
+            >
+              <svg
+                aria-label="octocat approved these changes"
+                class="text-green-500"
+                fill="currentColor"
+                focusable="false"
+                height="12"
+                role="img"
+                style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+                viewBox="0 0 16 16"
+                width="12"
+              >
+                <path
+                  d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"
+                />
+              </svg>
+              1
+            </button>
+            <button
+              class="flex gap-1 items-center m-0.5 rounded-full bg-gray-100 px-1 text-xxs hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700"
+              title="gitify-app requested changes"
+              type="button"
+            >
+              <svg
+                aria-label="gitify-app requested changes"
+                class="text-red-500"
+                fill="currentColor"
+                focusable="false"
+                height="12"
+                role="img"
+                style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+                viewBox="0 0 16 16"
+                width="12"
+              >
+                <path
+                  d="M1 1.75C1 .784 1.784 0 2.75 0h7.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073ZM8 3.25a.75.75 0 0 1 .75.75v1.5h1.5a.75.75 0 0 1 0 1.5h-1.5v1.5a.75.75 0 0 1-1.5 0V7h-1.5a.75.75 0 0 1 0-1.5h1.5V4A.75.75 0 0 1 8 3.25Zm-3 8a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Z"
+                />
+              </svg>
+              1
+            </button>
+          </div>
+        </div>
+      </div>
+      <div
+        class="flex items-center justify-center gap-2 opacity-0 transition-opacity group-hover:opacity-80"
+      >
+        <button
+          class="h-full hover:text-green-500 focus:outline-none"
+          title="Mark as Done"
+          type="button"
+        >
+          <svg
+            aria-label="Mark as Done"
+            class="octicon octicon-check"
+            fill="currentColor"
+            focusable="false"
+            height="16"
+            role="img"
+            style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+            viewBox="0 0 16 16"
+            width="16"
+          >
+            <path
+              d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"
+            />
+          </svg>
+        </button>
+        <button
+          class="h-full hover:text-green-500 focus:outline-none"
+          title="Mark as Read"
+          type="button"
+        >
+          <svg
+            aria-label="Mark as Read"
+            class="octicon octicon-read"
+            fill="currentColor"
+            focusable="false"
+            height="14"
+            role="img"
+            style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+            viewBox="0 0 16 16"
+            width="14"
+          >
+            <path
+              d="M7.115.65a1.752 1.752 0 0 1 1.77 0l6.25 3.663c.536.314.865.889.865 1.51v6.427A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25V5.823c0-.621.33-1.196.865-1.51Zm1.011 1.293a.252.252 0 0 0-.252 0l-5.72 3.353L6.468 7.76a2.748 2.748 0 0 1 3.066 0l4.312-2.464-5.719-3.353ZM13.15 12.5 8.772 9.06a1.25 1.25 0 0 0-1.544 0L2.85 12.5Zm1.35-5.85-3.687 2.106 3.687 2.897ZM5.187 8.756 1.5 6.65v5.003Z"
+            />
+          </svg>
+        </button>
+        <button
+          class="h-full hover:text-green-500 focus:outline-none"
+          title="Unsubscribe from Thread"
+          type="button"
+        >
+          <svg
+            aria-label="Unsubscribe from Thread"
+            class="octicon octicon-bell-slash"
+            fill="currentColor"
+            focusable="false"
+            height="14"
+            role="img"
+            style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+            viewBox="0 0 16 16"
+            width="14"
+          >
+            <path
+              d="m4.182 4.31.016.011 10.104 7.316.013.01 1.375.996a.75.75 0 1 1-.88 1.214L13.626 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947V5.305L.31 3.357a.75.75 0 1 1 .88-1.214Zm7.373 7.19L4.5 6.391v1.556c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01c0 .005.002.009.005.012l.006.004.007.001ZM8 1.5c-.997 0-1.895.416-2.534 1.086A.75.75 0 1 1 4.38 1.55 5 5 0 0 1 13 5v2.373a.75.75 0 0 1-1.5 0V5A3.5 3.5 0 0 0 8 1.5ZM8 16a2 2 0 0 1-1.985-1.75c-.017-.137.097-.25.235-.25h3.5c.138 0 .252.113.235.25A2 2 0 0 1 8 16Z"
+            />
+          </svg>
+        </button>
+      </div>
+    </div>
+  </div>,
+  "debug": [Function],
+  "findAllByAltText": [Function],
+  "findAllByDisplayValue": [Function],
+  "findAllByLabelText": [Function],
+  "findAllByPlaceholderText": [Function],
+  "findAllByRole": [Function],
+  "findAllByTestId": [Function],
+  "findAllByText": [Function],
+  "findAllByTitle": [Function],
+  "findByAltText": [Function],
+  "findByDisplayValue": [Function],
+  "findByLabelText": [Function],
+  "findByPlaceholderText": [Function],
+  "findByRole": [Function],
+  "findByTestId": [Function],
+  "findByText": [Function],
+  "findByTitle": [Function],
+  "getAllByAltText": [Function],
+  "getAllByDisplayValue": [Function],
+  "getAllByLabelText": [Function],
+  "getAllByPlaceholderText": [Function],
+  "getAllByRole": [Function],
+  "getAllByTestId": [Function],
+  "getAllByText": [Function],
+  "getAllByTitle": [Function],
+  "getByAltText": [Function],
+  "getByDisplayValue": [Function],
+  "getByLabelText": [Function],
+  "getByPlaceholderText": [Function],
+  "getByRole": [Function],
+  "getByTestId": [Function],
+  "getByText": [Function],
+  "getByTitle": [Function],
+  "queryAllByAltText": [Function],
+  "queryAllByDisplayValue": [Function],
+  "queryAllByLabelText": [Function],
+  "queryAllByPlaceholderText": [Function],
+  "queryAllByRole": [Function],
+  "queryAllByTestId": [Function],
+  "queryAllByText": [Function],
+  "queryAllByTitle": [Function],
+  "queryByAltText": [Function],
+  "queryByDisplayValue": [Function],
+  "queryByLabelText": [Function],
+  "queryByPlaceholderText": [Function],
+  "queryByRole": [Function],
+  "queryByTestId": [Function],
+  "queryByText": [Function],
+  "queryByTitle": [Function],
+  "rerender": [Function],
+  "unmount": [Function],
+}
+`;
+
+exports[`components/NotificationRow.tsx should render itself & its children - hide numbers 1`] = `
+{
+  "asFragment": [Function],
+  "baseElement": <body>
+    <div>
+      <div
+        class="group flex border-b border-gray-100 bg-white px-3 py-2 hover:bg-gray-100 dark:border-gray-darker dark:bg-gray-dark dark:text-white dark:hover:bg-gray-darker"
+        id="138661096"
+      >
+        <div
+          class="mr-3 flex items-center justify-center text-green-500"
+          title="Open Issue"
+        >
+          <svg
+            aria-label="Issue"
+            class="octicon octicon-issue-opened"
+            fill="currentColor"
+            focusable="false"
+            height="16"
+            role="img"
+            style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+            viewBox="0 0 16 16"
+            width="16"
+          >
+            <path
+              d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"
+            />
+            <path
+              d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"
+            />
+          </svg>
+        </div>
+        <div
+          class="flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap cursor-pointer"
+        >
+          <div
+            class="mb-1 truncate text-sm"
+            role="main"
+            title="I am a robot and this is a test!"
+          >
+            I am a robot and this is a test!
+            <span
+              class="text-xxs ml-1 opacity-50 hidden"
+            />
           </div>
           <div
             class="flex flex-wrap items-center gap-1 text-xs capitalize opacity-80"
@@ -678,6 +1114,9 @@ exports[`components/NotificationRow.tsx should render itself & its children - gr
           title="I am a robot and this is a test!"
         >
           I am a robot and this is a test!
+          <span
+            class="text-xxs ml-1 opacity-50 hidden"
+          />
         </div>
         <div
           class="flex flex-wrap items-center gap-1 text-xs capitalize opacity-80"
diff --git a/src/components/settings/AppearanceSettings.test.tsx b/src/components/settings/AppearanceSettings.test.tsx
index dcf8a6d0..d7ea2138 100644
--- a/src/components/settings/AppearanceSettings.test.tsx
+++ b/src/components/settings/AppearanceSettings.test.tsx
@@ -84,6 +84,31 @@ describe('routes/components/settings/AppearanceSettings.tsx', () => {
     expect(updateSetting).toHaveBeenCalledWith('showPills', false);
   });
 
+  it('should toggle show number checkbox', async () => {
+    await act(async () => {
+      render(
+        <AppContext.Provider
+          value={{
+            auth: mockAuth,
+            settings: mockSettings,
+            updateSetting,
+          }}
+        >
+          <MemoryRouter>
+            <AppearanceSettings />
+          </MemoryRouter>
+        </AppContext.Provider>,
+      );
+    });
+
+    await screen.findByLabelText('Show number');
+
+    fireEvent.click(screen.getByLabelText('Show number'));
+
+    expect(updateSetting).toHaveBeenCalledTimes(1);
+    expect(updateSetting).toHaveBeenCalledWith('showNumber', false);
+  });
+
   it('should toggle account hostname checkbox', async () => {
     await act(async () => {
       render(
diff --git a/src/context/App.test.tsx b/src/context/App.test.tsx
index 415aac0b..121fdc68 100644
--- a/src/context/App.test.tsx
+++ b/src/context/App.test.tsx
@@ -379,6 +379,7 @@ describe('context/App.tsx', () => {
           showAccountHostname: false,
           delayNotificationState: false,
           showPills: true,
+          showNumber: true,
           keyboardShortcut: true,
           groupBy: 'REPOSITORY',
           filterReasons: [],
@@ -433,6 +434,7 @@ describe('context/App.tsx', () => {
           showAccountHostname: false,
           delayNotificationState: false,
           showPills: true,
+          showNumber: true,
           keyboardShortcut: true,
           groupBy: 'REPOSITORY',
           filterReasons: [],
diff --git a/src/routes/__snapshots__/Filters.test.tsx.snap b/src/routes/__snapshots__/Filters.test.tsx.snap
index fc2c4fba..af8151c8 100644
--- a/src/routes/__snapshots__/Filters.test.tsx.snap
+++ b/src/routes/__snapshots__/Filters.test.tsx.snap
@@ -42,8 +42,8 @@ exports[`routes/Filters.tsx General should render itself & its children 1`] = `
       class="mb-3"
     >
       <legend
-        class="mb-1 mt-2 font-semibold"
-        id="notifications"
+        class="mb-1 mt-2 font-semibold flex items-center"
+        id="users"
       >
         <svg
           aria-hidden="true"
@@ -113,8 +113,8 @@ exports[`routes/Filters.tsx General should render itself & its children 1`] = `
       class="mb-3"
     >
       <legend
-        class="mb-1 mt-2 font-semibold"
-        id="appearance"
+        class="mb-1 mt-2 font-semibold flex items-center"
+        id="reason"
       >
         <svg
           aria-hidden="true"
diff --git a/src/routes/__snapshots__/Settings.test.tsx.snap b/src/routes/__snapshots__/Settings.test.tsx.snap
index 0e2fa07a..2241044b 100644
--- a/src/routes/__snapshots__/Settings.test.tsx.snap
+++ b/src/routes/__snapshots__/Settings.test.tsx.snap
@@ -231,6 +231,54 @@ exports[`routes/Settings.tsx should render itself & its children 1`] = `
           </div>
         </div>
       </div>
+      <div
+        class="mb-3 mt-1 text-sm"
+      >
+        <div
+          class="flex items-start"
+        >
+          <div
+            class="flex h-5 items-center"
+          >
+            <input
+              checked=""
+              class="size-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
+              id="showNumber"
+              type="checkbox"
+            />
+          </div>
+          <div
+            class="ml-3"
+          >
+            <label
+              class="font-medium text-gray-700 dark:text-gray-200"
+              for="showNumber"
+            >
+              Show number
+              <span
+                aria-label="tooltip-showNumber"
+                class="relative"
+                id="tooltip-showNumber"
+              >
+                <svg
+                  aria-hidden="true"
+                  class="ml-1 text-blue-500"
+                  fill="currentColor"
+                  focusable="false"
+                  height="16"
+                  style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+                  viewBox="0 0 16 16"
+                  width="16"
+                >
+                  <path
+                    d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.92 6.085h.001a.749.749 0 1 1-1.342-.67c.169-.339.436-.701.849-.977C6.845 4.16 7.369 4 8 4a2.756 2.756 0 0 1 1.637.525c.503.377.863.965.863 1.725 0 .448-.115.83-.329 1.15-.205.307-.47.513-.692.662-.109.072-.22.138-.313.195l-.006.004a6.24 6.24 0 0 0-.26.16.952.952 0 0 0-.276.245.75.75 0 0 1-1.248-.832c.184-.264.42-.489.692-.661.103-.067.207-.132.313-.195l.007-.004c.1-.061.182-.11.258-.161a.969.969 0 0 0 .277-.245C8.96 6.514 9 6.427 9 6.25a.612.612 0 0 0-.262-.525A1.27 1.27 0 0 0 8 5.5c-.369 0-.595.09-.74.187a1.01 1.01 0 0 0-.34.398ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"
+                  />
+                </svg>
+              </span>
+            </label>
+          </div>
+        </div>
+      </div>
       <div
         class="mb-3 mt-1 text-sm"
       >
diff --git a/src/utils/subject.test.ts b/src/utils/subject.test.ts
index 5b030539..bb53ac8c 100644
--- a/src/utils/subject.test.ts
+++ b/src/utils/subject.test.ts
@@ -221,6 +221,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'ANSWERED',
           user: {
             login: mockDiscussionAuthor.login,
@@ -247,6 +248,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'DUPLICATE',
           user: {
             login: mockDiscussionAuthor.login,
@@ -273,6 +275,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'OPEN',
           user: {
             login: mockDiscussionAuthor.login,
@@ -299,6 +302,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'OUTDATED',
           user: {
             login: mockDiscussionAuthor.login,
@@ -325,6 +329,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'REOPENED',
           user: {
             login: mockDiscussionAuthor.login,
@@ -351,6 +356,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'RESOLVED',
           user: {
             login: mockDiscussionAuthor.login,
@@ -385,6 +391,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'ANSWERED',
           user: {
             login: mockDiscussionAuthor.login,
@@ -414,7 +421,12 @@ describe('utils/subject.ts', () => {
       it('open issue state', async () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/issues/1')
-          .reply(200, { state: 'open', user: mockAuthor, labels: [] });
+          .reply(200, {
+            number: 123,
+            state: 'open',
+            user: mockAuthor,
+            labels: [],
+          });
 
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/issues/comments/302888448')
@@ -423,6 +435,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'open',
           user: {
             login: mockCommenter.login,
@@ -437,7 +450,12 @@ describe('utils/subject.ts', () => {
       it('closed issue state', async () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/issues/1')
-          .reply(200, { state: 'closed', user: mockAuthor, labels: [] });
+          .reply(200, {
+            number: 123,
+            state: 'closed',
+            user: mockAuthor,
+            labels: [],
+          });
 
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/issues/comments/302888448')
@@ -446,6 +464,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'closed',
           user: {
             login: mockCommenter.login,
@@ -461,6 +480,7 @@ describe('utils/subject.ts', () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/issues/1')
           .reply(200, {
+            number: 123,
             state: 'closed',
             state_reason: 'completed',
             user: mockAuthor,
@@ -474,6 +494,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'completed',
           user: {
             login: mockCommenter.login,
@@ -489,6 +510,7 @@ describe('utils/subject.ts', () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/issues/1')
           .reply(200, {
+            number: 123,
             state: 'open',
             state_reason: 'not_planned',
             user: mockAuthor,
@@ -502,6 +524,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'not_planned',
           user: {
             login: mockCommenter.login,
@@ -517,6 +540,7 @@ describe('utils/subject.ts', () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/issues/1')
           .reply(200, {
+            number: 123,
             state: 'open',
             state_reason: 'reopened',
             user: mockAuthor,
@@ -530,6 +554,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'reopened',
           user: {
             login: mockCommenter.login,
@@ -547,6 +572,7 @@ describe('utils/subject.ts', () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/issues/1')
           .reply(200, {
+            number: 123,
             state: 'open',
             draft: false,
             merged: false,
@@ -557,6 +583,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'open',
           user: {
             login: mockAuthor.login,
@@ -573,6 +600,7 @@ describe('utils/subject.ts', () => {
           nock('https://api.github.com')
             .get('/repos/gitify-app/notifications-test/issues/1')
             .reply(200, {
+              number: 123,
               state: 'open',
               user: mockAuthor,
               labels: [{ name: 'enhancement' }],
@@ -587,6 +615,7 @@ describe('utils/subject.ts', () => {
           const result = await getGitifySubjectDetails(mockNotification);
 
           expect(result).toEqual({
+            number: 123,
             state: 'open',
             user: {
               login: mockCommenter.login,
@@ -602,6 +631,7 @@ describe('utils/subject.ts', () => {
           nock('https://api.github.com')
             .get('/repos/gitify-app/notifications-test/issues/1')
             .reply(200, {
+              number: 123,
               state: 'open',
               user: mockAuthor,
               labels: null,
@@ -616,6 +646,7 @@ describe('utils/subject.ts', () => {
           const result = await getGitifySubjectDetails(mockNotification);
 
           expect(result).toEqual({
+            number: 123,
             state: 'open',
             user: {
               login: mockCommenter.login,
@@ -646,6 +677,7 @@ describe('utils/subject.ts', () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/pulls/1')
           .reply(200, {
+            number: 123,
             state: 'closed',
             draft: false,
             merged: false,
@@ -664,6 +696,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'closed',
           user: {
             login: mockCommenter.login,
@@ -681,6 +714,7 @@ describe('utils/subject.ts', () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/pulls/1')
           .reply(200, {
+            number: 123,
             state: 'open',
             draft: true,
             merged: false,
@@ -699,6 +733,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'draft',
           user: {
             login: mockCommenter.login,
@@ -716,6 +751,7 @@ describe('utils/subject.ts', () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/pulls/1')
           .reply(200, {
+            number: 123,
             state: 'open',
             draft: false,
             merged: true,
@@ -734,6 +770,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'merged',
           user: {
             login: mockCommenter.login,
@@ -751,6 +788,7 @@ describe('utils/subject.ts', () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/pulls/1')
           .reply(200, {
+            number: 123,
             state: 'open',
             draft: false,
             merged: false,
@@ -769,6 +807,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'open',
           user: {
             login: mockCommenter.login,
@@ -789,6 +828,7 @@ describe('utils/subject.ts', () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/pulls/1')
           .reply(200, {
+            number: 123,
             state: 'open',
             draft: false,
             merged: false,
@@ -803,6 +843,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'open',
           user: {
             login: mockAuthor.login,
@@ -822,6 +863,7 @@ describe('utils/subject.ts', () => {
         nock('https://api.github.com')
           .get('/repos/gitify-app/notifications-test/pulls/1')
           .reply(200, {
+            number: 123,
             state: 'open',
             draft: false,
             merged: false,
@@ -836,6 +878,7 @@ describe('utils/subject.ts', () => {
         const result = await getGitifySubjectDetails(mockNotification);
 
         expect(result).toEqual({
+          number: 123,
           state: 'open',
           user: {
             login: mockAuthor.login,
@@ -912,6 +955,7 @@ describe('utils/subject.ts', () => {
           nock('https://api.github.com')
             .get('/repos/gitify-app/notifications-test/pulls/1')
             .reply(200, {
+              number: 123,
               state: 'open',
               draft: false,
               merged: false,
@@ -932,6 +976,7 @@ describe('utils/subject.ts', () => {
           const result = await getGitifySubjectDetails(mockNotification);
 
           expect(result).toEqual({
+            number: 123,
             state: 'open',
             user: {
               login: mockCommenter.login,
@@ -949,6 +994,7 @@ describe('utils/subject.ts', () => {
           nock('https://api.github.com')
             .get('/repos/gitify-app/notifications-test/pulls/1')
             .reply(200, {
+              number: 123,
               state: 'open',
               draft: false,
               merged: false,
@@ -969,6 +1015,7 @@ describe('utils/subject.ts', () => {
           const result = await getGitifySubjectDetails(mockNotification);
 
           expect(result).toEqual({
+            number: 123,
             state: 'open',
             user: {
               login: mockCommenter.login,
@@ -1293,6 +1340,7 @@ function mockDiscussionNode(
   isAnswered: boolean,
 ): Discussion {
   return {
+    number: 123,
     title: 'This is a mock discussion',
     url: 'https://github.com/gitify-app/notifications-test/discussions/1' as Link,
     stateReason: state,