@playruo/embed 1.1.3 → 1.1.5

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/index.cjs CHANGED
@@ -51,20 +51,84 @@ var PlayruoEmbed = ({
51
51
  onDemoCompleted,
52
52
  onPurchaseRequest,
53
53
  onError,
54
- renderState
54
+ renderState,
55
+ iframeRef: externalIframeRef
55
56
  }) => {
56
- const iframeRef = (0, import_react.useRef)(null);
57
+ const internalIframeRef = (0, import_react.useRef)(null);
58
+ const iframeRef = externalIframeRef || internalIframeRef;
57
59
  const [isReady, setIsReady] = (0, import_react.useState)(false);
58
60
  const [state, setState] = (0, import_react.useState)(null);
59
61
  const [errorMessage, setErrorMessage] = (0, import_react.useState)(null);
60
62
  const src = (0, import_react.useMemo)(() => buildEmbedUrl({ baseUrl, operation, storeUrl }), [baseUrl, operation, storeUrl]);
63
+ const checkKeyboardLockPermission = async () => {
64
+ if (!navigator.permissions) {
65
+ console.log("[PlayruoEmbed] Permissions API not supported");
66
+ return false;
67
+ }
68
+ try {
69
+ const { state: state2 } = await navigator.permissions.query({
70
+ name: "keyboard-lock"
71
+ });
72
+ if (state2 === "granted" || state2 === "prompt") {
73
+ console.log(`[PlayruoEmbed] Keyboard lock permission: ${state2}`);
74
+ return true;
75
+ }
76
+ console.log("[PlayruoEmbed] Keyboard lock permission denied");
77
+ return false;
78
+ } catch (error) {
79
+ console.warn("[PlayruoEmbed] Error checking keyboard lock permission:", error);
80
+ return false;
81
+ }
82
+ };
83
+ const requestFullscreenWithKeyboardLock = async () => {
84
+ const iframe = iframeRef.current;
85
+ if (!iframe?.requestFullscreen) {
86
+ console.log("[PlayruoEmbed] Fullscreen not supported on this browser");
87
+ return false;
88
+ }
89
+ try {
90
+ const fullscreenPromise = iframe.requestFullscreen();
91
+ if (navigator.keyboard) {
92
+ const permissionPromise = checkKeyboardLockPermission();
93
+ const keyboardLockPromise = navigator.keyboard.lock(["Escape"]);
94
+ void Promise.all([permissionPromise, keyboardLockPromise]).then(([hasPermission]) => {
95
+ if (hasPermission) {
96
+ console.log("[PlayruoEmbed] Keyboard locked successfully");
97
+ }
98
+ }).catch((err) => {
99
+ console.warn("[PlayruoEmbed] Keyboard lock failed:", err);
100
+ });
101
+ } else {
102
+ console.log("[PlayruoEmbed] Keyboard API not supported");
103
+ }
104
+ void fullscreenPromise.then(() => {
105
+ console.log("[PlayruoEmbed] Fullscreen activated successfully");
106
+ }).catch((err) => {
107
+ console.warn("[PlayruoEmbed] Fullscreen failed:", err);
108
+ });
109
+ return true;
110
+ } catch (error) {
111
+ console.error("[PlayruoEmbed] Error requesting fullscreen:", error);
112
+ return false;
113
+ }
114
+ };
61
115
  const sendCommand = (type) => {
62
116
  if (!iframeRef.current?.contentWindow) {
63
117
  console.warn(`PlayruoEmbed: Cannot send ${type} command, iframe not ready`);
64
118
  return;
65
119
  }
120
+ if (type === "try_now") {
121
+ requestFullscreenWithKeyboardLock();
122
+ }
66
123
  iframeRef.current.contentWindow.postMessage({ type }, "*");
67
124
  };
125
+ (0, import_react.useEffect)(() => {
126
+ if (!self.crossOriginIsolated) {
127
+ console.warn(
128
+ '[PlayruoEmbed] \u26A0\uFE0F Not in a cross-origin isolated context.\nSharedArrayBuffer and high-precision timers may not work.\n\nAdd these headers to your server:\n Cross-Origin-Opener-Policy: same-origin\n Cross-Origin-Embedder-Policy: credentialless\n\nAlternative (stricter, if not using credentialless iframes):\n Cross-Origin-Embedder-Policy: require-corp\n\nFor Next.js, add to next.config.js:\n async headers() {\n return [{\n source: "/:path*",\n headers: [\n { key: "Cross-Origin-Opener-Policy", value: "same-origin" },\n { key: "Cross-Origin-Embedder-Policy", value: "credentialless" }\n ]\n }];\n }'
129
+ );
130
+ }
131
+ }, []);
68
132
  (0, import_react.useEffect)(() => {
69
133
  const handler = (event) => {
70
134
  const msg = event?.data ?? {};
@@ -117,8 +181,9 @@ var PlayruoEmbed = ({
117
181
  {
118
182
  ref: iframeRef,
119
183
  src,
120
- allow: "fullscreen *; autoplay *; gamepad *",
184
+ allow: "fullscreen *; autoplay *; gamepad *; clipboard-write *; web-share *; encrypted-media *; accelerometer *; gyroscope *",
121
185
  className: "w-full h-[70vh] rounded-lg border",
186
+ ...{ credentialless: "true" },
122
187
  title: "Playruo",
123
188
  style: {
124
189
  position: showIframe ? void 0 : "absolute",
package/dist/index.d.cts CHANGED
@@ -16,6 +16,15 @@ interface DemoCompletedPayload {
16
16
  storeUrl?: string;
17
17
  }
18
18
 
19
+ interface Keyboard {
20
+ lock: (keys: string[]) => Promise<void>;
21
+ unlock: () => void;
22
+ }
23
+ declare global {
24
+ interface Navigator {
25
+ keyboard?: Keyboard;
26
+ }
27
+ }
19
28
  interface PlayruoEmbedActions {
20
29
  /** Start the demo session */
21
30
  tryNow: () => void;
@@ -49,6 +58,10 @@ interface PlayruoEmbedProps {
49
58
  * Provides status, message, and available actions based on current state.
50
59
  */
51
60
  renderState?: (render: PlayruoEmbedRenderState) => ReactNode;
61
+ /**
62
+ * Ref to access the iframe element for fullscreen requests
63
+ */
64
+ iframeRef?: React.RefObject<HTMLIFrameElement>;
52
65
  }
53
66
  declare const PlayruoEmbed: FC<PlayruoEmbedProps>;
54
67
 
package/dist/index.d.ts CHANGED
@@ -16,6 +16,15 @@ interface DemoCompletedPayload {
16
16
  storeUrl?: string;
17
17
  }
18
18
 
19
+ interface Keyboard {
20
+ lock: (keys: string[]) => Promise<void>;
21
+ unlock: () => void;
22
+ }
23
+ declare global {
24
+ interface Navigator {
25
+ keyboard?: Keyboard;
26
+ }
27
+ }
19
28
  interface PlayruoEmbedActions {
20
29
  /** Start the demo session */
21
30
  tryNow: () => void;
@@ -49,6 +58,10 @@ interface PlayruoEmbedProps {
49
58
  * Provides status, message, and available actions based on current state.
50
59
  */
51
60
  renderState?: (render: PlayruoEmbedRenderState) => ReactNode;
61
+ /**
62
+ * Ref to access the iframe element for fullscreen requests
63
+ */
64
+ iframeRef?: React.RefObject<HTMLIFrameElement>;
52
65
  }
53
66
  declare const PlayruoEmbed: FC<PlayruoEmbedProps>;
54
67
 
package/dist/index.js CHANGED
@@ -22,20 +22,84 @@ var PlayruoEmbed = ({
22
22
  onDemoCompleted,
23
23
  onPurchaseRequest,
24
24
  onError,
25
- renderState
25
+ renderState,
26
+ iframeRef: externalIframeRef
26
27
  }) => {
27
- const iframeRef = useRef(null);
28
+ const internalIframeRef = useRef(null);
29
+ const iframeRef = externalIframeRef || internalIframeRef;
28
30
  const [isReady, setIsReady] = useState(false);
29
31
  const [state, setState] = useState(null);
30
32
  const [errorMessage, setErrorMessage] = useState(null);
31
33
  const src = useMemo(() => buildEmbedUrl({ baseUrl, operation, storeUrl }), [baseUrl, operation, storeUrl]);
34
+ const checkKeyboardLockPermission = async () => {
35
+ if (!navigator.permissions) {
36
+ console.log("[PlayruoEmbed] Permissions API not supported");
37
+ return false;
38
+ }
39
+ try {
40
+ const { state: state2 } = await navigator.permissions.query({
41
+ name: "keyboard-lock"
42
+ });
43
+ if (state2 === "granted" || state2 === "prompt") {
44
+ console.log(`[PlayruoEmbed] Keyboard lock permission: ${state2}`);
45
+ return true;
46
+ }
47
+ console.log("[PlayruoEmbed] Keyboard lock permission denied");
48
+ return false;
49
+ } catch (error) {
50
+ console.warn("[PlayruoEmbed] Error checking keyboard lock permission:", error);
51
+ return false;
52
+ }
53
+ };
54
+ const requestFullscreenWithKeyboardLock = async () => {
55
+ const iframe = iframeRef.current;
56
+ if (!iframe?.requestFullscreen) {
57
+ console.log("[PlayruoEmbed] Fullscreen not supported on this browser");
58
+ return false;
59
+ }
60
+ try {
61
+ const fullscreenPromise = iframe.requestFullscreen();
62
+ if (navigator.keyboard) {
63
+ const permissionPromise = checkKeyboardLockPermission();
64
+ const keyboardLockPromise = navigator.keyboard.lock(["Escape"]);
65
+ void Promise.all([permissionPromise, keyboardLockPromise]).then(([hasPermission]) => {
66
+ if (hasPermission) {
67
+ console.log("[PlayruoEmbed] Keyboard locked successfully");
68
+ }
69
+ }).catch((err) => {
70
+ console.warn("[PlayruoEmbed] Keyboard lock failed:", err);
71
+ });
72
+ } else {
73
+ console.log("[PlayruoEmbed] Keyboard API not supported");
74
+ }
75
+ void fullscreenPromise.then(() => {
76
+ console.log("[PlayruoEmbed] Fullscreen activated successfully");
77
+ }).catch((err) => {
78
+ console.warn("[PlayruoEmbed] Fullscreen failed:", err);
79
+ });
80
+ return true;
81
+ } catch (error) {
82
+ console.error("[PlayruoEmbed] Error requesting fullscreen:", error);
83
+ return false;
84
+ }
85
+ };
32
86
  const sendCommand = (type) => {
33
87
  if (!iframeRef.current?.contentWindow) {
34
88
  console.warn(`PlayruoEmbed: Cannot send ${type} command, iframe not ready`);
35
89
  return;
36
90
  }
91
+ if (type === "try_now") {
92
+ requestFullscreenWithKeyboardLock();
93
+ }
37
94
  iframeRef.current.contentWindow.postMessage({ type }, "*");
38
95
  };
96
+ useEffect(() => {
97
+ if (!self.crossOriginIsolated) {
98
+ console.warn(
99
+ '[PlayruoEmbed] \u26A0\uFE0F Not in a cross-origin isolated context.\nSharedArrayBuffer and high-precision timers may not work.\n\nAdd these headers to your server:\n Cross-Origin-Opener-Policy: same-origin\n Cross-Origin-Embedder-Policy: credentialless\n\nAlternative (stricter, if not using credentialless iframes):\n Cross-Origin-Embedder-Policy: require-corp\n\nFor Next.js, add to next.config.js:\n async headers() {\n return [{\n source: "/:path*",\n headers: [\n { key: "Cross-Origin-Opener-Policy", value: "same-origin" },\n { key: "Cross-Origin-Embedder-Policy", value: "credentialless" }\n ]\n }];\n }'
100
+ );
101
+ }
102
+ }, []);
39
103
  useEffect(() => {
40
104
  const handler = (event) => {
41
105
  const msg = event?.data ?? {};
@@ -88,8 +152,9 @@ var PlayruoEmbed = ({
88
152
  {
89
153
  ref: iframeRef,
90
154
  src,
91
- allow: "fullscreen *; autoplay *; gamepad *",
155
+ allow: "fullscreen *; autoplay *; gamepad *; clipboard-write *; web-share *; encrypted-media *; accelerometer *; gyroscope *",
92
156
  className: "w-full h-[70vh] rounded-lg border",
157
+ ...{ credentialless: "true" },
93
158
  title: "Playruo",
94
159
  style: {
95
160
  position: showIframe ? void 0 : "absolute",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playruo/embed",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "React SDK to embed Playruo with postMessage API.",
5
5
  "license": "MIT",
6
6
  "type": "module",