mirror of
https://github.com/SlimeVR/SlimeVR-Server.git
synced 2026-04-06 02:01:58 +02:00
4
package-lock.json
generated
4
package-lock.json
generated
@@ -14780,7 +14780,7 @@
|
||||
},
|
||||
"node_modules/solarxr-protocol": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "git+ssh://git@github.com/SlimeVR/SolarXR-Protocol.git#d726aed10154539717e9179323babdf55fbf3a16",
|
||||
"resolved": "git+ssh://git@github.com/SlimeVR/SolarXR-Protocol.git#40e3c5ef8431ec7c9b5ea0446a7fe3590bb7596f",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"flatbuffers": "^2.0.6"
|
||||
@@ -25335,7 +25335,7 @@
|
||||
}
|
||||
},
|
||||
"solarxr-protocol": {
|
||||
"version": "git+ssh://git@github.com/SlimeVR/SolarXR-Protocol.git#d726aed10154539717e9179323babdf55fbf3a16",
|
||||
"version": "git+ssh://git@github.com/SlimeVR/SolarXR-Protocol.git#40e3c5ef8431ec7c9b5ea0446a7fe3590bb7596f",
|
||||
"from": "solarxr-protocol@github:SlimeVR/SolarXR-Protocol",
|
||||
"requires": {
|
||||
"flatbuffers": "^2.0.6"
|
||||
|
||||
@@ -23,7 +23,7 @@ export function BVHButton() {
|
||||
return (
|
||||
<BigButton
|
||||
text={recording ? 'Recording...' : 'Record BVH'}
|
||||
icon={<RecordIcon />}
|
||||
icon={<RecordIcon width={20} />}
|
||||
onClick={toggleBVH}
|
||||
></BigButton>
|
||||
);
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Navbar } from './Navbar';
|
||||
import { ResetButton } from './home/ResetButton';
|
||||
import { TopBar } from './TopBar';
|
||||
import classNames from 'classnames';
|
||||
import { OverlayWidget } from './widgets/OverlayWidget';
|
||||
|
||||
export function MainLayoutRoute({
|
||||
children,
|
||||
@@ -39,16 +40,15 @@ export function MainLayoutRoute({
|
||||
{children}
|
||||
</div>
|
||||
{widgets && (
|
||||
<div className="flex flex-col px-4 min-w-[274px] w-[274px] gap-2 pt-4 rounded-xl overflow-y-auto bg-background-70">
|
||||
<div className="flex">
|
||||
<div className="flex flex-col px-2 min-w-[274px] w-[274px] gap-2 pt-2 rounded-xl overflow-y-auto bg-background-70">
|
||||
<div className="grid grid-cols-3 gap-2 w-full">
|
||||
<ResetButton type={ResetType.Quick}></ResetButton>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<ResetButton type={ResetType.Full}></ResetButton>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<BVHButton></BVHButton>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<OverlayWidget></OverlayWidget>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@ export function BigButton({
|
||||
{...props}
|
||||
type="button"
|
||||
className={classNames(
|
||||
'flex w-full justify-center rounded-md py-5 gap-5 px-5 cursor-pointer items-center ',
|
||||
'flex flex-col justify-center rounded-md py-3 gap-1 px-3 cursor-pointer items-center ',
|
||||
{
|
||||
'bg-background-60 hover:bg-background-60 cursor-not-allowed text-background-40 fill-background-40':
|
||||
disabled,
|
||||
|
||||
@@ -38,7 +38,7 @@ export function CheckBox({
|
||||
<Controller
|
||||
control={control}
|
||||
name={name}
|
||||
render={({ field: { onChange, value, ref } }) => (
|
||||
render={({ field: { onChange, value, ref, onBlur, name } }) => (
|
||||
<div
|
||||
className={classNames(
|
||||
{
|
||||
@@ -58,6 +58,7 @@ export function CheckBox({
|
||||
ref={ref}
|
||||
onChange={onChange}
|
||||
checked={value}
|
||||
name={name}
|
||||
className={classes.checkbox}
|
||||
type="checkbox"
|
||||
{...props}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export function RecordIcon() {
|
||||
export function RecordIcon({ width = 33 }: { width?: number }) {
|
||||
return (
|
||||
<svg width="33" height="29" viewBox="0 0 24 24">
|
||||
<svg width={width} viewBox="0 0 24 24">
|
||||
<path d="M20.84 2.18L16.91 2.96L19.65 6.5L21.62 6.1L20.84 2.18M13.97 3.54L12 3.93L14.75 7.46L16.71 7.07L13.97 3.54M9.07 4.5L7.1 4.91L9.85 8.44L11.81 8.05L9.07 4.5M4.16 5.5L3.18 5.69A2 2 0 0 0 1.61 8.04L2 10L6.9 9.03L4.16 5.5M2 10V20C2 21.11 2.9 22 4 22H20C21.11 22 22 21.11 22 20V10H2Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export function ResetIcon() {
|
||||
export function ResetIcon({ width = 33 }: { width?: number }) {
|
||||
return (
|
||||
<svg
|
||||
width="33"
|
||||
width={width}
|
||||
height="29"
|
||||
viewBox="0 0 33 29"
|
||||
fill="none"
|
||||
@@ -25,11 +25,10 @@ export function ResetIcon() {
|
||||
);
|
||||
}
|
||||
|
||||
export function QuickResetIcon() {
|
||||
export function QuickResetIcon({ width = 33 }: { width?: number }) {
|
||||
return (
|
||||
<svg
|
||||
width="33"
|
||||
height="29"
|
||||
width={width}
|
||||
viewBox="0 0 33 29"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@@ -42,7 +42,13 @@ export function ResetButton({ type }: { type: ResetType }) {
|
||||
: 'Reset'
|
||||
: `${3 - timer}`
|
||||
}
|
||||
icon={type === ResetType.Quick ? <QuickResetIcon /> : <ResetIcon />}
|
||||
icon={
|
||||
type === ResetType.Quick ? (
|
||||
<QuickResetIcon width={20} />
|
||||
) : (
|
||||
<ResetIcon width={20} />
|
||||
)
|
||||
}
|
||||
onClick={reset}
|
||||
disabled={reseting}
|
||||
></BigButton>
|
||||
|
||||
70
src/components/widgets/OverlayWidget.tsx
Normal file
70
src/components/widgets/OverlayWidget.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import {
|
||||
OverlayDisplayModeChangeRequestT,
|
||||
OverlayDisplayModeRequestT,
|
||||
OverlayDisplayModeResponseT,
|
||||
RpcMessage,
|
||||
} from 'solarxr-protocol';
|
||||
import { useWebsocketAPI } from '../../hooks/websocket-api';
|
||||
import { CheckBox } from '../commons/Checkbox';
|
||||
|
||||
export function OverlayWidget() {
|
||||
const { sendRPCPacket, useRPCPacket } = useWebsocketAPI();
|
||||
|
||||
const { reset, control, handleSubmit, watch, setValue } = useForm<{
|
||||
isVisible: boolean;
|
||||
isMirrored: boolean;
|
||||
}>({
|
||||
defaultValues: {
|
||||
isVisible: false,
|
||||
isMirrored: false,
|
||||
},
|
||||
});
|
||||
|
||||
useRPCPacket(
|
||||
RpcMessage.OverlayDisplayModeResponse,
|
||||
(res: OverlayDisplayModeResponseT) => {
|
||||
reset({
|
||||
isMirrored: res.isMirrored,
|
||||
isVisible: res.isVisible,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
sendRPCPacket(
|
||||
RpcMessage.OverlayDisplayModeRequest,
|
||||
new OverlayDisplayModeRequestT()
|
||||
);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const subscription = watch(() => handleSubmit(onSubmit)());
|
||||
return () => subscription.unsubscribe();
|
||||
}, []);
|
||||
|
||||
const onSubmit = (val: { isVisible: boolean; isMirrored: boolean }) => {
|
||||
const req = new OverlayDisplayModeChangeRequestT();
|
||||
req.isMirrored = val.isMirrored;
|
||||
req.isVisible = val.isVisible;
|
||||
sendRPCPacket(RpcMessage.OverlayDisplayModeChangeRequest, req);
|
||||
};
|
||||
|
||||
return (
|
||||
<form className="bg-background-60 flex flex-col w-full rounded-md px-2">
|
||||
<CheckBox
|
||||
control={control}
|
||||
name="isVisible"
|
||||
variant="toggle"
|
||||
label="Show overlay in SteamVR"
|
||||
></CheckBox>
|
||||
<CheckBox
|
||||
control={control}
|
||||
name="isMirrored"
|
||||
variant="toggle"
|
||||
label="display overlay as mirror"
|
||||
></CheckBox>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user