Repository: gitify-app/gitify
Pull request #1493 (2024-08-25 18:41:37)

feat: login with github app
Add `Login with GitHub App` option to account management screen.

Also simplify display of platform type to prevent overflow


Patch:
diff --git a/src/routes/Accounts.tsx b/src/routes/Accounts.tsx
index 6831259d..ae8ffc8b 100644
--- a/src/routes/Accounts.tsx
+++ b/src/routes/Accounts.tsx
@@ -1,6 +1,7 @@
 import {
   FeedPersonIcon,
   KeyIcon,
+  MarkGithubIcon,
   PersonIcon,
   PlusIcon,
   SignOutIcon,
@@ -9,6 +10,7 @@ import {
   SyncIcon,
 } from '@primer/octicons-react';
 
+import log from 'electron-log';
 import { type FC, useCallback, useContext } from 'react';
 import { useNavigate } from 'react-router-dom';
 import { Header } from '../components/Header';
@@ -29,7 +31,8 @@ import {
 import { saveState } from '../utils/storage';
 
 export const AccountsRoute: FC = () => {
-  const { auth, settings, logoutFromAccount } = useContext(AppContext);
+  const { auth, settings, loginWithGitHubApp, logoutFromAccount } =
+    useContext(AppContext);
   const navigate = useNavigate();
 
   const logoutAccount = useCallback(
@@ -48,6 +51,14 @@ export const AccountsRoute: FC = () => {
     navigate('/accounts', { replace: true });
   }, []);
 
+  const loginWithGitHub = useCallback(async () => {
+    try {
+      await loginWithGitHubApp();
+    } catch (err) {
+      log.error('Auth: failed to login with GitHub', err);
+    }
+  }, []);
+
   const loginWithPersonalAccessToken = useCallback(() => {
     return navigate('/login-personal-access-token', { replace: true });
   }, []);
@@ -97,7 +108,7 @@ export const AccountsRoute: FC = () => {
                     onClick={() => openHost(account.hostname)}
                   >
                     <PlatformIcon type={account.platform} size={Size.XSMALL} />
-                    {account.platform} - {account.hostname}
+                    {account.hostname}
                   </button>
                 </div>
                 <div>
@@ -172,6 +183,18 @@ export const AccountsRoute: FC = () => {
       <div className="flex items-center justify-between bg-gray-200 px-8 py-1 text-sm dark:bg-gray-darker">
         <div className="font-semibold italic">Add new account</div>
         <div>
+          <button
+            type="button"
+            className={BUTTON_CLASS_NAME}
+            title="Login with GitHub App"
+            onClick={loginWithGitHub}
+          >
+            <MarkGithubIcon
+              size={Size.LARGE}
+              aria-label="Login with GitHub App"
+            />
+            <PlusIcon size={Size.SMALL} className="mb-2 ml-1" />
+          </button>
           <button
             type="button"
             className={BUTTON_CLASS_NAME}


Test patch:
diff --git a/src/routes/Accounts.test.tsx b/src/routes/Accounts.test.tsx
index 7fdae52f..768c7f25 100644
--- a/src/routes/Accounts.test.tsx
+++ b/src/routes/Accounts.test.tsx
@@ -238,6 +238,27 @@ describe('routes/Accounts.tsx', () => {
   });
 
   describe('Add new accounts', () => {
+    it('should show login with github app', async () => {
+      await act(async () => {
+        render(
+          <AppContext.Provider
+            value={{
+              auth: { accounts: [mockOAuthAccount] },
+              settings: mockSettings,
+            }}
+          >
+            <MemoryRouter>
+              <AccountsRoute />
+            </MemoryRouter>
+          </AppContext.Provider>,
+        );
+      });
+
+      expect(screen.getByTitle('Login with GitHub App').hidden).toBe(false);
+
+      fireEvent.click(screen.getByTitle('Login with GitHub App'));
+    });
+
     it('should show login with personal access token', async () => {
       await act(async () => {
         render(
diff --git a/src/routes/__snapshots__/Accounts.test.tsx.snap b/src/routes/__snapshots__/Accounts.test.tsx.snap
index 26e7de18..4da1a9b8 100644
--- a/src/routes/__snapshots__/Accounts.test.tsx.snap
+++ b/src/routes/__snapshots__/Accounts.test.tsx.snap
@@ -113,8 +113,6 @@ exports[`routes/Accounts.tsx General should render itself & its children 1`] = `
                   />
                 </svg>
               </span>
-              GitHub Cloud
-               - 
               github.com
             </button>
           </div>
@@ -288,8 +286,6 @@ exports[`routes/Accounts.tsx General should render itself & its children 1`] = `
                   />
                 </svg>
               </span>
-              GitHub Enterprise Server
-               - 
               github.gitify.io
             </button>
           </div>
@@ -463,8 +459,6 @@ exports[`routes/Accounts.tsx General should render itself & its children 1`] = `
                   />
                 </svg>
               </span>
-              GitHub Cloud
-               - 
               github.com
             </button>
           </div>
@@ -596,6 +590,41 @@ exports[`routes/Accounts.tsx General should render itself & its children 1`] = `
       Add new account
     </div>
     <div>
+      <button
+        class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none"
+        title="Login with GitHub App"
+        type="button"
+      >
+        <svg
+          aria-label="Login with GitHub App"
+          class="octicon octicon-mark-github"
+          fill="currentColor"
+          focusable="false"
+          height="18"
+          role="img"
+          style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+          viewBox="0 0 16 16"
+          width="18"
+        >
+          <path
+            d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"
+          />
+        </svg>
+        <svg
+          aria-hidden="true"
+          class="mb-2 ml-1"
+          fill="currentColor"
+          focusable="false"
+          height="14"
+          style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+          viewBox="0 0 16 16"
+          width="14"
+        >
+          <path
+            d="M7.75 2a.75.75 0 0 1 .75.75V7h4.25a.75.75 0 0 1 0 1.5H8.5v4.25a.75.75 0 0 1-1.5 0V8.5H2.75a.75.75 0 0 1 0-1.5H7V2.75A.75.75 0 0 1 7.75 2Z"
+          />
+        </svg>
+      </button>
       <button
         class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none"
         title="Login with Personal Access Token"