Clean shutdown, stability
This commit is contained in:
+46
-22
@@ -6,7 +6,7 @@ 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 ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
||||
|
||||
import JackHostStatus from './JackHostStatus';
|
||||
import { PiPedalError } from './PiPedalError';
|
||||
@@ -16,12 +16,9 @@ import { Theme, createStyles } from '@mui/material/styles';
|
||||
import { withStyles, WithStyles } from '@mui/styles';
|
||||
import Slide, { SlideProps } from '@mui/material/Slide';
|
||||
|
||||
|
||||
interface AboutDialogProps extends WithStyles<typeof styles> {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
|
||||
|
||||
};
|
||||
|
||||
interface AboutDialogState {
|
||||
@@ -76,6 +73,15 @@ const styles = (theme: Theme) => createStyles({
|
||||
},
|
||||
secondaryItem: {
|
||||
|
||||
},
|
||||
can_select: {
|
||||
userSelect: "text",
|
||||
cursor: "text"
|
||||
},
|
||||
no_select: {
|
||||
userSelect: "none",
|
||||
cursor: "text"
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +179,7 @@ const AboutDialog = withStyles(styles, { withTheme: true })(
|
||||
this.updateNotifications();
|
||||
}
|
||||
componentDidUpdate(prevProps: Readonly<AboutDialogProps>, prevState: Readonly<AboutDialogState>, snapshot: any): void {
|
||||
super.componentDidUpdate?.(prevProps,prevState,snapshot);
|
||||
super.componentDidUpdate?.(prevProps, prevState, snapshot);
|
||||
this.updateNotifications();
|
||||
}
|
||||
|
||||
@@ -185,6 +191,11 @@ const AboutDialog = withStyles(styles, { withTheme: true })(
|
||||
render() {
|
||||
let classes = this.props.classes;
|
||||
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}
|
||||
@@ -210,13 +221,16 @@ const AboutDialog = withStyles(styles, { withTheme: true })(
|
||||
overflowX: "hidden", overflowY: "auto", userSelect: "text"
|
||||
}}
|
||||
>
|
||||
<div style={{ margin: 24 }}>
|
||||
<Typography noWrap display="block" variant="h6" color="textPrimary">
|
||||
PiPedal <span style={{ fontSize: "0.7em" }}>
|
||||
{(this.model.serverVersion ? this.model.serverVersion.serverVersion : "")
|
||||
+ (this.model.serverVersion?.debug ? " (Debug)" : "")}
|
||||
</span>
|
||||
</Typography>
|
||||
<div id="debug_info" className={classes.can_select} style={{ 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 © 2022-2024 Robin Davies.
|
||||
</Typography>
|
||||
@@ -235,24 +249,34 @@ const AboutDialog = withStyles(styles, { withTheme: true })(
|
||||
<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 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>
|
||||
|
||||
<Divider />
|
||||
<Typography display="block" variant="caption" >
|
||||
LEGAL NOTICES
|
||||
</Typography>
|
||||
<div dangerouslySetInnerHTML={{ __html: this.state.openSourceNotices }} style={{ fontSize: "0.8em",maxWidth: 400 }}>
|
||||
<div dangerouslySetInnerHTML={{ __html: this.state.openSourceNotices }} style={{ fontSize: "0.8em", maxWidth: 400 }}>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
+8
-4
@@ -59,11 +59,13 @@ const theme = createTheme(
|
||||
styleOverrides: {
|
||||
containedPrimary: {
|
||||
borderRadius: '9999px',
|
||||
paddingLeft: "14px", paddingRight: "16px"
|
||||
paddingLeft: "16px", paddingRight: "16px",
|
||||
textTransform: "none"
|
||||
},
|
||||
containedSecondary: {
|
||||
borderRadius: '9999px',
|
||||
paddingLeft: "14px", paddingRight: "16px"
|
||||
paddingLeft: "16px", paddingRight: "16px",
|
||||
textTransform: "none"
|
||||
}
|
||||
|
||||
},
|
||||
@@ -103,11 +105,13 @@ const theme = createTheme(
|
||||
styleOverrides: {
|
||||
containedPrimary: {
|
||||
borderRadius: '9999px',
|
||||
paddingLeft: "14px", paddingRight: "16px"
|
||||
paddingLeft: "16px", paddingRight: "16px",
|
||||
textTransform: "none"
|
||||
},
|
||||
containedSecondary: {
|
||||
borderRadius: '9999px',
|
||||
paddingLeft: "14px", paddingRight: "16px"
|
||||
paddingLeft: "16px", paddingRight: "16px",
|
||||
textTransform: "none"
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
+92
-31
@@ -48,7 +48,7 @@ import SettingsDialog from './SettingsDialog';
|
||||
import AboutDialog from './AboutDialog';
|
||||
import BankDialog from './BankDialog';
|
||||
|
||||
import { PiPedalModelFactory, PiPedalModel, State, ZoomedControlInfo,wantsLoadingScreen } from './PiPedalModel';
|
||||
import { PiPedalModelFactory, PiPedalModel, State, ZoomedControlInfo, wantsLoadingScreen } from './PiPedalModel';
|
||||
import ZoomedUiControl from './ZoomedUiControl'
|
||||
import MainPage from './MainPage';
|
||||
import DialogContent from '@mui/material/DialogContent';
|
||||
@@ -67,7 +67,7 @@ import { ReactComponent as SaveBankAsIcon } from './svg/ic_save_bank_as.svg';
|
||||
import { ReactComponent as EditBanksIcon } from './svg/ic_edit_banks.svg';
|
||||
import { ReactComponent as SettingsIcon } from './svg/ic_settings.svg';
|
||||
import { ReactComponent as HelpOutlineIcon } from './svg/ic_help_outline.svg';
|
||||
import DialogEx from './DialogEx';
|
||||
import DialogEx, { DialogStackState } from './DialogEx';
|
||||
|
||||
|
||||
const appStyles = (theme: Theme) => createStyles({
|
||||
@@ -139,10 +139,11 @@ const appStyles = (theme: Theme) => createStyles({
|
||||
marginTop: 0,
|
||||
fontWeight: 500,
|
||||
fontSize: "13pt",
|
||||
maxWidth: 350,
|
||||
opacity: 1,
|
||||
zIndex: 2010,
|
||||
paddingTop: 12,
|
||||
gravity: "center",
|
||||
textAlign: "center"
|
||||
},
|
||||
|
||||
errorMessageBox: {
|
||||
@@ -164,8 +165,6 @@ const appStyles = (theme: Theme) => createStyles({
|
||||
position: "relative",
|
||||
top: "20%",
|
||||
color: isDarkMode() ? theme.palette.text.secondary : "#888",
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
// border: "3px solid #888",
|
||||
borderRadius: "12px",
|
||||
padding: "12px",
|
||||
@@ -351,9 +350,40 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
this.handleCloseAlert = this.handleCloseAlert.bind(this);
|
||||
this.banksChangedHandler = this.banksChangedHandler.bind(this);
|
||||
this.showStatusMonitorHandler = this.showStatusMonitorHandler.bind(this);
|
||||
|
||||
this.onPopStateHandler = this.onPopStateHandler.bind(this);
|
||||
}
|
||||
|
||||
showDrawer() {
|
||||
if (!this.state.isDrawerOpen) {
|
||||
this.setState({ isDrawerOpen: true })
|
||||
this.pushOpenMenuState();
|
||||
}
|
||||
}
|
||||
hideDrawer(loadingDialog: boolean = false) {
|
||||
if (!loadingDialog && window.location.hash === "#menu") {
|
||||
window.history.back();
|
||||
} else {
|
||||
this.setState({ isDrawerOpen: false })
|
||||
}
|
||||
}
|
||||
|
||||
pushOpenMenuState() {
|
||||
let stackState = { tag: "OpenMenu", previousState: null };
|
||||
window.history.replaceState(stackState, "", window.location.href);
|
||||
window.history.pushState({}, "", "#menu");
|
||||
}
|
||||
onPopStateHandler(ev: PopStateEvent) {
|
||||
let stackState: DialogStackState | null = ev.state as (DialogStackState | null);
|
||||
if (stackState && stackState.tag === "OpenMenu") {
|
||||
if (this.state.isDrawerOpen) {
|
||||
this.setState({ isDrawerOpen: false });
|
||||
}
|
||||
ev.stopPropagation();
|
||||
window.history.replaceState(stackState.previousState, "", window.location.href);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
onOpenBank(bankId: number) {
|
||||
this.model_.openBank(bankId)
|
||||
@@ -524,11 +554,9 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
return undefined;
|
||||
}
|
||||
promptForUpdateHandler(newValue: boolean) {
|
||||
if (this.model_.enableAutoUpdate)
|
||||
{
|
||||
if (this.state.updateDialogOpen !== newValue)
|
||||
{
|
||||
this.setState({updateDialogOpen: newValue});
|
||||
if (this.model_.enableAutoUpdate) {
|
||||
if (this.state.updateDialogOpen !== newValue) {
|
||||
this.setState({ updateDialogOpen: newValue });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -537,6 +565,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
super.componentDidMount();
|
||||
window.addEventListener("beforeunload", this.beforeUnloadListener);
|
||||
window.addEventListener("unload", this.unloadListener);
|
||||
window.addEventListener("popstate", this.onPopStateHandler);
|
||||
|
||||
this.model_.errorMessage.addOnChangedHandler(this.errorChangeHandler_);
|
||||
this.model_.state.addOnChangedHandler(this.stateChangeHandler_);
|
||||
@@ -546,6 +575,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
this.model_.showStatusMonitor.addOnChangedHandler(this.showStatusMonitorHandler);
|
||||
this.model_.promptForUpdate.addOnChangedHandler(this.promptForUpdateHandler);
|
||||
this.alertMessageChangedHandler();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -568,6 +598,9 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
super.componentWillUnmount();
|
||||
window.removeEventListener("beforeunload", this.beforeUnloadListener);
|
||||
|
||||
window.removeEventListener("popstate", this.onPopStateHandler);
|
||||
|
||||
|
||||
this.model_.promptForUpdate.removeOnChangedHandler(this.promptForUpdateHandler);
|
||||
this.model_.errorMessage.removeOnChangedHandler(this.errorChangeHandler_);
|
||||
this.model_.state.removeOnChangedHandler(this.stateChangeHandler_);
|
||||
@@ -634,12 +667,6 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
}
|
||||
}
|
||||
|
||||
showDrawer() {
|
||||
this.setState({ isDrawerOpen: true })
|
||||
}
|
||||
hideDrawer() {
|
||||
this.setState({ isDrawerOpen: false })
|
||||
}
|
||||
shortBankList(banks: BankIndex): BankIndexEntry[] {
|
||||
let n = this.state.bankDisplayItems;
|
||||
let entries = banks.entries;
|
||||
@@ -796,7 +823,11 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
{
|
||||
showBankSelectDialog && (
|
||||
<ListItem button key={'bankDOTDOTDOT'} selected={false}
|
||||
onClick={() => this.handleDrawerSelectBank()}
|
||||
onClick={(ev) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerSelectBank();
|
||||
}}
|
||||
>
|
||||
|
||||
<ListItemText primary={"..."} />
|
||||
@@ -808,19 +839,34 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
</List>
|
||||
<Divider />
|
||||
<List>
|
||||
<ListItem button key='RenameBank' onClick={() => { this.handleDrawerRenameBank() }}>
|
||||
<ListItem button key='RenameBank'
|
||||
onClick={(ev) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerRenameBank()
|
||||
}}>
|
||||
<ListItemIcon >
|
||||
<RenameOutlineIcon color='inherit' className={classes.menuIcon} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='Rename bank' />
|
||||
</ListItem>
|
||||
<ListItem button key='SaveBank' onClick={() => { this.handleDrawerSaveBankAs() }} >
|
||||
<ListItem button key='SaveBank'
|
||||
onClick={(ev) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerSaveBankAs();
|
||||
}} >
|
||||
<ListItemIcon>
|
||||
<SaveBankAsIcon color="inherit" className={classes.menuIcon} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='Save as new bank' />
|
||||
</ListItem>
|
||||
<ListItem button key='EditBanks' onClick={() => { this.handleDrawerManageBanks(); }}>
|
||||
<ListItem button key='EditBanks'
|
||||
onClick={(ev) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerManageBanks();
|
||||
}}>
|
||||
<ListItemIcon>
|
||||
<EditBanksIcon color="inherit" className={classes.menuIcon} />
|
||||
</ListItemIcon>
|
||||
@@ -829,19 +875,34 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
</List>
|
||||
<Divider />
|
||||
<List>
|
||||
<ListItem button key='Settings' onClick={() => { this.handleDrawerSettingsClick() }}>
|
||||
<ListItem button key='Settings'
|
||||
onClick={(ev) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerSettingsClick()
|
||||
}}>
|
||||
<ListItemIcon>
|
||||
<SettingsIcon color="inherit" className={classes.menuIcon} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='Settings' />
|
||||
</ListItem>
|
||||
<ListItem button key='About' onClick={() => { this.handleDrawerAboutClick() }}>
|
||||
<ListItem button key='About'
|
||||
onClick={(ev) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerAboutClick();
|
||||
}}>
|
||||
<ListItemIcon>
|
||||
<HelpOutlineIcon color="inherit" className={classes.menuIcon} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='About' />
|
||||
</ListItem>
|
||||
<ListItem button key='Donations' onClick={() => { this.handleDrawerDonationClick() }}>
|
||||
<ListItem button key='Donations'
|
||||
onClick={(ev) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerDonationClick();
|
||||
}}>
|
||||
<ListItemIcon >
|
||||
<VolunteerActivismIcon className={classes.menuIcon} color="inherit" />
|
||||
</ListItemIcon>
|
||||
@@ -865,10 +926,10 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
</div>
|
||||
</main>
|
||||
<BankDialog show={this.state.bankDialogOpen} isEditDialog={this.state.editBankDialogOpen} onDialogClose={() => this.setState({ bankDialogOpen: false })} />
|
||||
{ (this.state.aboutDialogOpen)&&
|
||||
(
|
||||
<AboutDialog open={this.state.aboutDialogOpen} onClose={() => this.setState({ aboutDialogOpen: false })} />
|
||||
)}
|
||||
{(this.state.aboutDialogOpen) &&
|
||||
(
|
||||
<AboutDialog open={this.state.aboutDialogOpen} onClose={() => this.setState({ aboutDialogOpen: false })} />
|
||||
)}
|
||||
<SettingsDialog
|
||||
open={this.state.isSettingsDialogOpen}
|
||||
onboarding={this.state.onboarding}
|
||||
@@ -931,7 +992,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
<div className={classes.errorContent} style={{
|
||||
display: (
|
||||
wantsLoadingScreen(this.state.displayState)
|
||||
? "block" : "none"
|
||||
? "block" : "none"
|
||||
)
|
||||
}}
|
||||
>
|
||||
@@ -941,7 +1002,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
<div className={classes.loadingBoxItem}>
|
||||
<CircularProgress color="inherit" className={classes.loadingBoxItem} />
|
||||
</div>
|
||||
<Typography noWrap variant="body2" className={classes.progressText}>
|
||||
<Typography display="block" noWrap variant="body2" className={classes.progressText}>
|
||||
{this.getReloadingMessage()}
|
||||
</Typography>
|
||||
</div>
|
||||
@@ -961,7 +1022,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ paddingTop: 50, paddingLeft: 36, textAlign: "left" }}>
|
||||
<Button variant='contained' color="primary"
|
||||
<Button variant='contained' color="primary"
|
||||
onClick={() => this.handleReload()} >
|
||||
Reload
|
||||
</Button>
|
||||
|
||||
+45
-23
@@ -31,21 +31,17 @@ interface DialogExState {
|
||||
}
|
||||
|
||||
class DialogStackEntry {
|
||||
constructor(tag: string)
|
||||
constructor(dialog: DialogEx)
|
||||
{
|
||||
this.tag = tag;
|
||||
this.tag = dialog.props.tag;
|
||||
this.dialog = dialog;
|
||||
}
|
||||
tag: string;
|
||||
dialog: DialogEx;
|
||||
};
|
||||
|
||||
let dialogStack: DialogStackEntry[] = [];
|
||||
|
||||
function peekDialogStack(): string {
|
||||
if (dialogStack.length !== 0) {
|
||||
return dialogStack[dialogStack.length-1].tag;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function popDialogStack(): void {
|
||||
if (dialogStack.length !== 0)
|
||||
@@ -53,12 +49,33 @@ function popDialogStack(): void {
|
||||
dialogStack.splice(dialogStack.length-1,1);
|
||||
}
|
||||
}
|
||||
function pushDialogStack(tag: string): void {
|
||||
dialogStack.push(new DialogStackEntry(tag));
|
||||
function pushDialogStack(dialog: DialogEx): void {
|
||||
dialogStack.push(new DialogStackEntry(dialog));
|
||||
}
|
||||
|
||||
export interface DialogStackState{
|
||||
tag: String;
|
||||
previousState: DialogStackState | null;
|
||||
};
|
||||
|
||||
|
||||
// Close all dialogs higher in the dialog stack than "tag".
|
||||
export function removeDialogStackEntriesAbove(tag: string)
|
||||
{
|
||||
for (let i = dialogStack.length-1; i >= 0; --i)
|
||||
{
|
||||
let entry = dialogStack[i];
|
||||
if (entry.tag === tag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
popDialogStack();
|
||||
if (entry.dialog.props.open && entry.dialog.props.onClose)
|
||||
{
|
||||
entry.dialog.props.onClose({}, "backdropClick");
|
||||
}
|
||||
}
|
||||
}
|
||||
class DialogEx extends React.Component<DialogExProps,DialogExState> {
|
||||
constructor(props: DialogExProps)
|
||||
{
|
||||
@@ -75,22 +92,28 @@ class DialogEx extends React.Component<DialogExProps,DialogExState> {
|
||||
hasHooks: boolean = false;
|
||||
stateWasPopped: boolean = false;
|
||||
|
||||
handlePopState(e: any): any
|
||||
handlePopState(ev: PopStateEvent): any
|
||||
{
|
||||
let shouldClose = (peekDialogStack() === this.props.tag);
|
||||
if (shouldClose)
|
||||
{
|
||||
let evTag: DialogStackState | null = ev.state as DialogStackState | null;
|
||||
if (evTag && evTag.tag === this.props.tag) {
|
||||
removeDialogStackEntriesAbove(this.props.tag);
|
||||
|
||||
if (!this.stateWasPopped)
|
||||
{
|
||||
this.stateWasPopped = true;
|
||||
popDialogStack();
|
||||
if (this.props.open) {
|
||||
this.props.onClose?.(e,"backdropClick");
|
||||
this.props.onClose?.(ev,"backdropClick");
|
||||
}
|
||||
}
|
||||
window.history.replaceState(evTag.previousState,"",window.location.href);
|
||||
window.removeEventListener("popstate",this.handlePopState);
|
||||
e.stopPropagation();
|
||||
|
||||
if (window.location.hash === "#menu") // The menu popstate is next?
|
||||
{
|
||||
window.history.back(); // then clear off the menu popstate too.
|
||||
}
|
||||
ev.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,19 +128,18 @@ class DialogEx extends React.Component<DialogExProps,DialogExState> {
|
||||
this.stateWasPopped = false;
|
||||
window.addEventListener("popstate",this.handlePopState);
|
||||
|
||||
pushDialogStack(this.props.tag);
|
||||
let state: {tag: string} = {tag: this.props.tag};
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
history.pushState(
|
||||
state,
|
||||
pushDialogStack(this);
|
||||
let dialogStackState: DialogStackState = {tag: this.props.tag,previousState: window.history.state as DialogStackState | null};
|
||||
window.history.replaceState(dialogStackState,"",window.location.href);
|
||||
window.history.pushState(
|
||||
null,
|
||||
"",
|
||||
"#" + this.props.tag
|
||||
);
|
||||
} else {
|
||||
if (!this.stateWasPopped)
|
||||
{
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
history.back();
|
||||
window.history.back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -793,17 +793,47 @@ export class PiPedalModel //implements PiPedalModel
|
||||
return this.webSocket;
|
||||
}
|
||||
|
||||
androidReconnectTimeout?: NodeJS.Timeout = undefined;
|
||||
|
||||
cancelAndroidReconnectTimer()
|
||||
{
|
||||
if (this.androidReconnectTimeout) {
|
||||
clearTimeout(this.androidReconnectTimeout);
|
||||
this.androidReconnectTimeout = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
startAndroidReconnectTimer()
|
||||
{
|
||||
this.cancelAndroidReconnectTimer();
|
||||
this.androidReconnectTimeout = setTimeout(()=>{
|
||||
this.androidReconnectTimeout = undefined;
|
||||
this.androidHost?.setDisconnected(true);
|
||||
},20*1000);
|
||||
}
|
||||
onSocketConnectionLost() {
|
||||
// remove all the events and subscriptions we have.
|
||||
if (this.isClosed)
|
||||
{
|
||||
return; // page unloading. do NOT change the UI.
|
||||
}
|
||||
this.vuSubscriptions = [];
|
||||
this.monitorPatchPropertyListeners = [];
|
||||
|
||||
if (this.isAndroidHosted()) {
|
||||
this.androidHost?.setDisconnected(true);
|
||||
// if unexpected, go back to the device browser immediately.
|
||||
if (this.reconnectReason === ReconnectReason.Disconnected)
|
||||
{
|
||||
this.androidHost?.setDisconnected(true);
|
||||
} else {
|
||||
this.startAndroidReconnectTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
onSocketReconnected() {
|
||||
this.cancelOnNetworkChanging();
|
||||
this.cancelAndroidReconnectTimer();
|
||||
|
||||
if (this.isAndroidHosted()) {
|
||||
this.androidHost?.setDisconnected(false);
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ class PiPedalSocket {
|
||||
ws.onerror = null;
|
||||
reject("Connection closed unexpectedly.");
|
||||
};
|
||||
ws.onerror = (evWheent: Event) => {
|
||||
ws.onerror = (evt: Event) => {
|
||||
ws.onclose = null;
|
||||
ws.onerror = null;
|
||||
reject("Failed to connect.");
|
||||
|
||||
@@ -451,7 +451,6 @@ const WifiConfigDialog = withStyles(styles, { withTheme: true })(
|
||||
InputLabelProps={{
|
||||
shrink: true
|
||||
}}
|
||||
disabled={!enabled}
|
||||
/>
|
||||
<div style={{ marginBottom: 8, flexGrow: 1, flexBasis: 1 }}>
|
||||
<form autoComplete='off' onSubmit={() => false}> {/*Prevents chrome from saving passwords */}
|
||||
@@ -477,7 +476,9 @@ const WifiConfigDialog = withStyles(styles, { withTheme: true })(
|
||||
}}
|
||||
InputProps={{
|
||||
startAdornment:
|
||||
this.props.wifiConfigSettings.hasSavedPassword && !this.state.hasPassword && !this.state.showPassword ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : ""
|
||||
!this.state.hasPassword && !this.state.showPassword ?
|
||||
(this.props.wifiConfigSettings.hasSavedPassword? "(Unchanged)" : "(Required)")
|
||||
: ""
|
||||
,
|
||||
endAdornment: (
|
||||
<IconButton size="small"
|
||||
|
||||
Reference in New Issue
Block a user