Skip to content

Commit 4749ea4

Browse files
committed
fix(camera): derive WebUI camera state from resolved config
1 parent e1d66ca commit 4749ea4

3 files changed

Lines changed: 42 additions & 10 deletions

File tree

src/webui/server/routes/camera-routes.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import type { Router, Response } from 'express';
66
import type { AuthenticatedRequest } from '../auth-middleware';
7-
import { CameraStatusResponse, StandardAPIResponse } from '../../types/web-api.types';
7+
import type { CameraStatusResponse, StandardAPIResponse } from '../../types/web-api.types';
88
import { toAppError } from '../../../utils/error.utils';
99
import { resolveContext, sendErrorResponse, type RouteDependencies } from './route-helpers';
1010

@@ -20,10 +20,25 @@ export function registerCameraRoutes(router: Router, deps: RouteDependencies): v
2020
);
2121
}
2222

23-
const isAvailable = deps.backendManager.isFeatureAvailable(
24-
contextResult.contextId,
25-
'camera'
23+
const { contextId, context } = contextResult;
24+
const features = deps.backendManager.getFeatures(contextId);
25+
if (!features) {
26+
return sendErrorResponse<StandardAPIResponse>(
27+
res,
28+
500,
29+
'Failed to get printer features'
30+
);
31+
}
32+
33+
const { resolveCameraConfig, getCameraUserConfig } = await import(
34+
'../../../utils/camera-utils'
2635
);
36+
const cameraConfig = resolveCameraConfig({
37+
printerIpAddress: context.printerDetails.IPAddress,
38+
printerFeatures: features,
39+
userConfig: getCameraUserConfig(contextId)
40+
});
41+
const isAvailable = cameraConfig.isAvailable;
2742

2843
const response: CameraStatusResponse = {
2944
available: isAvailable,
@@ -97,7 +112,7 @@ export function registerCameraRoutes(router: Router, deps: RouteDependencies): v
97112
}
98113

99114
let streamStatus = rtspStreamService.getStreamStatus(contextId);
100-
if (!streamStatus) {
115+
if (!streamStatus || streamStatus.rtspUrl !== cameraConfig.streamUrl) {
101116
try {
102117
const { rtspFrameRate, rtspQuality } = context.printerDetails;
103118
await rtspStreamService.setupStream(contextId, cameraConfig.streamUrl, {
@@ -131,7 +146,7 @@ export function registerCameraRoutes(router: Router, deps: RouteDependencies): v
131146
const cameraProxyService = getCameraProxyService();
132147
let status = cameraProxyService.getStatusForContext(contextId);
133148

134-
if (!status) {
149+
if (!status || status.sourceUrl !== cameraConfig.streamUrl) {
135150
try {
136151
await cameraProxyService.setStreamUrl(contextId, cameraConfig.streamUrl);
137152
status = cameraProxyService.getStatusForContext(contextId);

src/webui/server/routes/printer-status-routes.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import type { Router, Response } from 'express';
99
import type { AuthenticatedRequest } from '../auth-middleware';
10-
import {
10+
import type {
1111
PrinterStatusResponse,
1212
PrinterFeatures,
1313
MaterialStationStatusResponse,
@@ -143,7 +143,7 @@ export function registerPrinterStatusRoutes(router: Router, deps: RouteDependenc
143143
);
144144
}
145145

146-
const { contextId } = contextResult;
146+
const { contextId, context } = contextResult;
147147
const features = deps.backendManager.getFeatures(contextId);
148148

149149
if (!features) {
@@ -154,8 +154,17 @@ export function registerPrinterStatusRoutes(router: Router, deps: RouteDependenc
154154
);
155155
}
156156

157+
const { resolveCameraConfig, getCameraUserConfig } = await import(
158+
'../../../utils/camera-utils'
159+
);
160+
const cameraConfig = resolveCameraConfig({
161+
printerIpAddress: context.printerDetails.IPAddress,
162+
printerFeatures: features,
163+
userConfig: getCameraUserConfig(contextId)
164+
});
165+
157166
const featureResponse: PrinterFeatures = {
158-
hasCamera: deps.backendManager.isFeatureAvailable(contextId, 'camera'),
167+
hasCamera: cameraConfig.isAvailable,
159168
hasLED: deps.backendManager.isFeatureAvailable(contextId, 'led-control'),
160169
hasFiltration: deps.backendManager.isFeatureAvailable(contextId, 'filtration'),
161170
hasMaterialStation: deps.backendManager.isFeatureAvailable(contextId, 'material-station'),

src/webui/static/features/camera.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ export async function loadCameraStream(): Promise<void> {
7272
try {
7373
const config = await apiRequest<CameraProxyConfigResponse>('/api/camera/proxy-config');
7474

75+
if (!config.success) {
76+
showElement('camera-placeholder');
77+
hideElement('camera-stream');
78+
hideElement('camera-canvas');
79+
cameraPlaceholder.textContent = config.error || 'Camera unavailable';
80+
return;
81+
}
82+
7583
if (config.streamType === 'rtsp') {
7684
if (config.ffmpegAvailable === false) {
7785
showElement('camera-placeholder');
@@ -143,7 +151,7 @@ export async function loadCameraStream(): Promise<void> {
143151
}
144152

145153
export function initializeCamera(): void {
146-
if (!state.printerFeatures?.hasCamera) {
154+
if (state.printerFeatures && !state.printerFeatures.hasCamera) {
147155
teardownCameraStreamElements();
148156
return;
149157
}

0 commit comments

Comments
 (0)