@camstack/ui-library 1.2.159 → 1.2.161

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.
@@ -4,6 +4,14 @@ export interface DetectionOverlayProps {
4
4
  readonly showMotionZones?: boolean;
5
5
  readonly showMotionRaw?: boolean;
6
6
  readonly showDetections?: boolean;
7
+ /**
8
+ * Draw subjects the tracker calls MOVING (and the ones it has not judged
9
+ * yet — an unclassified track is not a still one, and hiding it would make a
10
+ * new subject invisible for its first frames).
11
+ */
12
+ readonly showMoving?: boolean;
13
+ /** Draw subjects the tracker calls `stationary` or `loitering`. */
14
+ readonly showStationary?: boolean;
7
15
  readonly showPhaseIndicator?: boolean;
8
16
  }
9
- export declare function DetectionOverlay({ detections: { motion, motionRaw, detection, phase }, showMotionZones, showMotionRaw, showDetections, showPhaseIndicator, }: DetectionOverlayProps): import("react").JSX.Element | null;
17
+ export declare function DetectionOverlay({ detections: { motion, motionRaw, detection, phase }, showMotionZones, showMotionRaw, showDetections, showMoving, showStationary, showPhaseIndicator, }: DetectionOverlayProps): import("react").JSX.Element | null;
package/dist/index.cjs CHANGED
@@ -27875,10 +27875,24 @@ function getPhaseVisual(phase) {
27875
27875
  * Pure component — receives all data via props. Use with useDeviceDetections hook.
27876
27876
  * Positioned absolute inside a relative parent (e.g., video container).
27877
27877
  */
27878
- function DetectionOverlay({ detections: { motion, motionRaw, detection, phase }, showMotionZones = true, showMotionRaw = true, showDetections = true, showPhaseIndicator = true }) {
27878
+ /**
27879
+ * Whether the tracker has said this subject is not going anywhere.
27880
+ *
27881
+ * The verdict is the tracker's `TrackState`, and `idle` is its word for still —
27882
+ * the SAME field the evidence ledger judges an observation on (D494), so the
27883
+ * overlay and the registry can never disagree about one box. An ABSENT verdict
27884
+ * is NOT still: the tracker needs ~10 s to settle on `idle`, and treating "no
27885
+ * verdict yet" as still would file every new subject under the wrong switch for
27886
+ * its first seconds.
27887
+ */
27888
+ function isStill(d) {
27889
+ return d.track?.movementState === "idle";
27890
+ }
27891
+ function DetectionOverlay({ detections: { motion, motionRaw, detection, phase }, showMotionZones = true, showMotionRaw = true, showDetections = true, showMoving = true, showStationary = true, showPhaseIndicator = true }) {
27879
27892
  const hasMotion = showMotionZones && motion && motion.zones.length > 0;
27880
27893
  const hasMotionRaw = showMotionRaw && motionRaw && motionRaw.boxes.length > 0;
27881
- const hasDets = showDetections && detection && detection.detections.length > 0;
27894
+ const visibleDets = showDetections && detection ? detection.detections.filter((d) => isStill(d) ? showStationary : showMoving) : [];
27895
+ const hasDets = visibleDets.length > 0;
27882
27896
  if (!hasMotion && !hasMotionRaw && !hasDets && !showPhaseIndicator) return null;
27883
27897
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
27884
27898
  className: "absolute inset-0 pointer-events-none z-10",
@@ -27887,7 +27901,7 @@ function DetectionOverlay({ detections: { motion, motionRaw, detection, phase },
27887
27901
  hasMotionRaw && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MotionRawBoxes, { raw: motionRaw }),
27888
27902
  hasMotion && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MotionZones, { motion }),
27889
27903
  hasDets && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DetectionBoxes, {
27890
- detections: detection.detections,
27904
+ detections: visibleDets,
27891
27905
  frameWidth: detection.frameWidth,
27892
27906
  frameHeight: detection.frameHeight
27893
27907
  })
@@ -48927,6 +48941,8 @@ function StreamPanel({ serverUrl, createSession, sendAnswer, handleOffer, getIce
48927
48941
  const recordedPlayback = useRecordedPlayback();
48928
48942
  const [isPlaying, setIsPlaying] = (0, react$1.useState)(autoPlay);
48929
48943
  const [showDetections, setShowDetections] = (0, react$1.useState)(defaultShowDetections);
48944
+ const [showMoving, setShowMoving] = (0, react$1.useState)(true);
48945
+ const [showStationary, setShowStationary] = (0, react$1.useState)(true);
48930
48946
  const [showMotion, setShowMotion] = (0, react$1.useState)(defaultShowMotion);
48931
48947
  const [internalStreamId, setInternalStreamId] = (0, react$1.useState)(null);
48932
48948
  const [vodQuality, setVodQuality] = (0, react$1.useState)([]);
@@ -49182,15 +49198,27 @@ function StreamPanel({ serverUrl, createSession, sendAnswer, handleOffer, getIce
49182
49198
  })
49183
49199
  ]
49184
49200
  }),
49185
- hasDetections && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuToggle, {
49186
- label: "Show detections",
49187
- active: showDetections,
49188
- onClick: () => setShowDetections((v) => !v)
49189
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuToggle, {
49190
- label: "Show motion",
49191
- active: showMotion,
49192
- onClick: () => setShowMotion((v) => !v)
49193
- })] }),
49201
+ hasDetections && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
49202
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuToggle, {
49203
+ label: "Show detections",
49204
+ active: showDetections,
49205
+ onClick: () => setShowDetections((v) => !v)
49206
+ }),
49207
+ showDetections && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuToggle, {
49208
+ label: "…moving",
49209
+ active: showMoving,
49210
+ onClick: () => setShowMoving((v) => !v)
49211
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuToggle, {
49212
+ label: "…stationary",
49213
+ active: showStationary,
49214
+ onClick: () => setShowStationary((v) => !v)
49215
+ })] }),
49216
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuToggle, {
49217
+ label: "Show motion",
49218
+ active: showMotion,
49219
+ onClick: () => setShowMotion((v) => !v)
49220
+ })
49221
+ ] }),
49194
49222
  ptzAvailable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuToggle, {
49195
49223
  label: "PTZ controls",
49196
49224
  active: ptzShown,
@@ -49238,7 +49266,9 @@ function StreamPanel({ serverUrl, createSession, sendAnswer, handleOffer, getIce
49238
49266
  showPhaseIndicator: false,
49239
49267
  showMotionZones: showMotion,
49240
49268
  showMotionRaw: showMotion,
49241
- showDetections
49269
+ showDetections,
49270
+ showMoving,
49271
+ showStationary
49242
49272
  }),
49243
49273
  extraOverlay,
49244
49274
  ptzOverlayVisible && ptzOverlay
package/dist/index.js CHANGED
@@ -27851,10 +27851,24 @@ function getPhaseVisual(phase) {
27851
27851
  * Pure component — receives all data via props. Use with useDeviceDetections hook.
27852
27852
  * Positioned absolute inside a relative parent (e.g., video container).
27853
27853
  */
27854
- function DetectionOverlay({ detections: { motion, motionRaw, detection, phase }, showMotionZones = true, showMotionRaw = true, showDetections = true, showPhaseIndicator = true }) {
27854
+ /**
27855
+ * Whether the tracker has said this subject is not going anywhere.
27856
+ *
27857
+ * The verdict is the tracker's `TrackState`, and `idle` is its word for still —
27858
+ * the SAME field the evidence ledger judges an observation on (D494), so the
27859
+ * overlay and the registry can never disagree about one box. An ABSENT verdict
27860
+ * is NOT still: the tracker needs ~10 s to settle on `idle`, and treating "no
27861
+ * verdict yet" as still would file every new subject under the wrong switch for
27862
+ * its first seconds.
27863
+ */
27864
+ function isStill(d) {
27865
+ return d.track?.movementState === "idle";
27866
+ }
27867
+ function DetectionOverlay({ detections: { motion, motionRaw, detection, phase }, showMotionZones = true, showMotionRaw = true, showDetections = true, showMoving = true, showStationary = true, showPhaseIndicator = true }) {
27855
27868
  const hasMotion = showMotionZones && motion && motion.zones.length > 0;
27856
27869
  const hasMotionRaw = showMotionRaw && motionRaw && motionRaw.boxes.length > 0;
27857
- const hasDets = showDetections && detection && detection.detections.length > 0;
27870
+ const visibleDets = showDetections && detection ? detection.detections.filter((d) => isStill(d) ? showStationary : showMoving) : [];
27871
+ const hasDets = visibleDets.length > 0;
27858
27872
  if (!hasMotion && !hasMotionRaw && !hasDets && !showPhaseIndicator) return null;
27859
27873
  return /* @__PURE__ */ jsxs("div", {
27860
27874
  className: "absolute inset-0 pointer-events-none z-10",
@@ -27863,7 +27877,7 @@ function DetectionOverlay({ detections: { motion, motionRaw, detection, phase },
27863
27877
  hasMotionRaw && /* @__PURE__ */ jsx(MotionRawBoxes, { raw: motionRaw }),
27864
27878
  hasMotion && /* @__PURE__ */ jsx(MotionZones, { motion }),
27865
27879
  hasDets && /* @__PURE__ */ jsx(DetectionBoxes, {
27866
- detections: detection.detections,
27880
+ detections: visibleDets,
27867
27881
  frameWidth: detection.frameWidth,
27868
27882
  frameHeight: detection.frameHeight
27869
27883
  })
@@ -48903,6 +48917,8 @@ function StreamPanel({ serverUrl, createSession, sendAnswer, handleOffer, getIce
48903
48917
  const recordedPlayback = useRecordedPlayback();
48904
48918
  const [isPlaying, setIsPlaying] = useState(autoPlay);
48905
48919
  const [showDetections, setShowDetections] = useState(defaultShowDetections);
48920
+ const [showMoving, setShowMoving] = useState(true);
48921
+ const [showStationary, setShowStationary] = useState(true);
48906
48922
  const [showMotion, setShowMotion] = useState(defaultShowMotion);
48907
48923
  const [internalStreamId, setInternalStreamId] = useState(null);
48908
48924
  const [vodQuality, setVodQuality] = useState([]);
@@ -49158,15 +49174,27 @@ function StreamPanel({ serverUrl, createSession, sendAnswer, handleOffer, getIce
49158
49174
  })
49159
49175
  ]
49160
49176
  }),
49161
- hasDetections && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(MenuToggle, {
49162
- label: "Show detections",
49163
- active: showDetections,
49164
- onClick: () => setShowDetections((v) => !v)
49165
- }), /* @__PURE__ */ jsx(MenuToggle, {
49166
- label: "Show motion",
49167
- active: showMotion,
49168
- onClick: () => setShowMotion((v) => !v)
49169
- })] }),
49177
+ hasDetections && /* @__PURE__ */ jsxs(Fragment$1, { children: [
49178
+ /* @__PURE__ */ jsx(MenuToggle, {
49179
+ label: "Show detections",
49180
+ active: showDetections,
49181
+ onClick: () => setShowDetections((v) => !v)
49182
+ }),
49183
+ showDetections && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(MenuToggle, {
49184
+ label: "…moving",
49185
+ active: showMoving,
49186
+ onClick: () => setShowMoving((v) => !v)
49187
+ }), /* @__PURE__ */ jsx(MenuToggle, {
49188
+ label: "…stationary",
49189
+ active: showStationary,
49190
+ onClick: () => setShowStationary((v) => !v)
49191
+ })] }),
49192
+ /* @__PURE__ */ jsx(MenuToggle, {
49193
+ label: "Show motion",
49194
+ active: showMotion,
49195
+ onClick: () => setShowMotion((v) => !v)
49196
+ })
49197
+ ] }),
49170
49198
  ptzAvailable && /* @__PURE__ */ jsx(MenuToggle, {
49171
49199
  label: "PTZ controls",
49172
49200
  active: ptzShown,
@@ -49214,7 +49242,9 @@ function StreamPanel({ serverUrl, createSession, sendAnswer, handleOffer, getIce
49214
49242
  showPhaseIndicator: false,
49215
49243
  showMotionZones: showMotion,
49216
49244
  showMotionRaw: showMotion,
49217
- showDetections
49245
+ showDetections,
49246
+ showMoving,
49247
+ showStationary
49218
49248
  }),
49219
49249
  extraOverlay,
49220
49250
  ptzOverlayVisible && ptzOverlay
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/ui-library",
3
- "version": "1.2.159",
3
+ "version": "1.2.161",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",