@luxonis/depthai-viewer-common 0.0.1
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/README.md +11 -0
- package/package.json +20 -0
- package/src/components/ButtonLink.tsx +12 -0
- package/src/components/CTASubLabel.tsx +39 -0
- package/src/components/Link.tsx +10 -0
- package/src/components/Pipeline.tsx +35 -0
- package/src/components/Resizable.tsx +56 -0
- package/src/components/Streams.tsx +256 -0
- package/src/constants/connection.ts +45 -0
- package/src/constants/streams.ts +11 -0
- package/src/constants/url.ts +6 -0
- package/src/dai-connection/connection.ts +402 -0
- package/src/dai-connection/decoder.worker.ts +50 -0
- package/src/hooks/connection.ts +191 -0
- package/src/hooks/navigation.ts +25 -0
- package/src/hooks/search.ts +45 -0
- package/src/index.ts +27 -0
- package/src/providers/ConnectionProvider.tsx +39 -0
- package/src/providers/DataProvider.tsx +71 -0
- package/src/utils/arrays.ts +10 -0
- package/src/utils/dynamic-base-worker.ts +21 -0
- package/src/utils/functions.ts +3 -0
- package/src/utils/sorting.ts +42 -0
- package/src/utils/url.ts +8 -0
- package/src/window.d.ts +7 -0
- package/tsconfig.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# DepthAI Web Viewer | Common | Luxonis
|
|
2
|
+
This package is a workspace common library
|
|
3
|
+
|
|
4
|
+
## Exports
|
|
5
|
+
- Navigational components `ButtonLink` and `Link` supporing dynamic base path
|
|
6
|
+
- `Pipeline` and `Streams` sections
|
|
7
|
+
- `Resizable` for resizable panes
|
|
8
|
+
- Connection and URL constants
|
|
9
|
+
- Visualizer connection and [Decoding Worker](https://github.com/luxonis/depthai-visualizer-lib?tab=readme-ov-file#important-notes-and-considerations)
|
|
10
|
+
- Connection, navigation and search hooks supporing dynamic base path
|
|
11
|
+
- Data and Connection providers
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@luxonis/depthai-viewer-common",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Common utilities and components for building a frontend application for DepthAI projects",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"author": "Luxonis Holding Corporation",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "index.js",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc --build",
|
|
14
|
+
"build:clean": "rm -fr ../../node_modules/.tmp/tsconfig-common.tsbuildinfo dist && npm run build",
|
|
15
|
+
"prepublishOnly": "npm run build:clean"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { Button, type ButtonProps } from '@luxonis/common-fe-components';
|
|
3
|
+
import { Link, type LinkProps } from './Link.js';
|
|
4
|
+
|
|
5
|
+
export type ButtonLinkProps = ButtonProps & {
|
|
6
|
+
linkProps: LinkProps;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const ButtonLink: React.FC<ButtonLinkProps> = ({ linkProps, ...buttonProps }) => {
|
|
10
|
+
const button = <Button {...buttonProps} />;
|
|
11
|
+
return !buttonProps.disabled ? <Link {...linkProps}>{button}</Link> : button;
|
|
12
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ExternalLink, Flex, SubLabel } from '@luxonis/common-fe-components';
|
|
2
|
+
import { useConnection } from '../providers/ConnectionProvider.js';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
const DISPLAY_LABEL_TIMEOUT = 30_000 as const;
|
|
6
|
+
|
|
7
|
+
export const CTASubLabel = () => {
|
|
8
|
+
const { connected, topics } = useConnection();
|
|
9
|
+
const [shouldDisplayLabel, setShouldDisplayLabel] = React.useState(false);
|
|
10
|
+
React.useEffect(() => {
|
|
11
|
+
if (connected && topics.length === 0 && !shouldDisplayLabel) {
|
|
12
|
+
const timeout = setTimeout(() => setShouldDisplayLabel(true), DISPLAY_LABEL_TIMEOUT);
|
|
13
|
+
return () => clearTimeout(timeout);
|
|
14
|
+
}
|
|
15
|
+
}, [connected, topics, shouldDisplayLabel]);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
shouldDisplayLabel && (
|
|
19
|
+
<Flex textAlign="center">
|
|
20
|
+
<SubLabel
|
|
21
|
+
text={
|
|
22
|
+
<p>
|
|
23
|
+
You can purchase an OAK camera from the{' '}
|
|
24
|
+
<ExternalLink raw to="https://shop.luxonis.com" color="light.active">
|
|
25
|
+
<SubLabel color="link" text="Luxonis Store" />
|
|
26
|
+
</ExternalLink>
|
|
27
|
+
. After your purchase,
|
|
28
|
+
<br /> explore the{' '}
|
|
29
|
+
<ExternalLink raw to="https://rvc4.docs.luxonis.com/hardware" color="light.active">
|
|
30
|
+
<SubLabel color="link" text="Luxonis Documentation" />
|
|
31
|
+
</ExternalLink>{' '}
|
|
32
|
+
for comprehensive setup tutorials to get started.
|
|
33
|
+
</p>
|
|
34
|
+
}
|
|
35
|
+
/>
|
|
36
|
+
</Flex>
|
|
37
|
+
)
|
|
38
|
+
);
|
|
39
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Link as _Link } from 'react-router-dom';
|
|
2
|
+
import { useNavigation } from '../hooks/navigation.js';
|
|
3
|
+
|
|
4
|
+
export type LinkProps = { to: 'pipeline' | 'streams' };
|
|
5
|
+
|
|
6
|
+
export const Link: React.FC<React.PropsWithChildren<LinkProps>> = ({ to, children }) => {
|
|
7
|
+
const { makePath } = useNavigation();
|
|
8
|
+
|
|
9
|
+
return <_Link to={makePath(to)}>{children}</_Link>;
|
|
10
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Flex, Header } from '@luxonis/common-fe-components';
|
|
2
|
+
import { PipelineCanvas } from '@luxonis/depthai-pipeline-lib';
|
|
3
|
+
import { useConnection } from '../providers/ConnectionProvider.js';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
const PIPELINE_LOADING_TIMEOUT = 60_000;
|
|
7
|
+
|
|
8
|
+
export const Pipeline: React.FC = () => {
|
|
9
|
+
const { pipeline, isPipelineLoading, setIsPipelineLoading } = useConnection();
|
|
10
|
+
|
|
11
|
+
React.useEffect(() => {
|
|
12
|
+
if (isPipelineLoading && pipeline === undefined) {
|
|
13
|
+
const timeout = setTimeout(() => {
|
|
14
|
+
setIsPipelineLoading(false);
|
|
15
|
+
}, PIPELINE_LOADING_TIMEOUT);
|
|
16
|
+
return () => clearTimeout(timeout);
|
|
17
|
+
}
|
|
18
|
+
}, [isPipelineLoading, pipeline, setIsPipelineLoading]);
|
|
19
|
+
|
|
20
|
+
if (isPipelineLoading) {
|
|
21
|
+
return (
|
|
22
|
+
<Flex align="center" justify="center" full>
|
|
23
|
+
<Header text="Loading pipeline..." />
|
|
24
|
+
</Flex>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return pipeline === undefined ? (
|
|
29
|
+
<Flex align="center" justify="center" full>
|
|
30
|
+
<Header text="Pipeline is not available" />
|
|
31
|
+
</Flex>
|
|
32
|
+
) : (
|
|
33
|
+
<PipelineCanvas pipeline={pipeline} height="full" />
|
|
34
|
+
);
|
|
35
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
|
|
3
|
+
|
|
4
|
+
export type ResizableItem = {
|
|
5
|
+
component: React.ReactNode;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type ResizableLayoutProps = {
|
|
9
|
+
id?: string | null;
|
|
10
|
+
items: ResizableItem[][];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const ResizableLayout: React.FC<ResizableLayoutProps> = ({
|
|
14
|
+
items,
|
|
15
|
+
id = 'resizable-layout',
|
|
16
|
+
}) => {
|
|
17
|
+
const groupStyles: React.CSSProperties = React.useMemo(
|
|
18
|
+
() => ({
|
|
19
|
+
display: 'flex',
|
|
20
|
+
gap: '5px',
|
|
21
|
+
}),
|
|
22
|
+
[],
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const panels = React.useMemo(
|
|
26
|
+
() =>
|
|
27
|
+
items.map((row, rowIndex) => (
|
|
28
|
+
<React.Fragment key={`resizable-row-${rowIndex}`}>
|
|
29
|
+
<Panel order={rowIndex}>
|
|
30
|
+
<PanelGroup
|
|
31
|
+
autoSaveId={id && `${id}-${rowIndex}`}
|
|
32
|
+
direction="horizontal"
|
|
33
|
+
style={groupStyles}
|
|
34
|
+
>
|
|
35
|
+
{row.map((item, itemIndex) => (
|
|
36
|
+
<React.Fragment key={`resizable-row-${rowIndex}-item-${itemIndex}`}>
|
|
37
|
+
<Panel order={itemIndex} style={{ display: 'flex' }}>
|
|
38
|
+
{item.component}
|
|
39
|
+
</Panel>
|
|
40
|
+
{itemIndex !== row.length - 1 && <PanelResizeHandle />}
|
|
41
|
+
</React.Fragment>
|
|
42
|
+
))}
|
|
43
|
+
</PanelGroup>
|
|
44
|
+
</Panel>
|
|
45
|
+
{rowIndex !== items.length - 1 && <PanelResizeHandle />}
|
|
46
|
+
</React.Fragment>
|
|
47
|
+
)),
|
|
48
|
+
[groupStyles, id, items],
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<PanelGroup autoSaveId={id} direction="vertical" style={groupStyles}>
|
|
53
|
+
{panels}
|
|
54
|
+
</PanelGroup>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Button,
|
|
3
|
+
DropdownMenu,
|
|
4
|
+
DropdownMenuCheckboxItem,
|
|
5
|
+
DropdownMenuContent,
|
|
6
|
+
DropdownMenuTrigger,
|
|
7
|
+
Flex,
|
|
8
|
+
Header,
|
|
9
|
+
Input,
|
|
10
|
+
NormalText,
|
|
11
|
+
SubHeader,
|
|
12
|
+
Tooltip,
|
|
13
|
+
} from '@luxonis/common-fe-components';
|
|
14
|
+
import { ImagePanel, PanelLayout, PointCloudPanel } from '@luxonis/visualizer-protobuf';
|
|
15
|
+
import React from 'react';
|
|
16
|
+
|
|
17
|
+
import { ResizableLayout, type Topic } from '@luxonis/depthai-viewer-common';
|
|
18
|
+
import { StreamTypes } from '../constants/streams.js';
|
|
19
|
+
import { useConnection } from '../providers/ConnectionProvider.js';
|
|
20
|
+
import { useData } from '../providers/DataProvider.js';
|
|
21
|
+
import { makeColumns } from '../utils/arrays.js';
|
|
22
|
+
import { CTASubLabel } from './CTASubLabel.js';
|
|
23
|
+
import type { Configuration } from '@luxonis/depthai-viewer/src/models/configuration.js';
|
|
24
|
+
import { FaUsersViewfinder as VisualizerIcon } from 'react-icons/fa6';
|
|
25
|
+
import { sortStreamsDefault } from '../utils/sorting.js';
|
|
26
|
+
|
|
27
|
+
const EnabledStreamsView: React.FC<{
|
|
28
|
+
topics: Topic[][];
|
|
29
|
+
targetFps?: number;
|
|
30
|
+
isRawSteamEnabledManually?: boolean;
|
|
31
|
+
setIsRawSteamEnabledManually?: (value: boolean) => void;
|
|
32
|
+
triggerToast?: () => void;
|
|
33
|
+
deviceOptions?: Configuration | null;
|
|
34
|
+
}> = ({
|
|
35
|
+
topics,
|
|
36
|
+
targetFps,
|
|
37
|
+
triggerToast,
|
|
38
|
+
isRawSteamEnabledManually,
|
|
39
|
+
setIsRawSteamEnabledManually,
|
|
40
|
+
}) => {
|
|
41
|
+
const { toggleTopic } = useConnection();
|
|
42
|
+
|
|
43
|
+
const items = React.useMemo(() => {
|
|
44
|
+
return topics.map((row) => {
|
|
45
|
+
let filteredRow = row;
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
row.some((topic) => topic.name === StreamTypes.PointCloud) &&
|
|
49
|
+
row.some((topic) => topic.name !== StreamTypes.Encoded) &&
|
|
50
|
+
!isRawSteamEnabledManually
|
|
51
|
+
) {
|
|
52
|
+
filteredRow = row.filter((topic) => topic.name !== StreamTypes.Encoded);
|
|
53
|
+
}
|
|
54
|
+
return filteredRow.map(({ name, annotations, extraAnnotations, kind }) => ({
|
|
55
|
+
component:
|
|
56
|
+
kind === 'pointCloud' || name === StreamTypes.PointCloud ? (
|
|
57
|
+
<PointCloudPanel
|
|
58
|
+
key={name}
|
|
59
|
+
toggleTopic={(topic) => {
|
|
60
|
+
if (!isRawSteamEnabledManually) {
|
|
61
|
+
toggleTopic(StreamTypes.Encoded);
|
|
62
|
+
}
|
|
63
|
+
toggleTopic(topic);
|
|
64
|
+
}}
|
|
65
|
+
topic={name}
|
|
66
|
+
/>
|
|
67
|
+
) : name !== StreamTypes.Raw &&
|
|
68
|
+
name !== StreamTypes.LeftRaw &&
|
|
69
|
+
name !== StreamTypes.RightRaw &&
|
|
70
|
+
!navigator.userAgent.includes('Chrome') ? (
|
|
71
|
+
<PanelLayout>
|
|
72
|
+
<Flex
|
|
73
|
+
full
|
|
74
|
+
justify="center"
|
|
75
|
+
align="center"
|
|
76
|
+
direction="column"
|
|
77
|
+
gap="sm"
|
|
78
|
+
textAlign="center"
|
|
79
|
+
>
|
|
80
|
+
<SubHeader text={`${name} is only supported in Google Chrome.`} />
|
|
81
|
+
<SubHeader text="Please switch to Chrome for the best experience." />
|
|
82
|
+
</Flex>
|
|
83
|
+
</PanelLayout>
|
|
84
|
+
) : (
|
|
85
|
+
<ImagePanel
|
|
86
|
+
key={name}
|
|
87
|
+
toggleTopic={(topic) => {
|
|
88
|
+
if (isRawSteamEnabledManually && topic === StreamTypes.Encoded) {
|
|
89
|
+
setIsRawSteamEnabledManually?.(false);
|
|
90
|
+
}
|
|
91
|
+
toggleTopic(topic);
|
|
92
|
+
}}
|
|
93
|
+
topic={name}
|
|
94
|
+
annotationTopics={annotations}
|
|
95
|
+
extraAnnotationTopics={extraAnnotations}
|
|
96
|
+
targetFps={targetFps}
|
|
97
|
+
triggerToast={triggerToast}
|
|
98
|
+
disableAnnotations={
|
|
99
|
+
name === StreamTypes.LeftRaw ||
|
|
100
|
+
name === StreamTypes.RightRaw ||
|
|
101
|
+
name === StreamTypes.LeftEncoded ||
|
|
102
|
+
name === StreamTypes.RightEncoded
|
|
103
|
+
}
|
|
104
|
+
/>
|
|
105
|
+
),
|
|
106
|
+
}));
|
|
107
|
+
});
|
|
108
|
+
}, [topics, targetFps, triggerToast, isRawSteamEnabledManually, setIsRawSteamEnabledManually]);
|
|
109
|
+
|
|
110
|
+
return <ResizableLayout items={items} />;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export const Streams: React.FC<{
|
|
114
|
+
targetFps?: number;
|
|
115
|
+
triggerToast?: () => void;
|
|
116
|
+
setIsRawSteamEnabledManually?: (value: boolean) => void;
|
|
117
|
+
isRawSteamEnabledManually?: boolean;
|
|
118
|
+
deviceOptions?: Configuration | null;
|
|
119
|
+
}> = ({
|
|
120
|
+
targetFps,
|
|
121
|
+
triggerToast,
|
|
122
|
+
isRawSteamEnabledManually = true,
|
|
123
|
+
setIsRawSteamEnabledManually,
|
|
124
|
+
deviceOptions,
|
|
125
|
+
}) => {
|
|
126
|
+
const { changeWsUrl, columns, connectionType, wsUrl } = useData();
|
|
127
|
+
const { connected, topics, toggleTopic } = useConnection();
|
|
128
|
+
const [shouldDisplayHelper, setShouldDisplayHelper] = React.useState(false);
|
|
129
|
+
const [connecting, setConnecting] = React.useState(false);
|
|
130
|
+
|
|
131
|
+
const enabledTopics = React.useMemo(
|
|
132
|
+
() =>
|
|
133
|
+
makeColumns(
|
|
134
|
+
topics.filter((topic) => topic.enabled),
|
|
135
|
+
columns,
|
|
136
|
+
),
|
|
137
|
+
[columns, topics],
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
const wsUrlRef = React.useRef<HTMLInputElement>(null);
|
|
141
|
+
|
|
142
|
+
const handleChangeUrl = React.useCallback(
|
|
143
|
+
() => wsUrlRef.current?.value && changeWsUrl(wsUrlRef.current.value),
|
|
144
|
+
[changeWsUrl],
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
const shouldSuggestUrlChange = React.useMemo(
|
|
148
|
+
() => window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1',
|
|
149
|
+
[],
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
React.useEffect(() => {
|
|
153
|
+
if (!shouldDisplayHelper && !shouldSuggestUrlChange) {
|
|
154
|
+
setTimeout(() => {
|
|
155
|
+
setShouldDisplayHelper(true);
|
|
156
|
+
}, 10_000);
|
|
157
|
+
}
|
|
158
|
+
}, [shouldDisplayHelper, shouldSuggestUrlChange]);
|
|
159
|
+
|
|
160
|
+
const sortedTopics = React.useMemo(() => sortStreamsDefault(topics), [topics]);
|
|
161
|
+
|
|
162
|
+
// TODO: Store detections in url or global provider
|
|
163
|
+
// to persist on re-renders
|
|
164
|
+
return (
|
|
165
|
+
<PanelLayout>
|
|
166
|
+
{enabledTopics.length === 0 || enabledTopics[0].length === 0 ? (
|
|
167
|
+
<Flex full justify="center" align="center" direction="column" gap="sm">
|
|
168
|
+
<Header
|
|
169
|
+
text={
|
|
170
|
+
connected ? (
|
|
171
|
+
sortedTopics.length === 0 ? (
|
|
172
|
+
'DepthAI connected, awaiting device...'
|
|
173
|
+
) : (
|
|
174
|
+
<p>
|
|
175
|
+
To view stream(s), select it with Streams Button{' '}
|
|
176
|
+
<DropdownMenu>
|
|
177
|
+
<Tooltip content="Streams">
|
|
178
|
+
<DropdownMenuTrigger>
|
|
179
|
+
<Button icon={VisualizerIcon} variant="outline" colorVariant="white" />
|
|
180
|
+
</DropdownMenuTrigger>
|
|
181
|
+
</Tooltip>
|
|
182
|
+
<DropdownMenuContent>
|
|
183
|
+
{sortedTopics.map((topic, i) => (
|
|
184
|
+
<DropdownMenuCheckboxItem key={i} onClick={() => toggleTopic(topic.name)}>
|
|
185
|
+
{topic.name}
|
|
186
|
+
</DropdownMenuCheckboxItem>
|
|
187
|
+
))}
|
|
188
|
+
</DropdownMenuContent>
|
|
189
|
+
</DropdownMenu>{' '}
|
|
190
|
+
either here or in the top right corner
|
|
191
|
+
</p>
|
|
192
|
+
)
|
|
193
|
+
) : // TODO: connection details (state, errors, retries, webrtc stage)
|
|
194
|
+
connectionType === 'ws' ? (
|
|
195
|
+
'Connecting to DepthAI via WebSocket...'
|
|
196
|
+
) : (
|
|
197
|
+
'Connecting to DepthAI via WebRTC...'
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
/>
|
|
201
|
+
|
|
202
|
+
{!connected &&
|
|
203
|
+
(shouldSuggestUrlChange ? (
|
|
204
|
+
<>
|
|
205
|
+
<SubHeader
|
|
206
|
+
text={connectionType === 'ws' ? 'Use another URL?' : 'Connect via WebSocket?'}
|
|
207
|
+
/>
|
|
208
|
+
<form
|
|
209
|
+
onSubmit={(event) => {
|
|
210
|
+
event.stopPropagation();
|
|
211
|
+
event.preventDefault();
|
|
212
|
+
|
|
213
|
+
setConnecting(true);
|
|
214
|
+
|
|
215
|
+
handleChangeUrl();
|
|
216
|
+
}}
|
|
217
|
+
>
|
|
218
|
+
<Flex>
|
|
219
|
+
<Input
|
|
220
|
+
type="text"
|
|
221
|
+
ref={wsUrlRef}
|
|
222
|
+
placeholder={wsUrl}
|
|
223
|
+
roundedRight={0}
|
|
224
|
+
onChange={() => setConnecting(false)}
|
|
225
|
+
/>
|
|
226
|
+
<Button
|
|
227
|
+
type="submit"
|
|
228
|
+
label={connecting ? 'Connecting...' : 'Connect'}
|
|
229
|
+
style={{
|
|
230
|
+
borderTopLeftRadius: 0,
|
|
231
|
+
borderBottomLeftRadius: 0,
|
|
232
|
+
}}
|
|
233
|
+
/>
|
|
234
|
+
</Flex>
|
|
235
|
+
</form>
|
|
236
|
+
</>
|
|
237
|
+
) : (
|
|
238
|
+
shouldDisplayHelper && (
|
|
239
|
+
<NormalText text="Please check that you have the correct link to DepthAI Visualizer and that your device is running. You need a new link after any app or device restart." />
|
|
240
|
+
)
|
|
241
|
+
))}
|
|
242
|
+
<CTASubLabel />
|
|
243
|
+
</Flex>
|
|
244
|
+
) : (
|
|
245
|
+
<EnabledStreamsView
|
|
246
|
+
topics={enabledTopics}
|
|
247
|
+
targetFps={targetFps}
|
|
248
|
+
triggerToast={triggerToast}
|
|
249
|
+
isRawSteamEnabledManually={isRawSteamEnabledManually}
|
|
250
|
+
setIsRawSteamEnabledManually={setIsRawSteamEnabledManually}
|
|
251
|
+
deviceOptions={deviceOptions}
|
|
252
|
+
/>
|
|
253
|
+
)}
|
|
254
|
+
</PanelLayout>
|
|
255
|
+
);
|
|
256
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
2
|
+
export type DAIResponse<T = any> = {
|
|
3
|
+
data: T;
|
|
4
|
+
error: Error | string | null;
|
|
5
|
+
message: string | null;
|
|
6
|
+
status: number;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const DAI_SERVICE_NAME = {
|
|
10
|
+
topicGroups: 'topicGroups',
|
|
11
|
+
pipelineSchema: 'pipelineSchema',
|
|
12
|
+
keyPressed: 'keyPressed',
|
|
13
|
+
// Devices
|
|
14
|
+
getDevices: 'getDevices',
|
|
15
|
+
startDevice: 'startDevice',
|
|
16
|
+
stopDevice: 'stopDevice',
|
|
17
|
+
getDeviceOptions: 'getDeviceOptions',
|
|
18
|
+
getFpsRange: 'getFpsRange',
|
|
19
|
+
// Configs
|
|
20
|
+
getSensors: 'getSensors',
|
|
21
|
+
setSensors: 'setSensors',
|
|
22
|
+
getStereoDepth: 'getStereoDepth',
|
|
23
|
+
setStereoDepth: 'setStereoDepth',
|
|
24
|
+
getStereoDepthPreset: 'getStereoDepthPreset',
|
|
25
|
+
setStereoDepthPreset: 'setStereoDepthPreset',
|
|
26
|
+
getStereoDepthCalibration: 'getStereoDepthCalibration',
|
|
27
|
+
setStereoDepthCalibration: 'setStereoDepthCalibration',
|
|
28
|
+
setIr: 'setIr',
|
|
29
|
+
setPointCloud: 'setPointCloud',
|
|
30
|
+
setThermal: 'setThermal',
|
|
31
|
+
getCameraIntrinsics: 'getCameraIntrinsics',
|
|
32
|
+
// Neural networks
|
|
33
|
+
getNeuralNetworks: 'getNeuralNetworks',
|
|
34
|
+
setNeuralNetwork: 'setNeuralNetwork',
|
|
35
|
+
getNeuralNetworkConfiguration: 'getNeuralNetworkConfiguration',
|
|
36
|
+
setNeuralNetworkConfiguration: 'setNeuralNetworkConfiguration',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const SIGNALING_SERVER_URL = 'wss://signal.cloud.luxonis.com/session/';
|
|
40
|
+
export const ICE_SERVERS_API_ENDPOINT =
|
|
41
|
+
'https://signal.cloud-stg.luxonis.com/api/v1/turn-credentials';
|
|
42
|
+
|
|
43
|
+
export const DEFAULT_ICE_SERVERS: RTCIceServer[] = [
|
|
44
|
+
{ urls: ['stun:stun.l.google.com:19302', 'stun:stun1.l.google.com:19302'] },
|
|
45
|
+
];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const StreamTypes = {
|
|
2
|
+
Encoded: 'H.264 Stream',
|
|
3
|
+
LeftEncoded: 'Left H.264 Stream',
|
|
4
|
+
RightEncoded: 'Right H.264 Stream',
|
|
5
|
+
Disparity: 'Disparity Stream',
|
|
6
|
+
Raw: 'Raw Stream',
|
|
7
|
+
LeftRaw: 'Left Raw Stream',
|
|
8
|
+
RightRaw: 'Right Raw Stream',
|
|
9
|
+
PointCloud: 'Point Cloud',
|
|
10
|
+
NeuralNetwork: 'Neural Network Stream',
|
|
11
|
+
} as const;
|