Skip to content

Commit 35955f7

Browse files
committed
Added modal to show user if udev rules aren't installed. Added function to get path to exe dir inside react. Moved the Error collecting consent modal to a page.
1 parent cd7a585 commit 35955f7

16 files changed

Lines changed: 217 additions & 20 deletions

File tree

gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ spotlessVersion=8.0.0
1818
shadowJarVersion=8.3.2
1919
buildconfigVersion=5.5.0
2020
grgitVersion=5.2.2
21+
ktor_version=3.0.3

gui/electron/main/index.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
findSystemJRE,
2323
getGuiDataFolder,
2424
getLogsFolder,
25+
getExeFolder,
2526
getServerDataFolder,
2627
getWindowStateFile,
2728
} from './paths';
@@ -111,15 +112,15 @@ handleIpc(IPC_CHANNELS.LOG, (e, type, ...args) => {
111112
});
112113

113114
handleIpc(IPC_CHANNELS.OPEN_URL, (e, url) => {
114-
const allowed_urls = [
115+
const allowsd_urls = [
115116
/steam:\/\/.*/,
116117
/ms-settings:network$/,
117118
/https:\/\/.*\.slimevr\.dev.*/,
118119
/https:\/\/github\.com\/.*/,
119120
/https:\/\/discord\.gg\/slimevr$/,
120121
];
121-
if (allowed_urls.find((a) => url.match(a))) open(url);
122-
else logger.error({ url }, 'attempted to open non-whitelisted URL');
122+
if (allowsd_urls.find((a) => url.match(a))) open(url);
123+
else logger.error({ url }, 'trying to open non allowed url');
123124
});
124125

125126
handleIpc(IPC_CHANNELS.STORAGE, async (e, { type, method, key, value }) => {
@@ -171,6 +172,8 @@ handleIpc(IPC_CHANNELS.GET_FOLDER, (e, folder) => {
171172
return getGuiDataFolder();
172173
case 'logs':
173174
return getLogsFolder();
175+
case 'exe':
176+
return getExeFolder();
174177
}
175178
});
176179

@@ -336,11 +339,10 @@ const isServerRunning = async () => !await isPortAvailable(21110)
336339

337340
const spawnServer = async () => {
338341
if (options.skipServerIfRunning && await isServerRunning()) {
339-
logger.info({ skipServerIfRunning: options.skipServerIfRunning }, 'Server is already running, skipping server start');
342+
logger.info({ skipServerIfRunning: options.skipServerIfRunning }, 'Server alredy running, skipping');
340343
return;
341344
}
342345

343-
344346
const serverJar = findServerJar();
345347
if (!serverJar) {
346348
logger.info('server jar not found, skipping');
@@ -357,7 +359,8 @@ const spawnServer = async () => {
357359
return;
358360
}
359361

360-
logger.info({ javaBin, serverJar }, 'Found Java and server jar');
362+
logger.info({ serverJar }, 'found server jar');
363+
361364

362365
const process = spawn(javaBin, ['-Xmx128M', '-jar', serverJar, 'run']);
363366

@@ -392,6 +395,7 @@ app.whenReady().then(async () => {
392395
});
393396

394397
checkEnvironmentVariables();
398+
395399
const server = await spawnServer();
396400

397401
createWindow();

gui/electron/main/paths.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ export const getLogsFolder = () => {
4848
return join(getGuiDataFolder(), 'logs');
4949
};
5050

51+
export const getExeFolder = () => {
52+
return path.dirname(app.getPath('exe'));
53+
}
54+
5155
export const getWindowStateFile = () =>
5256
join(getServerDataFolder(), '.window-state.json');
5357

@@ -60,6 +64,7 @@ const javaHomeBin = () => {
6064
const javaHome = process.env['JAVA_HOME'];
6165
if (!javaHome) return null;
6266
const javaHomeJre = join(javaHome, 'bin', javaBin);
67+
console.log(javaHomeJre);
6368
return javaHomeJre;
6469
};
6570

gui/electron/preload/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ contextBridge.exposeInMainWorld('electronAPI', {
3535
openLogsFolder: async () => ipcRenderer.invoke(IPC_CHANNELS.OPEN_FILE, await ipcRenderer.invoke(IPC_CHANNELS.GET_FOLDER, 'logs')),
3636
openFile: (path) => ipcRenderer.invoke(IPC_CHANNELS.OPEN_FILE, path),
3737
ghGet: (req) => ipcRenderer.invoke(IPC_CHANNELS.GH_FETCH, req),
38-
setPresence: (options) => ipcRenderer.invoke(IPC_CHANNELS.DISCORD_PRESENCE, options)
38+
setPresence: (options) => ipcRenderer.invoke(IPC_CHANNELS.DISCORD_PRESENCE, options),
39+
getInstallDir: () => ipcRenderer.invoke(IPC_CHANNELS.GET_FOLDER, 'exe')
3940
} satisfies IElectronAPI);

gui/electron/preload/interface.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export interface IElectronAPI {
5555
openFile: (path: string) => void;
5656
ghGet: <T extends GHGet>(options: T) => Promise<GHReturn[T['type']]>;
5757
setPresence: (options: DiscordPresence) => void;
58+
getInstallDir: () => Promise<string>;
5859
}
5960

6061
declare global {

gui/electron/shared.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export interface IpcInvokeMap {
4141
value?: unknown;
4242
}) => Promise<unknown>;
4343
[IPC_CHANNELS.OPEN_FILE]: (path: string) => void;
44-
[IPC_CHANNELS.GET_FOLDER]: (folder: 'config' | 'logs') => string;
44+
[IPC_CHANNELS.GET_FOLDER]: (folder: 'config' | 'logs' | 'exe') => string;
4545
[IPC_CHANNELS.GH_FETCH]: <T extends GHGet>(
4646
options: T
4747
) => Promise<GHReturn[T['type']]>;

gui/public/i18n/en/translation.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,10 @@ onboarding-reset_tutorial-2 = Tap the highlighted tracker { $taps } times to tri
980980
981981
You need to be in a pose like you are skiing as shown in the Automatic Mounting wizard, and you have a 3 second delay (configurable) before it gets triggered.
982982
983+
## Install info
984+
install-info_udev-rules_modal_title = UDEV Rules not found
985+
install-info_udev-rules_warning = Please make sure your udev rules are setup correctly. So you can connect trackers and dongle to USB
986+
install-info_udev-rules_modal_button = Close
983987
## Setup start
984988
onboarding-home = Welcome to SlimeVR
985989
onboarding-home-start = Let's get set up!

gui/src/App.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { AutomaticProportionsPage } from './components/onboarding/pages/body-pro
1717
import { ManualProportionsPage } from './components/onboarding/pages/body-proportions/ManualProportions';
1818
import { ConnectTrackersPage } from './components/onboarding/pages/ConnectTracker';
1919
import { HomePage } from './components/onboarding/pages/Home';
20+
import { ErrorCollectingConsentPage } from './components/onboarding/pages/ErrorCollectingConstent';
2021
import { AutomaticMountingPage } from './components/onboarding/pages/mounting/AutomaticMounting';
2122
import { ManualMountingPage } from './components/onboarding/pages/mounting/ManualMounting';
2223
import { TrackersAssignPage } from './components/onboarding/pages/trackers-assign/TrackerAssignment';
@@ -53,6 +54,7 @@ import { ChecklistPage } from './components/tracking-checklist/TrackingChecklist
5354
import { ElectronContextC, provideElectron } from './hooks/electron';
5455
import { AppLocalizationProvider } from './i18n/config';
5556
import { openUrl } from './hooks/crossplatform';
57+
import { UdevRulesModal } from './components/onboarding/UdevRulesModal';
5658

5759
export const GH_REPO = 'SlimeVR/SlimeVR-Server';
5860
export const VersionContext = createContext('');
@@ -70,6 +72,7 @@ function Layout() {
7072
<SerialDetectionModal />
7173
<VersionUpdateModal />
7274
<UnknownDeviceModal />
75+
<UdevRulesModal />
7376
<SentryRoutes>
7477
<Route element={<AppLayout />}>
7578
<Route
@@ -147,6 +150,10 @@ function Layout() {
147150
}
148151
>
149152
<Route path="home" element={<HomePage />} />
153+
<Route
154+
path="error-collecting-consent"
155+
element={<ErrorCollectingConsentPage />}
156+
/>
150157
<Route path="wifi-creds" element={<WifiCredsPage />} />
151158
<Route path="connect-trackers" element={<ConnectTrackersPage />} />
152159
<Route path="trackers-assign" element={<TrackersAssignPage />} />

gui/src/AppLayout.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { useLayoutEffect } from 'react';
22
import { useConfig } from './hooks/config';
3-
import { Outlet, useNavigate } from 'react-router-dom';
3+
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
44

55
export function AppLayout() {
66
const { config } = useConfig();
7+
const { pathname } = useLocation();
78
const navigate = useNavigate();
89

910
useLayoutEffect(() => {
@@ -28,10 +29,14 @@ export function AppLayout() {
2829
}, [config]);
2930

3031
useLayoutEffect(() => {
31-
if (config && !config.doneOnboarding) {
32+
if (
33+
config &&
34+
!config.doneOnboarding &&
35+
!pathname.startsWith('/onboarding/')
36+
) {
3237
navigate('/onboarding/home');
3338
}
34-
}, [config?.doneOnboarding]);
39+
}, [config]);
3540

3641
return (
3742
<>

gui/src/components/TopBar.tsx

Lines changed: 0 additions & 6 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 { ErrorConsentModal } from './ErrorConsentModal';
2625
import { useAtomValue } from 'jotai';
2726
import { connectedIMUTrackersAtom } from '@/store/app-store';
2827
import { useElectron } from '@/hooks/electron';
@@ -286,11 +285,6 @@ export function TopBar({
286285
setConnectedTrackerWarning(false);
287286
}}
288287
/>
289-
<ErrorConsentModal
290-
isOpen={config?.errorTracking === null}
291-
accept={() => setConfig({ errorTracking: true })}
292-
cancel={() => setConfig({ errorTracking: false })}
293-
/>
294288
</>
295289
);
296290
}

0 commit comments

Comments
 (0)