Skip to content

Commit 20d3094

Browse files
committed
refactor: update core utilities for Tauri environment
- Update comms.ts to use isTauriEnvironment checks - Update auth utils for Tauri OAuth callback handling - Update App context for Tauri environment - Update index.tsx entry point
1 parent 3af635c commit 20d3094

File tree

4 files changed

+119
-41
lines changed

4 files changed

+119
-41
lines changed

src/context/App.tsx

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ import {
6060
mapThemeModeToColorScheme,
6161
} from '../utils/theme';
6262
import { setTrayIconColorAndTitle } from '../utils/tray';
63-
import { zoomLevelToPercentage, zoomPercentageToLevel } from '../utils/zoom';
63+
import {
64+
getCurrentZoomLevel,
65+
zoomLevelToPercentage,
66+
zoomPercentageToLevel,
67+
} from '../utils/zoom';
6468
import {
6569
defaultAuth,
6670
defaultFilterSettings,
@@ -305,11 +309,13 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
305309
}, [settings.openAtStartup]);
306310

307311
useEffect(() => {
308-
window.gitify.onResetApp(() => {
309-
clearState();
310-
setAuth(defaultAuth);
311-
setSettings(defaultSettings);
312-
});
312+
if (typeof window !== 'undefined' && window.gitify !== undefined) {
313+
window.gitify.onResetApp(() => {
314+
clearState();
315+
setAuth(defaultAuth);
316+
setSettings(defaultSettings);
317+
});
318+
}
313319
}, []);
314320

315321
const clearFilters = useCallback(() => {
@@ -356,8 +362,19 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
356362
// Global window zoom handler / listener
357363
// biome-ignore lint/correctness/useExhaustiveDependencies: We want to update on settings.zoomPercentage changes
358364
useEffect(() => {
359-
// Set the zoom level when settings.zoomPercentage changes
360-
window.gitify.zoom.setLevel(zoomPercentageToLevel(settings.zoomPercentage));
365+
// Apply zoom level from settings - works in both Tauri and browser
366+
const zoomLevel = zoomPercentageToLevel(settings.zoomPercentage);
367+
if (typeof window !== 'undefined' && window.gitify !== undefined) {
368+
window.gitify.zoom.setLevel(zoomLevel);
369+
} else {
370+
// Browser fallback using CSS zoom
371+
localStorage.setItem('zoomLevel', zoomLevel.toString());
372+
const zoomFactor = 1.2 ** zoomLevel;
373+
const rootElement = document.getElementById('root');
374+
if (rootElement) {
375+
rootElement.style.zoom = zoomFactor.toString();
376+
}
377+
}
361378

362379
// Sync zoom percentage in settings when window is resized
363380
let timeout: NodeJS.Timeout;
@@ -366,12 +383,9 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
366383
const handleResize = () => {
367384
clearTimeout(timeout);
368385
timeout = setTimeout(() => {
369-
const zoomPercentage = zoomLevelToPercentage(
370-
window.gitify.zoom.getLevel(),
371-
);
372-
373-
if (zoomPercentage !== settings.zoomPercentage) {
374-
updateSetting('zoomPercentage', zoomPercentage);
386+
const currentZoom = zoomLevelToPercentage(getCurrentZoomLevel());
387+
if (currentZoom !== settings.zoomPercentage) {
388+
updateSetting('zoomPercentage', currentZoom);
375389
}
376390
}, DELAY);
377391
};

src/index.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
import { createRoot } from 'react-dom/client';
22

3+
import './theme.css';
4+
35
import { App } from './App';
46

5-
const container = document.getElementById('root');
6-
if (container) {
7-
const root = createRoot(container);
8-
root.render(<App />);
9-
}
7+
// Initialize Tauri bridge (sets up window.gitify) then render app
8+
// In browser mode, the import fails gracefully and app renders without Tauri features
9+
const initApp = async () => {
10+
try {
11+
await import('./tauri-bridge');
12+
} catch {
13+
// Browser mode - Tauri bridge not available
14+
}
15+
16+
const container = document.getElementById('root');
17+
if (container) {
18+
const root = createRoot(container);
19+
root.render(<App />);
20+
}
21+
};
22+
23+
initApp();

src/utils/auth/utils.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,26 @@ export function authGitHub(
6161
}
6262
};
6363

64-
window.gitify.onAuthCallback((callbackUrl: string) => {
65-
rendererLogInfo(
66-
'renderer:auth-callback',
67-
`received authentication callback URL ${callbackUrl}`,
64+
// Check if auth callback is available (Tauri mode or test environment with mocks)
65+
if (
66+
typeof window !== 'undefined' &&
67+
window.gitify?.onAuthCallback !== undefined
68+
) {
69+
window.gitify.onAuthCallback((callbackUrl: string) => {
70+
rendererLogInfo(
71+
'renderer:auth-callback',
72+
`received authentication callback URL ${callbackUrl}`,
73+
);
74+
handleCallback(callbackUrl);
75+
});
76+
} else {
77+
// Browser fallback - OAuth won't work without Tauri
78+
reject(
79+
new Error(
80+
'OAuth authentication is not available in browser mode. Please run the app with Tauri.',
81+
),
6882
);
69-
handleCallback(callbackUrl);
70-
});
83+
}
7184
});
7285
}
7386

src/utils/comms.ts

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { defaultSettings } from '../context/defaults';
22
import { type Link, OpenPreference } from '../types';
3+
import { isTauriEnvironment } from './environment';
34
import { loadState } from './storage';
45

56
export function openExternalLink(url: Link): void {
@@ -10,51 +11,83 @@ export function openExternalLink(url: Link): void {
1011
: defaultSettings.openLinks;
1112

1213
if (url.toLowerCase().startsWith('https://')) {
13-
window.gitify.openExternalLink(
14-
url,
15-
openPreference === OpenPreference.FOREGROUND,
16-
);
14+
if (isTauriEnvironment()) {
15+
window.gitify.openExternalLink(
16+
url,
17+
openPreference === OpenPreference.FOREGROUND,
18+
);
19+
} else {
20+
// Browser fallback - open in new tab
21+
window.open(url, '_blank');
22+
}
1723
}
1824
}
1925

2026
export async function getAppVersion(): Promise<string> {
21-
return await window.gitify.app.version();
27+
if (isTauriEnvironment()) {
28+
return await window.gitify.app.version();
29+
}
30+
return 'dev';
2231
}
2332

2433
export async function encryptValue(value: string): Promise<string> {
25-
return await window.gitify.encryptValue(value);
34+
if (isTauriEnvironment()) {
35+
return await window.gitify.encryptValue(value);
36+
}
37+
// Browser fallback - no encryption (dev mode only)
38+
return value;
2639
}
2740

2841
export async function decryptValue(value: string): Promise<string> {
29-
return await window.gitify.decryptValue(value);
42+
if (isTauriEnvironment()) {
43+
return await window.gitify.decryptValue(value);
44+
}
45+
// Browser fallback - no decryption (dev mode only)
46+
return value;
3047
}
3148

3249
export function quitApp(): void {
33-
window.gitify.app.quit();
50+
if (isTauriEnvironment()) {
51+
window.gitify.app.quit();
52+
}
3453
}
3554

3655
export function showWindow(): void {
37-
window.gitify.app.show();
56+
if (isTauriEnvironment()) {
57+
window.gitify.app.show();
58+
}
3859
}
3960

4061
export function hideWindow(): void {
41-
window.gitify.app.hide();
62+
if (isTauriEnvironment()) {
63+
window.gitify.app.hide();
64+
}
4265
}
4366

4467
export function setAutoLaunch(value: boolean): void {
45-
window.gitify.setAutoLaunch(value);
68+
if (isTauriEnvironment()) {
69+
window.gitify.setAutoLaunch(value);
70+
}
4671
}
4772

4873
export function setUseAlternateIdleIcon(value: boolean): void {
49-
window.gitify.tray.useAlternateIdleIcon(value);
74+
if (isTauriEnvironment()) {
75+
// biome-ignore lint/correctness/useHookAtTopLevel: This is a Tauri tray method, not a React hook
76+
window.gitify.tray.useAlternateIdleIcon(value);
77+
}
5078
}
5179

5280
export function setUseUnreadActiveIcon(value: boolean): void {
53-
window.gitify.tray.useUnreadActiveIcon(value);
81+
if (isTauriEnvironment()) {
82+
// biome-ignore lint/correctness/useHookAtTopLevel: This is a Tauri tray method, not a React hook
83+
window.gitify.tray.useUnreadActiveIcon(value);
84+
}
5485
}
5586

5687
export function setKeyboardShortcut(keyboardShortcut: boolean): void {
57-
window.gitify.setKeyboardShortcut(keyboardShortcut);
88+
if (isTauriEnvironment()) {
89+
window.gitify.setKeyboardShortcut(keyboardShortcut);
90+
}
5891
}
5992

6093
/**
@@ -65,7 +98,9 @@ export function setKeyboardShortcut(keyboardShortcut: boolean): void {
6598
* @param notificationsLength The number of unread notifications
6699
*/
67100
export function updateTrayColor(notificationsLength: number): void {
68-
window.gitify.tray.updateColor(notificationsLength);
101+
if (isTauriEnvironment()) {
102+
window.gitify.tray.updateColor(notificationsLength);
103+
}
69104
}
70105

71106
/**
@@ -74,5 +109,7 @@ export function updateTrayColor(notificationsLength: number): void {
74109
* @param title The title to set on the tray icon
75110
*/
76111
export function updateTrayTitle(title: string): void {
77-
window.gitify.tray.updateTitle(title);
112+
if (isTauriEnvironment()) {
113+
window.gitify.tray.updateTitle(title);
114+
}
78115
}

0 commit comments

Comments
 (0)