Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
"rules": {
"recommended": true,
"correctness": {
"useExhaustiveDependencies": "warn"
"useExhaustiveDependencies": {
"level": "warn",
"options": {
"hooks": [{ "name": "useNavigate", "stableResult": true }]
}
}
}
}
},
Expand Down
6 changes: 3 additions & 3 deletions first-run.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { app, dialog } = require('electron');

const fs = require('fs');
const path = require('path');
const fs = require('node:fs');
const path = require('node:path');

async function onFirstRunMaybe() {
if (isFirstRun()) {
Expand Down Expand Up @@ -49,7 +49,7 @@ function isFirstRun() {

fs.writeFileSync(configPath, '');
} catch (error) {
console.warn(`First run: Unable to write firstRun file`, error);
console.warn('First run: Unable to write firstRun file', error);
}

return true;
Expand Down
2 changes: 1 addition & 1 deletion main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const { ipcMain, app, nativeTheme } = require('electron');
const { menubar } = require('menubar');
const { autoUpdater } = require('electron-updater');
const { onFirstRunMaybe } = require('./first-run');
const path = require('path');
const path = require('node:path');

require('@electron/remote/main').initialize();

Expand Down
1 change: 1 addition & 0 deletions src/__mocks__/@electron/remote.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class BrowserWindow {
if (!instance) {
instance = this;
}
// biome-ignore lint/correctness/noConstructorReturn: This is a mock class
return instance;
}
loadURL = jest.fn();
Expand Down
8 changes: 4 additions & 4 deletions src/components/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const DARK_GRADIENT_END = '#555B6E';
export const Logo = ({ isDark, onClick, className = '', ...props }: IProps) => (
<svg
className={className}
onClick={() => onClick && onClick()}
onClick={() => onClick?.()}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
viewBox="0 0 500 500"
Expand All @@ -32,11 +32,11 @@ export const Logo = ({ isDark, onClick, className = '', ...props }: IProps) => (
<stop
stopColor={isDark ? DARK_GRADIENT_START : LIGHT_GRADIENT_START}
offset="0%"
></stop>
/>
<stop
stopColor={isDark ? DARK_GRADIENT_END : LIGHT_GRADIENT_END}
offset="100%"
></stop>
/>
</linearGradient>
</defs>
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
Expand All @@ -48,7 +48,7 @@ export const Logo = ({ isDark, onClick, className = '', ...props }: IProps) => (
})`}
fillRule="nonzero"
>
<path d="M330.391053,10.2526316 C361.413773,10.2526316 386.562656,35.4015165 386.562656,66.4242368 C386.562656,97.4469571 361.413773,122.595841 330.391053,122.595842 L330.365421,122.570211 L247.319105,122.570211 C180.042515,122.499128 125.399186,176.890222 125.159,244.166421 L125.133789,244.219632 L125.154247,245.84774 C126.219609,301.255958 164.473457,349.116728 218.453292,362.268048 C272.940509,375.542983 329.466993,350.045988 355.583747,300.428701 L272.258632,300.427737 C257.346614,300.427737 243.046846,294.496977 232.512078,283.942976 C221.97731,273.388975 216.072618,259.078414 216.099748,244.166421 C216.099748,213.150778 241.242989,188.007632 272.258632,188.007632 L371.119632,188.007632 C379.28704,188.480415 386.935401,192.166372 392.393842,198.260263 L474.869789,300.324632 L474.978789,300.325211 L474.952789,300.426632 L474.953158,300.427737 L474.951789,300.427632 L474.173714,303.448935 C446.939817,406.220475 353.906452,478.028529 247.319105,478.080211 C118.007789,478.080211 12.8157895,373.144526 12.8157895,244.166421 C12.8157895,115.188316 117.905263,10.2526316 247.319105,10.2526316 L330.391053,10.2526316 Z"></path>
<path d="M330.391053,10.2526316 C361.413773,10.2526316 386.562656,35.4015165 386.562656,66.4242368 C386.562656,97.4469571 361.413773,122.595841 330.391053,122.595842 L330.365421,122.570211 L247.319105,122.570211 C180.042515,122.499128 125.399186,176.890222 125.159,244.166421 L125.133789,244.219632 L125.154247,245.84774 C126.219609,301.255958 164.473457,349.116728 218.453292,362.268048 C272.940509,375.542983 329.466993,350.045988 355.583747,300.428701 L272.258632,300.427737 C257.346614,300.427737 243.046846,294.496977 232.512078,283.942976 C221.97731,273.388975 216.072618,259.078414 216.099748,244.166421 C216.099748,213.150778 241.242989,188.007632 272.258632,188.007632 L371.119632,188.007632 C379.28704,188.480415 386.935401,192.166372 392.393842,198.260263 L474.869789,300.324632 L474.978789,300.325211 L474.952789,300.426632 L474.953158,300.427737 L474.951789,300.427632 L474.173714,303.448935 C446.939817,406.220475 353.906452,478.028529 247.319105,478.080211 C118.007789,478.080211 12.8157895,373.144526 12.8157895,244.166421 C12.8157895,115.188316 117.905263,10.2526316 247.319105,10.2526316 L330.391053,10.2526316 Z" />
</g>
</g>
</svg>
Expand Down
6 changes: 4 additions & 2 deletions src/components/NotificationRow.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('components/NotificationRow.tsx', () => {
it('should render itself & its children', async () => {
jest
.spyOn(global.Date, 'now')
.mockImplementation(() => new Date('2014').valueOf());
.mockImplementation(() => new Date('2024').valueOf());

const props = {
notification: mockedSingleNotification,
Expand All @@ -34,7 +34,9 @@ describe('components/NotificationRow.tsx', () => {
});

it('should render itself & its children without avatar', async () => {
(global as any).Date.now = jest.fn(() => new Date('2024'));
jest
.spyOn(global.Date, 'now')
.mockImplementation(() => new Date('2024').valueOf());

const mockNotification = mockedSingleNotification;
mockNotification.subject.user = null;
Expand Down
28 changes: 24 additions & 4 deletions src/components/NotificationRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import {
ReadIcon,
} from '@primer/octicons-react';
import { formatDistanceToNow, parseISO } from 'date-fns';
import { type FC, type MouseEvent, useCallback, useContext } from 'react';
import {
type FC,
type KeyboardEvent,
type MouseEvent,
useCallback,
useContext,
} from 'react';

import { AppContext } from '../context/App';
import type { Notification } from '../typesGithub';
Expand Down Expand Up @@ -55,7 +61,9 @@ export const NotificationRow: FC<IProps> = ({ notification, hostname }) => {
unsubscribeNotification(notification.id, hostname);
};

const openUserProfile = (event: MouseEvent<HTMLElement>) => {
const openUserProfile = (
event: MouseEvent<HTMLElement> | KeyboardEvent<HTMLElement>,
) => {
// Don't trigger onClick of parent element.
event.stopPropagation();

Expand Down Expand Up @@ -89,7 +97,11 @@ export const NotificationRow: FC<IProps> = ({ notification, hostname }) => {
<NotificationIcon size={18} aria-label={notification.subject.type} />
</div>

<div className="flex-1 overflow-hidden" onClick={() => pressTitle()}>
<div
className="flex-1 overflow-hidden"
onClick={() => pressTitle()}
onKeyDown={() => pressTitle()}
>
<div
className="mb-1 text-sm whitespace-nowrap overflow-ellipsis overflow-hidden cursor-pointer"
role="main"
Expand All @@ -102,11 +114,16 @@ export const NotificationRow: FC<IProps> = ({ notification, hostname }) => {
<span className="flex items-center">
<span title={updatedLabel} className="flex">
{notification.subject.user ? (
<span title="View User Profile" onClick={openUserProfile}>
<span
title="View User Profile"
onClick={openUserProfile}
onKeyDown={openUserProfile}
>
<img
className="rounded-full w-4 h-4 cursor-pointer"
src={notification.subject.user.avatar_url}
title={notification.subject.user.login}
alt={`${notification.subject.user.login}'s avatar`}
/>
</span>
) : (
Expand All @@ -128,6 +145,7 @@ export const NotificationRow: FC<IProps> = ({ notification, hostname }) => {

<div className="flex justify-center items-center gap-2 opacity-0 group-hover:opacity-80 transition-opacity">
<button
type="button"
className="focus:outline-none h-full hover:text-green-500"
title="Mark as Done"
onClick={() => markNotificationDone(notification.id, hostname)}
Expand All @@ -136,6 +154,7 @@ export const NotificationRow: FC<IProps> = ({ notification, hostname }) => {
</button>

<button
type="button"
className="focus:outline-none h-full hover:text-red-500"
title="Unsubscribe"
onClick={unsubscribe}
Expand All @@ -144,6 +163,7 @@ export const NotificationRow: FC<IProps> = ({ notification, hostname }) => {
</button>

<button
type="button"
className="focus:outline-none h-full hover:text-green-500"
title="Mark as Read"
onClick={() => markNotificationRead(notification.id, hostname)}
Expand Down
15 changes: 13 additions & 2 deletions src/components/Repository.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,33 @@ export const RepositoryNotifications: FC<IProps> = ({
}, [repoNotifications, hostname]);

const avatarUrl = repoNotifications[0].repository.owner.avatar_url;
const repoSlug = repoNotifications[0].repository.full_name;

return (
<>
<div className="flex py-2 px-3 bg-gray-100 dark:bg-gray-darker dark:text-white group">
<div className="flex flex-1 space-x-3 items-center mt-0 text-sm font-medium overflow-hidden overflow-ellipsis whitespace-nowrap">
{avatarUrl ? (
<img className="rounded w-5 h-5" src={avatarUrl} />
<img
className="rounded w-5 h-5"
src={avatarUrl}
alt={`${repoSlug}'s avatar`}
/>
) : (
<MarkGithubIcon size={18} />
)}
<span className="cursor-pointer" onClick={openBrowser}>
<span
className="cursor-pointer"
onClick={openBrowser}
onKeyDown={openBrowser}
>
{repoName}
</span>
</div>

<div className="flex justify-center items-center gap-2 opacity-0 group-hover:opacity-80 transition-opacity">
<button
type="button"
className="focus:outline-none h-full hover:text-green-500"
title="Mark Repository as Done"
onClick={markRepoAsDone}
Expand All @@ -65,6 +75,7 @@ export const RepositoryNotifications: FC<IProps> = ({
<div className="w-[14px]" />

<button
type="button"
className="focus:outline-none h-full hover:text-green-500"
title="Mark Repository as Read"
onClick={markRepoAsRead}
Expand Down
7 changes: 6 additions & 1 deletion src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const Sidebar: FC = () => {
}, []);

const onOpenGitHubNotifications = useCallback(() => {
openExternalLink(`https://github.com/notifications`);
openExternalLink('https://github.com/notifications');
}, []);

const quitApp = useCallback(() => {
Expand All @@ -46,6 +46,7 @@ export const Sidebar: FC = () => {
<div className="flex flex-col fixed left-14 w-14 -ml-14 h-full bg-gray-sidebar overflow-y-auto">
<div className="flex flex-col flex-1 items-center py-4">
<button
type="button"
className="w-5 my-3 mx-auto cursor-pointer outline-none"
title="Open Gitify on GitHub"
onClick={onOpenBrowser}
Expand All @@ -55,6 +56,7 @@ export const Sidebar: FC = () => {
</button>

<button
type="button"
className={`flex justify-around self-stretch items-center my-1 py-1 px-2 text-xs font-extrabold cursor-pointer ${
notificationsCount > 0 ? 'text-green-500' : 'text-white'
}`}
Expand All @@ -73,6 +75,7 @@ export const Sidebar: FC = () => {
{isLoggedIn && (
<>
<button
type="button"
className={sidebarButtonClasses}
title="Refresh Notifications"
onClick={() => {
Expand All @@ -89,6 +92,7 @@ export const Sidebar: FC = () => {
</button>

<button
type="button"
className={sidebarButtonClasses}
title="Settings"
onClick={() => {
Expand All @@ -106,6 +110,7 @@ export const Sidebar: FC = () => {

{!isLoggedIn && (
<button
type="button"
className={sidebarButtonClasses}
title="Quit Gitify"
aria-label="Quit Gitify"
Expand Down
14 changes: 12 additions & 2 deletions src/components/__snapshots__/NotificationRow.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ exports[`components/NotificationRow.tsx should render itself & its children 1`]
<div
className="flex-1 overflow-hidden"
onClick={[Function]}
onKeyDown={[Function]}
>
<div
className="mb-1 text-sm whitespace-nowrap overflow-ellipsis overflow-hidden cursor-pointer"
Expand All @@ -53,13 +54,15 @@ exports[`components/NotificationRow.tsx should render itself & its children 1`]
>
<span
className="flex"
title="manosim updated in over 3 years"
title="manosim updated over 6 years ago"
>
<span
onClick={[Function]}
onKeyDown={[Function]}
title="View User Profile"
>
<img
alt="manosim's avatar"
className="rounded-full w-4 h-4 cursor-pointer"
src="https://avatars0.githubusercontent.com/u/6333409?v=3"
title="manosim"
Expand All @@ -74,7 +77,7 @@ exports[`components/NotificationRow.tsx should render itself & its children 1`]
<span
className="ml-1"
>
in over 3 years
over 6 years ago
</span>
</span>
</span>
Expand All @@ -87,6 +90,7 @@ exports[`components/NotificationRow.tsx should render itself & its children 1`]
className="focus:outline-none h-full hover:text-green-500"
onClick={[Function]}
title="Mark as Done"
type="button"
>
<svg
aria-label="Mark as Done"
Expand Down Expand Up @@ -115,6 +119,7 @@ exports[`components/NotificationRow.tsx should render itself & its children 1`]
className="focus:outline-none h-full hover:text-red-500"
onClick={[Function]}
title="Unsubscribe"
type="button"
>
<svg
aria-label="Unsubscribe"
Expand Down Expand Up @@ -143,6 +148,7 @@ exports[`components/NotificationRow.tsx should render itself & its children 1`]
className="focus:outline-none h-full hover:text-green-500"
onClick={[Function]}
title="Mark as Read"
type="button"
>
<svg
aria-label="Mark as Read"
Expand Down Expand Up @@ -208,6 +214,7 @@ exports[`components/NotificationRow.tsx should render itself & its children with
<div
className="flex-1 overflow-hidden"
onClick={[Function]}
onKeyDown={[Function]}
>
<div
className="mb-1 text-sm whitespace-nowrap overflow-ellipsis overflow-hidden cursor-pointer"
Expand Down Expand Up @@ -271,6 +278,7 @@ exports[`components/NotificationRow.tsx should render itself & its children with
className="focus:outline-none h-full hover:text-green-500"
onClick={[Function]}
title="Mark as Done"
type="button"
>
<svg
aria-label="Mark as Done"
Expand Down Expand Up @@ -299,6 +307,7 @@ exports[`components/NotificationRow.tsx should render itself & its children with
className="focus:outline-none h-full hover:text-red-500"
onClick={[Function]}
title="Unsubscribe"
type="button"
>
<svg
aria-label="Unsubscribe"
Expand Down Expand Up @@ -327,6 +336,7 @@ exports[`components/NotificationRow.tsx should render itself & its children with
className="focus:outline-none h-full hover:text-green-500"
onClick={[Function]}
title="Mark as Read"
type="button"
>
<svg
aria-label="Mark as Read"
Expand Down
Loading