@camstack/ui-library 1.2.290 → 1.2.292
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{MaskShapeCanvas-DI4BY7W2.js → MaskShapeCanvas-C9cJlxvG.js} +3 -1
- package/dist/{MaskShapeCanvas-BByN3jvt.cjs → MaskShapeCanvas-NCNwu9_5.cjs} +3 -1
- package/dist/{MotionZonesSettings-CiYjd-yl.js → MotionZonesSettings-Bv8XzCa3.js} +45 -48
- package/dist/{MotionZonesSettings-BK9R9NIr.cjs → MotionZonesSettings-CPRH536-.cjs} +44 -47
- package/dist/{PrivacyMaskSettings-DuXUCUev.cjs → PrivacyMaskSettings-BUWvVF_n.cjs} +33 -42
- package/dist/{PrivacyMaskSettings-BmRdUrPp.js → PrivacyMaskSettings-BlkbESYj.js} +34 -43
- package/dist/{SceneMonitorEditor-COgAjtq5.cjs → SceneMonitorEditor-D_jkzQ2o.cjs} +189 -86
- package/dist/{SceneMonitorEditor-J4Ix_0tu.js → SceneMonitorEditor-i3-nXAEU.js} +190 -87
- package/dist/composites/addon-global-settings-form.d.ts +0 -12
- package/dist/composites/cap-settings/AutotrackSection.d.ts +0 -16
- package/dist/composites/cap-settings/CameraGridLayoutEditor.d.ts +0 -21
- package/dist/composites/cap-settings/ConsumablesPanel.d.ts +0 -18
- package/dist/composites/cap-settings/MaskShapeCanvas.d.ts +0 -102
- package/dist/composites/cap-settings/MotionZonesSettings.d.ts +0 -38
- package/dist/composites/cap-settings/SceneReferenceGallery.d.ts +0 -38
- package/dist/composites/cap-settings/scene-monitor-copy.d.ts +12 -6
- package/dist/composites/clips/clip-source-state.d.ts +3 -2
- package/dist/composites/clips/clip-thumbnail-fetch.d.ts +2 -1
- package/dist/composites/clips/clip-tile-media.d.ts +3 -2
- package/dist/composites/clips/clip-view-state.d.ts +2 -1
- package/dist/composites/confirm-dialog.d.ts +0 -62
- package/dist/composites/data-table.d.ts +2 -11
- package/dist/composites/detection-canvas.d.ts +0 -9
- package/dist/composites/detection-result-tree.d.ts +0 -12
- package/dist/composites/device-controls/container-primary-hero.d.ts +0 -17
- package/dist/composites/device-controls/humidifier-control.d.ts +0 -17
- package/dist/composites/device-controls/lawn-mower-control.d.ts +2 -1
- package/dist/composites/device-controls/pet-feeder-panel.d.ts +0 -18
- package/dist/composites/device-controls/script-automation-controls.d.ts +2 -1
- package/dist/composites/device-controls/sensor-hero-card.d.ts +0 -18
- package/dist/composites/device-controls/update-control.d.ts +0 -13
- package/dist/composites/device-controls/vacuum-control.d.ts +2 -1
- package/dist/composites/device-controls/valve-control.d.ts +2 -1
- package/dist/composites/device-controls/weather-control.d.ts +2 -1
- package/dist/composites/device-item/actions.d.ts +0 -22
- package/dist/composites/device-item/helpers.d.ts +2 -1
- package/dist/composites/device-item/index.d.ts +0 -9
- package/dist/composites/device-list/batch-actions-bar.d.ts +0 -11
- package/dist/composites/device-list/filter-chips.d.ts +0 -13
- package/dist/composites/device-list/page-size-select.d.ts +2 -1
- package/dist/composites/device-list/url-state.d.ts +2 -3
- package/dist/composites/device-meta.d.ts +14 -7
- package/dist/composites/device-picker/DevicePicker.d.ts +9 -1
- package/dist/composites/device-picker/device-filter-bar.d.ts +2 -1
- package/dist/composites/device-picker/device-parent.d.ts +2 -1
- package/dist/composites/device-picker/device-selection-rows.d.ts +6 -1
- package/dist/composites/device-selector-picker.d.ts +25 -1
- package/dist/composites/device-step-matrix.d.ts +0 -26
- package/dist/composites/error-box.d.ts +0 -15
- package/dist/composites/event-stream.d.ts +2 -1
- package/dist/composites/extensions/extensions-view-state.d.ts +2 -1
- package/dist/composites/hls-quality.d.ts +3 -2
- package/dist/composites/index.d.ts +0 -2
- package/dist/composites/notification-targets-field.d.ts +2 -2
- package/dist/composites/option-select/OptionSelect.d.ts +6 -0
- package/dist/composites/pipeline-matrix-shared.d.ts +2 -1
- package/dist/composites/provider-entries/AddProviderEntryDialog.d.ts +1 -1
- package/dist/composites/provider-entries/ProviderEntryPills.d.ts +1 -1
- package/dist/composites/ptz-overlay.d.ts +0 -19
- package/dist/composites/qr-code.d.ts +0 -14
- package/dist/composites/scope-picker.d.ts +2 -1
- package/dist/composites/step-inspector/layered-settings-form.d.ts +0 -11
- package/dist/composites/step-inspector/step-inspector-panel.d.ts +0 -6
- package/dist/composites/stream-broker-selector.d.ts +0 -21
- package/dist/composites/training/TrainingBaseModelPicker.d.ts +0 -10
- package/dist/composites/training/retrain-review-badge.d.ts +2 -1
- package/dist/composites/webrtc-diagnostics/endpoint-test.d.ts +2 -1
- package/dist/composites/webrtc-diagnostics/nat-mapping.d.ts +2 -1
- package/dist/composites/webrtc-diagnostics/session-run.d.ts +2 -1
- package/dist/composites/webrtc-diagnostics/session-verdict.d.ts +2 -1
- package/dist/contexts/ui-text.d.ts +49 -0
- package/dist/generated/system-hooks.d.ts +4 -0
- package/dist/i18n/addon-i18n.d.ts +46 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/use-addon-t.d.ts +57 -0
- package/dist/index.cjs +3309 -2368
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3297 -2368
- package/dist/lib/format-last-seen.d.ts +15 -1
- package/dist/lib/phase-config.d.ts +9 -3
- package/dist/lib/pipeline-mirror.d.ts +2 -1
- package/package.json +1 -1
- package/dist/composites/data-table/data-table-header.d.ts +0 -11
- package/dist/composites/data-table/data-table-pagination.d.ts +0 -10
- package/dist/composites/data-table/data-table-row.d.ts +0 -11
- package/dist/composites/data-table/data-table.d.ts +0 -3
- package/dist/composites/data-table/index.d.ts +0 -2
- package/dist/composites/data-table/types.d.ts +0 -34
- package/dist/composites/data-table-layout.d.ts +0 -31
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useUiText } from "./index.js";
|
|
1
2
|
import { memo, useCallback, useEffect, useRef, useState } from "react";
|
|
2
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
4
|
import { Arrow, Circle, Group, Layer, Line, Rect, Stage, Text } from "react-konva";
|
|
@@ -171,6 +172,7 @@ function isPointShape(shape) {
|
|
|
171
172
|
return shape.kind === "polygon" || shape.kind === "line";
|
|
172
173
|
}
|
|
173
174
|
function MaskShapeCanvasImpl({ items, selectedId, onSelect, onShapeChange, onDrawComplete, drawingKind, supportedShapes, transparent = false, backdrop, polygonVertices, grid }) {
|
|
175
|
+
const t = useUiText();
|
|
174
176
|
const containerRef = useRef(null);
|
|
175
177
|
const [size, setSize] = useState({
|
|
176
178
|
w: 800,
|
|
@@ -508,7 +510,7 @@ function MaskShapeCanvasImpl({ items, selectedId, onSelect, onShapeChange, onDra
|
|
|
508
510
|
}),
|
|
509
511
|
isDrawing ? /* @__PURE__ */ jsx("div", {
|
|
510
512
|
className: "px-3 py-1.5 bg-zinc-800/80 text-[11px] text-zinc-400 border-t border-zinc-700",
|
|
511
|
-
children: drawingKind === "line" ? "Click to set the start point, click again to complete the line" : drawingKind === "rect" ? "Click to drop a rectangle, then drag the corner to resize" : drawingKind === "grid" ? "Click to add the grid, then paint cells" : drawPoints.length < FLOOR_POLYGON_VERTICES ? "Click to add points (min 3). Double-click or click the first point to close." : "Continue adding points. Double-click or click the first point to close."
|
|
513
|
+
children: drawingKind === "line" ? t("uiLibrary.maskShapeCanvas.hintLine", "Click to set the start point, click again to complete the line") : drawingKind === "rect" ? t("uiLibrary.maskShapeCanvas.hintRect", "Click to drop a rectangle, then drag the corner to resize") : drawingKind === "grid" ? t("uiLibrary.maskShapeCanvas.hintGrid", "Click to add the grid, then paint cells") : drawPoints.length < FLOOR_POLYGON_VERTICES ? t("uiLibrary.maskShapeCanvas.hintPoints", "Click to add points (min 3). Double-click or click the first point to close.") : t("uiLibrary.maskShapeCanvas.hintMore", "Continue adding points. Double-click or click the first point to close.")
|
|
512
514
|
}) : null
|
|
513
515
|
]
|
|
514
516
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const require_index = require("./index.cjs");
|
|
1
2
|
let react = require("react");
|
|
2
3
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
3
4
|
let react_konva = require("react-konva");
|
|
@@ -171,6 +172,7 @@ function isPointShape(shape) {
|
|
|
171
172
|
return shape.kind === "polygon" || shape.kind === "line";
|
|
172
173
|
}
|
|
173
174
|
function MaskShapeCanvasImpl({ items, selectedId, onSelect, onShapeChange, onDrawComplete, drawingKind, supportedShapes, transparent = false, backdrop, polygonVertices, grid }) {
|
|
175
|
+
const t = require_index.useUiText();
|
|
174
176
|
const containerRef = (0, react.useRef)(null);
|
|
175
177
|
const [size, setSize] = (0, react.useState)({
|
|
176
178
|
w: 800,
|
|
@@ -508,7 +510,7 @@ function MaskShapeCanvasImpl({ items, selectedId, onSelect, onShapeChange, onDra
|
|
|
508
510
|
}),
|
|
509
511
|
isDrawing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
510
512
|
className: "px-3 py-1.5 bg-zinc-800/80 text-[11px] text-zinc-400 border-t border-zinc-700",
|
|
511
|
-
children: drawingKind === "line" ? "Click to set the start point, click again to complete the line" : drawingKind === "rect" ? "Click to drop a rectangle, then drag the corner to resize" : drawingKind === "grid" ? "Click to add the grid, then paint cells" : drawPoints.length < FLOOR_POLYGON_VERTICES ? "Click to add points (min 3). Double-click or click the first point to close." : "Continue adding points. Double-click or click the first point to close."
|
|
513
|
+
children: drawingKind === "line" ? t("uiLibrary.maskShapeCanvas.hintLine", "Click to set the start point, click again to complete the line") : drawingKind === "rect" ? t("uiLibrary.maskShapeCanvas.hintRect", "Click to drop a rectangle, then drag the corner to resize") : drawingKind === "grid" ? t("uiLibrary.maskShapeCanvas.hintGrid", "Click to add the grid, then paint cells") : drawPoints.length < FLOOR_POLYGON_VERTICES ? t("uiLibrary.maskShapeCanvas.hintPoints", "Click to add points (min 3). Double-click or click the first point to close.") : t("uiLibrary.maskShapeCanvas.hintMore", "Continue adding points. Double-click or click the first point to close.")
|
|
512
514
|
}) : null
|
|
513
515
|
]
|
|
514
516
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TEXT_HINT, WidgetPanel, _n as Grid2x2, isAbsentProvider, useDeviceProxy, usePlayerOverlayLayer, useSystem } from "./index.js";
|
|
2
|
-
import { MaskShapeCanvas } from "./MaskShapeCanvas-
|
|
1
|
+
import { TEXT_HINT, UiTrans, WidgetPanel, _n as Grid2x2, isAbsentProvider, useDeviceProxy, usePlayerOverlayLayer, useSystem, useUiText } from "./index.js";
|
|
2
|
+
import { MaskShapeCanvas } from "./MaskShapeCanvas-C9cJlxvG.js";
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
//#region src/composites/cap-settings/MotionZonesSettings.tsx
|
|
@@ -119,6 +119,7 @@ function expandCells(uiCells, cw, ch, m) {
|
|
|
119
119
|
return out;
|
|
120
120
|
}
|
|
121
121
|
function MotionZonesSettings({ deviceId }) {
|
|
122
|
+
const t = useUiText();
|
|
122
123
|
const dev = useDeviceProxy(useSystem().trpcClient, deviceId);
|
|
123
124
|
const [options, setOptions] = useState(null);
|
|
124
125
|
const [unsupported, setUnsupported] = useState(false);
|
|
@@ -292,41 +293,31 @@ function MotionZonesSettings({ deviceId }) {
|
|
|
292
293
|
const ready = !unsupported && options !== null && uiCells !== null;
|
|
293
294
|
if (!dev) return null;
|
|
294
295
|
return /* @__PURE__ */ jsx(WidgetPanel, {
|
|
295
|
-
title: "Motion Zones",
|
|
296
|
+
title: t("uiLibrary.motionZones.title", "Motion Zones"),
|
|
296
297
|
icon: /* @__PURE__ */ jsx(Grid2x2, { className: "h-3.5 w-3.5 text-foreground-subtle" }),
|
|
297
298
|
children: /* @__PURE__ */ jsx("div", {
|
|
298
299
|
className: "flex flex-col gap-3",
|
|
299
300
|
children: unsupported ? /* @__PURE__ */ jsx("p", {
|
|
300
301
|
className: `${TEXT_HINT} leading-relaxed`,
|
|
301
|
-
children: "This camera doesn't expose an on-board motion zones grid."
|
|
302
|
+
children: t("uiLibrary.motionZones.unsupported", "This camera doesn't expose an on-board motion zones grid.")
|
|
302
303
|
}) : !ready ? /* @__PURE__ */ jsx("p", {
|
|
303
304
|
className: `${TEXT_HINT} leading-relaxed`,
|
|
304
|
-
children: "Loading the camera's grid…"
|
|
305
|
-
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */
|
|
305
|
+
children: t("uiLibrary.motionZones.loading", "Loading the camera's grid…")
|
|
306
|
+
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("p", {
|
|
306
307
|
className: `${TEXT_HINT} leading-relaxed`,
|
|
307
|
-
children:
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
/* @__PURE__ */ jsx("strong", {
|
|
321
|
-
className: "text-foreground",
|
|
322
|
-
children: "Cell size"
|
|
323
|
-
}),
|
|
324
|
-
" for quicker, broad-stroke painting — it's resampled to the camera's native ",
|
|
325
|
-
options.grid.width,
|
|
326
|
-
"×",
|
|
327
|
-
options.grid.height,
|
|
328
|
-
" grid on save (×1 is the finest)."
|
|
329
|
-
]
|
|
308
|
+
children: /* @__PURE__ */ jsx(UiTrans, {
|
|
309
|
+
uiKey: "uiLibrary.motionZones.intro",
|
|
310
|
+
fallback: "Toggle <0>Edit grid</0> to paint the region directly on the live frame, then <1>Save</1> to push the mask to the camera. Pick a bigger <2>Cell size</2> for quicker, broad-stroke painting — it's resampled to the camera's native {{width}}×{{height}} grid on save (×1 is the finest).",
|
|
311
|
+
components: [
|
|
312
|
+
/* @__PURE__ */ jsx("strong", { className: "text-foreground" }, "e"),
|
|
313
|
+
/* @__PURE__ */ jsx("strong", { className: "text-foreground" }, "s"),
|
|
314
|
+
/* @__PURE__ */ jsx("strong", { className: "text-foreground" }, "c")
|
|
315
|
+
],
|
|
316
|
+
values: {
|
|
317
|
+
width: options.grid.width,
|
|
318
|
+
height: options.grid.height
|
|
319
|
+
}
|
|
320
|
+
})
|
|
330
321
|
}), /* @__PURE__ */ jsxs("div", {
|
|
331
322
|
className: "flex items-center gap-2 flex-wrap",
|
|
332
323
|
children: [
|
|
@@ -336,58 +327,64 @@ function MotionZonesSettings({ deviceId }) {
|
|
|
336
327
|
disabled: saving,
|
|
337
328
|
"aria-pressed": editing,
|
|
338
329
|
className: editing ? BTN_PRIMARY : BTN_NEUTRAL,
|
|
339
|
-
children: editing ? "Done editing" : "Edit grid"
|
|
330
|
+
children: editing ? t("uiLibrary.motionZones.doneEditing", "Done editing") : t("uiLibrary.motionZones.editGrid", "Edit grid")
|
|
340
331
|
}),
|
|
341
332
|
/* @__PURE__ */ jsx("button", {
|
|
342
333
|
type: "button",
|
|
343
334
|
onClick: () => setAll(true),
|
|
344
335
|
disabled: saving,
|
|
345
336
|
className: BTN_NEUTRAL,
|
|
346
|
-
children: "All on"
|
|
337
|
+
children: t("uiLibrary.motionZones.allOn", "All on")
|
|
347
338
|
}),
|
|
348
339
|
/* @__PURE__ */ jsx("button", {
|
|
349
340
|
type: "button",
|
|
350
341
|
onClick: () => setAll(false),
|
|
351
342
|
disabled: saving,
|
|
352
343
|
className: BTN_NEUTRAL,
|
|
353
|
-
children: "All off"
|
|
344
|
+
children: t("uiLibrary.motionZones.allOff", "All off")
|
|
354
345
|
}),
|
|
355
346
|
/* @__PURE__ */ jsx("button", {
|
|
356
347
|
type: "button",
|
|
357
348
|
onClick: invert,
|
|
358
349
|
disabled: saving,
|
|
359
350
|
className: BTN_NEUTRAL,
|
|
360
|
-
children: "Invert"
|
|
351
|
+
children: t("uiLibrary.motionZones.invert", "Invert")
|
|
361
352
|
}),
|
|
362
353
|
/* @__PURE__ */ jsxs("div", {
|
|
363
354
|
className: "flex items-center gap-1 ml-1",
|
|
364
355
|
role: "group",
|
|
365
|
-
"aria-label": "Cell size",
|
|
356
|
+
"aria-label": t("uiLibrary.motionZones.cellSize", "Cell size"),
|
|
366
357
|
children: [/* @__PURE__ */ jsx("span", {
|
|
367
358
|
className: `${TEXT_HINT} mr-0.5`,
|
|
368
|
-
children: "Cell size"
|
|
359
|
+
children: t("uiLibrary.motionZones.cellSize", "Cell size")
|
|
369
360
|
}), GRID_MULTIPLIERS.map((m) => /* @__PURE__ */ jsxs("button", {
|
|
370
361
|
type: "button",
|
|
371
362
|
onClick: () => changeMultiplier(m),
|
|
372
363
|
disabled: saving,
|
|
373
364
|
"aria-pressed": multiplier === m,
|
|
374
|
-
title: m === 1 ?
|
|
365
|
+
title: m === 1 ? t("uiLibrary.motionZones.cameraGrid", "Camera grid {{width}}×{{height}} (finest)", {
|
|
366
|
+
width: cw,
|
|
367
|
+
height: ch
|
|
368
|
+
}) : t("uiLibrary.motionZones.paintingGrid", "{{width}}×{{height}} painting grid · cells ×{{factor}} bigger", {
|
|
369
|
+
width: coarseDim(cw, m),
|
|
370
|
+
height: coarseDim(ch, m),
|
|
371
|
+
factor: m
|
|
372
|
+
}),
|
|
375
373
|
className: multiplier === m ? BTN_PRIMARY : BTN_NEUTRAL,
|
|
376
374
|
children: ["×", m]
|
|
377
375
|
}, m))]
|
|
378
376
|
}),
|
|
379
377
|
/* @__PURE__ */ jsxs("span", {
|
|
380
378
|
className: `${TEXT_HINT} ml-1 tabular-nums`,
|
|
381
|
-
children: [
|
|
382
|
-
activeCount,
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
]
|
|
379
|
+
children: [t("uiLibrary.motionZones.cells", "{{active}} / {{total}} cells · {{width}}×{{height}}", {
|
|
380
|
+
active: activeCount,
|
|
381
|
+
total: cameraTotal,
|
|
382
|
+
width: options.grid.width,
|
|
383
|
+
height: options.grid.height
|
|
384
|
+
}), multiplier !== 1 ? t("uiLibrary.motionZones.paintSuffix", " · paint {{width}}×{{height}}", {
|
|
385
|
+
width: uiWidth,
|
|
386
|
+
height: uiHeight
|
|
387
|
+
}) : ""]
|
|
391
388
|
}),
|
|
392
389
|
/* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
393
390
|
/* @__PURE__ */ jsx("button", {
|
|
@@ -395,14 +392,14 @@ function MotionZonesSettings({ deviceId }) {
|
|
|
395
392
|
onClick: revert,
|
|
396
393
|
disabled: saving || !dirty,
|
|
397
394
|
className: "rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors",
|
|
398
|
-
children: "Revert"
|
|
395
|
+
children: t("uiLibrary.motionZones.revert", "Revert")
|
|
399
396
|
}),
|
|
400
397
|
/* @__PURE__ */ jsx("button", {
|
|
401
398
|
type: "button",
|
|
402
399
|
onClick: () => void save(),
|
|
403
400
|
disabled: saving || !dirty,
|
|
404
401
|
className: BTN_PRIMARY,
|
|
405
|
-
children: saving ? "Saving…" : "Save"
|
|
402
|
+
children: saving ? t("uiLibrary.motionZones.saving", "Saving…") : t("uiLibrary.motionZones.save", "Save")
|
|
406
403
|
})
|
|
407
404
|
]
|
|
408
405
|
})] })
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_index = require("./index.cjs");
|
|
2
|
-
const require_MaskShapeCanvas = require("./MaskShapeCanvas-
|
|
2
|
+
const require_MaskShapeCanvas = require("./MaskShapeCanvas-NCNwu9_5.cjs");
|
|
3
3
|
let react = require("react");
|
|
4
4
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
5
|
//#region src/composites/cap-settings/MotionZonesSettings.tsx
|
|
@@ -119,6 +119,7 @@ function expandCells(uiCells, cw, ch, m) {
|
|
|
119
119
|
return out;
|
|
120
120
|
}
|
|
121
121
|
function MotionZonesSettings({ deviceId }) {
|
|
122
|
+
const t = require_index.useUiText();
|
|
122
123
|
const dev = require_index.useDeviceProxy$1(require_index.useSystem$1().trpcClient, deviceId);
|
|
123
124
|
const [options, setOptions] = (0, react.useState)(null);
|
|
124
125
|
const [unsupported, setUnsupported] = (0, react.useState)(false);
|
|
@@ -292,41 +293,31 @@ function MotionZonesSettings({ deviceId }) {
|
|
|
292
293
|
const ready = !unsupported && options !== null && uiCells !== null;
|
|
293
294
|
if (!dev) return null;
|
|
294
295
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.WidgetPanel, {
|
|
295
|
-
title: "Motion Zones",
|
|
296
|
+
title: t("uiLibrary.motionZones.title", "Motion Zones"),
|
|
296
297
|
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.Grid2x2, { className: "h-3.5 w-3.5 text-foreground-subtle" }),
|
|
297
298
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
298
299
|
className: "flex flex-col gap-3",
|
|
299
300
|
children: unsupported ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
300
301
|
className: `${require_index.TEXT_HINT} leading-relaxed`,
|
|
301
|
-
children: "This camera doesn't expose an on-board motion zones grid."
|
|
302
|
+
children: t("uiLibrary.motionZones.unsupported", "This camera doesn't expose an on-board motion zones grid.")
|
|
302
303
|
}) : !ready ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
303
304
|
className: `${require_index.TEXT_HINT} leading-relaxed`,
|
|
304
|
-
children: "Loading the camera's grid…"
|
|
305
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
305
|
+
children: t("uiLibrary.motionZones.loading", "Loading the camera's grid…")
|
|
306
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
306
307
|
className: `${require_index.TEXT_HINT} leading-relaxed`,
|
|
307
|
-
children:
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
|
|
321
|
-
className: "text-foreground",
|
|
322
|
-
children: "Cell size"
|
|
323
|
-
}),
|
|
324
|
-
" for quicker, broad-stroke painting — it's resampled to the camera's native ",
|
|
325
|
-
options.grid.width,
|
|
326
|
-
"×",
|
|
327
|
-
options.grid.height,
|
|
328
|
-
" grid on save (×1 is the finest)."
|
|
329
|
-
]
|
|
308
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.UiTrans, {
|
|
309
|
+
uiKey: "uiLibrary.motionZones.intro",
|
|
310
|
+
fallback: "Toggle <0>Edit grid</0> to paint the region directly on the live frame, then <1>Save</1> to push the mask to the camera. Pick a bigger <2>Cell size</2> for quicker, broad-stroke painting — it's resampled to the camera's native {{width}}×{{height}} grid on save (×1 is the finest).",
|
|
311
|
+
components: [
|
|
312
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { className: "text-foreground" }, "e"),
|
|
313
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { className: "text-foreground" }, "s"),
|
|
314
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { className: "text-foreground" }, "c")
|
|
315
|
+
],
|
|
316
|
+
values: {
|
|
317
|
+
width: options.grid.width,
|
|
318
|
+
height: options.grid.height
|
|
319
|
+
}
|
|
320
|
+
})
|
|
330
321
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
331
322
|
className: "flex items-center gap-2 flex-wrap",
|
|
332
323
|
children: [
|
|
@@ -336,58 +327,64 @@ function MotionZonesSettings({ deviceId }) {
|
|
|
336
327
|
disabled: saving,
|
|
337
328
|
"aria-pressed": editing,
|
|
338
329
|
className: editing ? BTN_PRIMARY : BTN_NEUTRAL,
|
|
339
|
-
children: editing ? "Done editing" : "Edit grid"
|
|
330
|
+
children: editing ? t("uiLibrary.motionZones.doneEditing", "Done editing") : t("uiLibrary.motionZones.editGrid", "Edit grid")
|
|
340
331
|
}),
|
|
341
332
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
342
333
|
type: "button",
|
|
343
334
|
onClick: () => setAll(true),
|
|
344
335
|
disabled: saving,
|
|
345
336
|
className: BTN_NEUTRAL,
|
|
346
|
-
children: "All on"
|
|
337
|
+
children: t("uiLibrary.motionZones.allOn", "All on")
|
|
347
338
|
}),
|
|
348
339
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
349
340
|
type: "button",
|
|
350
341
|
onClick: () => setAll(false),
|
|
351
342
|
disabled: saving,
|
|
352
343
|
className: BTN_NEUTRAL,
|
|
353
|
-
children: "All off"
|
|
344
|
+
children: t("uiLibrary.motionZones.allOff", "All off")
|
|
354
345
|
}),
|
|
355
346
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
356
347
|
type: "button",
|
|
357
348
|
onClick: invert,
|
|
358
349
|
disabled: saving,
|
|
359
350
|
className: BTN_NEUTRAL,
|
|
360
|
-
children: "Invert"
|
|
351
|
+
children: t("uiLibrary.motionZones.invert", "Invert")
|
|
361
352
|
}),
|
|
362
353
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
363
354
|
className: "flex items-center gap-1 ml-1",
|
|
364
355
|
role: "group",
|
|
365
|
-
"aria-label": "Cell size",
|
|
356
|
+
"aria-label": t("uiLibrary.motionZones.cellSize", "Cell size"),
|
|
366
357
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
367
358
|
className: `${require_index.TEXT_HINT} mr-0.5`,
|
|
368
|
-
children: "Cell size"
|
|
359
|
+
children: t("uiLibrary.motionZones.cellSize", "Cell size")
|
|
369
360
|
}), GRID_MULTIPLIERS.map((m) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
370
361
|
type: "button",
|
|
371
362
|
onClick: () => changeMultiplier(m),
|
|
372
363
|
disabled: saving,
|
|
373
364
|
"aria-pressed": multiplier === m,
|
|
374
|
-
title: m === 1 ?
|
|
365
|
+
title: m === 1 ? t("uiLibrary.motionZones.cameraGrid", "Camera grid {{width}}×{{height}} (finest)", {
|
|
366
|
+
width: cw,
|
|
367
|
+
height: ch
|
|
368
|
+
}) : t("uiLibrary.motionZones.paintingGrid", "{{width}}×{{height}} painting grid · cells ×{{factor}} bigger", {
|
|
369
|
+
width: coarseDim(cw, m),
|
|
370
|
+
height: coarseDim(ch, m),
|
|
371
|
+
factor: m
|
|
372
|
+
}),
|
|
375
373
|
className: multiplier === m ? BTN_PRIMARY : BTN_NEUTRAL,
|
|
376
374
|
children: ["×", m]
|
|
377
375
|
}, m))]
|
|
378
376
|
}),
|
|
379
377
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
380
378
|
className: `${require_index.TEXT_HINT} ml-1 tabular-nums`,
|
|
381
|
-
children: [
|
|
382
|
-
activeCount,
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
]
|
|
379
|
+
children: [t("uiLibrary.motionZones.cells", "{{active}} / {{total}} cells · {{width}}×{{height}}", {
|
|
380
|
+
active: activeCount,
|
|
381
|
+
total: cameraTotal,
|
|
382
|
+
width: options.grid.width,
|
|
383
|
+
height: options.grid.height
|
|
384
|
+
}), multiplier !== 1 ? t("uiLibrary.motionZones.paintSuffix", " · paint {{width}}×{{height}}", {
|
|
385
|
+
width: uiWidth,
|
|
386
|
+
height: uiHeight
|
|
387
|
+
}) : ""]
|
|
391
388
|
}),
|
|
392
389
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "flex-1" }),
|
|
393
390
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -395,14 +392,14 @@ function MotionZonesSettings({ deviceId }) {
|
|
|
395
392
|
onClick: revert,
|
|
396
393
|
disabled: saving || !dirty,
|
|
397
394
|
className: "rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors",
|
|
398
|
-
children: "Revert"
|
|
395
|
+
children: t("uiLibrary.motionZones.revert", "Revert")
|
|
399
396
|
}),
|
|
400
397
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
401
398
|
type: "button",
|
|
402
399
|
onClick: () => void save(),
|
|
403
400
|
disabled: saving || !dirty,
|
|
404
401
|
className: BTN_PRIMARY,
|
|
405
|
-
children: saving ? "Saving…" : "Save"
|
|
402
|
+
children: saving ? t("uiLibrary.motionZones.saving", "Saving…") : t("uiLibrary.motionZones.save", "Save")
|
|
406
403
|
})
|
|
407
404
|
]
|
|
408
405
|
})] })
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const require_mic_off = require("./mic-off-4nCMfrMI.cjs");
|
|
2
2
|
const require_index = require("./index.cjs");
|
|
3
|
-
const require_MaskShapeCanvas = require("./MaskShapeCanvas-
|
|
3
|
+
const require_MaskShapeCanvas = require("./MaskShapeCanvas-NCNwu9_5.cjs");
|
|
4
4
|
let react = require("react");
|
|
5
5
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
6
|
//#region src/composites/cap-settings/privacy-mask-audio.ts
|
|
@@ -53,6 +53,7 @@ function regionsEqual(a, b) {
|
|
|
53
53
|
return true;
|
|
54
54
|
}
|
|
55
55
|
function PrivacyMaskSettings({ deviceId }) {
|
|
56
|
+
const t = require_index.useUiText();
|
|
56
57
|
const dev = require_index.useDeviceProxy$1(require_index.useSystem$1().trpcClient, deviceId);
|
|
57
58
|
const [options, setOptions] = (0, react.useState)(null);
|
|
58
59
|
const [unsupported, setUnsupported] = (0, react.useState)(false);
|
|
@@ -144,8 +145,8 @@ function PrivacyMaskSettings({ deviceId }) {
|
|
|
144
145
|
id: r.id,
|
|
145
146
|
shape: r.shape,
|
|
146
147
|
enabled: r.enabled,
|
|
147
|
-
label:
|
|
148
|
-
})) : [], [draft]);
|
|
148
|
+
label: t("uiLibrary.privacyMaskSettings.zoneN", "Zone {{id}}", { id: r.id })
|
|
149
|
+
})) : [], [draft, t]);
|
|
149
150
|
const onShapeChange = (0, react.useCallback)((id, shape) => {
|
|
150
151
|
const next = toPrivacyMaskShape(shape);
|
|
151
152
|
if (!next) return;
|
|
@@ -290,35 +291,27 @@ function PrivacyMaskSettings({ deviceId }) {
|
|
|
290
291
|
const ready = !unsupported && !noShapes && !unreadable && options !== null && draft !== null;
|
|
291
292
|
if (!dev) return null;
|
|
292
293
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.WidgetPanel, {
|
|
293
|
-
title: "Privacy Mask",
|
|
294
|
+
title: t("uiLibrary.privacyMaskSettings.title", "Privacy Mask"),
|
|
294
295
|
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.EyeOff, { className: "h-3.5 w-3.5 text-foreground-subtle" }),
|
|
295
296
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
296
297
|
className: "flex flex-col gap-3",
|
|
297
298
|
children: [unsupported || noShapes ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
298
299
|
className: `${require_index.TEXT_HINT} leading-relaxed`,
|
|
299
|
-
children: "This camera doesn't support an on-board privacy mask."
|
|
300
|
+
children: t("uiLibrary.privacyMaskSettings.unsupported", "This camera doesn't support an on-board privacy mask.")
|
|
300
301
|
}) : unreadable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
301
302
|
className: `${require_index.TEXT_HINT} leading-relaxed`,
|
|
302
|
-
children: "This camera hasn't answered, so what it currently masks is unknown — the editor stays closed rather than showing an empty frame you could save over. A battery camera answers once it wakes; otherwise check that it is reachable."
|
|
303
|
+
children: t("uiLibrary.privacyMaskSettings.unreadable", "This camera hasn't answered, so what it currently masks is unknown — the editor stays closed rather than showing an empty frame you could save over. A battery camera answers once it wakes; otherwise check that it is reachable.")
|
|
303
304
|
}) : !ready ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
304
305
|
className: `${require_index.TEXT_HINT} leading-relaxed`,
|
|
305
|
-
children: "Loading the camera's privacy mask…"
|
|
306
|
+
children: t("uiLibrary.privacyMaskSettings.loading", "Loading the camera's privacy mask…")
|
|
306
307
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
307
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
308
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
308
309
|
className: `${require_index.TEXT_HINT} leading-relaxed`,
|
|
309
|
-
children:
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
}),
|
|
315
|
-
" to draw blanked-out zones on the live frame, then ",
|
|
316
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
|
|
317
|
-
className: "text-foreground",
|
|
318
|
-
children: "Save"
|
|
319
|
-
}),
|
|
320
|
-
" to push them to the camera. Drag a rectangle to move, its corner to resize; drag polygon vertices, click an edge midpoint to add one, or right-click a vertex to remove it."
|
|
321
|
-
]
|
|
310
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.UiTrans, {
|
|
311
|
+
uiKey: "uiLibrary.privacyMaskSettings.help",
|
|
312
|
+
fallback: "Toggle <0>Edit mask</0> to draw blanked-out zones on the live frame, then <1>Save</1> to push them to the camera. Drag a rectangle to move, its corner to resize; drag polygon vertices, click an edge midpoint to add one, or right-click a vertex to remove it.",
|
|
313
|
+
components: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { className: "text-foreground" }, "edit"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { className: "text-foreground" }, "save")]
|
|
314
|
+
})
|
|
322
315
|
}),
|
|
323
316
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
324
317
|
className: "flex items-center gap-2 flex-wrap",
|
|
@@ -329,7 +322,7 @@ function PrivacyMaskSettings({ deviceId }) {
|
|
|
329
322
|
disabled: saving,
|
|
330
323
|
"aria-pressed": editing,
|
|
331
324
|
className: editing ? BTN_PRIMARY : BTN_NEUTRAL,
|
|
332
|
-
children: editing ? "Done editing" : "Edit mask"
|
|
325
|
+
children: editing ? t("uiLibrary.privacyMaskSettings.doneEditing", "Done editing") : t("uiLibrary.privacyMaskSettings.editMask", "Edit mask")
|
|
333
326
|
}),
|
|
334
327
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
335
328
|
type: "button",
|
|
@@ -337,7 +330,7 @@ function PrivacyMaskSettings({ deviceId }) {
|
|
|
337
330
|
disabled: saving,
|
|
338
331
|
"aria-pressed": draft.enabled,
|
|
339
332
|
className: draft.enabled ? BTN_PRIMARY : BTN_NEUTRAL,
|
|
340
|
-
children: draft.enabled ? "Mask on" : "Mask off"
|
|
333
|
+
children: draft.enabled ? t("uiLibrary.privacyMaskSettings.maskOn", "Mask on") : t("uiLibrary.privacyMaskSettings.maskOff", "Mask off")
|
|
341
334
|
}),
|
|
342
335
|
supportsRect && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
343
336
|
type: "button",
|
|
@@ -345,8 +338,8 @@ function PrivacyMaskSettings({ deviceId }) {
|
|
|
345
338
|
disabled: saving || atCapacity,
|
|
346
339
|
"aria-pressed": drawingKind === "rect",
|
|
347
340
|
className: drawingKind === "rect" ? BTN_PRIMARY : BTN_NEUTRAL,
|
|
348
|
-
title: atCapacity ? "Maximum zones reached" : "Add a rectangle zone",
|
|
349
|
-
children: "+ Rect"
|
|
341
|
+
title: atCapacity ? t("uiLibrary.privacyMaskSettings.maxZones", "Maximum zones reached") : t("uiLibrary.privacyMaskSettings.addRect", "Add a rectangle zone"),
|
|
342
|
+
children: t("uiLibrary.privacyMaskSettings.rectButton", "+ Rect")
|
|
350
343
|
}),
|
|
351
344
|
supportsPolygon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
352
345
|
type: "button",
|
|
@@ -354,17 +347,15 @@ function PrivacyMaskSettings({ deviceId }) {
|
|
|
354
347
|
disabled: saving || atCapacity,
|
|
355
348
|
"aria-pressed": drawingKind === "polygon",
|
|
356
349
|
className: drawingKind === "polygon" ? BTN_PRIMARY : BTN_NEUTRAL,
|
|
357
|
-
title: atCapacity ? "Maximum zones reached" : "Add a polygon zone",
|
|
358
|
-
children: "+ Polygon"
|
|
350
|
+
title: atCapacity ? t("uiLibrary.privacyMaskSettings.maxZones", "Maximum zones reached") : t("uiLibrary.privacyMaskSettings.addPolygon", "Add a polygon zone"),
|
|
351
|
+
children: t("uiLibrary.privacyMaskSettings.polygonButton", "+ Polygon")
|
|
359
352
|
}),
|
|
360
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
353
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
361
354
|
className: `${require_index.TEXT_HINT} ml-1 tabular-nums`,
|
|
362
|
-
children:
|
|
363
|
-
activeCount,
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
" zones"
|
|
367
|
-
]
|
|
355
|
+
children: t("uiLibrary.privacyMaskSettings.zoneCount", "{{active}} / {{max}} zones", {
|
|
356
|
+
active: activeCount,
|
|
357
|
+
max: maxRegions
|
|
358
|
+
})
|
|
368
359
|
}),
|
|
369
360
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "flex-1" }),
|
|
370
361
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -372,14 +363,14 @@ function PrivacyMaskSettings({ deviceId }) {
|
|
|
372
363
|
onClick: revert,
|
|
373
364
|
disabled: saving || !dirty,
|
|
374
365
|
className: "rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors",
|
|
375
|
-
children: "Revert"
|
|
366
|
+
children: t("uiLibrary.privacyMaskSettings.revert", "Revert")
|
|
376
367
|
}),
|
|
377
368
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
378
369
|
type: "button",
|
|
379
370
|
onClick: () => void save(),
|
|
380
371
|
disabled: saving || !dirty,
|
|
381
372
|
className: BTN_PRIMARY,
|
|
382
|
-
children: saving ? "Saving…" : "Save"
|
|
373
|
+
children: saving ? t("uiLibrary.privacyMaskSettings.saving", "Saving…") : t("uiLibrary.privacyMaskSettings.save", "Save")
|
|
383
374
|
})
|
|
384
375
|
]
|
|
385
376
|
}),
|
|
@@ -397,7 +388,7 @@ function PrivacyMaskSettings({ deviceId }) {
|
|
|
397
388
|
className: "flex flex-1 items-center gap-2 text-left text-[11px] font-medium text-foreground-subtle hover:text-foreground disabled:opacity-40 transition-colors",
|
|
398
389
|
children: [
|
|
399
390
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShapeIcon, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
400
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
391
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("uiLibrary.privacyMaskSettings.zoneN", "Zone {{id}}", { id: r.id }) }),
|
|
401
392
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
402
393
|
className: "text-foreground-faint capitalize",
|
|
403
394
|
children: r.shape.kind
|
|
@@ -407,8 +398,8 @@ function PrivacyMaskSettings({ deviceId }) {
|
|
|
407
398
|
type: "button",
|
|
408
399
|
onClick: () => deleteRegion(r.id),
|
|
409
400
|
disabled: saving,
|
|
410
|
-
"aria-label":
|
|
411
|
-
title: "Delete zone",
|
|
401
|
+
"aria-label": t("uiLibrary.privacyMaskSettings.deleteZoneN", "Delete zone {{id}}", { id: r.id }),
|
|
402
|
+
title: t("uiLibrary.privacyMaskSettings.deleteZone", "Delete zone"),
|
|
412
403
|
className: "inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-surface text-foreground-subtle hover:border-red-400/40 hover:bg-red-500/10 hover:text-red-400 disabled:opacity-40 transition-colors",
|
|
413
404
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.Trash2, { className: "h-3.5 w-3.5" })
|
|
414
405
|
})]
|
|
@@ -424,15 +415,15 @@ function PrivacyMaskSettings({ deviceId }) {
|
|
|
424
415
|
"aria-checked": microphone.on === true,
|
|
425
416
|
disabled: !microphone.available || pendingAudio !== null,
|
|
426
417
|
onClick: () => void toggleMicrophone(),
|
|
427
|
-
title: microphone.on === null ? "Microphone — state unknown; the camera did not answer." : microphone.on ?
|
|
418
|
+
title: microphone.on === null ? t("uiLibrary.privacyMaskSettings.micTitleUnknown", "Microphone — state unknown; the camera did not answer.") : microphone.on ? t("uiLibrary.privacyMaskSettings.micTitleOn", "The camera is capturing sound. Turning it off: {{cost}}", { cost: microphone.costWhenOff }) : t("uiLibrary.privacyMaskSettings.micTitleOff", "The camera is silent. {{cost}}", { cost: microphone.costWhenOff }),
|
|
428
419
|
className: microphone.on === false || microphone.on === null ? BTN_NEUTRAL : BTN_PRIMARY,
|
|
429
420
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
430
421
|
className: "inline-flex items-center gap-1.5",
|
|
431
|
-
children: [microphone.on === false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_mic_off.MicOff, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.Mic, { className: "h-3.5 w-3.5" }), microphone.on === null ? "Microphone unknown" : microphone.on ? "Microphone on" : "Microphone off"]
|
|
422
|
+
children: [microphone.on === false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_mic_off.MicOff, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.Mic, { className: "h-3.5 w-3.5" }), microphone.on === null ? t("uiLibrary.privacyMaskSettings.micUnknown", "Microphone unknown") : microphone.on ? t("uiLibrary.privacyMaskSettings.micOn", "Microphone on") : t("uiLibrary.privacyMaskSettings.micOff", "Microphone off")]
|
|
432
423
|
})
|
|
433
424
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
434
425
|
className: `text-[10px] text-foreground-subtle flex-1 leading-relaxed`,
|
|
435
|
-
children: audioFailure !== null ?
|
|
426
|
+
children: audioFailure !== null ? t("uiLibrary.privacyMaskSettings.writeFailed", "Write failed: {{reason}}", { reason: audioFailure }) : microphone.on === null ? t("uiLibrary.privacyMaskSettings.micNotReported", "The camera did not report its microphone, so this state is unknown.") : microphone.costWhenOff
|
|
436
427
|
})]
|
|
437
428
|
})]
|
|
438
429
|
})
|