@camstack/ui-library 1.1.38 → 1.1.39
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RecordingRule, RecordingMode, RecordingConfig, RecordingStorageMode, RecordingSchedule, RecordingTriggers, RecordingRetention, CamProfile } from '@camstack/types';
|
|
1
|
+
import { RecordingRule, RecordingMode, RecordingConfig, RecordingStorageMode, RecordingSchedule, RecordingTriggers, RecordingRetention, ScrubThumbnailPreset, CamProfile } from '@camstack/types';
|
|
2
2
|
export declare function emptyRule(): RecordingRule;
|
|
3
3
|
export declare function isTriggerMode(mode: RecordingMode): boolean;
|
|
4
4
|
export declare function withRuleAt(rules: readonly RecordingRule[], index: number, patch: Partial<RecordingRule>): RecordingRule[];
|
|
@@ -18,6 +18,8 @@ export interface RecordingFormState {
|
|
|
18
18
|
readonly preBufferSec?: number;
|
|
19
19
|
readonly postBufferSec?: number;
|
|
20
20
|
readonly retention?: RecordingRetention;
|
|
21
|
+
/** Per-camera scrub-thumbnail fidelity preset (absent = standard). */
|
|
22
|
+
readonly scrubThumbnails?: ScrubThumbnailPreset;
|
|
21
23
|
}
|
|
22
24
|
/** Read a persisted/migrated config into the Basic form state. `mode` is read
|
|
23
25
|
* directly; a legacy mode-less config falls back to continuous/off by `enabled`. */
|
package/dist/index.cjs
CHANGED
|
@@ -33416,7 +33416,8 @@ function formStateFromConfig(cfg) {
|
|
|
33416
33416
|
triggers: cfg.triggers ?? {},
|
|
33417
33417
|
preBufferSec: cfg.preBufferSec,
|
|
33418
33418
|
postBufferSec: cfg.postBufferSec,
|
|
33419
|
-
retention: cfg.retention
|
|
33419
|
+
retention: cfg.retention,
|
|
33420
|
+
scrubThumbnails: cfg.scrubThumbnails
|
|
33420
33421
|
};
|
|
33421
33422
|
}
|
|
33422
33423
|
/** Serialize the Basic form state back to the wire config. `enabled` is derived
|
|
@@ -33432,7 +33433,8 @@ function configFromFormState(state) {
|
|
|
33432
33433
|
triggers: Object.keys(state.triggers).length > 0 ? state.triggers : void 0,
|
|
33433
33434
|
preBufferSec: state.preBufferSec,
|
|
33434
33435
|
postBufferSec: state.postBufferSec,
|
|
33435
|
-
retention: state.retention
|
|
33436
|
+
retention: state.retention,
|
|
33437
|
+
scrubThumbnails: state.scrubThumbnails
|
|
33436
33438
|
};
|
|
33437
33439
|
}
|
|
33438
33440
|
/**
|
|
@@ -33855,7 +33857,8 @@ function RecordingSettings({ initial, saving, onSave }) {
|
|
|
33855
33857
|
const [common, setCommon] = (0, react$1.useState)({
|
|
33856
33858
|
profiles: initial.profiles,
|
|
33857
33859
|
segmentSeconds: initial.segmentSeconds,
|
|
33858
|
-
retention: initial.retention
|
|
33860
|
+
retention: initial.retention,
|
|
33861
|
+
scrubThumbnails: initial.scrubThumbnails
|
|
33859
33862
|
});
|
|
33860
33863
|
const ret = common.retention ?? {};
|
|
33861
33864
|
const setRet = (patch) => setCommon({
|
|
@@ -33866,6 +33869,10 @@ function RecordingSettings({ initial, saving, onSave }) {
|
|
|
33866
33869
|
}
|
|
33867
33870
|
});
|
|
33868
33871
|
const numOrUndef = (v) => v === "" ? void 0 : Number(v);
|
|
33872
|
+
const parsePreset = (v) => {
|
|
33873
|
+
const parsed = _camstack_types.ScrubThumbnailPresetSchema.safeParse(v);
|
|
33874
|
+
return parsed.success ? parsed.data : _camstack_types.DEFAULT_SCRUB_THUMBNAIL_PRESET;
|
|
33875
|
+
};
|
|
33869
33876
|
const toggleProfile = (p) => {
|
|
33870
33877
|
const cur = common.profiles ?? [...PROFILES];
|
|
33871
33878
|
const next = cur.includes(p) ? cur.filter((x) => x !== p) : [...cur, p];
|
|
@@ -33890,14 +33897,16 @@ function RecordingSettings({ initial, saving, onSave }) {
|
|
|
33890
33897
|
...base,
|
|
33891
33898
|
profiles: common.profiles,
|
|
33892
33899
|
segmentSeconds: common.segmentSeconds,
|
|
33893
|
-
retention: common.retention
|
|
33900
|
+
retention: common.retention,
|
|
33901
|
+
scrubThumbnails: common.scrubThumbnails
|
|
33894
33902
|
}));
|
|
33895
33903
|
else onSave({
|
|
33896
33904
|
enabled: advEnabled,
|
|
33897
33905
|
rules,
|
|
33898
33906
|
profiles: common.profiles ? [...common.profiles] : void 0,
|
|
33899
33907
|
segmentSeconds: common.segmentSeconds,
|
|
33900
|
-
retention: common.retention
|
|
33908
|
+
retention: common.retention,
|
|
33909
|
+
scrubThumbnails: common.scrubThumbnails
|
|
33901
33910
|
});
|
|
33902
33911
|
};
|
|
33903
33912
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -34036,37 +34045,62 @@ function RecordingSettings({ initial, saving, onSave }) {
|
|
|
34036
34045
|
}),
|
|
34037
34046
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
34038
34047
|
className: "flex flex-wrap items-center gap-4 text-xs",
|
|
34039
|
-
children: [
|
|
34040
|
-
|
|
34041
|
-
|
|
34042
|
-
|
|
34043
|
-
|
|
34044
|
-
|
|
34045
|
-
|
|
34046
|
-
|
|
34047
|
-
|
|
34048
|
-
|
|
34049
|
-
|
|
34050
|
-
|
|
34051
|
-
|
|
34052
|
-
|
|
34053
|
-
|
|
34054
|
-
|
|
34055
|
-
"
|
|
34056
|
-
|
|
34057
|
-
|
|
34058
|
-
|
|
34059
|
-
|
|
34060
|
-
|
|
34048
|
+
children: [
|
|
34049
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
34050
|
+
className: "flex items-center gap-2",
|
|
34051
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
34052
|
+
className: "text-foreground-subtle",
|
|
34053
|
+
children: "Profiles:"
|
|
34054
|
+
}), PROFILES.map((p) => {
|
|
34055
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
34056
|
+
type: "button",
|
|
34057
|
+
onClick: () => toggleProfile(p),
|
|
34058
|
+
className: `rounded px-2 py-1 ${common.profiles == null || common.profiles.includes(p) ? "bg-primary text-primary-foreground" : "bg-surface-hover text-foreground-subtle"}`,
|
|
34059
|
+
children: p
|
|
34060
|
+
}, p);
|
|
34061
|
+
})]
|
|
34062
|
+
}),
|
|
34063
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
34064
|
+
className: "flex items-center gap-1",
|
|
34065
|
+
children: [
|
|
34066
|
+
"Segment",
|
|
34067
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
34068
|
+
type: "number",
|
|
34069
|
+
min: 1,
|
|
34070
|
+
value: common.segmentSeconds ?? "",
|
|
34071
|
+
placeholder: "default",
|
|
34072
|
+
onChange: (e) => setCommon({
|
|
34073
|
+
...common,
|
|
34074
|
+
segmentSeconds: numOrUndef(e.target.value)
|
|
34075
|
+
}),
|
|
34076
|
+
className: "w-16 rounded-md border border-border bg-background px-1 py-1 text-xs"
|
|
34077
|
+
}),
|
|
34078
|
+
"s"
|
|
34079
|
+
]
|
|
34080
|
+
}),
|
|
34081
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
34082
|
+
className: "flex items-center gap-1",
|
|
34083
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
34084
|
+
className: "text-foreground-subtle",
|
|
34085
|
+
children: "Scrub preview quality"
|
|
34086
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
34087
|
+
value: common.scrubThumbnails ?? _camstack_types.DEFAULT_SCRUB_THUMBNAIL_PRESET,
|
|
34061
34088
|
onChange: (e) => setCommon({
|
|
34062
34089
|
...common,
|
|
34063
|
-
|
|
34090
|
+
scrubThumbnails: parsePreset(e.target.value)
|
|
34064
34091
|
}),
|
|
34065
|
-
className: "
|
|
34066
|
-
|
|
34067
|
-
|
|
34068
|
-
|
|
34069
|
-
|
|
34092
|
+
className: "rounded-md border border-border bg-background px-1 py-1 text-xs",
|
|
34093
|
+
children: _camstack_types.SCRUB_THUMBNAIL_PRESET_ORDER.map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
34094
|
+
value: p,
|
|
34095
|
+
children: _camstack_types.SCRUB_THUMBNAIL_PRESET_LABELS[p]
|
|
34096
|
+
}, p))
|
|
34097
|
+
})]
|
|
34098
|
+
})
|
|
34099
|
+
]
|
|
34100
|
+
}),
|
|
34101
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
34102
|
+
className: "text-[11px] text-foreground-subtle",
|
|
34103
|
+
children: "Timeline scrub-preview resolution + quality. Higher = crisper previews but larger sprite sheets. Applies to NEW recordings only — existing preview sheets keep their original resolution."
|
|
34070
34104
|
}),
|
|
34071
34105
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
34072
34106
|
className: "mb-1.5 text-[11px] font-semibold uppercase tracking-wider text-foreground-subtle",
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import * as __mfHostReact from "react";
|
|
|
3
3
|
import React, { Fragment, Suspense, createContext, createElement, forwardRef, lazy, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
|
|
4
4
|
import * as __mfHostReactJsxRuntime from "react/jsx-runtime";
|
|
5
5
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
-
import { ALL_CAPABILITY_DEFINITIONS, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EventCategory, ExposedDeviceSchema, KNOWN_CAP_NAMES, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, RecordingConfigSchema, RecordingStatusSchema, SourceInfoSchema, TIMEZONES, buildModelVariantGroups, canConvertUnit, createDeviceProxy, createLazyTrpcSource, createSliceHandle, describeModelVariant, findTimezone, resolveVariantModelId, tryConvertUnit } from "@camstack/types";
|
|
6
|
+
import { ALL_CAPABILITY_DEFINITIONS, DEFAULT_SCRUB_THUMBNAIL_PRESET, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EventCategory, ExposedDeviceSchema, KNOWN_CAP_NAMES, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, RecordingConfigSchema, RecordingStatusSchema, SCRUB_THUMBNAIL_PRESET_LABELS, SCRUB_THUMBNAIL_PRESET_ORDER, ScrubThumbnailPresetSchema, SourceInfoSchema, TIMEZONES, buildModelVariantGroups, canConvertUnit, createDeviceProxy, createLazyTrpcSource, createSliceHandle, describeModelVariant, findTimezone, resolveVariantModelId, tryConvertUnit } from "@camstack/types";
|
|
7
7
|
import * as __mfHostReactDOM from "react-dom";
|
|
8
8
|
import { createPortal } from "react-dom";
|
|
9
9
|
import * as __mfHostReactDOMClient from "react-dom/client";
|
|
@@ -33392,7 +33392,8 @@ function formStateFromConfig(cfg) {
|
|
|
33392
33392
|
triggers: cfg.triggers ?? {},
|
|
33393
33393
|
preBufferSec: cfg.preBufferSec,
|
|
33394
33394
|
postBufferSec: cfg.postBufferSec,
|
|
33395
|
-
retention: cfg.retention
|
|
33395
|
+
retention: cfg.retention,
|
|
33396
|
+
scrubThumbnails: cfg.scrubThumbnails
|
|
33396
33397
|
};
|
|
33397
33398
|
}
|
|
33398
33399
|
/** Serialize the Basic form state back to the wire config. `enabled` is derived
|
|
@@ -33408,7 +33409,8 @@ function configFromFormState(state) {
|
|
|
33408
33409
|
triggers: Object.keys(state.triggers).length > 0 ? state.triggers : void 0,
|
|
33409
33410
|
preBufferSec: state.preBufferSec,
|
|
33410
33411
|
postBufferSec: state.postBufferSec,
|
|
33411
|
-
retention: state.retention
|
|
33412
|
+
retention: state.retention,
|
|
33413
|
+
scrubThumbnails: state.scrubThumbnails
|
|
33412
33414
|
};
|
|
33413
33415
|
}
|
|
33414
33416
|
/**
|
|
@@ -33831,7 +33833,8 @@ function RecordingSettings({ initial, saving, onSave }) {
|
|
|
33831
33833
|
const [common, setCommon] = useState({
|
|
33832
33834
|
profiles: initial.profiles,
|
|
33833
33835
|
segmentSeconds: initial.segmentSeconds,
|
|
33834
|
-
retention: initial.retention
|
|
33836
|
+
retention: initial.retention,
|
|
33837
|
+
scrubThumbnails: initial.scrubThumbnails
|
|
33835
33838
|
});
|
|
33836
33839
|
const ret = common.retention ?? {};
|
|
33837
33840
|
const setRet = (patch) => setCommon({
|
|
@@ -33842,6 +33845,10 @@ function RecordingSettings({ initial, saving, onSave }) {
|
|
|
33842
33845
|
}
|
|
33843
33846
|
});
|
|
33844
33847
|
const numOrUndef = (v) => v === "" ? void 0 : Number(v);
|
|
33848
|
+
const parsePreset = (v) => {
|
|
33849
|
+
const parsed = ScrubThumbnailPresetSchema.safeParse(v);
|
|
33850
|
+
return parsed.success ? parsed.data : DEFAULT_SCRUB_THUMBNAIL_PRESET;
|
|
33851
|
+
};
|
|
33845
33852
|
const toggleProfile = (p) => {
|
|
33846
33853
|
const cur = common.profiles ?? [...PROFILES];
|
|
33847
33854
|
const next = cur.includes(p) ? cur.filter((x) => x !== p) : [...cur, p];
|
|
@@ -33866,14 +33873,16 @@ function RecordingSettings({ initial, saving, onSave }) {
|
|
|
33866
33873
|
...base,
|
|
33867
33874
|
profiles: common.profiles,
|
|
33868
33875
|
segmentSeconds: common.segmentSeconds,
|
|
33869
|
-
retention: common.retention
|
|
33876
|
+
retention: common.retention,
|
|
33877
|
+
scrubThumbnails: common.scrubThumbnails
|
|
33870
33878
|
}));
|
|
33871
33879
|
else onSave({
|
|
33872
33880
|
enabled: advEnabled,
|
|
33873
33881
|
rules,
|
|
33874
33882
|
profiles: common.profiles ? [...common.profiles] : void 0,
|
|
33875
33883
|
segmentSeconds: common.segmentSeconds,
|
|
33876
|
-
retention: common.retention
|
|
33884
|
+
retention: common.retention,
|
|
33885
|
+
scrubThumbnails: common.scrubThumbnails
|
|
33877
33886
|
});
|
|
33878
33887
|
};
|
|
33879
33888
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -34012,37 +34021,62 @@ function RecordingSettings({ initial, saving, onSave }) {
|
|
|
34012
34021
|
}),
|
|
34013
34022
|
/* @__PURE__ */ jsxs("div", {
|
|
34014
34023
|
className: "flex flex-wrap items-center gap-4 text-xs",
|
|
34015
|
-
children: [
|
|
34016
|
-
|
|
34017
|
-
|
|
34018
|
-
|
|
34019
|
-
|
|
34020
|
-
|
|
34021
|
-
|
|
34022
|
-
|
|
34023
|
-
|
|
34024
|
-
|
|
34025
|
-
|
|
34026
|
-
|
|
34027
|
-
|
|
34028
|
-
|
|
34029
|
-
|
|
34030
|
-
|
|
34031
|
-
"
|
|
34032
|
-
|
|
34033
|
-
|
|
34034
|
-
|
|
34035
|
-
|
|
34036
|
-
|
|
34024
|
+
children: [
|
|
34025
|
+
/* @__PURE__ */ jsxs("div", {
|
|
34026
|
+
className: "flex items-center gap-2",
|
|
34027
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
34028
|
+
className: "text-foreground-subtle",
|
|
34029
|
+
children: "Profiles:"
|
|
34030
|
+
}), PROFILES.map((p) => {
|
|
34031
|
+
return /* @__PURE__ */ jsx("button", {
|
|
34032
|
+
type: "button",
|
|
34033
|
+
onClick: () => toggleProfile(p),
|
|
34034
|
+
className: `rounded px-2 py-1 ${common.profiles == null || common.profiles.includes(p) ? "bg-primary text-primary-foreground" : "bg-surface-hover text-foreground-subtle"}`,
|
|
34035
|
+
children: p
|
|
34036
|
+
}, p);
|
|
34037
|
+
})]
|
|
34038
|
+
}),
|
|
34039
|
+
/* @__PURE__ */ jsxs("label", {
|
|
34040
|
+
className: "flex items-center gap-1",
|
|
34041
|
+
children: [
|
|
34042
|
+
"Segment",
|
|
34043
|
+
/* @__PURE__ */ jsx("input", {
|
|
34044
|
+
type: "number",
|
|
34045
|
+
min: 1,
|
|
34046
|
+
value: common.segmentSeconds ?? "",
|
|
34047
|
+
placeholder: "default",
|
|
34048
|
+
onChange: (e) => setCommon({
|
|
34049
|
+
...common,
|
|
34050
|
+
segmentSeconds: numOrUndef(e.target.value)
|
|
34051
|
+
}),
|
|
34052
|
+
className: "w-16 rounded-md border border-border bg-background px-1 py-1 text-xs"
|
|
34053
|
+
}),
|
|
34054
|
+
"s"
|
|
34055
|
+
]
|
|
34056
|
+
}),
|
|
34057
|
+
/* @__PURE__ */ jsxs("label", {
|
|
34058
|
+
className: "flex items-center gap-1",
|
|
34059
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
34060
|
+
className: "text-foreground-subtle",
|
|
34061
|
+
children: "Scrub preview quality"
|
|
34062
|
+
}), /* @__PURE__ */ jsx("select", {
|
|
34063
|
+
value: common.scrubThumbnails ?? DEFAULT_SCRUB_THUMBNAIL_PRESET,
|
|
34037
34064
|
onChange: (e) => setCommon({
|
|
34038
34065
|
...common,
|
|
34039
|
-
|
|
34066
|
+
scrubThumbnails: parsePreset(e.target.value)
|
|
34040
34067
|
}),
|
|
34041
|
-
className: "
|
|
34042
|
-
|
|
34043
|
-
|
|
34044
|
-
|
|
34045
|
-
|
|
34068
|
+
className: "rounded-md border border-border bg-background px-1 py-1 text-xs",
|
|
34069
|
+
children: SCRUB_THUMBNAIL_PRESET_ORDER.map((p) => /* @__PURE__ */ jsx("option", {
|
|
34070
|
+
value: p,
|
|
34071
|
+
children: SCRUB_THUMBNAIL_PRESET_LABELS[p]
|
|
34072
|
+
}, p))
|
|
34073
|
+
})]
|
|
34074
|
+
})
|
|
34075
|
+
]
|
|
34076
|
+
}),
|
|
34077
|
+
/* @__PURE__ */ jsx("p", {
|
|
34078
|
+
className: "text-[11px] text-foreground-subtle",
|
|
34079
|
+
children: "Timeline scrub-preview resolution + quality. Higher = crisper previews but larger sprite sheets. Applies to NEW recordings only — existing preview sheets keep their original resolution."
|
|
34046
34080
|
}),
|
|
34047
34081
|
/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
|
|
34048
34082
|
className: "mb-1.5 text-[11px] font-semibold uppercase tracking-wider text-foreground-subtle",
|