Skip to content

Commit c5e0633

Browse files
add html iframe webcam support
1 parent 7e37592 commit c5e0633

File tree

12 files changed

+155
-6
lines changed

12 files changed

+155
-6
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { HtmlIframe } from "../html-iframe";
2+
import type { IIframeProps } from "../html-iframe";
3+
import type { IWHStyleWidget } from "@reflect-ui/core";
4+
import type { WidgetKey } from "../../widget-key";
5+
6+
const webcamurl = "https://frames-appbox.vercel.app/webcam";
7+
8+
type WebcamProps = Omit<IIframeProps, "src" | "srcDoc"> & {};
9+
10+
export class HtmlIframeWebcam extends HtmlIframe {
11+
constructor({
12+
key,
13+
allow = "camera",
14+
loading = "lazy",
15+
referrerpolicy = "no-referrer-when-downgrade",
16+
sandbox = ["allow-scripts", "allow-same-origin"],
17+
...rest
18+
}: { key: WidgetKey } & WebcamProps & IWHStyleWidget) {
19+
super({
20+
key,
21+
...rest,
22+
allow,
23+
loading,
24+
sandbox,
25+
referrerpolicy,
26+
src: webcamurl,
27+
});
28+
}
29+
}

packages/builder-web-core/widgets-native/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export { HtmlIframeGoogleMaps as GoogleMaps } from "./html-iframe-googlemaps";
1414
export { HtmlIframeOpenStreetMap as OpenStreetMap } from "./html-iframe-osm";
1515
export { HtmlIframeYoutube as Youtube } from "./html-iframe-youtube";
1616
export { HtmlIframeFigma as EmbedFigma } from "./html-iframe-figma";
17+
export { HtmlIframeWebcam as Webcam } from "./html-iframe-webcam";
1718
export * from "./error-widget";
1819

1920
export * from "@web-builder/core/widget-tree/widget";

packages/designto-token/support-flags/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import { tokenize_flagged_slider } from "./token-slider";
1919
import { tokenize_flagged_progress } from "./token-progress";
2020

2121
import { tokenize_flagged_google_maps_view } from "./token-x-google-maps-view";
22-
import { tokenize_gradient_direction_from_angle } from "../token-gradient";
2322
import { tokenize_flagged_youtube_view } from "./token-x-youtube-view";
23+
import { tokenize_flagged_camera_view } from "./token-x-camera-display";
2424

2525
export default function handleWithFlags(node: ReflectSceneNode) {
2626
const flags = parse(node.name);
@@ -81,6 +81,11 @@ function _handle_with_flags(node, flags: FlagsParseResult) {
8181
flags[keys.flag_key__x_youtube_view]
8282
);
8383
}
84+
85+
if (flags.__meta?.contains_camera_flag) {
86+
return tokenize_flagged_camera_view(node, flags[keys.flag_key__camera]);
87+
}
88+
8489
// #end exetnded views
8590

8691
// #region element altering flags
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import type {
2+
ReflectFrameNode,
3+
ReflectGroupNode,
4+
ReflectRectangleNode,
5+
ReflectSceneNode,
6+
} from "@design-sdk/figma-node";
7+
import type { Container } from "@reflect-ui/core";
8+
import { tokenizeLayout } from "../../token-layout";
9+
import { tokenizeContainer } from "../../token-container";
10+
import { unwrappedChild } from "../../wrappings";
11+
import type { CameraDisplayFlag } from "@code-features/flags";
12+
import { WrappingContainer, XCameraDisplayView } from "../../tokens";
13+
import assert from "assert";
14+
import { keyFromNode } from "../../key";
15+
16+
export function tokenize_flagged_camera_view(
17+
node: ReflectSceneNode,
18+
flag: CameraDisplayFlag
19+
) {
20+
if (!flag.value) {
21+
return;
22+
}
23+
24+
try {
25+
node = validate_input(node);
26+
const _key = keyFromNode(node);
27+
28+
const container = unwrappedChild(
29+
node.type === "RECTANGLE"
30+
? tokenizeContainer.fromRectangle(node)
31+
: tokenizeLayout.fromFrameOrGroup(node, [], { is_root: false }, {})
32+
) as Container;
33+
34+
return new WrappingContainer({
35+
...container,
36+
key: keyFromNode(node),
37+
child: new XCameraDisplayView({
38+
key: _key,
39+
...container,
40+
}),
41+
});
42+
} catch (e) {
43+
throw new Error(`failed to tokenize camera display view: ${e.message}`);
44+
}
45+
}
46+
47+
type CameraDisplayCompatNodeType =
48+
| ReflectFrameNode
49+
| ReflectGroupNode
50+
| ReflectRectangleNode;
51+
52+
function validate_input(node: ReflectSceneNode): CameraDisplayCompatNodeType {
53+
assert(
54+
node.type === "FRAME" || node.type === "GROUP" || node.type === "RECTANGLE",
55+
`camera display view target input must be a frame, group or rectangle, but "${node.type}" was given`
56+
);
57+
58+
return node;
59+
}

packages/designto-token/tokens/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from "./stretched";
22
export * from "./wrapping-container";
33

4+
export * from "./x-camera-display-view";
45
export * from "./x-figma-embed-view";
56
export * from "./x-google-maps-view";
67
export * from "./x-osm-view";
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Container, WidgetKey } from "@reflect-ui/core";
2+
3+
export class XCameraDisplayView extends Container {
4+
readonly _type = "x/camera-display-view";
5+
constructor({ key }: { key: WidgetKey } & {}) {
6+
super({ key });
7+
}
8+
}

packages/designto-token/tokens/x-youtube-view/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { Container, WidgetKey } from "@reflect-ui/core";
1+
import { Widget, WidgetKey } from "@reflect-ui/core";
22

3-
export class XYoutubeView extends Container {
3+
export class XYoutubeView extends Widget {
44
readonly _type = "x/youtube-view";
55
readonly video: string;
66
constructor({

packages/designto-web/tokens-to-web-widget/compose-xtended-views.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,40 @@ export function compose_xtended_views(
88
| special.XFigmaEmbedView
99
| special.XGoogleMapsView
1010
| special.XOSMView
11-
| special.XYoutubeView,
11+
| special.XYoutubeView
12+
| special.XCameraDisplayView,
1213
container?: core.Container
1314
) {
1415
if (widget instanceof special.XFigmaEmbedView) {
1516
throw new Error("not implemented");
1617
}
1718

1819
if (widget instanceof special.XGoogleMapsView) {
19-
return new web.GoogleMaps({ ...(container ?? {}), ...widget, key });
20+
return new web.GoogleMaps({
21+
...(container ?? ({} as core.Container)),
22+
...widget,
23+
key,
24+
});
2025
}
2126

2227
if (widget instanceof special.XOSMView) {
2328
throw new Error("not implemented");
2429
}
2530

2631
if (widget instanceof special.XYoutubeView) {
27-
return new web.Youtube({ ...(container ?? {}), ...widget, key });
32+
return new web.Youtube({
33+
...(container ?? ({} as core.Container)),
34+
...widget,
35+
key,
36+
});
37+
}
38+
39+
if (widget instanceof special.XCameraDisplayView) {
40+
return new web.Webcam({
41+
...(container ?? ({} as core.Container)),
42+
...widget,
43+
key,
44+
});
2845
}
2946

3047
throw new Error("not implemented");
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const flag_key__camera = "camera";
2+
3+
export const flag_key_alias__camera = [flag_key__camera];
4+
5+
export interface CameraDisplayFlag {
6+
flag: typeof flag_key__camera;
7+
value: boolean;
8+
}

packages/support-flags/keys.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import { flag_key_alias__fix_height, flag_key__fix_height } from "./--fix-height
3030

3131
import { flag_key_alias__declare, flag_key__declare } from "./--declare";
3232

33+
// prettier-ignore
34+
import { flag_key_alias__camera, flag_key__camera } from "./--camera-display";
3335
import { flag_key_alias__video, flag_key__video } from "./--video";
3436
import { flag_key_alias__webview, flag_key__webview } from "./--webview";
3537
// prettier-ignore
@@ -79,6 +81,7 @@ export { flag_key__fix_width, flag_key__fix_height };
7981
export { flag_key__declare };
8082

8183
export {
84+
flag_key__camera,
8285
flag_key__video,
8386
flag_key__webview,
8487
flag_key__x_figma_embed_view,
@@ -110,6 +113,7 @@ export const alias = {
110113
fix_width: flag_key_alias__fix_width,
111114
fix_height: flag_key_alias__fix_height,
112115
declare: flag_key_alias__declare,
116+
camera: flag_key_alias__camera,
113117
video: flag_key_alias__video,
114118
webview: flag_key_alias__webview,
115119
x_figma_embed_view: flag_key_alias__x_figma_embed_view,

0 commit comments

Comments
 (0)