Voicemeeter-remote-frontend/src/app/component/Bus.tsx
Maksym 3b2fb0264e modified: src/app/component/Bus.tsx
new file:   src/app/component/GainSlider.tsx
	modified:   src/app/component/Strip.tsx
	modified:   src/app/page.tsx
	new file:   src/utils/GetComponentState.ts
	new file:   src/utils/StopPropagation.ts
2024-10-16 18:19:10 +02:00

202 lines
5.7 KiB
TypeScript

"use client";
import {
Button,
ButtonGroup,
Grid,
Input,
Slider,
Stack,
styled,
TextField,
Typography,
} from "@mui/material";
import React from "react";
import { StripBusOutput, StripBusOutputEvent } from "./StripBusOutput";
import { EventCounter } from "@/utils/EventCounter";
import { getComponentState } from "@/utils/GetComponentState";
import { GainSlider, GainSliderOnChangeEvent } from "./GainSlider";
export interface BusProps {
values?: Partial<Omit<BusState, StateDefaultValueException>>;
width: number;
name: string;
onChange: (event: BusEvent) => any;
}
type StateDefaultValueException = "";
export interface BusState {
muted: boolean;
selected: boolean;
}
export type BusEvent = BusMuted | BusGainChanged | BusSelectToggle;
export interface BusGainChanged {
type: "StripGainChanged";
gain: number;
}
export interface BusMuted {
type: "StripMuted";
muted: boolean;
}
export interface BusSelectToggle {
type: "BusSelectToggle";
selected: boolean;
}
export class Bus extends React.Component<BusProps, BusState> {
private defaultValues: Omit<BusState, StateDefaultValueException> = {
selected: false,
muted: false,
};
constructor(props: BusProps) {
super(props);
let { values: initialValues } = props;
this.state = getComponentState<BusState, "">(props.values, this.defaultValues);
}
onKeyDown(event: React.KeyboardEvent) {
console.log(event);
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
event.preventDefault();
}
}
onGainSliderChange(event: GainSliderOnChangeEvent) {
const { gain, type } = event;
if (type === "GainChanged")
this.props.onChange({
type: "StripGainChanged",
gain,
});
}
onMuteToggle(event: React.MouseEvent) {
this.stopPropagation(event);
this.setState(
(state) => ({ muted: !state.muted }),
() => {
this.props.onChange({ type: "StripMuted", muted: this.state.muted });
}
);
}
onSelectToggle(event: React.MouseEvent) {
this.stopPropagation(event);
this.setState(
(state) => ({ selected: !state.selected }),
() => {
this.props.onChange({
type: "BusSelectToggle",
selected: this.state.selected,
});
}
);
}
stopPropagation(event: Event | React.MouseEvent) {
if (event instanceof Event) event.stopImmediatePropagation();
else event.nativeEvent.stopImmediatePropagation();
}
render() {
return (
<>
<Stack
alignItems={"center"}
direction={"row"}
spacing={0}
sx={{ width: "inherit" }}
>
{/* {this.props.width > 600 ? (
// <TextField
// inputProps={{
// "aria-labelledby": "input-slider",
// itemType: "number",
// style:{padding: 0}
// }}
// value={Bus.percentToGain(this.state.gainPercent).toFixed(1)}
// onWheel={(e) => this.onStripWheel(e)}
// onClick={(e) => this.stopPropagation(e)}
// onChange={(e) => {
// e.target.value = Bus.gainToPercent(
// parseInt(e.target.value)
// ).toFixed(0);
// this.onGainSliderChange(e as unknown as Event);
// }}
// size="small"
// label={this.props.name}
// type="number"
// variant="outlined"
// sx={{
// minWidth: "100px",
// maxWidth: "100px",
// height: "",
// marginBlockEnd: "8px",
// }}
// />
) : (
<Typography variant="caption">{this.props.name}</Typography>
)} */}
{/* {this.props.width <= 600 && (
<Typography
position={"absolute"}
paddingInlineStart={"10rem"}
paddingBlockEnd={"2rem"}
fontSize={"0.6rem"}
width={"fit-content"}
variant="caption"
>
{this.state.gain}dB
</Typography>
)} */}
<GainSlider
sliderProps={{
valueLabelDisplay: this.props.width > 600 ? "off" : "on",
}}
onChange={(e) => this.onGainSliderChange(e)}
/>
<ButtonGroup>
<Button
onClick={(e) => this.onMuteToggle(e)}
variant={this.state.muted ? "contained" : "outlined"}
color={"error"}
>
Mute
</Button>
<Button
onClick={(e) => this.onSelectToggle(e)}
sx={{}}
variant={this.state.selected ? "contained" : "outlined"}
color={"warning"}
>
S
</Button>
</ButtonGroup>
</Stack>
{/* <Stack>
<ButtonGroup orientation="vertical">
{[
...Array(this.props.physicalBuses + this.props.virtualBuses),
].map((_v, i) => (
<StripBusOutput
key={`${i < this.props.physicalBuses ? "a" : "b"}${
i < this.props.physicalBuses
? i
: i - this.props.physicalBuses
}`}
id={
i < this.props.physicalBuses
? i
: i - this.props.physicalBuses
}
isVirtual={i < this.props.physicalBuses ? false : true}
onChange={(ev) => this.onBusChange(ev)}
default={{ enabled: this.state.buses[i] }}
/>
))}
</ButtonGroup>
</Stack> */}
</>
);
}
}