datakeen-session-react 1.1.140-dev.30 → 1.1.140-dev.32

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.
@@ -20,29 +20,12 @@ var SelfieRecorder = function (_a) {
20
20
  var handleSelfie = _a.handleSelfie, _b = _a.onBeginCapture, onBeginCapture = _b === void 0 ? function () { } : _b; _a.isCapturing;
21
21
  var t = useI18n.useI18n().t;
22
22
  var recorderRef = React.useRef(null);
23
- var containerRef = React.useRef(null);
24
- var buttonBarRef = React.useRef(null);
25
- var _d = React.useState(undefined), videoMaxHeight = _d[0], setVideoMaxHeight = _d[1];
26
- var _e = React.useState(false), disableButton = _e[0], setDisableButton = _e[1];
27
- var _f = React.useState(false), recorderReady = _f[0], setRecorderReady = _f[1];
28
- var _g = React.useState("idle"), recordingState = _g[0], setRecordingState = _g[1];
23
+ var _d = React.useState(false), disableButton = _d[0], setDisableButton = _d[1];
24
+ var _e = React.useState(false), recorderReady = _e[0], setRecorderReady = _e[1];
25
+ var _f = React.useState("idle"), recordingState = _f[0], setRecordingState = _f[1];
29
26
  var capturedThumbnailRef = React.useRef(null);
30
- var _h = useLiveFrameCapture.useLiveFrameCapture(), captureFrame = _h.captureFrame, cleanup = _h.cleanup;
27
+ var _g = useLiveFrameCapture.useLiveFrameCapture(), captureFrame = _g.captureFrame, cleanup = _g.cleanup;
31
28
  useVideoRecorderStyles.default();
32
- var updateVideoMaxHeight = React.useCallback(function () {
33
- if (!containerRef.current || !buttonBarRef.current)
34
- return;
35
- var totalHeight = containerRef.current.clientHeight;
36
- var buttonBarHeight = buttonBarRef.current.offsetHeight;
37
- // Reserve space for header (~80px) + button bar
38
- var available = totalHeight - buttonBarHeight - 80;
39
- setVideoMaxHeight(Math.max(available, 200));
40
- }, []);
41
- React.useEffect(function () {
42
- updateVideoMaxHeight();
43
- window.addEventListener("resize", updateVideoMaxHeight);
44
- return function () { return window.removeEventListener("resize", updateVideoMaxHeight); };
45
- }, [updateVideoMaxHeight]);
46
29
  React.useEffect(function () {
47
30
  document.body.classList.add("recording-selfie");
48
31
  var cleanupObserver = videoElementStyles.setupVideoElementsObserver();
@@ -169,12 +152,11 @@ var SelfieRecorder = function (_a) {
169
152
  setRecordingState("processing");
170
153
  handleSelfie(enhancedEvent);
171
154
  };
172
- return (jsxRuntime.jsxs("div", { ref: containerRef, className: "selfie flex flex-col h-full w-full overflow-hidden min-h-0", children: [jsxRuntime.jsxs("div", { className: "p-4 text-center shrink-0", children: [jsxRuntime.jsx(Title.default, { className: "text-lg md:text-xl mb-1", children: t("selfie.recorder.title") }), jsxRuntime.jsx(Subtitle.default, { className: "text-xs text-gray-600 md:text-sm", children: t("selfie.recorder.subtitle") })] }), jsxRuntime.jsx("div", { className: "video-container flex-1 min-h-0 relative flex items-center justify-center overflow-hidden", style: videoMaxHeight ? { maxHeight: videoMaxHeight } : undefined, children: jsxRuntime.jsx(sdkReact.VideoRecorder, tslib_es6.__assign({ ref: recorderRef, preset: sdkReact.AcquisitionPreset.SELFIE_OPTIMIZED, hideCaptureBtn: true, faceChecker: "enabled", disableDebugMode: true, onRecorderReady: handleRecorderReady, onRecordCompleted: handleRecordCompleted, onRecord: recordStarting, style: { width: "100%", height: "100%" }, className: "video-recorder-no-radius w-full h-full" }, (selfieCaptureUtils.isIOS() && {
173
- // iOS-specific attributes for fixing black screen
155
+ return (jsxRuntime.jsxs("div", { className: "selfie fixed inset-0 z-50 flex flex-col", children: [jsxRuntime.jsxs("div", { className: "p-4 text-center bg-white shrink-0", children: [jsxRuntime.jsx(Title.default, { className: "text-lg md:text-xl mb-1", children: t("selfie.recorder.title") }), jsxRuntime.jsx(Subtitle.default, { className: "text-xs text-gray-600 md:text-sm", children: t("selfie.recorder.subtitle") })] }), jsxRuntime.jsx("div", { className: "video-container flex-1 relative overflow-hidden", children: jsxRuntime.jsx(sdkReact.VideoRecorder, tslib_es6.__assign({ ref: recorderRef, preset: sdkReact.AcquisitionPreset.SELFIE_OPTIMIZED, hideCaptureBtn: true, faceChecker: "enabled", disableDebugMode: true, onRecorderReady: handleRecorderReady, onRecordCompleted: handleRecordCompleted, onRecord: recordStarting, style: { width: "100%", height: "100%" }, className: "video-recorder-no-radius w-full h-full" }, (selfieCaptureUtils.isIOS() && {
174
156
  "data-playsinline": "true",
175
157
  "data-autoplay": "true",
176
158
  "data-muted": "true"
177
- }), { strings: unisseyStrings.getUnisseyStrings(t) })) }), jsxRuntime.jsx("div", { ref: buttonBarRef, className: "shrink-0 bg-white border-t border-gray-200 p-4 md:p-6", children: jsxRuntime.jsxs("div", { className: "max-w-md mx-auto", children: [jsxRuntime.jsx("div", { className: "text-center text-xs text-gray-400 mt-3", children: t("selfie.recorder.note") }), jsxRuntime.jsxs(Button.default, { onClick: recordStarting, className: "w-full py-3 md:py-4 relative selfie-button", disabled: disableButton || !recorderReady, children: [recordingState === "idle" && t("selfie.recorder.start"), recordingState === "preparing" && t("selfie.recorder.preparing"), recordingState === "recording" && (jsxRuntime.jsxs("span", { className: "flex items-center justify-center", children: [jsxRuntime.jsx("span", { className: "mr-2", children: t("selfie.recorder.recording_label") }), jsxRuntime.jsxs("span", { className: "flex space-x-1 loading-dots", children: [jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" })] })] })), recordingState === "processing" && t("selfie.recorder.processing")] })] }) })] }));
159
+ }), { strings: unisseyStrings.getUnisseyStrings(t) })) }), jsxRuntime.jsx("div", { className: "shrink-0 bg-white border-t border-gray-200 p-4 md:p-6 relative", style: { zIndex: 9999 }, children: jsxRuntime.jsxs("div", { className: "max-w-md mx-auto", children: [jsxRuntime.jsx("div", { className: "text-center text-xs text-gray-400 mt-3", children: t("selfie.recorder.note") }), jsxRuntime.jsxs(Button.default, { onClick: recordStarting, className: "w-full py-3 md:py-4 relative selfie-button", disabled: disableButton || !recorderReady, children: [recordingState === "idle" && t("selfie.recorder.start"), recordingState === "preparing" && t("selfie.recorder.preparing"), recordingState === "recording" && (jsxRuntime.jsxs("span", { className: "flex items-center justify-center", children: [jsxRuntime.jsx("span", { className: "mr-2", children: t("selfie.recorder.recording_label") }), jsxRuntime.jsxs("span", { className: "flex space-x-1 loading-dots", children: [jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" })] })] })), recordingState === "processing" && t("selfie.recorder.processing")] })] }) })] }));
178
160
  };
179
161
 
180
162
  exports.default = SelfieRecorder;
@@ -1 +1 @@
1
- {"version":3,"file":"SelfieRecorder.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieRecorder.tsx"],"sourcesContent":["import { useRef, useState, useEffect, useCallback } from \"react\";\nimport { AcquisitionPreset, VideoRecorder } from \"@unissey-web/sdk-react\";\nimport Button from \"../../ui/Button\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport useVideoRecorderStyles from \"../hooks/useVideoRecorderStyles\";\nimport { setupVideoElementsObserver } from \"../utils/videoElementStyles\";\nimport { delay, isIOS, waitForVideoFrame, getRecorderVideoElement } from \"../utils/selfieCaptureUtils\";\nimport { useLiveFrameCapture } from \"../hooks/useLiveFrameCapture\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { getUnisseyStrings } from \"../utils/unisseyStrings\";\n\ninterface SelfieRecorderProps {\n handleSelfie: (e: Event) => void;\n onBeginCapture?: () => void;\n isCapturing?: boolean;\n}\n\ninterface VideoRecorderRef extends HTMLElement {\n capture: () => void;\n}\n\nconst SelfieRecorder = ({\n handleSelfie,\n onBeginCapture = () => { },\n isCapturing = false,\n}: SelfieRecorderProps) => {\n const { t } = useI18n();\n const recorderRef = useRef<VideoRecorderRef | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const buttonBarRef = useRef<HTMLDivElement | null>(null);\n const [videoMaxHeight, setVideoMaxHeight] = useState<number | undefined>(undefined);\n const [disableButton, setDisableButton] = useState(false);\n const [recorderReady, setRecorderReady] = useState(false);\n const [recordingState, setRecordingState] = useState<\n \"idle\" | \"preparing\" | \"recording\" | \"processing\"\n >(\"idle\");\n const capturedThumbnailRef = useRef<string | null>(null);\n const { captureFrame, cleanup } = useLiveFrameCapture();\n\n useVideoRecorderStyles();\n\n const updateVideoMaxHeight = useCallback(() => {\n if (!containerRef.current || !buttonBarRef.current) return;\n const totalHeight = containerRef.current.clientHeight;\n const buttonBarHeight = buttonBarRef.current.offsetHeight;\n // Reserve space for header (~80px) + button bar\n const available = totalHeight - buttonBarHeight - 80;\n setVideoMaxHeight(Math.max(available, 200));\n }, []);\n\n useEffect(() => {\n updateVideoMaxHeight();\n window.addEventListener(\"resize\", updateVideoMaxHeight);\n return () => window.removeEventListener(\"resize\", updateVideoMaxHeight);\n }, [updateVideoMaxHeight]);\n\n useEffect(() => {\n document.body.classList.add(\"recording-selfie\");\n const cleanupObserver = setupVideoElementsObserver();\n\n // iOS-specific fix: Add required attributes to video elements after mount\n if (isIOS()) {\n const addIOSVideoAttributes = () => {\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder) => {\n // Try to access shadow DOM and video elements\n try {\n const shadowRoot = (recorder as any).shadowRoot;\n if (shadowRoot) {\n const videoElements = shadowRoot.querySelectorAll(\"video\");\n videoElements.forEach((video: HTMLVideoElement) => {\n video.setAttribute(\"playsinline\", \"true\");\n video.setAttribute(\"autoplay\", \"true\");\n video.setAttribute(\"muted\", \"true\");\n // Ensure video plays inline and autoplays\n video.playsInline = true;\n video.autoplay = true;\n video.muted = true;\n });\n }\n } catch (error) {\n console.log(\"Could not access shadow DOM:\", error);\n }\n\n // Also set attributes on the component itself\n recorder.setAttribute(\"playsinline\", \"true\");\n recorder.setAttribute(\"autoplay\", \"true\");\n recorder.setAttribute(\"muted\", \"true\");\n });\n };\n\n // Apply immediately and also after a delay to catch dynamically created elements\n addIOSVideoAttributes();\n const iosTimeout = setTimeout(addIOSVideoAttributes, 500);\n const iosInterval = setInterval(addIOSVideoAttributes, 1000);\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n clearTimeout(iosTimeout);\n clearInterval(iosInterval);\n };\n }\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n };\n }, [cleanup]);\n\n const recordStarting = () => {\n if (!recorderReady || recordingState !== \"idle\") return;\n onBeginCapture();\n setRecordingState(\"preparing\");\n setDisableButton(true);\n\n const triggerCapture = async () => {\n try {\n await waitForVideoFrame(recorderRef.current);\n await delay(200);\n setRecordingState(\"recording\");\n\n // Capture a frame from the live video during recording (after a short delay)\n setTimeout(() => {\n const videoElement = getRecorderVideoElement(recorderRef.current);\n if (videoElement) {\n const thumbnail = captureFrame(videoElement);\n capturedThumbnailRef.current = thumbnail;\n }\n }, 1000); // Capture frame 1 second into recording\n\n recorderRef.current?.capture();\n } catch (error) {\n console.error(\"SelfieRecorder: failed to capture frame\", error);\n setRecordingState(\"idle\");\n setDisableButton(false);\n }\n };\n\n void triggerCapture();\n };\n\n const handleRecorderReady = () => setRecorderReady(true);\n\n const handleRecordCompleted = (e: Event) => {\n const customEvent = e as CustomEvent<{ media?: Blob; metadata?: string }>;\n if (!customEvent.detail?.media || customEvent.detail.media.size === 0) {\n console.error(\"❌ No valid media captured\");\n\n // iOS-specific debugging\n if (isIOS()) {\n console.log(\"🍎 iOS detected - checking video elements for proper attributes\");\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder, index) => {\n console.log(`VideoRecorder ${index}:`, {\n playsinline: recorder.getAttribute(\"playsinline\"),\n autoplay: recorder.getAttribute(\"autoplay\"),\n muted: recorder.getAttribute(\"muted\")\n });\n });\n }\n\n setRecordingState(\"idle\");\n setDisableButton(false);\n return;\n }\n\n // Attach the captured thumbnail to the event\n const enhancedEvent = new CustomEvent('record-completed', {\n detail: {\n media: customEvent.detail.media,\n metadata: customEvent.detail.metadata || '',\n thumbnail: capturedThumbnailRef.current || undefined,\n }\n });\n\n setRecordingState(\"processing\");\n handleSelfie(enhancedEvent);\n };\n\n return (\n <div ref={containerRef} className=\"selfie flex flex-col h-full w-full overflow-hidden min-h-0\">\n <div className=\"p-4 text-center shrink-0\">\n <Title className=\"text-lg md:text-xl mb-1\">{t(\"selfie.recorder.title\")}</Title>\n <Subtitle className=\"text-xs text-gray-600 md:text-sm\">{t(\"selfie.recorder.subtitle\")}</Subtitle>\n </div>\n\n <div\n className=\"video-container flex-1 min-h-0 relative flex items-center justify-center overflow-hidden\"\n style={videoMaxHeight ? { maxHeight: videoMaxHeight } : undefined}\n >\n <VideoRecorder\n ref={recorderRef as any}\n preset={AcquisitionPreset.SELFIE_OPTIMIZED}\n hideCaptureBtn\n faceChecker=\"enabled\"\n disableDebugMode\n onRecorderReady={handleRecorderReady}\n onRecordCompleted={handleRecordCompleted}\n onRecord={recordStarting}\n style={{ width: \"100%\", height: \"100%\" }}\n className=\"video-recorder-no-radius w-full h-full\"\n {...(isIOS() && {\n // iOS-specific attributes for fixing black screen\n \"data-playsinline\": \"true\",\n \"data-autoplay\": \"true\",\n \"data-muted\": \"true\"\n })}\n strings={getUnisseyStrings(t)}\n />\n </div>\n\n <div ref={buttonBarRef} className=\"shrink-0 bg-white border-t border-gray-200 p-4 md:p-6\">\n <div className=\"max-w-md mx-auto\">\n <div className=\"text-center text-xs text-gray-400 mt-3\">\n {t(\"selfie.recorder.note\")}\n </div>\n\n <Button\n onClick={recordStarting}\n className=\"w-full py-3 md:py-4 relative selfie-button\"\n disabled={disableButton || !recorderReady}\n >\n {recordingState === \"idle\" && t(\"selfie.recorder.start\")}\n {recordingState === \"preparing\" && t(\"selfie.recorder.preparing\")}\n {recordingState === \"recording\" && (\n <span className=\"flex items-center justify-center\">\n <span className=\"mr-2\">{t(\"selfie.recorder.recording_label\")}</span>\n <span className=\"flex space-x-1 loading-dots\">\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n </span>\n </span>\n )}\n {recordingState === \"processing\" && t(\"selfie.recorder.processing\")}\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieRecorder;\n"],"names":["useI18n","useRef","useState","useLiveFrameCapture","useVideoRecorderStyles","useCallback","useEffect","setupVideoElementsObserver","isIOS","__awaiter","waitForVideoFrame","delay","getRecorderVideoElement","_jsxs","_jsx","Title","Subtitle","VideoRecorder","__assign","AcquisitionPreset","getUnisseyStrings","Button"],"mappings":"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"}
1
+ {"version":3,"file":"SelfieRecorder.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieRecorder.tsx"],"sourcesContent":["import { useRef, useState, useEffect } from \"react\";\nimport { AcquisitionPreset, VideoRecorder } from \"@unissey-web/sdk-react\";\nimport Button from \"../../ui/Button\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport useVideoRecorderStyles from \"../hooks/useVideoRecorderStyles\";\nimport { setupVideoElementsObserver } from \"../utils/videoElementStyles\";\nimport { delay, isIOS, waitForVideoFrame, getRecorderVideoElement } from \"../utils/selfieCaptureUtils\";\nimport { useLiveFrameCapture } from \"../hooks/useLiveFrameCapture\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { getUnisseyStrings } from \"../utils/unisseyStrings\";\n\ninterface SelfieRecorderProps {\n handleSelfie: (e: Event) => void;\n onBeginCapture?: () => void;\n isCapturing?: boolean;\n}\n\ninterface VideoRecorderRef extends HTMLElement {\n capture: () => void;\n}\n\nconst SelfieRecorder = ({\n handleSelfie,\n onBeginCapture = () => { },\n isCapturing = false,\n}: SelfieRecorderProps) => {\n const { t } = useI18n();\n const recorderRef = useRef<VideoRecorderRef | null>(null);\n const [disableButton, setDisableButton] = useState(false);\n const [recorderReady, setRecorderReady] = useState(false);\n const [recordingState, setRecordingState] = useState<\n \"idle\" | \"preparing\" | \"recording\" | \"processing\"\n >(\"idle\");\n const capturedThumbnailRef = useRef<string | null>(null);\n const { captureFrame, cleanup } = useLiveFrameCapture();\n\n useVideoRecorderStyles();\n\n useEffect(() => {\n document.body.classList.add(\"recording-selfie\");\n const cleanupObserver = setupVideoElementsObserver();\n\n // iOS-specific fix: Add required attributes to video elements after mount\n if (isIOS()) {\n const addIOSVideoAttributes = () => {\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder) => {\n // Try to access shadow DOM and video elements\n try {\n const shadowRoot = (recorder as any).shadowRoot;\n if (shadowRoot) {\n const videoElements = shadowRoot.querySelectorAll(\"video\");\n videoElements.forEach((video: HTMLVideoElement) => {\n video.setAttribute(\"playsinline\", \"true\");\n video.setAttribute(\"autoplay\", \"true\");\n video.setAttribute(\"muted\", \"true\");\n // Ensure video plays inline and autoplays\n video.playsInline = true;\n video.autoplay = true;\n video.muted = true;\n });\n }\n } catch (error) {\n console.log(\"Could not access shadow DOM:\", error);\n }\n\n // Also set attributes on the component itself\n recorder.setAttribute(\"playsinline\", \"true\");\n recorder.setAttribute(\"autoplay\", \"true\");\n recorder.setAttribute(\"muted\", \"true\");\n });\n };\n\n // Apply immediately and also after a delay to catch dynamically created elements\n addIOSVideoAttributes();\n const iosTimeout = setTimeout(addIOSVideoAttributes, 500);\n const iosInterval = setInterval(addIOSVideoAttributes, 1000);\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n clearTimeout(iosTimeout);\n clearInterval(iosInterval);\n };\n }\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n };\n }, [cleanup]);\n\n const recordStarting = () => {\n if (!recorderReady || recordingState !== \"idle\") return;\n onBeginCapture();\n setRecordingState(\"preparing\");\n setDisableButton(true);\n\n const triggerCapture = async () => {\n try {\n await waitForVideoFrame(recorderRef.current);\n await delay(200);\n setRecordingState(\"recording\");\n\n // Capture a frame from the live video during recording (after a short delay)\n setTimeout(() => {\n const videoElement = getRecorderVideoElement(recorderRef.current);\n if (videoElement) {\n const thumbnail = captureFrame(videoElement);\n capturedThumbnailRef.current = thumbnail;\n }\n }, 1000); // Capture frame 1 second into recording\n\n recorderRef.current?.capture();\n } catch (error) {\n console.error(\"SelfieRecorder: failed to capture frame\", error);\n setRecordingState(\"idle\");\n setDisableButton(false);\n }\n };\n\n void triggerCapture();\n };\n\n const handleRecorderReady = () => setRecorderReady(true);\n\n const handleRecordCompleted = (e: Event) => {\n const customEvent = e as CustomEvent<{ media?: Blob; metadata?: string }>;\n if (!customEvent.detail?.media || customEvent.detail.media.size === 0) {\n console.error(\"❌ No valid media captured\");\n\n // iOS-specific debugging\n if (isIOS()) {\n console.log(\"🍎 iOS detected - checking video elements for proper attributes\");\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder, index) => {\n console.log(`VideoRecorder ${index}:`, {\n playsinline: recorder.getAttribute(\"playsinline\"),\n autoplay: recorder.getAttribute(\"autoplay\"),\n muted: recorder.getAttribute(\"muted\")\n });\n });\n }\n\n setRecordingState(\"idle\");\n setDisableButton(false);\n return;\n }\n\n // Attach the captured thumbnail to the event\n const enhancedEvent = new CustomEvent('record-completed', {\n detail: {\n media: customEvent.detail.media,\n metadata: customEvent.detail.metadata || '',\n thumbnail: capturedThumbnailRef.current || undefined,\n }\n });\n\n setRecordingState(\"processing\");\n handleSelfie(enhancedEvent);\n };\n\n return (\n <div className=\"selfie fixed inset-0 z-50 flex flex-col\">\n <div className=\"p-4 text-center bg-white shrink-0\">\n <Title className=\"text-lg md:text-xl mb-1\">{t(\"selfie.recorder.title\")}</Title>\n <Subtitle className=\"text-xs text-gray-600 md:text-sm\">{t(\"selfie.recorder.subtitle\")}</Subtitle>\n </div>\n\n <div className=\"video-container flex-1 relative overflow-hidden\">\n <VideoRecorder\n ref={recorderRef as any}\n preset={AcquisitionPreset.SELFIE_OPTIMIZED}\n hideCaptureBtn\n faceChecker=\"enabled\"\n disableDebugMode\n onRecorderReady={handleRecorderReady}\n onRecordCompleted={handleRecordCompleted}\n onRecord={recordStarting}\n style={{ width: \"100%\", height: \"100%\" }}\n className=\"video-recorder-no-radius w-full h-full\"\n {...(isIOS() && {\n \"data-playsinline\": \"true\",\n \"data-autoplay\": \"true\",\n \"data-muted\": \"true\"\n })}\n strings={getUnisseyStrings(t)}\n />\n </div>\n\n <div className=\"shrink-0 bg-white border-t border-gray-200 p-4 md:p-6 relative\" style={{ zIndex: 9999 }}>\n <div className=\"max-w-md mx-auto\">\n <div className=\"text-center text-xs text-gray-400 mt-3\">\n {t(\"selfie.recorder.note\")}\n </div>\n\n <Button\n onClick={recordStarting}\n className=\"w-full py-3 md:py-4 relative selfie-button\"\n disabled={disableButton || !recorderReady}\n >\n {recordingState === \"idle\" && t(\"selfie.recorder.start\")}\n {recordingState === \"preparing\" && t(\"selfie.recorder.preparing\")}\n {recordingState === \"recording\" && (\n <span className=\"flex items-center justify-center\">\n <span className=\"mr-2\">{t(\"selfie.recorder.recording_label\")}</span>\n <span className=\"flex space-x-1 loading-dots\">\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n </span>\n </span>\n )}\n {recordingState === \"processing\" && t(\"selfie.recorder.processing\")}\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieRecorder;\n"],"names":["useI18n","useRef","useState","useLiveFrameCapture","useVideoRecorderStyles","useEffect","setupVideoElementsObserver","isIOS","__awaiter","waitForVideoFrame","delay","getRecorderVideoElement","_jsxs","_jsx","Title","Subtitle","VideoRecorder","__assign","AcquisitionPreset","getUnisseyStrings","Button"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { __assign, __awaiter, __generator } from '../../../node_modules/tslib/tslib.es6.js';
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { useRef, useState, useCallback, useEffect } from 'react';
3
+ import { useRef, useState, useEffect } from 'react';
4
4
  import { VideoRecorder, AcquisitionPreset } from '@unissey-web/sdk-react';
5
5
  import Button from '../../ui/Button.js';
6
6
  import Title from '../../ui/Title.js';
@@ -16,29 +16,12 @@ var SelfieRecorder = function (_a) {
16
16
  var handleSelfie = _a.handleSelfie, _b = _a.onBeginCapture, onBeginCapture = _b === void 0 ? function () { } : _b; _a.isCapturing;
17
17
  var t = useI18n().t;
18
18
  var recorderRef = useRef(null);
19
- var containerRef = useRef(null);
20
- var buttonBarRef = useRef(null);
21
- var _d = useState(undefined), videoMaxHeight = _d[0], setVideoMaxHeight = _d[1];
22
- var _e = useState(false), disableButton = _e[0], setDisableButton = _e[1];
23
- var _f = useState(false), recorderReady = _f[0], setRecorderReady = _f[1];
24
- var _g = useState("idle"), recordingState = _g[0], setRecordingState = _g[1];
19
+ var _d = useState(false), disableButton = _d[0], setDisableButton = _d[1];
20
+ var _e = useState(false), recorderReady = _e[0], setRecorderReady = _e[1];
21
+ var _f = useState("idle"), recordingState = _f[0], setRecordingState = _f[1];
25
22
  var capturedThumbnailRef = useRef(null);
26
- var _h = useLiveFrameCapture(), captureFrame = _h.captureFrame, cleanup = _h.cleanup;
23
+ var _g = useLiveFrameCapture(), captureFrame = _g.captureFrame, cleanup = _g.cleanup;
27
24
  useVideoRecorderStyles();
28
- var updateVideoMaxHeight = useCallback(function () {
29
- if (!containerRef.current || !buttonBarRef.current)
30
- return;
31
- var totalHeight = containerRef.current.clientHeight;
32
- var buttonBarHeight = buttonBarRef.current.offsetHeight;
33
- // Reserve space for header (~80px) + button bar
34
- var available = totalHeight - buttonBarHeight - 80;
35
- setVideoMaxHeight(Math.max(available, 200));
36
- }, []);
37
- useEffect(function () {
38
- updateVideoMaxHeight();
39
- window.addEventListener("resize", updateVideoMaxHeight);
40
- return function () { return window.removeEventListener("resize", updateVideoMaxHeight); };
41
- }, [updateVideoMaxHeight]);
42
25
  useEffect(function () {
43
26
  document.body.classList.add("recording-selfie");
44
27
  var cleanupObserver = setupVideoElementsObserver();
@@ -165,12 +148,11 @@ var SelfieRecorder = function (_a) {
165
148
  setRecordingState("processing");
166
149
  handleSelfie(enhancedEvent);
167
150
  };
168
- return (jsxs("div", { ref: containerRef, className: "selfie flex flex-col h-full w-full overflow-hidden min-h-0", children: [jsxs("div", { className: "p-4 text-center shrink-0", children: [jsx(Title, { className: "text-lg md:text-xl mb-1", children: t("selfie.recorder.title") }), jsx(Subtitle, { className: "text-xs text-gray-600 md:text-sm", children: t("selfie.recorder.subtitle") })] }), jsx("div", { className: "video-container flex-1 min-h-0 relative flex items-center justify-center overflow-hidden", style: videoMaxHeight ? { maxHeight: videoMaxHeight } : undefined, children: jsx(VideoRecorder, __assign({ ref: recorderRef, preset: AcquisitionPreset.SELFIE_OPTIMIZED, hideCaptureBtn: true, faceChecker: "enabled", disableDebugMode: true, onRecorderReady: handleRecorderReady, onRecordCompleted: handleRecordCompleted, onRecord: recordStarting, style: { width: "100%", height: "100%" }, className: "video-recorder-no-radius w-full h-full" }, (isIOS() && {
169
- // iOS-specific attributes for fixing black screen
151
+ return (jsxs("div", { className: "selfie fixed inset-0 z-50 flex flex-col", children: [jsxs("div", { className: "p-4 text-center bg-white shrink-0", children: [jsx(Title, { className: "text-lg md:text-xl mb-1", children: t("selfie.recorder.title") }), jsx(Subtitle, { className: "text-xs text-gray-600 md:text-sm", children: t("selfie.recorder.subtitle") })] }), jsx("div", { className: "video-container flex-1 relative overflow-hidden", children: jsx(VideoRecorder, __assign({ ref: recorderRef, preset: AcquisitionPreset.SELFIE_OPTIMIZED, hideCaptureBtn: true, faceChecker: "enabled", disableDebugMode: true, onRecorderReady: handleRecorderReady, onRecordCompleted: handleRecordCompleted, onRecord: recordStarting, style: { width: "100%", height: "100%" }, className: "video-recorder-no-radius w-full h-full" }, (isIOS() && {
170
152
  "data-playsinline": "true",
171
153
  "data-autoplay": "true",
172
154
  "data-muted": "true"
173
- }), { strings: getUnisseyStrings(t) })) }), jsx("div", { ref: buttonBarRef, className: "shrink-0 bg-white border-t border-gray-200 p-4 md:p-6", children: jsxs("div", { className: "max-w-md mx-auto", children: [jsx("div", { className: "text-center text-xs text-gray-400 mt-3", children: t("selfie.recorder.note") }), jsxs(Button, { onClick: recordStarting, className: "w-full py-3 md:py-4 relative selfie-button", disabled: disableButton || !recorderReady, children: [recordingState === "idle" && t("selfie.recorder.start"), recordingState === "preparing" && t("selfie.recorder.preparing"), recordingState === "recording" && (jsxs("span", { className: "flex items-center justify-center", children: [jsx("span", { className: "mr-2", children: t("selfie.recorder.recording_label") }), jsxs("span", { className: "flex space-x-1 loading-dots", children: [jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsx("span", { className: "h-1 w-1 bg-white rounded-full" })] })] })), recordingState === "processing" && t("selfie.recorder.processing")] })] }) })] }));
155
+ }), { strings: getUnisseyStrings(t) })) }), jsx("div", { className: "shrink-0 bg-white border-t border-gray-200 p-4 md:p-6 relative", style: { zIndex: 9999 }, children: jsxs("div", { className: "max-w-md mx-auto", children: [jsx("div", { className: "text-center text-xs text-gray-400 mt-3", children: t("selfie.recorder.note") }), jsxs(Button, { onClick: recordStarting, className: "w-full py-3 md:py-4 relative selfie-button", disabled: disableButton || !recorderReady, children: [recordingState === "idle" && t("selfie.recorder.start"), recordingState === "preparing" && t("selfie.recorder.preparing"), recordingState === "recording" && (jsxs("span", { className: "flex items-center justify-center", children: [jsx("span", { className: "mr-2", children: t("selfie.recorder.recording_label") }), jsxs("span", { className: "flex space-x-1 loading-dots", children: [jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsx("span", { className: "h-1 w-1 bg-white rounded-full" })] })] })), recordingState === "processing" && t("selfie.recorder.processing")] })] }) })] }));
174
156
  };
175
157
 
176
158
  export { SelfieRecorder as default };
@@ -1 +1 @@
1
- {"version":3,"file":"SelfieRecorder.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieRecorder.tsx"],"sourcesContent":["import { useRef, useState, useEffect, useCallback } from \"react\";\nimport { AcquisitionPreset, VideoRecorder } from \"@unissey-web/sdk-react\";\nimport Button from \"../../ui/Button\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport useVideoRecorderStyles from \"../hooks/useVideoRecorderStyles\";\nimport { setupVideoElementsObserver } from \"../utils/videoElementStyles\";\nimport { delay, isIOS, waitForVideoFrame, getRecorderVideoElement } from \"../utils/selfieCaptureUtils\";\nimport { useLiveFrameCapture } from \"../hooks/useLiveFrameCapture\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { getUnisseyStrings } from \"../utils/unisseyStrings\";\n\ninterface SelfieRecorderProps {\n handleSelfie: (e: Event) => void;\n onBeginCapture?: () => void;\n isCapturing?: boolean;\n}\n\ninterface VideoRecorderRef extends HTMLElement {\n capture: () => void;\n}\n\nconst SelfieRecorder = ({\n handleSelfie,\n onBeginCapture = () => { },\n isCapturing = false,\n}: SelfieRecorderProps) => {\n const { t } = useI18n();\n const recorderRef = useRef<VideoRecorderRef | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const buttonBarRef = useRef<HTMLDivElement | null>(null);\n const [videoMaxHeight, setVideoMaxHeight] = useState<number | undefined>(undefined);\n const [disableButton, setDisableButton] = useState(false);\n const [recorderReady, setRecorderReady] = useState(false);\n const [recordingState, setRecordingState] = useState<\n \"idle\" | \"preparing\" | \"recording\" | \"processing\"\n >(\"idle\");\n const capturedThumbnailRef = useRef<string | null>(null);\n const { captureFrame, cleanup } = useLiveFrameCapture();\n\n useVideoRecorderStyles();\n\n const updateVideoMaxHeight = useCallback(() => {\n if (!containerRef.current || !buttonBarRef.current) return;\n const totalHeight = containerRef.current.clientHeight;\n const buttonBarHeight = buttonBarRef.current.offsetHeight;\n // Reserve space for header (~80px) + button bar\n const available = totalHeight - buttonBarHeight - 80;\n setVideoMaxHeight(Math.max(available, 200));\n }, []);\n\n useEffect(() => {\n updateVideoMaxHeight();\n window.addEventListener(\"resize\", updateVideoMaxHeight);\n return () => window.removeEventListener(\"resize\", updateVideoMaxHeight);\n }, [updateVideoMaxHeight]);\n\n useEffect(() => {\n document.body.classList.add(\"recording-selfie\");\n const cleanupObserver = setupVideoElementsObserver();\n\n // iOS-specific fix: Add required attributes to video elements after mount\n if (isIOS()) {\n const addIOSVideoAttributes = () => {\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder) => {\n // Try to access shadow DOM and video elements\n try {\n const shadowRoot = (recorder as any).shadowRoot;\n if (shadowRoot) {\n const videoElements = shadowRoot.querySelectorAll(\"video\");\n videoElements.forEach((video: HTMLVideoElement) => {\n video.setAttribute(\"playsinline\", \"true\");\n video.setAttribute(\"autoplay\", \"true\");\n video.setAttribute(\"muted\", \"true\");\n // Ensure video plays inline and autoplays\n video.playsInline = true;\n video.autoplay = true;\n video.muted = true;\n });\n }\n } catch (error) {\n console.log(\"Could not access shadow DOM:\", error);\n }\n\n // Also set attributes on the component itself\n recorder.setAttribute(\"playsinline\", \"true\");\n recorder.setAttribute(\"autoplay\", \"true\");\n recorder.setAttribute(\"muted\", \"true\");\n });\n };\n\n // Apply immediately and also after a delay to catch dynamically created elements\n addIOSVideoAttributes();\n const iosTimeout = setTimeout(addIOSVideoAttributes, 500);\n const iosInterval = setInterval(addIOSVideoAttributes, 1000);\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n clearTimeout(iosTimeout);\n clearInterval(iosInterval);\n };\n }\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n };\n }, [cleanup]);\n\n const recordStarting = () => {\n if (!recorderReady || recordingState !== \"idle\") return;\n onBeginCapture();\n setRecordingState(\"preparing\");\n setDisableButton(true);\n\n const triggerCapture = async () => {\n try {\n await waitForVideoFrame(recorderRef.current);\n await delay(200);\n setRecordingState(\"recording\");\n\n // Capture a frame from the live video during recording (after a short delay)\n setTimeout(() => {\n const videoElement = getRecorderVideoElement(recorderRef.current);\n if (videoElement) {\n const thumbnail = captureFrame(videoElement);\n capturedThumbnailRef.current = thumbnail;\n }\n }, 1000); // Capture frame 1 second into recording\n\n recorderRef.current?.capture();\n } catch (error) {\n console.error(\"SelfieRecorder: failed to capture frame\", error);\n setRecordingState(\"idle\");\n setDisableButton(false);\n }\n };\n\n void triggerCapture();\n };\n\n const handleRecorderReady = () => setRecorderReady(true);\n\n const handleRecordCompleted = (e: Event) => {\n const customEvent = e as CustomEvent<{ media?: Blob; metadata?: string }>;\n if (!customEvent.detail?.media || customEvent.detail.media.size === 0) {\n console.error(\"❌ No valid media captured\");\n\n // iOS-specific debugging\n if (isIOS()) {\n console.log(\"🍎 iOS detected - checking video elements for proper attributes\");\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder, index) => {\n console.log(`VideoRecorder ${index}:`, {\n playsinline: recorder.getAttribute(\"playsinline\"),\n autoplay: recorder.getAttribute(\"autoplay\"),\n muted: recorder.getAttribute(\"muted\")\n });\n });\n }\n\n setRecordingState(\"idle\");\n setDisableButton(false);\n return;\n }\n\n // Attach the captured thumbnail to the event\n const enhancedEvent = new CustomEvent('record-completed', {\n detail: {\n media: customEvent.detail.media,\n metadata: customEvent.detail.metadata || '',\n thumbnail: capturedThumbnailRef.current || undefined,\n }\n });\n\n setRecordingState(\"processing\");\n handleSelfie(enhancedEvent);\n };\n\n return (\n <div ref={containerRef} className=\"selfie flex flex-col h-full w-full overflow-hidden min-h-0\">\n <div className=\"p-4 text-center shrink-0\">\n <Title className=\"text-lg md:text-xl mb-1\">{t(\"selfie.recorder.title\")}</Title>\n <Subtitle className=\"text-xs text-gray-600 md:text-sm\">{t(\"selfie.recorder.subtitle\")}</Subtitle>\n </div>\n\n <div\n className=\"video-container flex-1 min-h-0 relative flex items-center justify-center overflow-hidden\"\n style={videoMaxHeight ? { maxHeight: videoMaxHeight } : undefined}\n >\n <VideoRecorder\n ref={recorderRef as any}\n preset={AcquisitionPreset.SELFIE_OPTIMIZED}\n hideCaptureBtn\n faceChecker=\"enabled\"\n disableDebugMode\n onRecorderReady={handleRecorderReady}\n onRecordCompleted={handleRecordCompleted}\n onRecord={recordStarting}\n style={{ width: \"100%\", height: \"100%\" }}\n className=\"video-recorder-no-radius w-full h-full\"\n {...(isIOS() && {\n // iOS-specific attributes for fixing black screen\n \"data-playsinline\": \"true\",\n \"data-autoplay\": \"true\",\n \"data-muted\": \"true\"\n })}\n strings={getUnisseyStrings(t)}\n />\n </div>\n\n <div ref={buttonBarRef} className=\"shrink-0 bg-white border-t border-gray-200 p-4 md:p-6\">\n <div className=\"max-w-md mx-auto\">\n <div className=\"text-center text-xs text-gray-400 mt-3\">\n {t(\"selfie.recorder.note\")}\n </div>\n\n <Button\n onClick={recordStarting}\n className=\"w-full py-3 md:py-4 relative selfie-button\"\n disabled={disableButton || !recorderReady}\n >\n {recordingState === \"idle\" && t(\"selfie.recorder.start\")}\n {recordingState === \"preparing\" && t(\"selfie.recorder.preparing\")}\n {recordingState === \"recording\" && (\n <span className=\"flex items-center justify-center\">\n <span className=\"mr-2\">{t(\"selfie.recorder.recording_label\")}</span>\n <span className=\"flex space-x-1 loading-dots\">\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n </span>\n </span>\n )}\n {recordingState === \"processing\" && t(\"selfie.recorder.processing\")}\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieRecorder;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"SelfieRecorder.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieRecorder.tsx"],"sourcesContent":["import { useRef, useState, useEffect } from \"react\";\nimport { AcquisitionPreset, VideoRecorder } from \"@unissey-web/sdk-react\";\nimport Button from \"../../ui/Button\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport useVideoRecorderStyles from \"../hooks/useVideoRecorderStyles\";\nimport { setupVideoElementsObserver } from \"../utils/videoElementStyles\";\nimport { delay, isIOS, waitForVideoFrame, getRecorderVideoElement } from \"../utils/selfieCaptureUtils\";\nimport { useLiveFrameCapture } from \"../hooks/useLiveFrameCapture\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { getUnisseyStrings } from \"../utils/unisseyStrings\";\n\ninterface SelfieRecorderProps {\n handleSelfie: (e: Event) => void;\n onBeginCapture?: () => void;\n isCapturing?: boolean;\n}\n\ninterface VideoRecorderRef extends HTMLElement {\n capture: () => void;\n}\n\nconst SelfieRecorder = ({\n handleSelfie,\n onBeginCapture = () => { },\n isCapturing = false,\n}: SelfieRecorderProps) => {\n const { t } = useI18n();\n const recorderRef = useRef<VideoRecorderRef | null>(null);\n const [disableButton, setDisableButton] = useState(false);\n const [recorderReady, setRecorderReady] = useState(false);\n const [recordingState, setRecordingState] = useState<\n \"idle\" | \"preparing\" | \"recording\" | \"processing\"\n >(\"idle\");\n const capturedThumbnailRef = useRef<string | null>(null);\n const { captureFrame, cleanup } = useLiveFrameCapture();\n\n useVideoRecorderStyles();\n\n useEffect(() => {\n document.body.classList.add(\"recording-selfie\");\n const cleanupObserver = setupVideoElementsObserver();\n\n // iOS-specific fix: Add required attributes to video elements after mount\n if (isIOS()) {\n const addIOSVideoAttributes = () => {\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder) => {\n // Try to access shadow DOM and video elements\n try {\n const shadowRoot = (recorder as any).shadowRoot;\n if (shadowRoot) {\n const videoElements = shadowRoot.querySelectorAll(\"video\");\n videoElements.forEach((video: HTMLVideoElement) => {\n video.setAttribute(\"playsinline\", \"true\");\n video.setAttribute(\"autoplay\", \"true\");\n video.setAttribute(\"muted\", \"true\");\n // Ensure video plays inline and autoplays\n video.playsInline = true;\n video.autoplay = true;\n video.muted = true;\n });\n }\n } catch (error) {\n console.log(\"Could not access shadow DOM:\", error);\n }\n\n // Also set attributes on the component itself\n recorder.setAttribute(\"playsinline\", \"true\");\n recorder.setAttribute(\"autoplay\", \"true\");\n recorder.setAttribute(\"muted\", \"true\");\n });\n };\n\n // Apply immediately and also after a delay to catch dynamically created elements\n addIOSVideoAttributes();\n const iosTimeout = setTimeout(addIOSVideoAttributes, 500);\n const iosInterval = setInterval(addIOSVideoAttributes, 1000);\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n clearTimeout(iosTimeout);\n clearInterval(iosInterval);\n };\n }\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n };\n }, [cleanup]);\n\n const recordStarting = () => {\n if (!recorderReady || recordingState !== \"idle\") return;\n onBeginCapture();\n setRecordingState(\"preparing\");\n setDisableButton(true);\n\n const triggerCapture = async () => {\n try {\n await waitForVideoFrame(recorderRef.current);\n await delay(200);\n setRecordingState(\"recording\");\n\n // Capture a frame from the live video during recording (after a short delay)\n setTimeout(() => {\n const videoElement = getRecorderVideoElement(recorderRef.current);\n if (videoElement) {\n const thumbnail = captureFrame(videoElement);\n capturedThumbnailRef.current = thumbnail;\n }\n }, 1000); // Capture frame 1 second into recording\n\n recorderRef.current?.capture();\n } catch (error) {\n console.error(\"SelfieRecorder: failed to capture frame\", error);\n setRecordingState(\"idle\");\n setDisableButton(false);\n }\n };\n\n void triggerCapture();\n };\n\n const handleRecorderReady = () => setRecorderReady(true);\n\n const handleRecordCompleted = (e: Event) => {\n const customEvent = e as CustomEvent<{ media?: Blob; metadata?: string }>;\n if (!customEvent.detail?.media || customEvent.detail.media.size === 0) {\n console.error(\"❌ No valid media captured\");\n\n // iOS-specific debugging\n if (isIOS()) {\n console.log(\"🍎 iOS detected - checking video elements for proper attributes\");\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder, index) => {\n console.log(`VideoRecorder ${index}:`, {\n playsinline: recorder.getAttribute(\"playsinline\"),\n autoplay: recorder.getAttribute(\"autoplay\"),\n muted: recorder.getAttribute(\"muted\")\n });\n });\n }\n\n setRecordingState(\"idle\");\n setDisableButton(false);\n return;\n }\n\n // Attach the captured thumbnail to the event\n const enhancedEvent = new CustomEvent('record-completed', {\n detail: {\n media: customEvent.detail.media,\n metadata: customEvent.detail.metadata || '',\n thumbnail: capturedThumbnailRef.current || undefined,\n }\n });\n\n setRecordingState(\"processing\");\n handleSelfie(enhancedEvent);\n };\n\n return (\n <div className=\"selfie fixed inset-0 z-50 flex flex-col\">\n <div className=\"p-4 text-center bg-white shrink-0\">\n <Title className=\"text-lg md:text-xl mb-1\">{t(\"selfie.recorder.title\")}</Title>\n <Subtitle className=\"text-xs text-gray-600 md:text-sm\">{t(\"selfie.recorder.subtitle\")}</Subtitle>\n </div>\n\n <div className=\"video-container flex-1 relative overflow-hidden\">\n <VideoRecorder\n ref={recorderRef as any}\n preset={AcquisitionPreset.SELFIE_OPTIMIZED}\n hideCaptureBtn\n faceChecker=\"enabled\"\n disableDebugMode\n onRecorderReady={handleRecorderReady}\n onRecordCompleted={handleRecordCompleted}\n onRecord={recordStarting}\n style={{ width: \"100%\", height: \"100%\" }}\n className=\"video-recorder-no-radius w-full h-full\"\n {...(isIOS() && {\n \"data-playsinline\": \"true\",\n \"data-autoplay\": \"true\",\n \"data-muted\": \"true\"\n })}\n strings={getUnisseyStrings(t)}\n />\n </div>\n\n <div className=\"shrink-0 bg-white border-t border-gray-200 p-4 md:p-6 relative\" style={{ zIndex: 9999 }}>\n <div className=\"max-w-md mx-auto\">\n <div className=\"text-center text-xs text-gray-400 mt-3\">\n {t(\"selfie.recorder.note\")}\n </div>\n\n <Button\n onClick={recordStarting}\n className=\"w-full py-3 md:py-4 relative selfie-button\"\n disabled={disableButton || !recorderReady}\n >\n {recordingState === \"idle\" && t(\"selfie.recorder.start\")}\n {recordingState === \"preparing\" && t(\"selfie.recorder.preparing\")}\n {recordingState === \"recording\" && (\n <span className=\"flex items-center justify-center\">\n <span className=\"mr-2\">{t(\"selfie.recorder.recording_label\")}</span>\n <span className=\"flex space-x-1 loading-dots\">\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n </span>\n </span>\n )}\n {recordingState === \"processing\" && t(\"selfie.recorder.processing\")}\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieRecorder;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datakeen-session-react",
3
- "version": "1.1.140-dev.30",
3
+ "version": "1.1.140-dev.32",
4
4
  "description": "React SDK component to manage and render Datakeen session experiences easily.",
5
5
  "publishConfig": {
6
6
  "access": "public",