Repository: gitify-app/gitify
Pull request #1276 (2024-06-19 13:50:00)

feat: show notification number for issues, prs, discussions
**_Updated_**
![Screenshot 2024-06-21 at 7 17 43 AM](https://github.com/gitify-app/gitify/assets/386277/da07571b-27a1-4c54-bfb8-93884ce45c0f)



**_Original_**
<img width="505" alt="Screenshot 2024-06-19 at 9 49 02 AM" src="https://github.com/gitify-app/gitify/assets/386277/8f12fb94-fff3-4dc2-b2c9-c417aff63fe1">


afonsojramos: Maybe reducing opacity to like 60? And making it a font step smaller?
setchy: > I'd leave this one marinating a bit... I'm not sure if this is useful information and it is polluting an already quite polluted UI.

It's consistent with the GitHub UI experience.  Nowhere in our current UX do we mention the issue numbers which seems like a bit of a miss 🙃 
setchy: > Maybe reducing opacity to like 60? And making it a font step smaller?

I have already set it as `xs` instead of `sm`.  Are you suggesting it should be even smaller?
setchy: Now with updated opacity to 60

<img width="497" alt="Screenshot 2024-06-19 at 11 17 19 AM" src="https://github.com/gitify-app/gitify/assets/386277/694d9fc0-48e5-4455-ad56-b830d06560e0">


setchy: An alternate idea, we could model this as a another `pill`

<img width="502" alt="Screenshot 2024-06-19 at 11 23 21 AM" src="https://github.com/gitify-app/gitify/assets/386277/ca41220a-cb7d-4596-b23a-a1141a033622">

setchy: Another option, adding it below the notification type icon (it's rough, needs proper formatting)

<img width="508" alt="Screenshot 2024-06-19 at 11 39 00 AM" src="https://github.com/gitify-app/gitify/assets/386277/f311f990-7a17-4ef9-b02f-fc9721dac60f">


afonsojramos: > It's another step on our journey to GitHub UI/UX consistency.

I agree with the part about consistency, but we must have less UI elements, because we don't have the luxury of a full page imo
setchy: > > Maybe reducing opacity to like 60? 
> 
> Now with updated opacity to 60
> 
> <img width="497" alt="Screenshot 2024-06-19 at 11 17 19 AM" src="https://github.com/gitify-app/gitify/assets/386277/694d9fc0-48e5-4455-ad56-b830d06560e0">
> 
> 

This remains as my preferred approach 
afonsojramos: My preferred approach is no issue number at the end of the day. I've locally played around with `xxs` and `opacity-50`, but it all comes down to this: what is the use of the issue number? As something that should focus on the essential, this is definitely not essential. I'd say this even goes against the following non-goal that we defined in #655:

> Specific UX/UI changes that add options and/or visual complexity for minor workflow improvements.
afonsojramos: @bmulholland @setchy @Araxeus @adufr opinions on the above?
Araxeus: I personally don't see value in showing issue number in Gitify, but I guess it could be optional?
setchy: I still think this is pretty innocent change 😅 

![image](https://github.com/gitify-app/gitify/assets/386277/ccd2c824-7cd9-414e-aed2-94c53cc4252a)

for short titles, you'll see the number as you do in the other GitHub Notification UIs
for long titles it will overflow off the screen and only be visible on notification mouse-over


afonsojramos: > If it's such a big concern, another option could be only having it in the mouse-over label text 🤷‍♂️

Point still remains, what is the value of it?
Araxeus: > I personally use the Issue/PR numbers a lot with the GH CLI

Would you really check out a branch based on a number from a notification title?

I think you would usually enter the notification, see what's actually inside it, then decide if you should check out or not
adufr: I'll give my opinion on this since I've been tagged, even though I haven't contributed recently

I like the fact that Gitify can be modular. I personally don't have a use case for this, but IMO it's worth adding it behind a setting (probably disabled by default though?)

> we don't have the luxury of a full page imo

@afonsojramos: you are very right, that's why I'd disable it by default, but having multiple features like this that could be enabled/disabled would solve this problem; the user can just add whatever elements he wants and which fits its use-case

@setchy: about the design, I think I prefer this one too 😁 
<img width="322" alt="image" src="https://github.com/gitify-app/gitify/assets/26418696/dc9a8e95-d3df-4cba-b9b3-c930aca9b7de">

setchy: Updated with the latest draft proposal

![Screenshot 2024-06-21 at 7 17 43 AM](https://github.com/gitify-app/gitify/assets/386277/c6d6460f-33a5-480c-be63-0f40f5b2a0f5)


afonsojramos: > @afonsojramos: you are very right, that's why I'd disable it by default, but having multiple features like this that could be enabled/disabled would solve this problem; the user can just add whatever elements he wants and which fits its use-case

The issue with "the user can just add whatever elements he wants and which fits its use-case", is that then we'll need to have this in mind with future developments, as they are things that we might not be seeing in local development and might break or affect without us realising. Too many options can be very hard to work with. 

**But**, this is minimal I suppose, so I think I'll move forward with this 🚀 
setchy: > However, we'll need another setting for this I reckon

the `detailed notification` setting already controls this ;) 
afonsojramos: > the issue/pr/discussion number is already flagged with the `detailed notification` setting 🙂

@setchy So do colors, last commenter and state, which I think are very useful and with no extra UI elements, while this one does add a new element, hence the ask for a new setting.
setchy: Added a new setting.  
setchy: Just remembered I need to do some small changes to disable if the detailed notifications setting isn't enabled 

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/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/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__/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,