Fix config shenanigans (#836)

This commit is contained in:
Uriel
2023-09-02 17:14:41 -03:00
committed by GitHub
parent 17306c1976
commit 5d773a37ab
5 changed files with 155 additions and 132 deletions

View File

@@ -1,5 +1,5 @@
export default {
"**/*.{ts,tsx}": () => "tsc -p tsconfig.json --noEmit",
"**/*.{js,jsx,ts,tsx}": "eslint --cache --fix",
"**/*.{js,jsx,ts,tsx}": "eslint --max-warnings=0 --cache --fix",
"**/*.{js,jsx,ts,tsx,css,md,json}": "prettier --write"
};

View File

@@ -35,7 +35,6 @@ import { SerialDetectionModal } from './components/SerialDetectionModal';
import { VRCOSCSettings } from './components/settings/pages/VRCOSCSettings';
import { TopBar } from './components/TopBar';
import { TrackerSettingsPage } from './components/tracker/TrackerSettings';
import { useConfig } from './hooks/config';
import { OSCRouterSettings } from './components/settings/pages/OSCRouterSettings';
import { useLocalization } from '@fluent/react';
import * as os from '@tauri-apps/plugin-os';
@@ -52,6 +51,7 @@ import { useBreakpoint } from './hooks/breakpoint';
import { VRModePage } from './components/vr-mode/VRModePage';
import { InterfaceSettings } from './components/settings/pages/InterfaceSettings';
import { error, log } from './utils/logging';
import { AppLayout } from './AppLayout';
export const GH_REPO = 'SlimeVR/SlimeVR-Server';
export const VersionContext = createContext('');
@@ -59,92 +59,94 @@ export const DOCS_SITE = 'https://docs.slimevr.dev';
export const SLIMEVR_DISCORD = 'https://discord.gg/slimevr';
function Layout() {
const { loading } = useConfig();
if (loading) return <></>;
const { isMobile } = useBreakpoint('mobile');
return (
<>
<SerialDetectionModal></SerialDetectionModal>
<VersionUpdateModal></VersionUpdateModal>
<Routes>
<Route
path="/"
element={
<MainLayoutRoute isMobile={isMobile}>
<Home />
</MainLayoutRoute>
}
/>
<Route
path="/vr-mode"
element={
<MainLayoutRoute isMobile={isMobile}>
<VRModePage />
</MainLayoutRoute>
}
/>
<Route
path="/tracker/:trackernum/:deviceid"
element={
<MainLayoutRoute background={false} isMobile={isMobile}>
<TrackerSettingsPage />
</MainLayoutRoute>
}
/>
<Route
path="/settings"
element={
<SettingsLayoutRoute>
<Outlet></Outlet>
</SettingsLayoutRoute>
}
>
<Route path="trackers" element={<GeneralSettings />} />
<Route path="serial" element={<Serial />} />
<Route path="osc/router" element={<OSCRouterSettings />} />
<Route path="osc/vrchat" element={<VRCOSCSettings />} />
<Route path="osc/vmc" element={<VMCSettings />} />
<Route path="interface" element={<InterfaceSettings />} />
<Route element={<AppLayout />}>
<Route
path="/"
element={
<MainLayoutRoute isMobile={isMobile}>
<Home />
</MainLayoutRoute>
}
/>
<Route
path="/vr-mode"
element={
<MainLayoutRoute isMobile={isMobile}>
<VRModePage />
</MainLayoutRoute>
}
/>
<Route
path="/tracker/:trackernum/:deviceid"
element={
<MainLayoutRoute background={false} isMobile={isMobile}>
<TrackerSettingsPage />
</MainLayoutRoute>
}
/>
<Route
path="/settings"
element={
<SettingsLayoutRoute>
<Outlet />
</SettingsLayoutRoute>
}
>
<Route path="trackers" element={<GeneralSettings />} />
<Route path="serial" element={<Serial />} />
<Route path="osc/router" element={<OSCRouterSettings />} />
<Route path="osc/vrchat" element={<VRCOSCSettings />} />
<Route path="osc/vmc" element={<VMCSettings />} />
<Route path="interface" element={<InterfaceSettings />} />
</Route>
<Route
path="/onboarding"
element={
<OnboardingLayout>
<Outlet />
</OnboardingLayout>
}
>
<Route path="home" element={<HomePage />} />
<Route path="wifi-creds" element={<WifiCredsPage />} />
<Route path="connect-trackers" element={<ConnectTrackersPage />} />
<Route
path="calibration-tutorial"
element={<CalibrationTutorialPage />}
/>
<Route
path="assign-tutorial"
element={<AssignmentTutorialPage />}
/>
<Route path="trackers-assign" element={<TrackersAssignPage />} />
<Route path="enter-vr" element={<EnterVRPage />} />
<Route path="mounting/choose" element={<MountingChoose />}></Route>
<Route path="mounting/auto" element={<AutomaticMountingPage />} />
<Route path="mounting/manual" element={<ManualMountingPage />} />
<Route path="reset-tutorial" element={<ResetTutorialPage />} />
<Route
path="body-proportions/choose"
element={<ProportionsChoose />}
/>
<Route
path="body-proportions/auto"
element={<AutomaticProportionsPage />}
/>
<Route
path="body-proportions/manual"
element={<ManualProportionsPage />}
/>
<Route path="done" element={<DonePage />} />
</Route>
<Route path="*" element={<TopBar></TopBar>}></Route>
</Route>
<Route
path="/onboarding"
element={
<OnboardingLayout>
<Outlet></Outlet>
</OnboardingLayout>
}
>
<Route path="home" element={<HomePage />} />
<Route path="wifi-creds" element={<WifiCredsPage />} />
<Route path="connect-trackers" element={<ConnectTrackersPage />} />
<Route
path="calibration-tutorial"
element={<CalibrationTutorialPage />}
/>
<Route path="assign-tutorial" element={<AssignmentTutorialPage />} />
<Route path="trackers-assign" element={<TrackersAssignPage />} />
<Route path="enter-vr" element={<EnterVRPage />} />
<Route path="mounting/choose" element={<MountingChoose />}></Route>
<Route path="mounting/auto" element={<AutomaticMountingPage />} />
<Route path="mounting/manual" element={<ManualMountingPage />} />
<Route path="reset-tutorial" element={<ResetTutorialPage />} />
<Route
path="body-proportions/choose"
element={<ProportionsChoose />}
/>
<Route
path="body-proportions/auto"
element={<AutomaticProportionsPage />}
/>
<Route
path="body-proportions/manual"
element={<ManualProportionsPage />}
/>
<Route path="done" element={<DonePage />} />
</Route>
<Route path="*" element={<TopBar></TopBar>}></Route>
</Routes>
</>
);

51
gui/src/AppLayout.tsx Normal file
View File

@@ -0,0 +1,51 @@
import { useLayoutEffect } from 'react';
import { useConfig } from './hooks/config';
import { Outlet, useNavigate } from 'react-router-dom';
export function AppLayout() {
const { loading, config } = useConfig();
const navigate = useNavigate();
useLayoutEffect(() => {
if (loading || !config) return;
if (config.theme !== undefined) {
document.documentElement.dataset.theme = config.theme;
}
if (config.fonts !== undefined) {
document.documentElement.style.setProperty(
'--font-name',
config.fonts.map((x) => `"${x}"`).join(',')
);
}
if (config.textSize !== undefined) {
document.documentElement.style.setProperty(
'--font-size',
`${config.textSize}rem`
);
}
}, [config, loading]);
useLayoutEffect(() => {
if (config && !config.doneOnboarding) {
navigate('/onboarding/home');
}
}, [config?.doneOnboarding]);
// const location = useLocation();
// const navigationType = useNavigationType();
// useEffect(() => {
// if (import.meta.env.PROD) return;
// console.log('The current URL is', { ...location });
// console.log('The last navigation action was', navigationType);
// }, [location, navigationType]);
if (loading) return <></>;
return (
<>
<Outlet />
</>
);
}

View File

@@ -4,11 +4,9 @@ import {
Reducer,
useContext,
useEffect,
useLayoutEffect,
useMemo,
useReducer,
} from 'react';
import { useNavigate } from 'react-router-dom';
import {
BoneT,
DataFeedMessage,
@@ -59,7 +57,6 @@ export function useProvideAppContext(): AppContext {
useWebsocketAPI();
const { config } = useConfig();
const { dataFeedConfig } = useDataFeedConfig();
const navigate = useNavigate();
const [state, dispatch] = useReducer<Reducer<AppState, AppStateAction>>(reducer, {
datafeed: new DataFeedUpdateT(),
});
@@ -72,12 +69,6 @@ export function useProvideAppContext(): AppContext {
}
}, [isConnected]);
useLayoutEffect(() => {
if (config && !config.doneOnboarding) {
navigate('/onboarding/home');
}
}, [config]);
const trackers = useMemo(
() =>
(state.datafeed?.devices || []).reduce<FlatDeviceTracker[]>(

View File

@@ -1,8 +1,9 @@
import { BaseDirectory, readTextFile } from '@tauri-apps/plugin-fs';
import { createContext, useContext, useRef, useState } from 'react';
import { createContext, useContext, useState } from 'react';
import { DeveloperModeWidgetForm } from '../components/widgets/DeveloperModeWidget';
import { error } from '../utils/logging';
import { useDebouncedEffect } from './timeout';
export interface WindowConfig {
width: number;
@@ -50,42 +51,28 @@ function fallbackToDefaults(loadedConfig: any): Config {
}
export function useConfigProvider(): ConfigContext {
const debounceTimer = useRef<NodeJS.Timeout | null>(null);
const [currConfig, set] = useState<Config | null>(null);
const [loading, setLoading] = useState(false);
useDebouncedEffect(
() => {
if (!currConfig) return;
localStorage.setItem('config.json', JSON.stringify(currConfig));
},
[currConfig],
100
);
const setConfig = async (config: Partial<Config>) => {
const newConfig = config
? {
...currConfig,
...config,
}
: null;
set(newConfig as Config);
if (config.theme !== undefined) {
document.documentElement.dataset.theme = config.theme;
}
if (config.fonts !== undefined) {
document.documentElement.style.setProperty(
'--font-name',
config.fonts.map((x) => `"${x}"`).join(',')
);
}
if (config.textSize !== undefined) {
document.documentElement.style.setProperty(
'--font-size',
`${config.textSize}rem`
);
}
if (!debounceTimer.current) {
debounceTimer.current = setTimeout(async () => {
localStorage.setItem('config.json', JSON.stringify(newConfig));
debounceTimer.current = null;
}, 10);
}
set((curr) =>
config
? ({
...curr,
...config,
} as Config)
: null
);
};
return {
@@ -112,15 +99,7 @@ export function useConfigProvider(): ConfigContext {
const loadedConfig = fallbackToDefaults(JSON.parse(json));
set(loadedConfig);
document.documentElement.dataset.theme = loadedConfig.theme;
document.documentElement.style.setProperty(
'--font-size',
`${loadedConfig.textSize}rem`
);
document.documentElement.style.setProperty(
'--font-name',
loadedConfig.fonts.map((x) => `"${x}"`).join(',')
);
setLoading(false);
return loadedConfig;
} catch (e) {