Repository: gitify-app/gitify (TypeScript)

Issue:
Use GHE domain for links in the sidebar
### 📝 Feature description

Currently, links navigate to github.com
I use the app with only one account (GHE). This means it would work for me like this: when one account is added then take the domain for links from it.

Ideally, it should work for everyone. The links can use the domain from a currently selected account.
But when I logged in to my GitHub account and saw no concept like a current account.

So this feature can have a simple initial implementation as described and improved if something like an account switcher or filtering per account is added.

I'm open to implementing simple if this feature looks valuable to the project.





Discussion:

Patch:
diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx
index e5c007f45..b9f8f1564 100644
--- a/src/components/Sidebar.tsx
+++ b/src/components/Sidebar.tsx
@@ -12,6 +12,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
 import { AppContext } from '../context/App';
 import { Size } from '../types';
 import { quitApp } from '../utils/comms';
+import Constants from '../utils/constants';
 import { getFilterCount } from '../utils/helpers';
 import {
   openGitHubIssues,
@@ -27,8 +28,18 @@ export const Sidebar: FC = () => {
   const navigate = useNavigate();
   const location = useLocation();
 
-  const { notifications, fetchNotifications, isLoggedIn, status, settings } =
-    useContext(AppContext);
+  const {
+    notifications,
+    fetchNotifications,
+    isLoggedIn,
+    status,
+    settings,
+    auth,
+  } = useContext(AppContext);
+
+  // We naively assume that the first account is the primary account for the purposes of our sidebar quick links
+  const primaryAccountHostname =
+    auth.accounts[0]?.hostname ?? Constants.DEFAULT_AUTH_OPTIONS.hostname;
 
   const toggleFilters = () => {
     if (location.pathname.startsWith('/filters')) {
@@ -77,19 +88,19 @@ export const Sidebar: FC = () => {
           title={`${notificationsCount} Unread Notifications`}
           metric={notificationsCount}
           icon={BellIcon}
-          onClick={() => openGitHubNotifications()}
+          onClick={() => openGitHubNotifications(primaryAccountHostname)}
         />
 
         <SidebarButton
           title="My Issues"
           icon={IssueOpenedIcon}
-          onClick={() => openGitHubIssues()}
+          onClick={() => openGitHubIssues(primaryAccountHostname)}
         />
 
         <SidebarButton
           title="My Pull Requests"
           icon={GitPullRequestIcon}
-          onClick={() => openGitHubPulls()}
+          onClick={() => openGitHubPulls(primaryAccountHostname)}
         />
       </div>
 
diff --git a/src/context/App.tsx b/src/context/App.tsx
index 4b57a36ce..5bd6ddad0 100644
--- a/src/context/App.tsx
+++ b/src/context/App.tsx
@@ -173,7 +173,7 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
     const newSettings = { ...settings, ...defaultFilters };
     setSettings(newSettings);
     saveState({ auth, settings: newSettings });
-  }, [auth]);
+  }, [auth, settings]);
 
   const resetSettings = useCallback(() => {
     setSettings(defaultSettings);
diff --git a/src/utils/auth/migration.ts b/src/utils/auth/migration.ts
index 018b3d9ff..643edcb35 100644
--- a/src/utils/auth/migration.ts
+++ b/src/utils/auth/migration.ts
@@ -13,7 +13,6 @@ export async function migrateAuthenticatedAccounts() {
   const existing = loadState();
 
   if (!hasAccountsToMigrate(existing.auth)) {
-    log.info('Account Migration: No accounts need migrating');
     return;
   }
 
diff --git a/src/utils/links.ts b/src/utils/links.ts
index 6edd44772..e19aaadde 100644
--- a/src/utils/links.ts
+++ b/src/utils/links.ts
@@ -15,16 +15,22 @@ export function openGitifyReleaseNotes(version: string) {
   );
 }
 
-export function openGitHubNotifications() {
-  openExternalLink('https://github.com/notifications' as Link);
+export function openGitHubNotifications(hostname: Hostname) {
+  const url = new URL(`https://${hostname}`);
+  url.pathname = 'notifications';
+  openExternalLink(url.toString() as Link);
 }
 
-export function openGitHubIssues() {
-  openExternalLink('https://github.com/issues' as Link);
+export function openGitHubIssues(hostname: Hostname) {
+  const url = new URL(`https://${hostname}`);
+  url.pathname = 'issues';
+  openExternalLink(url.toString() as Link);
 }
 
-export function openGitHubPulls() {
-  openExternalLink('https://github.com/pulls' as Link);
+export function openGitHubPulls(hostname: Hostname) {
+  const url = new URL(`https://${hostname}`);
+  url.pathname = 'pulls';
+  openExternalLink(url.toString() as Link);
 }
 
 export function openAccountProfile(account: Account) {


Test patch:
diff --git a/src/components/Sidebar.test.tsx b/src/components/Sidebar.test.tsx
index 7958fd2e1..3ecf154e5 100644
--- a/src/components/Sidebar.test.tsx
+++ b/src/components/Sidebar.test.tsx
@@ -1,7 +1,7 @@
 import { fireEvent, render, screen } from '@testing-library/react';
 import { MemoryRouter } from 'react-router-dom';
 import { mockAccountNotifications } from '../__mocks__/notifications-mocks';
-import { mockSettings } from '../__mocks__/state-mocks';
+import { mockAuth, mockSettings } from '../__mocks__/state-mocks';
 import { AppContext } from '../context/App';
 import { IconColor } from '../types';
 import * as comms from '../utils/comms';
@@ -27,8 +27,9 @@ describe('components/Sidebar.tsx', () => {
     const tree = render(
       <AppContext.Provider
         value={{
-          settings: mockSettings,
           notifications: mockAccountNotifications,
+          auth: mockAuth,
+          settings: mockSettings,
         }}
       >
         <MemoryRouter>
@@ -46,6 +47,7 @@ describe('components/Sidebar.tsx', () => {
         value={{
           isLoggedIn: false,
           notifications: mockAccountNotifications,
+          auth: mockAuth,
           settings: mockSettings,
         }}
       >
@@ -61,7 +63,12 @@ describe('components/Sidebar.tsx', () => {
   it('should open the gitify repository', () => {
     render(
       <AppContext.Provider
-        value={{ isLoggedIn: false, notifications: [], settings: mockSettings }}
+        value={{
+          isLoggedIn: false,
+          notifications: [],
+          auth: mockAuth,
+          settings: mockSettings,
+        }}
       >
         <MemoryRouter>
           <Sidebar />
@@ -85,6 +92,7 @@ describe('components/Sidebar.tsx', () => {
             value={{
               isLoggedIn: true,
               notifications: [],
+              auth: mockAuth,
               settings: mockSettings,
             }}
           >
@@ -114,6 +122,7 @@ describe('components/Sidebar.tsx', () => {
             value={{
               isLoggedIn: true,
               notifications: mockAccountNotifications,
+              auth: mockAuth,
               settings: mockSettings,
             }}
           >
@@ -146,6 +155,7 @@ describe('components/Sidebar.tsx', () => {
         value={{
           isLoggedIn: true,
           notifications: mockAccountNotifications,
+          auth: mockAuth,
           settings: mockSettings,
         }}
       >
@@ -169,6 +179,7 @@ describe('components/Sidebar.tsx', () => {
         value={{
           isLoggedIn: true,
           notifications: mockAccountNotifications,
+          auth: mockAuth,
           settings: mockSettings,
         }}
       >
@@ -193,6 +204,7 @@ describe('components/Sidebar.tsx', () => {
           value={{
             isLoggedIn: true,
             notifications: [],
+            auth: mockAuth,
             settings: mockSettings,
             fetchNotifications,
             status: 'success',
@@ -215,6 +227,7 @@ describe('components/Sidebar.tsx', () => {
           value={{
             isLoggedIn: true,
             notifications: [],
+            auth: mockAuth,
             settings: mockSettings,
             fetchNotifications,
             status: 'loading',
@@ -239,6 +252,7 @@ describe('components/Sidebar.tsx', () => {
           value={{
             isLoggedIn: true,
             notifications: [],
+            auth: mockAuth,
             settings: mockSettings,
           }}
         >
@@ -257,6 +271,7 @@ describe('components/Sidebar.tsx', () => {
           value={{
             isLoggedIn: true,
             notifications: [],
+            auth: mockAuth,
             settings: mockSettings,
           }}
         >
@@ -277,6 +292,7 @@ describe('components/Sidebar.tsx', () => {
           value={{
             isLoggedIn: true,
             notifications: [],
+            auth: mockAuth,
             settings: mockSettings,
           }}
         >
@@ -297,6 +313,7 @@ describe('components/Sidebar.tsx', () => {
           value={{
             isLoggedIn: true,
             notifications: [],
+            auth: mockAuth,
             settings: mockSettings,
             fetchNotifications,
           }}
@@ -322,6 +339,7 @@ describe('components/Sidebar.tsx', () => {
         value={{
           isLoggedIn: true,
           notifications: mockAccountNotifications,
+          auth: mockAuth,
           settings: mockSettings,
         }}
       >
@@ -345,6 +363,7 @@ describe('components/Sidebar.tsx', () => {
         value={{
           isLoggedIn: true,
           notifications: mockAccountNotifications,
+          auth: mockAuth,
           settings: mockSettings,
         }}
       >
@@ -368,6 +387,7 @@ describe('components/Sidebar.tsx', () => {
         value={{
           isLoggedIn: true,
           notifications: mockAccountNotifications,
+          auth: mockAuth,
           settings: mockSettings,
         }}
       >
@@ -388,7 +408,12 @@ describe('components/Sidebar.tsx', () => {
 
     render(
       <AppContext.Provider
-        value={{ isLoggedIn: false, notifications: [], settings: mockSettings }}
+        value={{
+          isLoggedIn: false,
+          notifications: [],
+          auth: mockAuth,
+          settings: mockSettings,
+        }}
       >
         <MemoryRouter>
           <Sidebar />
@@ -406,7 +431,12 @@ describe('components/Sidebar.tsx', () => {
 
     render(
       <AppContext.Provider
-        value={{ isLoggedIn: false, notifications: [], settings: mockSettings }}
+        value={{
+          isLoggedIn: false,
+          notifications: [],
+          auth: mockAuth,
+          settings: mockSettings,
+        }}
       >
         <MemoryRouter>
           <Sidebar />
@@ -427,6 +457,7 @@ describe('components/Sidebar.tsx', () => {
           value={{
             isLoggedIn: true,
             notifications: [],
+            auth: mockAuth,
             settings: mockSettings,
           }}
         >
@@ -448,6 +479,7 @@ describe('components/Sidebar.tsx', () => {
           value={{
             isLoggedIn: true,
             notifications: mockAccountNotifications,
+            auth: mockAuth,
             settings: mockSettings,
           }}
         >
diff --git a/src/utils/links.test.ts b/src/utils/links.test.ts
index ee1bb5a51..d4c4f6566 100644
--- a/src/utils/links.test.ts
+++ b/src/utils/links.test.ts
@@ -46,21 +46,21 @@ describe('utils/links.ts', () => {
   });
 
   it('openGitHubNotifications', () => {
-    openGitHubNotifications();
+    openGitHubNotifications(mockGitHubCloudAccount.hostname);
     expect(openExternalLinkMock).toHaveBeenCalledWith(
       'https://github.com/notifications',
     );
   });
 
   it('openGitHubIssues', () => {
-    openGitHubIssues();
+    openGitHubIssues(mockGitHubCloudAccount.hostname);
     expect(openExternalLinkMock).toHaveBeenCalledWith(
       'https://github.com/issues',
     );
   });
 
   it('openGitHubPulls', () => {
-    openGitHubPulls();
+    openGitHubPulls(mockGitHubCloudAccount.hostname);
     expect(openExternalLinkMock).toHaveBeenCalledWith(
       'https://github.com/pulls',
     );