modified: .gitignore
modified: next.config.mjs modified: package-lock.json modified: package.json new file: public/manifest.json renamed: src/app/component/BusStrip.tsx -> src/app/component/Bus.tsx modified: src/app/component/Strip.tsx modified: src/app/component/StripBusOutput.tsx modified: src/app/layout.tsx modified: src/app/page.tsx
This commit is contained in:
parent
628cbfe735
commit
df1bb8c35a
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -34,3 +34,6 @@ yarn-error.log*
|
||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
|
**/public/sw.js*
|
||||||
|
**/public/workbox-*.js*
|
|
@ -1,4 +1,14 @@
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {};
|
import nextPWA from "next-pwa";
|
||||||
|
|
||||||
|
const withPWA = nextPWA({
|
||||||
|
dest: "public",
|
||||||
|
register: true,
|
||||||
|
skipWaiting: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const nextConfig = withPWA({
|
||||||
|
experimental: {},
|
||||||
|
});
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|
3675
package-lock.json
generated
3675
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -13,6 +13,7 @@
|
||||||
"@emotion/styled": "^11.11.5",
|
"@emotion/styled": "^11.11.5",
|
||||||
"@mui/material": "^5.15.20",
|
"@mui/material": "^5.15.20",
|
||||||
"next": "14.2.4",
|
"next": "14.2.4",
|
||||||
|
"next-pwa": "^5.6.0",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18"
|
"react-dom": "^18"
|
||||||
},
|
},
|
||||||
|
|
12
public/manifest.json
Normal file
12
public/manifest.json
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"theme_color": "#121212",
|
||||||
|
"background_color": "#121212",
|
||||||
|
"display": "fullscreen",
|
||||||
|
"scope": "/",
|
||||||
|
"start_url": "/",
|
||||||
|
"name": "Voicemeeter Remote Control",
|
||||||
|
"short_name": "VMRC",
|
||||||
|
"icons": {
|
||||||
|
"name": "favicon.ico"
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ export interface StripProps {
|
||||||
physicalBuses: number;
|
physicalBuses: number;
|
||||||
virtualBuses: number;
|
virtualBuses: number;
|
||||||
default?: Partial<StripState>;
|
default?: Partial<StripState>;
|
||||||
onChange: <T extends StripEvent>(event: StripEvent) => any;
|
onChange: (event: BusEvent) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StripState {
|
export interface StripState {
|
||||||
|
@ -16,7 +16,7 @@ export interface StripState {
|
||||||
muted: boolean;
|
muted: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type StripEvent = StripBusOutputChanged | StripMuted | StripGainChanged;
|
export type BusEvent = StripBusOutputChanged | StripMuted | StripGainChanged;
|
||||||
|
|
||||||
export interface StripBusOutputChanged extends StripBusOutputEvent {
|
export interface StripBusOutputChanged extends StripBusOutputEvent {
|
||||||
type: "StripBusOutputChanged";
|
type: "StripBusOutputChanged";
|
||||||
|
@ -31,7 +31,7 @@ export interface StripMuted {
|
||||||
muted: boolean;
|
muted: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Strip extends React.Component<StripProps, StripState> {
|
export class Bus extends React.Component<StripProps, StripState> {
|
||||||
constructor(props: StripProps) {
|
constructor(props: StripProps) {
|
||||||
super(props);
|
super(props);
|
||||||
const buses = (props.default && props.default.buses) || [];
|
const buses = (props.default && props.default.buses) || [];
|
||||||
|
@ -50,6 +50,8 @@ export class Strip extends React.Component<StripProps, StripState> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
onKeyDown(event: React.KeyboardEvent) {
|
onKeyDown(event: React.KeyboardEvent) {
|
||||||
|
console.log(event);
|
||||||
|
|
||||||
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
@ -83,6 +85,9 @@ export class Strip extends React.Component<StripProps, StripState> {
|
||||||
enabled: event.enabled,
|
enabled: event.enabled,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
onStripWheel(event: React.WheelEvent) {
|
||||||
|
console.log(event);
|
||||||
|
}
|
||||||
onMuteToggle() {
|
onMuteToggle() {
|
||||||
this.setState(
|
this.setState(
|
||||||
(state) => ({ muted: !state.muted }),
|
(state) => ({ muted: !state.muted }),
|
||||||
|
@ -94,34 +99,28 @@ export class Strip extends React.Component<StripProps, StripState> {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Grid container>
|
<Grid container sx={{ width: "100%"}}>
|
||||||
<Stack alignItems={"center"}>
|
<Stack alignItems={"center"} direction={"row"}>
|
||||||
<Input
|
<Input
|
||||||
inputProps={{
|
inputProps={{
|
||||||
"aria-labelledby": "input-slider",
|
"aria-labelledby": "input-slider",
|
||||||
itemType: "number",
|
itemType: "number",
|
||||||
}}
|
}}
|
||||||
value={this.state.gain}
|
value={this.state.gain}
|
||||||
|
onWheel={(ev) => this.onStripWheel(ev)}
|
||||||
size="small"
|
size="small"
|
||||||
sx={{ width: "50px" }}
|
sx={{ width: "50px" }}
|
||||||
/>
|
/>
|
||||||
<Slider
|
<Slider
|
||||||
sx={
|
sx={{
|
||||||
{
|
margin: "5px",
|
||||||
margin: "3vh",
|
}}
|
||||||
// minHeight: "30%",
|
// orientation="vertical"
|
||||||
'& input[type="range"]': {
|
|
||||||
WebkitAppearance: "slider-vertical",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
orientation="vertical"
|
|
||||||
defaultValue={0.0}
|
defaultValue={0.0}
|
||||||
step={0.1}
|
step={0.1}
|
||||||
min={-60}
|
min={-60}
|
||||||
max={12}
|
max={12}
|
||||||
value={this.state.gain}
|
value={this.state.gain}
|
||||||
aria-label="Temperature"
|
|
||||||
onChange={(ev) =>
|
onChange={(ev) =>
|
||||||
this.onChange(
|
this.onChange(
|
||||||
ev as unknown as React.ChangeEvent<HTMLInputElement>
|
ev as unknown as React.ChangeEvent<HTMLInputElement>
|
||||||
|
@ -130,15 +129,25 @@ export class Strip extends React.Component<StripProps, StripState> {
|
||||||
onKeyDown={(ev) => this.onKeyDown(ev)}
|
onKeyDown={(ev) => this.onKeyDown(ev)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<ButtonGroup>
|
||||||
onClick={() => this.onMuteToggle()}
|
<Button
|
||||||
variant={this.state.muted ? "contained" : "outlined"}
|
onClick={() => this.onMuteToggle()}
|
||||||
color={"error"}
|
variant={this.state.muted ? "contained" : "outlined"}
|
||||||
>
|
color={"error"}
|
||||||
Mute
|
>
|
||||||
</Button>
|
Mute
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => this.onMuteToggle()}
|
||||||
|
sx={{ }}
|
||||||
|
variant={this.state.muted ? "contained" : "outlined"}
|
||||||
|
color={"warning"}
|
||||||
|
>
|
||||||
|
S
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
{/* <Stack>
|
||||||
<ButtonGroup orientation="vertical">
|
<ButtonGroup orientation="vertical">
|
||||||
{[
|
{[
|
||||||
...Array(this.props.physicalBuses + this.props.virtualBuses),
|
...Array(this.props.physicalBuses + this.props.virtualBuses),
|
||||||
|
@ -160,7 +169,7 @@ export class Strip extends React.Component<StripProps, StripState> {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</Stack>
|
</Stack> */}
|
||||||
</Grid>
|
</Grid>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
|
@ -7,7 +7,7 @@ export interface StripProps {
|
||||||
physicalBuses: number;
|
physicalBuses: number;
|
||||||
virtualBuses: number;
|
virtualBuses: number;
|
||||||
default?: Partial<StripState>;
|
default?: Partial<StripState>;
|
||||||
onChange: <T extends StripEvent>(event: StripEvent) => any;
|
onChange: (event: StripEvent) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StripState {
|
export interface StripState {
|
||||||
|
@ -50,6 +50,8 @@ export class Strip extends React.Component<StripProps, StripState> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
onKeyDown(event: React.KeyboardEvent) {
|
onKeyDown(event: React.KeyboardEvent) {
|
||||||
|
console.log(event);
|
||||||
|
|
||||||
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
@ -98,7 +100,7 @@ export class Strip extends React.Component<StripProps, StripState> {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Grid container>
|
<Grid container sx={{ minHeight: "263px", minWidth: "112px" }}>
|
||||||
<Stack alignItems={"center"}>
|
<Stack alignItems={"center"}>
|
||||||
<Input
|
<Input
|
||||||
inputProps={{
|
inputProps={{
|
||||||
|
@ -113,10 +115,6 @@ export class Strip extends React.Component<StripProps, StripState> {
|
||||||
<Slider
|
<Slider
|
||||||
sx={{
|
sx={{
|
||||||
margin: "5px",
|
margin: "5px",
|
||||||
// minHeight: "30%",
|
|
||||||
'& input[type="range"]': {
|
|
||||||
WebkitAppearance: "slider-vertical",
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
orientation="vertical"
|
orientation="vertical"
|
||||||
defaultValue={0.0}
|
defaultValue={0.0}
|
||||||
|
|
|
@ -47,7 +47,7 @@ export class StripBusOutput extends React.Component<StripProps, StripState> {
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
sx={{ width: "5px" }}
|
sx={{ width: "5px", height: "35px" }}
|
||||||
onClick={(ev) => this.onClick(ev)}
|
onClick={(ev) => this.onClick(ev)}
|
||||||
variant={this.state.enabled ? "contained" : "outlined"}
|
variant={this.state.enabled ? "contained" : "outlined"}
|
||||||
>
|
>
|
||||||
|
|
|
@ -2,6 +2,9 @@ import "@fontsource/roboto/300.css";
|
||||||
import "@fontsource/roboto/400.css";
|
import "@fontsource/roboto/400.css";
|
||||||
import "@fontsource/roboto/500.css";
|
import "@fontsource/roboto/500.css";
|
||||||
import "@fontsource/roboto/700.css";
|
import "@fontsource/roboto/700.css";
|
||||||
|
import { createTheme, CssBaseline, ThemeProvider } from "@mui/material";
|
||||||
|
import { Metadata, Viewport } from "next";
|
||||||
|
import Head from "next/head";
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
|
@ -10,6 +13,9 @@ export default function RootLayout({
|
||||||
}>) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
<Head>
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
</Head>
|
||||||
<body>{children}</body>
|
<body>{children}</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|
117
src/app/page.tsx
117
src/app/page.tsx
|
@ -1,7 +1,17 @@
|
||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Strip, StripEvent } from "./component/Strip";
|
import { Strip, StripEvent } from "./component/Strip";
|
||||||
import { Button, Container, Divider, Stack } from "@mui/material";
|
import {
|
||||||
|
Button,
|
||||||
|
Container,
|
||||||
|
createTheme,
|
||||||
|
CssBaseline,
|
||||||
|
Divider,
|
||||||
|
Stack,
|
||||||
|
ThemeProvider,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { Bus } from "./component/Bus";
|
||||||
|
|
||||||
function random(min: number, max: number, floor: boolean = true) {
|
function random(min: number, max: number, floor: boolean = true) {
|
||||||
const value = Math.random() * (max - min + 1) + min;
|
const value = Math.random() * (max - min + 1) + min;
|
||||||
|
@ -15,35 +25,86 @@ export default function Home() {
|
||||||
const physicalBuses = 5;
|
const physicalBuses = 5;
|
||||||
const virtualBuses = 3;
|
const virtualBuses = 3;
|
||||||
const strips = physicalBuses + virtualBuses;
|
const strips = physicalBuses + virtualBuses;
|
||||||
|
let clicks = 0;
|
||||||
|
let timeout: NodeJS.Timeout | undefined;
|
||||||
|
document.body.onclick = (e) => {
|
||||||
|
clicks++;
|
||||||
|
if (timeout !== undefined) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = undefined;
|
||||||
|
}
|
||||||
|
timeout = setTimeout(() => (clicks = 0), 500);
|
||||||
|
if (clicks < 2) return;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
clicks = 0;
|
||||||
|
console.log(e.target);
|
||||||
|
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
if (document.fullscreenElement !== null) document.exitFullscreen();
|
||||||
|
else document.body.requestFullscreen({ navigationUI: "hide" });
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container fixed maxWidth="xl" sx={{ height: "100%" }}>
|
<ThemeProvider theme={createTheme({ palette: { mode: "dark" } })}>
|
||||||
<Stack direction={"row"}>
|
<Container maxWidth="xl" sx={{ height: "100%" }}>
|
||||||
{[...Array(strips)].map((_v, i) => (
|
<div>
|
||||||
<React.Fragment
|
<CssBaseline />
|
||||||
key={`${i < physicalBuses ? "a" : "b"}${
|
<Typography variant="h5">Inputs</Typography>
|
||||||
i < physicalBuses ? i : i - physicalBuses
|
<Stack direction={"row"}>
|
||||||
}`}
|
{[...Array(strips)].map((_v, i) => (
|
||||||
>
|
<React.Fragment
|
||||||
{i === physicalBuses ? (
|
key={`${i < physicalBuses ? "a" : "b"}${
|
||||||
<Divider
|
i < physicalBuses ? i : i - physicalBuses
|
||||||
orientation="vertical"
|
}`}
|
||||||
variant="middle"
|
>
|
||||||
sx={{ margin: "5px" }}
|
{i === physicalBuses ? (
|
||||||
/>
|
<Divider
|
||||||
) : (
|
orientation="vertical"
|
||||||
""
|
variant="middle"
|
||||||
)}
|
sx={{ marginInlineEnd: "15px" }}
|
||||||
<Strip
|
/>
|
||||||
onChange={(ev) => onStripEvent(ev)}
|
) : (
|
||||||
physicalBuses={physicalBuses}
|
""
|
||||||
virtualBuses={virtualBuses}
|
)}
|
||||||
/>
|
<Strip
|
||||||
</React.Fragment>
|
onChange={(ev) => onStripEvent(ev)}
|
||||||
))}
|
physicalBuses={physicalBuses}
|
||||||
</Stack>
|
virtualBuses={virtualBuses}
|
||||||
|
/>
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
<Typography variant="h5">Outputs</Typography>
|
||||||
|
<Stack direction={"column"}>
|
||||||
|
{[...Array(strips)].map((_v, i) => (
|
||||||
|
<React.Fragment
|
||||||
|
key={`${i < physicalBuses ? "a" : "b"}${
|
||||||
|
i < physicalBuses ? i : i - physicalBuses
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{i === physicalBuses ? (
|
||||||
|
<Divider
|
||||||
|
orientation="vertical"
|
||||||
|
variant="middle"
|
||||||
|
sx={{ margin: "5px" }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
<Bus
|
||||||
|
onChange={(ev) => onStripEvent(ev)}
|
||||||
|
physicalBuses={physicalBuses}
|
||||||
|
virtualBuses={virtualBuses}
|
||||||
|
/>
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
|
||||||
<Button></Button>
|
<Button></Button>
|
||||||
</Container>
|
</div>
|
||||||
|
</Container>
|
||||||
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user