Files
op-pedal/vite/src/pipedal/AboutDialog.tsx
T
Extremesecrecy d02fe63cce UI Console Errors and Git Errors Fixes, + recommendations (Take 2, careful with const vs var)
UI Console Errors and Git Errors Fixes, + recommendations
Converted several variables to constants and removed unused function parameters in the AboutDialog component, addressing lint warnings

Introduced strict JSON interfaces in AlsaDeviceInfo to replace untyped “any” parameters and ensured returned arrays use constants

Simplified styling callbacks and defined props more strictly in App, while using constants for URL parsing

Updated the WithStyles helper to accept unknown argument lists and return types rather than “any”

Added a workflow step so CI runs npm run lint -- --fix inside the vite directory

Testing
2025-07-24 10:03:57 -07:00

240 lines
9.0 KiB
TypeScript

import React, { SyntheticEvent, Component } from 'react';
import IconButtonEx from './IconButtonEx';
import Typography from '@mui/material/Typography';
import { PiPedalModel, PiPedalModelFactory, State } from './PiPedalModel';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import Divider from '@mui/material/Divider';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import JackHostStatus from './JackHostStatus';
import { PiPedalError } from './PiPedalError';
import DialogEx from './DialogEx';
import Slide, { SlideProps } from '@mui/material/Slide';
interface AboutDialogProps {
open: boolean;
onClose: () => void;
};
interface AboutDialogState {
jackStatus?: JackHostStatus;
openSourceNotices: string;
};
const Transition = React.forwardRef(function Transition(
props: SlideProps, ref: React.Ref<unknown>
) {
return (<Slide direction="up" ref={ref} {...props} />);
});
const AboutDialog = class extends Component<AboutDialogProps, AboutDialogState> {
model: PiPedalModel;
refNotices: React.RefObject<HTMLDivElement | null >;
constructor(props: AboutDialogProps) {
super(props);
this.model = PiPedalModelFactory.getInstance();
this.refNotices = React.createRef();
this.handleDialogClose = this.handleDialogClose.bind(this);
this.state = {
jackStatus: undefined,
openSourceNotices: ""
};
}
mounted: boolean = false;
subscribed: boolean = false;
tick() {
if (this.model.state.get() === State.Ready) {
this.model.getJackStatus()
.then(jackStatus => {
this.setState({ jackStatus: jackStatus });
})
.catch(() => { /* ignore*/ });
}
}
timerHandle?: number;
updateNotifications() {
let subscribed = this.mounted && this.props.open;
if (subscribed !== this.subscribed) {
if (subscribed) {
this.timerHandle = setInterval(() => this.tick(), 1000);
} else {
if (this.timerHandle) {
clearInterval(this.timerHandle);
this.timerHandle = undefined;
}
}
this.subscribed = subscribed;
}
}
startFossRequest() {
if (this.state.openSourceNotices === "") {
fetch("var/notices.txt")
.then((request) => {
if (!request.ok) {
throw new PiPedalError("notices request failed.");
}
return request.text();
})
.then((text) => {
if (this.mounted) {
this.setState({ openSourceNotices: text });
}
})
.catch((err) => {
// ok in debug builds. File doesn't get placed until install time.
console.log("Failed to fetch open-source notices. " + err.toString());
});
}
}
componentDidMount() {
super.componentDidMount?.();
this.mounted = true;
this.updateNotifications();
this.startFossRequest();
}
componentWillUnmount() {
super.componentWillUnmount?.();
this.mounted = false;
this.updateNotifications();
}
componentDidUpdate(prevProps: Readonly<AboutDialogProps>, prevState: Readonly<AboutDialogState>, snapshot: unknown): void {
super.componentDidUpdate?.(prevProps, prevState, snapshot);
this.updateNotifications();
}
handleDialogClose() {
this.props.onClose();
}
render() {
let addressKey = 0;
let serverVersion = this.model.serverVersion?.serverVersion ?? "";
let nPos = serverVersion.indexOf(' ');
if (nPos !== -1) {
serverVersion = serverVersion.substring(nPos + 1);
}
return (
<DialogEx tag="about" fullScreen open={this.props.open}
onClose={() => { this.props.onClose() }} TransitionComponent={Transition}
onEnterKey={() => { this.props.onClose() }}
style={{ userSelect: "none" }}
>
<div style={{ display: "flex", flexDirection: "column", flexWrap: "nowrap", width: "100%", height: "100%", overflow: "hidden" }}>
<div style={{ flex: "0 0 auto" }}>
<AppBar style={{
position: 'relative',
top: 0, left: 0
}} >
<Toolbar>
<IconButtonEx tooltip="Back" edge="start" color="inherit" onClick={this.handleDialogClose} aria-label="back"
>
<ArrowBackIcon />
</IconButtonEx>
<Typography noWrap variant="h6"
sx={{ marginLeft: 2, flex: 1 }}
>
About
</Typography>
</Toolbar>
</AppBar>
</div>
<div style={{
flex: "1 1 auto", position: "relative", overflow: "hidden",
overflowX: "hidden", overflowY: "auto", userSelect: "text"
}}
>
<div id="debug_info" style={{
userSelect: "text",
cursor: "text",margin: 24
}}>
<div style={{ display: "flex", flexFlow: "row nowrap" }}>
<Typography noWrap display="block" variant="h6" color="textPrimary" style={{ flexGrow: 1, flexShrink: 1 }}>
PiPedal <span style={{ fontSize: "0.7em" }}>
{serverVersion
+ (this.model.serverVersion?.debug ? " (Debug)" : "")}
</span>
</Typography>
</div>
<Typography noWrap display="block" variant="body2" style={{ marginBottom: 12 }} >
Copyright &#169; 2022-2025 Robin Davies.
</Typography>
{this.model.isAndroidHosted() && (
<Typography noWrap display="block" variant="body2" style={{ marginBottom: 0 }} >
{this.model.getAndroidHostVersion()}
</Typography>
)}
{this.model.isAndroidHosted() && (
<Typography noWrap display="block" variant="body2" style={{ marginBottom: 12 }} >
Copyright &#169; 2022-2024 Robin Davies.
</Typography>
)}
<Divider />
<Typography noWrap display="block" variant="caption" >
ADDRESSES
</Typography>
<div style={{ marginBottom: 16 }}>
{
this.model.serverVersion?.webAddresses.map((address) =>
(
<Typography key={addressKey++} display="block" variant="body2" style={{ marginBottom: 0, marginLeft: 24 }} >
{address}
</Typography>
))
}
</div>
<Divider />
<Typography noWrap display="block" variant="caption" >
SERVER OS
</Typography>
<div style={{ marginBottom: 16 }}>
<Typography display="block" variant="body2" style={{ marginBottom: 0, marginLeft: 24 }} >
{this.model.serverVersion?.osVersion ?? ""}
</Typography>
</div>
</div><div style={{marginLeft: 24, marginRight: 24}}>
<Divider />
<Typography display="block" variant="caption" >
LEGAL NOTICES
</Typography>
<div dangerouslySetInnerHTML={{ __html: this.state.openSourceNotices }} style={{ fontSize: "0.8em", maxWidth: 400 }}>
</div>
</div>
</div>
</div>
</DialogEx >
);
}
};
export default AboutDialog;