unstable
This commit is contained in:
@@ -46,7 +46,6 @@ pub struct DSP408Snapshot {
|
||||
pub state: types::DSPState,
|
||||
pub input_meters: types::InputMeters,
|
||||
pub output_meters: types::OutputMeters,
|
||||
pub mode: types::DSPMode,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -104,7 +103,6 @@ pub async fn get_dsp_snapshot(
|
||||
state: device.dsp.state().clone(),
|
||||
input_meters: device.dsp.input_meters().clone(),
|
||||
output_meters: device.dsp.output_meters().clone(),
|
||||
mode: device.dsp.mode(),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import './App.css';
|
||||
import { DSP, AppPage } from './types';
|
||||
import { DSP, AppPage, isConnected } from './types';
|
||||
import TopBar from './components/Topbar/Topbar';
|
||||
import DSPPage from './pages/DspPage/DspPage';
|
||||
import AddDSPForm from './pages/AddDspPage/AddDspPage';
|
||||
@@ -17,7 +17,7 @@ function App() {
|
||||
const [selected, setSelected] = useState<number | null>(null);
|
||||
const [page, setPage] = useState<AppPage>('home');
|
||||
const { notifications, notify, removeNotification, hoverNotification } = useNotifications();
|
||||
const connectedDspCount = dsps.filter((dsp) => dsp.status === 'connected').length;
|
||||
const connectedDspCount = dsps.filter((dsp) => isConnected(dsp)).length;
|
||||
|
||||
const activeDsp = dsps.find((d) => d.id === selected) ?? null;
|
||||
const activeInstance = activeDsp ? createDSPInstance(activeDsp, setDsps, notify) : null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { DSP, AppPage } from '../../types';
|
||||
import { DSP, AppPage, isConnected } from '../../types';
|
||||
import AnimatedLogo from '../../assets/icons/AnimatedLogo';
|
||||
import { PlusIcon } from '../../assets/icons/PlusIcon';
|
||||
import { CrownIcon } from '../../assets/icons/CrownIcon';
|
||||
@@ -36,7 +36,7 @@ function Tab({
|
||||
onDisconnect: (dsp: DSP) => void;
|
||||
actions?: React.ReactNode;
|
||||
}) {
|
||||
const isConnected = dsp.status === 'connected';
|
||||
const isDspConnected = isConnected(dsp);
|
||||
|
||||
const handleTabKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
@@ -60,18 +60,26 @@ function Tab({
|
||||
<button
|
||||
type="button"
|
||||
className="tab-led"
|
||||
aria-label={isConnected ? `Disconnect ${dsp.name}` : `Connect ${dsp.name}`}
|
||||
aria-label={isDspConnected ? `Disconnect ${dsp.name}` : `Connect ${dsp.name}`}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (isConnected) {
|
||||
if (isDspConnected) {
|
||||
onDisconnect(dsp);
|
||||
} else {
|
||||
onConnect(dsp);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Led status={dsp.status} />
|
||||
<Led
|
||||
status={
|
||||
dsp.isConnecting
|
||||
? 'connecting'
|
||||
: isConnected(dsp)
|
||||
? 'connected'
|
||||
: 'disconnected'
|
||||
}
|
||||
/>
|
||||
</button>
|
||||
|
||||
<span className="tab-name" title={dsp.name}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DSP } from '../../../../types';
|
||||
import { DSP, isConnected } from '../../../../types';
|
||||
import Button from '../../../../components/Button/Button';
|
||||
import Card from '../../../../components/Card/Card';
|
||||
import Led from '../../../../components/Led/Led';
|
||||
@@ -15,12 +15,19 @@ function ConnectionPanel({
|
||||
onDisconnect: () => void;
|
||||
}) {
|
||||
const statusLabel =
|
||||
dsp.status === 'connected'
|
||||
isConnected(dsp)
|
||||
? 'Connected'
|
||||
: dsp.status === 'connecting'
|
||||
: dsp.isConnecting
|
||||
? 'Connecting…'
|
||||
: 'Disconnected';
|
||||
|
||||
console.log('ConnectionPanel render:', {
|
||||
id: dsp.id,
|
||||
connection: dsp.type === 'DSP408' ? dsp.state.connection : undefined,
|
||||
isConnected: isConnected(dsp),
|
||||
isConnecting: dsp.isConnecting,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="connection-section">
|
||||
<Card className="connection-panel">
|
||||
@@ -35,10 +42,10 @@ function ConnectionPanel({
|
||||
|
||||
<div className="connection-panel__status">
|
||||
<span className="connection-panel__led">
|
||||
<Led status={dsp.status} />
|
||||
{/* <Led status={dsp.status} /> */}
|
||||
</span>
|
||||
|
||||
<span className={`status-label status-label--${dsp.status}`}>{statusLabel}</span>
|
||||
{/* <span className={`status-label status-label--${dsp.status}`}>{statusLabel}</span> */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -64,13 +71,13 @@ function ConnectionPanel({
|
||||
</dl>
|
||||
|
||||
<div className="connection-panel__actions">
|
||||
{dsp.status === 'connected' ? (
|
||||
{isConnected(dsp) ? (
|
||||
<Button variant="outline" onClick={onDisconnect}>
|
||||
Disconnect
|
||||
</Button>
|
||||
) : (
|
||||
<Button variant="primary" onClick={onConnect} disabled={dsp.status === 'connecting'}>
|
||||
{dsp.status === 'connecting' ? 'Connecting…' : 'Connect'}
|
||||
<Button variant="primary" onClick={onConnect} disabled={dsp.isConnecting}>
|
||||
{dsp.isConnecting ? 'Connecting…' : 'Connect'}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
PEQBand,
|
||||
InputSource,
|
||||
DSP408Snapshot,
|
||||
DSPMode,
|
||||
} from './types';
|
||||
import { SetDsps, NotifyFn, updateDSP, setPollingPaused } from '../../dsp/dspShared';
|
||||
import { registerPollStopper } from '../../dsp/pollRegistry';
|
||||
@@ -117,8 +118,8 @@ export async function create(params: {
|
||||
ip: params.ip,
|
||||
port: params.port,
|
||||
deviceId: params.deviceId,
|
||||
mode: snapshot.mode,
|
||||
status: 'disconnected',
|
||||
mode: params.demo ? DSPMode.Demo: DSPMode.Normal,
|
||||
isConnecting: false,
|
||||
pollingPaused: true,
|
||||
state: snapshot.state,
|
||||
input_meters: snapshot.input_meters,
|
||||
@@ -130,6 +131,7 @@ export function forDSP408(dsp: DSP408, setDsps: SetDsps, notify: NotifyFn) {
|
||||
async function updateDSPState(): Promise<DSP408['state']> {
|
||||
try {
|
||||
const state = await invoke<DSP408['state']>('get_dsp_state', { id: dsp.id });
|
||||
|
||||
updateDSP(setDsps, dsp.id, (d) => ({ ...d, state }) as DSP408);
|
||||
|
||||
return state;
|
||||
@@ -143,11 +145,11 @@ export function forDSP408(dsp: DSP408, setDsps: SetDsps, notify: NotifyFn) {
|
||||
|
||||
async function abortLocked() {
|
||||
await invoke('disconnect_dsp408', { id: dsp.id }).catch(() => {});
|
||||
updateDSP(setDsps, dsp.id, (d) => ({ ...d, status: 'disconnected', passwordRequired: true }));
|
||||
updateDSP(setDsps, dsp.id, (d) => ({ ...d, passwordRequired: true }));
|
||||
}
|
||||
|
||||
async function connectInternal(password?: string) {
|
||||
updateDSP(setDsps, dsp.id, (d) => ({ ...d, status: 'connecting', passwordRequired: false }));
|
||||
updateDSP(setDsps, dsp.id, (d) => ({ ...d, isConnecting: true, passwordRequired: false }));
|
||||
try {
|
||||
await invoke('connect_dsp408', { id: dsp.id });
|
||||
|
||||
@@ -159,13 +161,10 @@ export function forDSP408(dsp: DSP408, setDsps: SetDsps, notify: NotifyFn) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await invoke('unlock_device', { id: dsp.id, password }); // adjust name/signature
|
||||
} catch {
|
||||
// wrong password
|
||||
}
|
||||
let r = await invoke('unlock_device', { id: dsp.id, password });
|
||||
|
||||
state = await updateDSPState();
|
||||
|
||||
if (isLocked(state)) {
|
||||
await abortLocked();
|
||||
notify('Wrong password', 'error', dsp.name);
|
||||
@@ -173,11 +172,11 @@ export function forDSP408(dsp: DSP408, setDsps: SetDsps, notify: NotifyFn) {
|
||||
}
|
||||
}
|
||||
|
||||
updateDSP(setDsps, dsp.id, (d) => ({ ...d, status: 'connected', pollingPaused: false }));
|
||||
updateDSP(setDsps, dsp.id, (d) => ({ ...d, isConnecting: false, pollingPaused: false }));
|
||||
notify('Connected', 'success', dsp.name);
|
||||
startPolling(dsp, setDsps);
|
||||
} catch (err) {
|
||||
updateDSP(setDsps, dsp.id, (d) => ({ ...d, status: 'disconnected' }));
|
||||
updateDSP(setDsps, dsp.id, (d) => ({ ...d, isConnecting: false }));
|
||||
notify(`Connection failed: ${String(err)}`, 'error', dsp.name);
|
||||
}
|
||||
}
|
||||
@@ -216,7 +215,6 @@ export function forDSP408(dsp: DSP408, setDsps: SetDsps, notify: NotifyFn) {
|
||||
|
||||
updateDSP(setDsps, dsp.id, (d) => ({
|
||||
...d,
|
||||
status: 'disconnected',
|
||||
pollingPaused: true,
|
||||
}));
|
||||
|
||||
|
||||
@@ -243,15 +243,23 @@ export type DSPState = {
|
||||
flags: DeviceFlags;
|
||||
presets: PresetBank;
|
||||
current_config: DSPConfigState;
|
||||
connection: ConnectionStatus,
|
||||
};
|
||||
|
||||
export type DSPMode = 'demo' | 'disconnected' | 'connected';
|
||||
export enum ConnectionStatus {
|
||||
Connected,
|
||||
Disconnected,
|
||||
}
|
||||
|
||||
export enum DSPMode {
|
||||
Demo,
|
||||
Normal,
|
||||
}
|
||||
|
||||
export type DSP408Snapshot = {
|
||||
state: DSPState;
|
||||
input_meters: DSP408InputMeters;
|
||||
output_meters: DSP408OutputMeters;
|
||||
mode: DSPMode;
|
||||
};
|
||||
|
||||
export interface Meter {
|
||||
|
||||
+7
-5
@@ -3,10 +3,9 @@ import {
|
||||
DSPMode,
|
||||
DSP408OutputMeters,
|
||||
DSP408InputMeters,
|
||||
ConnectionStatus,
|
||||
} from './features/dsp408/types';
|
||||
|
||||
export type DSPStatus = 'connected' | 'connecting' | 'disconnected';
|
||||
|
||||
export type NotificationType = 'success' | 'error' | 'warning';
|
||||
export type Notification = {
|
||||
id: number;
|
||||
@@ -39,12 +38,15 @@ interface DSPBase {
|
||||
mode: DSPMode;
|
||||
|
||||
passwordRequired?: boolean;
|
||||
|
||||
status: DSPStatus;
|
||||
|
||||
isConnecting: boolean;
|
||||
pollingPaused: boolean;
|
||||
}
|
||||
|
||||
export function isConnected(dsp: DSP): boolean {
|
||||
return dsp.type === 'DSP408'
|
||||
&& dsp.state.connection === ConnectionStatus.Connected;
|
||||
}
|
||||
|
||||
export type DSP408 = DSPBase & {
|
||||
type: 'DSP408';
|
||||
state: DSP408State;
|
||||
|
||||
Reference in New Issue
Block a user