fix bugs and stuff

This commit is contained in:
Uriel
2024-12-19 21:54:42 +01:00
parent 9d65477af7
commit b7a54f6aef
9 changed files with 109 additions and 78 deletions

View File

@@ -266,6 +266,11 @@ tracker-settings-name_section-label = Tracker name
tracker-settings-forget = Forget tracker
tracker-settings-forget-description = Removes the tracker from the SlimeVR Server and prevent it from connecting to it until the server is restarted. The configuration of the tracker won't be lost.
tracker-settings-forget-label = Forget tracker
tracker-settings-update-unavailable = Cannot be updated (DIY)
tracker-settings-update-up_to_date = Up to date
tracker-settings-update-available = { $versionName } is now available
tracker-settings-update = Update now
tracker-settings-update-title = Firmware version
## Tracker part card info
tracker-part_card-no_name = No name
@@ -1210,8 +1215,8 @@ firmware-update_status_ERROR_UNKNOWN = Unknown error
## Dedicated Firmware Update Page
firmware-update_title = Firmware update
firmware-update_devices = Available Devices
firmware-update_devices_desc = Please select the trackers you want to update to the lastest version of SlimeVR firmware
firmware-update_no-devices = Plase make sure that the trackers you want to update are ON and connected to Wi-Fi!
firmware-update_devices_desc = Please select the trackers you want to update to the latest version of SlimeVR firmware
firmware-update_no-devices = Plase make sure that the trackers you want to update are ON and connected to the Wi-Fi!
firmware-update_changelog_title = Updating to {$version}
firmware-update_looking-for-devices = Looking for devices to update...
firmware-update_retry = Retry

View File

@@ -1,11 +1,13 @@
import { open } from '@tauri-apps/plugin-shell';
import { ReactNode } from 'react';
export function A({ href, children }: { href: string; children?: ReactNode }) {
export function A({ href, children }: { href?: string; children?: ReactNode }) {
return (
<a
href="javascript:void(0)"
onClick={() => open(href).catch(() => window.open(href, '_blank'))}
onClick={() =>
href && open(href).catch(() => window.open(href, '_blank'))
}
className="underline"
>
{children}

View File

@@ -10,6 +10,7 @@ import {
FirmwareUpdateStatus,
FirmwareUpdateStatusResponseT,
FirmwareUpdateStopQueuesRequestT,
HardwareInfoT,
RpcMessage,
TrackerStatus,
} from 'solarxr-protocol';
@@ -19,7 +20,7 @@ import { Button } from '@/components/commons/Button';
import Markdown from 'react-markdown';
import remark from 'remark-gfm';
import { WarningBox } from '@/components/commons/TipBox';
import { useAppContext } from '@/hooks/app';
import { FirmwareRelease, useAppContext } from '@/hooks/app';
import { DeviceCardControl } from '@/components/firmware-tool/DeviceCard';
import { Control, useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom';
@@ -32,6 +33,23 @@ import {
import { yupResolver } from '@hookform/resolvers/yup';
import { object } from 'yup';
import { LoaderIcon, SlimeState } from '@/components/commons/icon/LoaderIcon';
import { A } from '@/components/commons/A';
export function checkForUpdate(
currentFirmwareRelease: FirmwareRelease,
hardwareInfo: HardwareInfoT
) {
return (
// TODO: This is temporary, end goal is to support all board types
hardwareInfo.officialBoardType === BoardType.SLIMEVR &&
semver.valid(currentFirmwareRelease.version) &&
semver.valid(hardwareInfo.firmwareVersion?.toString() ?? 'none') &&
semver.lt(
hardwareInfo.firmwareVersion?.toString() ?? 'none',
currentFirmwareRelease.version
)
);
}
interface FirmwareUpdateForm {
selectedDevices: { [key: string]: boolean };
@@ -88,9 +106,7 @@ const StatusList = ({ status }: { status: Record<string, UpdateStatus> }) => {
};
const MarkdownLink = (props: ComponentProps<'a'>) => (
<a target="_blank" href={props.href}>
{props.children}
</a>
<A href={props.href}>{props.children}</A>
);
export function FirmwareUpdate() {
@@ -105,15 +121,10 @@ export function FirmwareUpdate() {
state.datafeed?.devices.filter(
({ trackers, hardwareInfo }) =>
trackers.length > 0 &&
hardwareInfo?.officialBoardType === BoardType.SLIMEVR &&
currentFirmwareRelease &&
semver.valid(currentFirmwareRelease.version) &&
semver.valid(hardwareInfo?.firmwareVersion?.toString() ?? 'none') &&
semver.lt(
hardwareInfo?.firmwareVersion?.toString() ?? 'none',
currentFirmwareRelease.version
) &&
trackers.every(({ status }) => status == TrackerStatus.OK)
hardwareInfo &&
checkForUpdate(currentFirmwareRelease, hardwareInfo) &&
trackers.every(({ status }) => status === TrackerStatus.OK)
) || [];
useRPCPacket(
@@ -127,7 +138,7 @@ export function FirmwareUpdate() {
if (!id) throw new Error('invalid device id');
const selectedDevice = selectedDevices?.find(
({ deviceId }) => deviceId == id.toString()
({ deviceId }) => deviceId === id.toString()
);
// We skip the status as it can be old trackers still sending status
@@ -186,6 +197,7 @@ export function FirmwareUpdate() {
useEffect(() => {
if (!currentFirmwareRelease) {
navigate('/');
return;
}
return () => {
clear();
@@ -196,7 +208,6 @@ export function FirmwareUpdate() {
clear();
const firmwareFile = currentFirmwareRelease?.firmwareFile;
if (!firmwareFile) throw new Error('invalid state - no firmware file');
console.log(firmwareFile);
const requests = getFlashingRequests(
selectedDevices,
[{ isFirmware: true, firmwareId: '', url: firmwareFile, offset: 0 }],
@@ -209,8 +220,12 @@ export function FirmwareUpdate() {
});
};
const trackerWithErrors = Object.keys(status).filter((id) =>
firmwareUpdateErrorStatus.includes(status[id].status)
const trackerWithErrors = useMemo(
() =>
Object.keys(status).filter((id) =>
firmwareUpdateErrorStatus.includes(status[id].status)
),
[status]
);
const hasPendingTrackers = useMemo(
@@ -252,7 +267,7 @@ export function FirmwareUpdate() {
reset({
selectedDevices: devices.reduce(
(curr, { deviceId }) => ({ ...curr, [deviceId]: false }),
(curr, { deviceId }) => ({ ...curr, [deviceId]: true }),
{}
),
});
@@ -263,7 +278,7 @@ export function FirmwareUpdate() {
const selectedDevices = Object.keys(selectedDevicesForm)
.filter((d) => selectedDevicesForm[d])
.map((id) => {
const device = devices.find(({ id: dId }) => id == dId?.id.toString());
const device = devices.find(({ id: dId }) => id === dId?.id.toString());
if (!device) throw new Error('no device found');
return {
@@ -285,22 +300,20 @@ export function FirmwareUpdate() {
const statusKeys = Object.keys(status);
return (
<div className="flex flex-col p-4 w-full items-center justify-center h-screen">
<div className="mobile:w-full w-10/12 h-full flex flex-col gap-2">
<div className="flex flex-col p-4 w-full items-center justify-center">
<div className="mobile:w-full w-10/12 h-full flex flex-col gap-2">
<Localized id="firmware-update_title">
<Typography variant="main-title"></Typography>
</Localized>
<div className="grid md:grid-cols-2 xs:grid-cols-1 gap-5">
<div className={'flex flex-col gap-2'}>
<div className="flex flex-col gap-2">
<Localized id="firmware-update_devices">
<Typography variant="section-title"></Typography>
</Localized>
<Localized id="firmware-update_devices_desc">
<Typography variant="standard" color="secondary"></Typography>
</Localized>
<div
className={'flex flex-col gap-4 overflow-y-auto xs:max-h-[530px]'}
>
<div className="flex flex-col gap-4 overflow-y-auto xs:max-h-[530px]">
{devices.length === 0 &&
!hasPendingTrackers &&
statusKeys.length == 0 && (
@@ -309,7 +322,7 @@ export function FirmwareUpdate() {
</Localized>
)}
{shouldShowRebootWarning && (
<Localized id="firmware-tool-flashing-step-warning">
<Localized id="firmware-tool_flashing-step_warning">
<WarningBox>Warning</WarningBox>
</Localized>
)}
@@ -346,7 +359,9 @@ export function FirmwareUpdate() {
remarkPlugins={[remark]}
components={{ a: MarkdownLink }}
className={classNames(
'w-full text-sm prose-xl prose text-background-10 prose-h1:text-background-10 prose-h2:text-background-10 prose-a:text-background-20 prose-strong:text-background-10 prose-code:text-background-20'
'w-full text-sm prose-xl prose text-background-10 prose-h1:text-background-10',
'prose-h2:text-background-10 prose-a:text-background-20 prose-strong:text-background-10',
'prose-code:text-background-20'
)}
>
{currentFirmwareRelease?.changelog}
@@ -354,7 +369,7 @@ export function FirmwareUpdate() {
</div>
</div>
</div>
<div className="flex justify-end w-full pb-2 gap-2 mobile:flex-col">
<div className="flex justify-end pb-2 gap-2 mobile:flex-col">
<Localized id="firmware-update_retry">
<Button
variant="secondary"
@@ -365,7 +380,6 @@ export function FirmwareUpdate() {
<Localized id="firmware-update_update">
<Button
variant="primary"
className="mobile:w-full"
disabled={!canStartUpdate}
onClick={startUpdate}
></Button>

View File

@@ -1,6 +1,5 @@
import { MouseEventHandler } from 'react';
import {
BoardType,
DeviceDataT,
TrackerDataT,
TrackerStatus as TrackerStatusEnum,
@@ -13,9 +12,9 @@ import classNames from 'classnames';
import { useTracker } from '@/hooks/tracker';
import { BodyPartIcon } from '@/components/commons/BodyPartIcon';
import { DownloadIcon } from '@/components/commons/icon/DownloadIcon';
import semver from 'semver';
import { Link } from 'react-router-dom';
import { useAppContext } from '@/hooks/app';
import { checkForUpdate } from '@/components/firmware-update/FirmwareUpdate';
function TrackerBig({
device,
@@ -169,17 +168,9 @@ export function TrackerCard({
</div>
{showUpdates &&
tracker.status !== TrackerStatusEnum.DISCONNECTED &&
// This is temporary, end goal is to support all board types
device?.hardwareInfo?.officialBoardType === BoardType.SLIMEVR &&
currentFirmwareRelease &&
semver.valid(currentFirmwareRelease.version) &&
semver.valid(
device?.hardwareInfo?.firmwareVersion?.toString() ?? 'none'
) &&
semver.lt(
device?.hardwareInfo?.firmwareVersion?.toString() ?? 'none',
currentFirmwareRelease.version
) && (
device?.hardwareInfo &&
checkForUpdate(currentFirmwareRelease, device.hardwareInfo) && (
<Link to="/firmware-update" className="absolute right-5 -top-2.5">
<div className="relative">
<div className="absolute rounded-full h-6 w-6 left-1 top-1 bg-accent-background-10 animate-[ping_2s_linear_infinite]"></div>

View File

@@ -1,4 +1,4 @@
import { useLocalization } from '@fluent/react';
import { Localized, useLocalization } from '@fluent/react';
import classNames from 'classnames';
import { IPv4 } from 'ip-num/IPNumber';
import { useEffect, useMemo, useState } from 'react';
@@ -38,6 +38,7 @@ import { Quaternion } from 'three';
import { useAppContext } from '@/hooks/app';
import { MagnetometerToggleSetting } from '@/components/settings/pages/MagnetometerToggleSetting';
import semver from 'semver';
import { checkForUpdate } from '@/components/firmware-update/FirmwareUpdate';
const rotationsLabels: [Quaternion, string][] = [
[rotationToQuatMap.BACK, 'tracker-rotation-back'],
@@ -186,16 +187,9 @@ export function TrackerSettingsPage() {
const { currentFirmwareRelease } = useAppContext();
const needUpdate =
tracker?.device?.hardwareInfo?.officialBoardType === BoardType.SLIMEVR &&
currentFirmwareRelease &&
semver.valid(currentFirmwareRelease.version) &&
semver.valid(
tracker?.device?.hardwareInfo?.firmwareVersion?.toString() ?? 'none'
) &&
semver.lt(
tracker?.device?.hardwareInfo?.firmwareVersion?.toString() ?? 'none',
currentFirmwareRelease.version
);
tracker?.device?.hardwareInfo &&
checkForUpdate(currentFirmwareRelease, tracker?.device?.hardwareInfo);
const updateUnavailable =
tracker?.device?.hardwareInfo?.officialBoardType !== BoardType.SLIMEVR ||
!semver.valid(
@@ -231,33 +225,50 @@ export function TrackerSettingsPage() {
)}
{
<div className="flex flex-col bg-background-70 p-3 rounded-lg gap-2">
<Typography bold>Firmware version</Typography>
<Localized id="tracker-settings-update-title">
<Typography variant="section-title">
Firmware version
</Typography>
</Localized>
<div className="flex gap-2">
<Typography color="secondary">
v{tracker?.device?.hardwareInfo?.firmwareVersion}
</Typography>
<Typography color="secondary">-</Typography>
{updateUnavailable && (
<Typography>Cannot be updated (DIY)</Typography>
<Localized id="tracker-settings-update-unavailable">
<Typography>Cannot be updated (DIY)</Typography>
</Localized>
)}
{!updateUnavailable && (
<>
{!needUpdate && <Typography>Up to date</Typography>}
{!needUpdate && (
<Localized id="tracker-settings-update-up_to_date">
<Typography>Up to date</Typography>
</Localized>
)}
{needUpdate && (
<Typography color="text-accent-background-10">
New version available {currentFirmwareRelease?.name}
</Typography>
<Localized
id="tracker-settings-update-available"
vars={{ versionName: currentFirmwareRelease?.name }}
>
<Typography color="text-accent-background-10">
New version available
</Typography>
</Localized>
)}
</>
)}
</div>
<Button
variant={needUpdate ? 'primary' : 'secondary'}
disabled={!needUpdate}
to="/firmware-update"
>
Update now
</Button>
<Localized id="tracker-settings-update">
<Button
variant={needUpdate ? 'primary' : 'secondary'}
disabled={!needUpdate}
to="/firmware-update"
>
Update now
</Button>
</Localized>
</div>
}

View File

@@ -135,7 +135,7 @@ export function useProvideAppContext(): AppContext {
() =>
fetch('https://api.github.com/repos/SlimeVR/SlimeVR-Tracker-ESP/releases')
.then((res) => res.text())
.catch((_) => 'null'),
.catch(() => 'null'),
1000 * 60 * 60
)
);
@@ -159,7 +159,7 @@ export function useProvideAppContext(): AppContext {
if (firstRelease) {
return {
name: firstRelease.name,
version: version,
version,
changelog: firstRelease.body,
firmwareFile: firstRelease.assets.find(
(asset: any) =>

View File

@@ -56,7 +56,7 @@ export async function cacheWrap(
const realItem = await store.get(key);
if (!realItem) {
const defaultItem = await orDefault();
cacheSet(key, defaultItem, ttl);
await cacheSet(key, defaultItem, ttl);
return defaultItem;
} else {
return (await cacheGet(key))!;

View File

@@ -382,6 +382,14 @@ body {
background: theme('colors.background.60');
}
.bg-background-60::-webkit-scrollbar-thumb:hover {
background: theme('colors.background.40');
}
.bg-background-60 {
scrollbar-color: theme('colors.background.50') transparent;
}
.dropdown-scroll {
scrollbar-color: theme('colors.background.40') theme('colors.background.50');
}

16
pnpm-lock.yaml generated
View File

@@ -191,7 +191,7 @@ importers:
version: 8.57.1
eslint-config-airbnb:
specifier: ^19.0.4
version: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.1(eslint@8.57.1))(eslint@8.57.1)
version: 19.0.4(eslint-plugin-import@2.31.0)(eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.1(eslint@8.57.1))(eslint@8.57.1)
eslint-import-resolver-typescript:
specifier: ^3.6.3
version: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1)
@@ -6195,7 +6195,7 @@ snapshots:
escape-string-regexp@5.0.0: {}
eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1))(eslint@8.57.1):
eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0)(eslint@8.57.1):
dependencies:
confusing-browser-globals: 1.0.11
eslint: 8.57.1
@@ -6204,10 +6204,10 @@ snapshots:
object.entries: 1.1.8
semver: 6.3.1
eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.1(eslint@8.57.1))(eslint@8.57.1):
eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0)(eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.1(eslint@8.57.1))(eslint@8.57.1):
dependencies:
eslint: 8.57.1
eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1))(eslint@8.57.1)
eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0)(eslint@8.57.1)
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1)
eslint-plugin-react: 7.37.1(eslint@8.57.1)
@@ -6229,7 +6229,7 @@ snapshots:
debug: 4.3.5
enhanced-resolve: 5.17.0
eslint: 8.57.1
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
fast-glob: 3.3.2
get-tsconfig: 4.7.5
is-bun-module: 1.2.1
@@ -6242,7 +6242,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1):
eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
dependencies:
debug: 3.2.7
optionalDependencies:
@@ -6253,7 +6253,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1):
eslint-module-utils@2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
dependencies:
debug: 3.2.7
optionalDependencies:
@@ -6274,7 +6274,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
hasown: 2.0.2
is-core-module: 2.15.1
is-glob: 4.0.3