Add virtual gamepad controls and fullscreen toggle for webxdc games
This commit is contained in:
Generated
+20
@@ -3062,6 +3062,7 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3075,6 +3076,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3088,6 +3090,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3101,6 +3104,7 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3114,6 +3118,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3127,6 +3132,7 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3140,6 +3146,7 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3153,6 +3160,7 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3166,6 +3174,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3179,6 +3188,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3192,6 +3202,7 @@
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3205,6 +3216,7 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3218,6 +3230,7 @@
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3231,6 +3244,7 @@
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3244,6 +3258,7 @@
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3257,6 +3272,7 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3270,6 +3286,7 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3283,6 +3300,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3296,6 +3314,7 @@
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -3309,6 +3328,7 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
||||
@@ -28,14 +28,8 @@ export function WebxdcEmbed({ url, uuid, name, icon, className }: WebxdcEmbedPro
|
||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||
const [iframeKey, setIframeKey] = useState(0);
|
||||
const [showGamepad, setShowGamepad] = useState(false);
|
||||
const [webxdcHandle, setWebxdcHandle] = useState<WebxdcHandle | null>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Callback ref: when the Webxdc component mounts, store the handle in state
|
||||
// so GameControls re-renders with a non-null handle.
|
||||
const webxdcHandleCallback = useCallback((handle: WebxdcHandle | null) => {
|
||||
setWebxdcHandle(handle);
|
||||
}, []);
|
||||
const webxdcHandleRef = useRef<WebxdcHandle>(null);
|
||||
|
||||
// Derive a stable iframe ID from the UUID or URL
|
||||
const iframeId = uuid ?? url.replace(/[^a-zA-Z0-9]/g, '').slice(0, 32);
|
||||
@@ -56,10 +50,10 @@ export function WebxdcEmbed({ url, uuid, name, icon, className }: WebxdcEmbedPro
|
||||
|
||||
const toggleGamepad = useCallback(() => {
|
||||
setShowGamepad((prev) => {
|
||||
if (!prev) webxdcHandle?.focus();
|
||||
if (!prev) webxdcHandleRef.current?.focus();
|
||||
return !prev;
|
||||
});
|
||||
}, [webxdcHandle]);
|
||||
}, []);
|
||||
|
||||
if (!launched) {
|
||||
return (
|
||||
@@ -208,7 +202,7 @@ export function WebxdcEmbed({ url, uuid, name, icon, className }: WebxdcEmbedPro
|
||||
<div className={cn(isFullscreen ? 'flex-1 relative' : 'relative')}>
|
||||
<WebxdcIframe
|
||||
key={iframeKey}
|
||||
ref={webxdcHandleCallback}
|
||||
ref={webxdcHandleRef}
|
||||
id={iframeId}
|
||||
url={url}
|
||||
uuid={uuid}
|
||||
@@ -222,7 +216,7 @@ export function WebxdcEmbed({ url, uuid, name, icon, className }: WebxdcEmbedPro
|
||||
'border-t border-border bg-background/80 backdrop-blur-sm',
|
||||
isFullscreen ? '' : 'rounded-b-2xl',
|
||||
)}>
|
||||
<GameControls webxdcHandle={webxdcHandle} />
|
||||
<GameControls webxdcHandle={webxdcHandleRef.current} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -247,6 +241,7 @@ const WebxdcIframe = forwardRef<WebxdcHandle, {
|
||||
id={id}
|
||||
xdc={url}
|
||||
webxdc={webxdc}
|
||||
allow="autoplay; fullscreen; gamepad"
|
||||
className="w-full border-0"
|
||||
style={{ height: isFullscreen ? '100%' : '400px' }}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user