Skip to content

Commit d138750

Browse files
committed
Progress
1 parent 50a2be8 commit d138750

24 files changed

+129
-94
lines changed

flake.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@
152152
name = "slimevr-electron";
153153

154154
buildInputs = with pkgs; [
155+
jdk17
156+
kotlin
155157
nodejs_22
156158
pnpm
157159
pkg-config

gui/electron/main/index.ts

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,31 @@ protocol.registerSchemesAsPrivileged([
4848
standard: true,
4949
secure: true,
5050
supportFetchAPI: true,
51-
corsEnabled: true
52-
}
53-
}
51+
corsEnabled: true,
52+
},
53+
},
5454
]);
5555

5656
let mainWindow: BrowserWindow | null = null;
5757

58+
handleIpc(IPC_CHANNELS.GH_FETCH, async (e, options) => {
59+
console.log(options)
60+
if (options.type === 'fw-releases') {
61+
return fetch(
62+
'https://api.github.com/repos/SlimeVR/SlimeVR-Tracker-ESP/releases'
63+
).then((res) => res.json());
64+
}
65+
if (options.type === 'asset') {
66+
if (
67+
!options.url.startsWith(
68+
'https://github.com/SlimeVR/SlimeVR-Tracker-ESP/releases/download'
69+
)
70+
)
71+
return null;
72+
return fetch(options.url).then((res) => res.json());
73+
}
74+
});
75+
5876
handleIpc(IPC_CHANNELS.OS_STATS, async () => {
5977
return {
6078
type: getPlatform(),
@@ -335,7 +353,7 @@ const checkEnvironmentVariables = () => {
335353
const findServerJar = () => {
336354
const paths = [
337355
options.path,
338-
// AppImage passes the fakeroot in `APPDIR` env var.
356+
// AppImage passes the fakeroot in `APPDIR` env var.
339357
process.env['APPDIR']
340358
? path.resolve(join(process.env['APPDIR'], 'usr/share/slimevr/'))
341359
: undefined,
@@ -351,31 +369,25 @@ const findServerJar = () => {
351369
.find((p) => existsSync(p));
352370
};
353371

354-
const validJavaPaths = () => {
355-
}
372+
const validJavaPaths = () => {};
356373

357374
const findJavaBin = (sharedDir: string) => {
358375
const javaBin = getPlatform() === 'windows' ? 'java.exe' : 'java';
359376
const jre = join(sharedDir, 'jre/bin', javaBin);
360377
if (!existsSync(jre)) {
361378
return validJavaPaths();
362379
}
363-
364-
365-
366-
}
380+
};
367381

368382
const spawnServer = () => {
369-
370-
const serverJar = findServerJar()
383+
const serverJar = findServerJar();
371384
if (!serverJar) {
372385
return false;
373386
}
374387
const sharedDir = dirname(serverJar);
375388
const javaBin = findJavaBin(sharedDir);
376389

377390
logger.info({ serverJar }, 'found server jar');
378-
379391
};
380392

381393
app.whenReady().then(() => {

gui/electron/preload/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron';
22
import { IElectronAPI, ServerStatusEvent } from './interface';
33
import { IPC_CHANNELS } from '../shared';
4-
// import { getGuiDataFolder, getLogsFolder } from 'electron/main/paths';
54

65
contextBridge.exposeInMainWorld('electronAPI', {
76
onServerStatus: (callback) => {
@@ -34,5 +33,6 @@ contextBridge.exposeInMainWorld('electronAPI', {
3433
saveDialog: (options) => ipcRenderer.invoke(IPC_CHANNELS.SAVE_DIALOG, options),
3534
openConfigFolder: async () => ipcRenderer.invoke(IPC_CHANNELS.OPEN_FILE, await ipcRenderer.invoke(IPC_CHANNELS.GET_FOLDER, 'config')),
3635
openLogsFolder: async () => ipcRenderer.invoke(IPC_CHANNELS.OPEN_FILE, await ipcRenderer.invoke(IPC_CHANNELS.GET_FOLDER, 'logs')),
37-
openFile: (path) => ipcRenderer.invoke(IPC_CHANNELS.OPEN_FILE, path)
36+
openFile: (path) => ipcRenderer.invoke(IPC_CHANNELS.OPEN_FILE, path),
37+
ghGet: (req) => ipcRenderer.invoke(IPC_CHANNELS.GH_FETCH, req),
3838
} satisfies IElectronAPI);

gui/electron/preload/interface.d.ts

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1-
import { OpenDialogOptions, OpenDialogReturnValue, SaveDialogOptions, SaveDialogReturnValue } from "electron";
1+
import {
2+
OpenDialogOptions,
3+
OpenDialogReturnValue,
4+
SaveDialogOptions,
5+
SaveDialogReturnValue,
6+
} from 'electron';
27

38
export type ServerStatusEvent = {
49
type: 'stdout' | 'stderr' | 'error' | 'terminated' | 'other';
510
message: string;
6-
}
11+
};
712

813
export type OSStats = {
914
type: 'linux' | 'windows' | 'macos' | 'unknown';
10-
}
15+
};
1116

1217
export interface CrossStorage {
1318
set(key: string, value: unknown): Promise<void>;
@@ -16,25 +21,37 @@ export interface CrossStorage {
1621
save(): Promise<boolean>;
1722
}
1823

24+
export type GHGet = { type: 'fw-releases' } | { type: 'asset'; url: string };
25+
export type GHReturn = {
26+
asset: [number, string][] | null;
27+
['fw-releases']:
28+
| {
29+
assets: { browser_download_url: string; name: string; digest: string }[];
30+
prerelease: boolean;
31+
tag_name: string;
32+
body: string;
33+
}[]
34+
| null;
35+
};
36+
1937
export interface IElectronAPI {
20-
onServerStatus: (
21-
cb: (data: ServerStatusEvent) => void
22-
) => () => void;
23-
openUrl: (url: string) => Promise<void>
24-
osStats: () => Promise<OSStats>,
25-
openLogsFolder: () => Promise<void>,
26-
openConfigFolder: () => Promise<void>,
38+
onServerStatus: (cb: (data: ServerStatusEvent) => void) => () => void;
39+
openUrl: (url: string) => Promise<void>;
40+
osStats: () => Promise<OSStats>;
41+
openLogsFolder: () => Promise<void>;
42+
openConfigFolder: () => Promise<void>;
2743
close: () => void;
2844
minimize: () => void;
2945
maximize: () => void;
3046
showDecorations: (decorations: boolean) => void;
3147
setTranslations: (translations: Record<string, string>) => void;
3248
i18nOverride: () => Promise<string | false>;
3349
getStorage: (type: 'settings' | 'cache') => Promise<CrossStorage>;
34-
openDialog: (options: OpenDialogOptions) => Promise<OpenDialogReturnValue>
35-
saveDialog: (options: SaveDialogOptions) => Promise<SaveDialogReturnValue>
50+
openDialog: (options: OpenDialogOptions) => Promise<OpenDialogReturnValue>;
51+
saveDialog: (options: SaveDialogOptions) => Promise<SaveDialogReturnValue>;
3652
log: (type: 'info' | 'error' | 'warn', ...args: unknown[]) => void;
3753
openFile: (path: string) => void;
54+
ghGet: <T extends GHGet>(options: T) => Promise<GHReturn[T['type']]>;
3855
}
3956

4057
declare global {

gui/electron/shared.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
import { OpenDialogOptions, OpenDialogReturnValue, SaveDialogOptions, SaveDialogReturnValue } from 'electron';
2-
import { OSStats, ServerStatusEvent } from './preload/interface';
1+
import {
2+
OpenDialogOptions,
3+
OpenDialogReturnValue,
4+
SaveDialogOptions,
5+
SaveDialogReturnValue,
6+
} from 'electron';
7+
import { GHGet, GHReturn, OSStats, ServerStatusEvent } from './preload/interface';
38

49
export const IPC_CHANNELS = {
510
SERVER_STATUS: 'server-status',
@@ -13,24 +18,32 @@ export const IPC_CHANNELS = {
1318
I18N_OVERRIDE: 'i18n-override',
1419
OPEN_FILE: 'open-file',
1520
GET_FOLDER: 'get-folder',
21+
GH_FETCH: 'gh-fetch',
1622
} as const;
1723

1824
export interface IpcInvokeMap {
1925
[IPC_CHANNELS.OPEN_URL]: (url: string) => void;
2026
[IPC_CHANNELS.OS_STATS]: () => Promise<OSStats>;
2127
[IPC_CHANNELS.WINDOW_ACTIONS]: (action: 'close' | 'minimize' | 'maximize') => void;
2228
[IPC_CHANNELS.LOG]: (type: 'info' | 'error' | 'warn', ...args: unknown[]) => void;
23-
[IPC_CHANNELS.OPEN_DIALOG]: (options: OpenDialogOptions) => Promise<OpenDialogReturnValue>;
24-
[IPC_CHANNELS.SAVE_DIALOG]: (options: SaveDialogOptions) => Promise<SaveDialogReturnValue>;
25-
[IPC_CHANNELS.I18N_OVERRIDE]: () => Promise<string | false>,
29+
[IPC_CHANNELS.OPEN_DIALOG]: (
30+
options: OpenDialogOptions
31+
) => Promise<OpenDialogReturnValue>;
32+
[IPC_CHANNELS.SAVE_DIALOG]: (
33+
options: SaveDialogOptions
34+
) => Promise<SaveDialogReturnValue>;
35+
[IPC_CHANNELS.I18N_OVERRIDE]: () => Promise<string | false>;
2636
[IPC_CHANNELS.STORAGE]: (args: {
2737
type: 'settings' | 'cache';
2838
method: 'get' | 'set' | 'delete' | 'save';
2939
key?: string;
30-
value?: unknown
40+
value?: unknown;
3141
}) => Promise<unknown>;
3242
[IPC_CHANNELS.OPEN_FILE]: (path: string) => void;
3343
[IPC_CHANNELS.GET_FOLDER]: (folder: 'config' | 'logs') => string;
44+
[IPC_CHANNELS.GH_FETCH]: <T extends GHGet>(
45+
options: T
46+
) => Promise<GHReturn[T['type']]>;
3447
}
3548

3649
/**

gui/src/App.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import { createContext, useEffect, useState } from 'react';
2-
import {
3-
HashRouter as Router,
4-
Outlet,
5-
Route,
6-
Routes,
7-
} from 'react-router-dom';
2+
import { HashRouter as Router, Outlet, Route, Routes } from 'react-router-dom';
83
import { Home } from './components/home/Home';
94
import { MainLayout } from './components/MainLayout';
105
import { AppContextProvider } from './components/providers/AppContext';
@@ -55,10 +50,7 @@ import { StayAlignedSetup } from './components/onboarding/pages/stay-aligned/Sta
5550
import { TrackingChecklistProvider } from './components/tracking-checklist/TrackingChecklistProvider';
5651
import { HomeScreenSettings } from './components/settings/pages/HomeScreenSettings';
5752
import { ChecklistPage } from './components/tracking-checklist/TrackingChecklist';
58-
import {
59-
ElectronContextC,
60-
provideElectron,
61-
} from './hooks/electron';
53+
import { ElectronContextC, provideElectron } from './hooks/electron';
6254
import { AppLocalizationProvider } from './i18n/config';
6355
import { openUrl } from './hooks/crossplatform';
6456

gui/src/components/TopBar.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { GearIcon } from './commons/icon/GearIcon';
2222
import { TrackersStillOnModal } from './TrackersStillOnModal';
2323
import { useConfig } from '@/hooks/config';
2424
import { TrayOrExitModal } from './TrayOrExitModal';
25-
import { useDoubleTap } from 'use-double-tap';
2625
import { ErrorConsentModal } from './ErrorConsentModal';
2726
import { useAtomValue } from 'jotai';
2827
import { connectedIMUTrackersAtom } from '@/store/app-store';
@@ -95,7 +94,6 @@ export function TopBar({
9594
}
9695
};
9796

98-
9997
// useEffect(() => {
10098
// if (!electron.isElectron) return;
10199

gui/src/components/VersionUpdateModal.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { useElectron } from '@/hooks/electron';
1010
import { openUrl } from '@/hooks/crossplatform';
1111

1212
export function VersionUpdateModal() {
13-
const electron = useElectron()
13+
const electron = useElectron();
1414
const { l10n } = useLocalization();
1515
const newVersion = useContext(VersionContext);
1616
const [forceClose, setForceClose] = useState(false);
@@ -53,10 +53,11 @@ export function VersionUpdateModal() {
5353
<Button
5454
variant="primary"
5555
onClick={async () => {
56-
const url = electron.isElectron && electron.data().os.type === 'windows'
57-
? 'https://slimevr.dev/download'
58-
: `https://github.com/${GH_REPO}/releases/latest`;
59-
await openUrl(url)
56+
const url =
57+
electron.isElectron && electron.data().os.type === 'windows'
58+
? 'https://slimevr.dev/download'
59+
: `https://github.com/${GH_REPO}/releases/latest`;
60+
await openUrl(url);
6061
closeModal();
6162
}}
6263
>

gui/src/components/commons/A.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ export function A({
1313
}) {
1414
return (
1515
<span
16-
onClick={() =>
17-
href && openUrl(href)
18-
}
16+
onClick={() => href && openUrl(href)}
1917
className={classNames(className, 'underline', 'cursor-pointer')}
2018
>
2119
{children}

gui/src/components/commons/SystemFileInput.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ export function InnerSytemFileInput({
3636
};
3737

3838
return (
39-
<div
40-
ref={ref}
41-
onClick={handleClick}
42-
>
39+
<div ref={ref} onClick={handleClick}>
4340
{value !== null
4441
? FileInputContentFile({
4542
directory,

0 commit comments

Comments
 (0)