From 53dc54488694f66c421edbe79185ffb660bb9579 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 4 May 2026 15:08:55 -0700 Subject: [PATCH 1/2] bad --- src/components/Dashboard/DeviceList.jsx | 25 +++++++------------------ src/components/explorer.jsx | 21 ++++++++++++++++++++- src/url.js | 10 +++++++++- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/components/Dashboard/DeviceList.jsx b/src/components/Dashboard/DeviceList.jsx index 591cb17f..d48e0db4 100644 --- a/src/components/Dashboard/DeviceList.jsx +++ b/src/components/Dashboard/DeviceList.jsx @@ -9,13 +9,14 @@ import SettingsIcon from '@material-ui/icons/Settings'; import MyCommaAuth from '@commaai/my-comma-auth'; import { devices as Devices } from '@commaai/api'; -import { updateDevices } from '../../actions'; +import { push } from 'connected-react-router'; + +import { selectDevice, updateDevices } from '../../actions'; import Colors from '../../colors'; import { deviceNamePretty, deviceIsOnline, filterRegularClick, emptyDevice } from '../../utils'; import VisibilityHandler from '../VisibilityHandler'; import AddDevice from './AddDevice'; -import DeviceSettingsModal from './DeviceSettingsModal'; const styles = (theme) => ({ deviceList: { @@ -89,24 +90,18 @@ class DeviceList extends Component { constructor(props) { super(props); - this.state = { - settingsModalDongleId: null, - }; - this.renderDevice = this.renderDevice.bind(this); this.handleOpenedSettingsModal = this.handleOpenedSettingsModal.bind(this); - this.handleClosedSettingsModal = this.handleClosedSettingsModal.bind(this); this.onVisible = this.onVisible.bind(this); } handleOpenedSettingsModal(dongleId, ev) { ev.stopPropagation(); ev.preventDefault(); - this.setState({ settingsModalDongleId: dongleId }); - } - - handleClosedSettingsModal() { - this.setState({ settingsModalDongleId: null }); + if (dongleId !== this.props.selectedDevice) { + this.props.dispatch(selectDevice(dongleId, false)); + } + this.props.dispatch(push(`/${dongleId}/settings`)); } async onVisible() { @@ -159,7 +154,6 @@ class DeviceList extends Component { } render() { - const { settingsModalDongleId } = this.state; const { classes, device, selectedDevice: dongleId } = this.props; let { devices } = this.props; @@ -203,11 +197,6 @@ class DeviceList extends Component { )} - ); } diff --git a/src/components/explorer.jsx b/src/components/explorer.jsx index 9e504733..42aa35c4 100644 --- a/src/components/explorer.jsx +++ b/src/components/explorer.jsx @@ -4,6 +4,8 @@ import Obstruction from 'obstruction'; import localforage from 'localforage'; import { replace } from 'connected-react-router'; +import { getDeviceSettings } from '../url'; + import { withStyles, Button, CircularProgress, Divider, Modal, Paper, Typography } from '@material-ui/core'; import 'mapbox-gl/src/css/mapbox-gl.css'; @@ -13,6 +15,7 @@ import AppHeader from './AppHeader'; import Dashboard from './Dashboard'; import IosPwaPopup from './IosPwaPopup'; import AppDrawer from './AppDrawer'; +import DeviceSettingsModal from './Dashboard/DeviceSettingsModal'; import PullDownReload from './utils/PullDownReload'; import { analyticsEvent, selectDevice, updateDevice, checkLastRoutesData } from '../actions'; @@ -76,6 +79,14 @@ class ExplorerApp extends Component { this.handleDrawerStateChanged = this.handleDrawerStateChanged.bind(this); this.updateHeaderRef = this.updateHeaderRef.bind(this); this.closePair = this.closePair.bind(this); + this.closeSettingsModal = this.closeSettingsModal.bind(this); + } + + closeSettingsModal() { + const settingsDongleId = getDeviceSettings(this.props.pathname); + if (settingsDongleId) { + this.props.dispatch(replace(`/${settingsDongleId}`)); + } } async componentDidMount() { @@ -179,8 +190,9 @@ class ExplorerApp extends Component { } render() { - const { classes, currentRoute, devices, dongleId } = this.props; + const { classes, currentRoute, devices, dongleId, pathname } = this.props; const { drawerIsOpen, pairLoading, pairError, pairDongleId, windowWidth } = this.state; + const settingsDongleId = getDeviceSettings(pathname); const noDevicesUpsell = (devices?.length === 0 && !dongleId); const isLarge = noDevicesUpsell || windowWidth > 1080; @@ -228,6 +240,13 @@ class ExplorerApp extends Component { : (currentRoute ? : )} + { settingsDongleId && devices && ( + + )} Pairing device diff --git a/src/url.js b/src/url.js index 75b8d592..10179e0f 100644 --- a/src/url.js +++ b/src/url.js @@ -46,4 +46,12 @@ export function getPrimeNav(pathname) { return true; } return false; -} \ No newline at end of file +} + +export function getDeviceSettings(pathname) { + const parts = pathname.split('/').filter((m) => m.length); + if (parts.length === 2 && dongleIdRegex.test(parts[0]) && parts[1] === 'settings') { + return parts[0]; + } + return null; +} From dcd5c8e5b0740464459965b7c17e7e2eab920741 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 4 May 2026 15:12:34 -0700 Subject: [PATCH 2/2] good? --- src/components/AppDrawer/index.jsx | 1 + src/components/Dashboard/DeviceList.jsx | 27 +++++++++++++++++++------ src/components/explorer.jsx | 21 +------------------ 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/components/AppDrawer/index.jsx b/src/components/AppDrawer/index.jsx index 46d75a1a..f634d55f 100644 --- a/src/components/AppDrawer/index.jsx +++ b/src/components/AppDrawer/index.jsx @@ -39,6 +39,7 @@ const AppDrawer = ({ onClose={toggleDrawerOff} variant={isPermanent ? 'permanent' : 'temporary'} PaperProps={{ style: { width, top: 'auto' } }} + ModalProps={{ keepMounted: true }} >
{!isPermanent diff --git a/src/components/Dashboard/DeviceList.jsx b/src/components/Dashboard/DeviceList.jsx index d48e0db4..9da3ce1f 100644 --- a/src/components/Dashboard/DeviceList.jsx +++ b/src/components/Dashboard/DeviceList.jsx @@ -9,14 +9,14 @@ import SettingsIcon from '@material-ui/icons/Settings'; import MyCommaAuth from '@commaai/my-comma-auth'; import { devices as Devices } from '@commaai/api'; -import { push } from 'connected-react-router'; - -import { selectDevice, updateDevices } from '../../actions'; +import { updateDevices } from '../../actions'; import Colors from '../../colors'; +import { getDeviceSettings } from '../../url'; import { deviceNamePretty, deviceIsOnline, filterRegularClick, emptyDevice } from '../../utils'; import VisibilityHandler from '../VisibilityHandler'; import AddDevice from './AddDevice'; +import DeviceSettingsModal from './DeviceSettingsModal'; const styles = (theme) => ({ deviceList: { @@ -90,18 +90,27 @@ class DeviceList extends Component { constructor(props) { super(props); + this.state = { + settingsModalDongleId: getDeviceSettings(window.location.pathname), + }; + this.renderDevice = this.renderDevice.bind(this); this.handleOpenedSettingsModal = this.handleOpenedSettingsModal.bind(this); + this.handleClosedSettingsModal = this.handleClosedSettingsModal.bind(this); this.onVisible = this.onVisible.bind(this); } handleOpenedSettingsModal(dongleId, ev) { ev.stopPropagation(); ev.preventDefault(); - if (dongleId !== this.props.selectedDevice) { - this.props.dispatch(selectDevice(dongleId, false)); + this.setState({ settingsModalDongleId: dongleId }); + } + + handleClosedSettingsModal() { + this.setState({ settingsModalDongleId: null }); + if (window.location.pathname.endsWith('/settings')) { + window.history.replaceState(null, '', `/${this.props.selectedDevice}`); } - this.props.dispatch(push(`/${dongleId}/settings`)); } async onVisible() { @@ -154,6 +163,7 @@ class DeviceList extends Component { } render() { + const { settingsModalDongleId } = this.state; const { classes, device, selectedDevice: dongleId } = this.props; let { devices } = this.props; @@ -197,6 +207,11 @@ class DeviceList extends Component {
)} + ); } diff --git a/src/components/explorer.jsx b/src/components/explorer.jsx index 42aa35c4..9e504733 100644 --- a/src/components/explorer.jsx +++ b/src/components/explorer.jsx @@ -4,8 +4,6 @@ import Obstruction from 'obstruction'; import localforage from 'localforage'; import { replace } from 'connected-react-router'; -import { getDeviceSettings } from '../url'; - import { withStyles, Button, CircularProgress, Divider, Modal, Paper, Typography } from '@material-ui/core'; import 'mapbox-gl/src/css/mapbox-gl.css'; @@ -15,7 +13,6 @@ import AppHeader from './AppHeader'; import Dashboard from './Dashboard'; import IosPwaPopup from './IosPwaPopup'; import AppDrawer from './AppDrawer'; -import DeviceSettingsModal from './Dashboard/DeviceSettingsModal'; import PullDownReload from './utils/PullDownReload'; import { analyticsEvent, selectDevice, updateDevice, checkLastRoutesData } from '../actions'; @@ -79,14 +76,6 @@ class ExplorerApp extends Component { this.handleDrawerStateChanged = this.handleDrawerStateChanged.bind(this); this.updateHeaderRef = this.updateHeaderRef.bind(this); this.closePair = this.closePair.bind(this); - this.closeSettingsModal = this.closeSettingsModal.bind(this); - } - - closeSettingsModal() { - const settingsDongleId = getDeviceSettings(this.props.pathname); - if (settingsDongleId) { - this.props.dispatch(replace(`/${settingsDongleId}`)); - } } async componentDidMount() { @@ -190,9 +179,8 @@ class ExplorerApp extends Component { } render() { - const { classes, currentRoute, devices, dongleId, pathname } = this.props; + const { classes, currentRoute, devices, dongleId } = this.props; const { drawerIsOpen, pairLoading, pairError, pairDongleId, windowWidth } = this.state; - const settingsDongleId = getDeviceSettings(pathname); const noDevicesUpsell = (devices?.length === 0 && !dongleId); const isLarge = noDevicesUpsell || windowWidth > 1080; @@ -240,13 +228,6 @@ class ExplorerApp extends Component { : (currentRoute ? : )} - { settingsDongleId && devices && ( - - )} Pairing device