diff --git a/packages/www/src/App.tsx b/packages/www/src/App.tsx index aad73ca6..766feb33 100644 --- a/packages/www/src/App.tsx +++ b/packages/www/src/App.tsx @@ -14,6 +14,7 @@ import { AuthProvider, useAuth } from './providers/auth'; import { Navigate, Route, Router } from "@solidjs/router"; import { globalStyle, macaron$ } from "@macaron-css/core"; import { Component, createSignal, Match, onCleanup, Switch } from 'solid-js'; +import TestComponent from './pages/test'; const Root = styled("div", { base: { @@ -87,12 +88,14 @@ export const App: Component = () => { ( - - {props.children} - + // + // {props.children} + props.children + // )} > + { diff --git a/packages/www/src/index.tsx b/packages/www/src/index.tsx index 0bada0f9..80a66cb8 100644 --- a/packages/www/src/index.tsx +++ b/packages/www/src/index.tsx @@ -8,7 +8,7 @@ import { render } from "solid-js/web"; import "modern-normalize/modern-normalize.css"; import { App } from "./App"; import { StorageProvider } from "./providers/account"; -import { ToastProvider, Toaster } from "solid-notifications"; +// import { ToastProvider, Toaster } from "solid-notifications"; const root = document.getElementById("root"); @@ -20,12 +20,12 @@ if (import.meta.env.DEV && !(root instanceof HTMLElement)) { render( () => ( - - + // + // - + // ), root! ); \ No newline at end of file diff --git a/packages/www/src/pages/play.tsx b/packages/www/src/pages/play.tsx index 5bc4712e..66f7bc67 100644 --- a/packages/www/src/pages/play.tsx +++ b/packages/www/src/pages/play.tsx @@ -1,11 +1,11 @@ import { Text } from "@nestri/www/ui/text"; -import { createSignal, createEffect, onCleanup, onMount, Show} from "solid-js"; +import { createSignal, createEffect, onCleanup, onMount, Show } from "solid-js"; import { Portal } from "solid-js/web"; import { useParams } from "@solidjs/router"; import { Keyboard, Mouse, WebRTCStream } from "@nestri/input"; import { Container, FullScreen } from "@nestri/www/ui/layout"; import { styled } from "@macaron-css/solid"; -import { theme } from "../ui/theme"; +import { lightClass, theme, darkClass } from "@nestri/www/ui/theme"; const Canvas = styled("canvas", { base: { @@ -14,289 +14,309 @@ const Canvas = styled("canvas", { height: "100%", objectFit: "contain", maxHeight: "100vh", - }}); + } +}); + +const ModalContainer = styled("div", { + base: { + width: "100%", + maxWidth: 370, + maxHeight: "75vh", + height: "auto", + // borderRadius: 12, + // borderWidth: 1, + // borderStyle: "solid", + // borderColor: theme.color.gray.d400, + // backgroundColor: theme.color.pink.d400, + backgroundColor: theme.color.red.d300, + // boxShadow: theme.color.boxShadow, + // backdropFilter: "blur(20px)", + padding: "20px 25px" + } +}) - const ModalContainer = styled("div", { - base: { - width: "100%", - maxWidth: 370, - maxHeight: "75vh", - borderRadius: 12, - borderWidth: 1, - borderStyle: "solid", - borderColor: theme.color.gray.d400, - backgroundColor: theme.color.pink.d400, - boxShadow: theme.color.boxShadow, - backdropFilter: "blur(20px)", - padding: "20px 25px" - } - }) export function PlayComponent() { - const params = useParams(); - const id = params.id; - - const [showBannerModal, setShowBannerModal] = createSignal(false); - const [showButtonModal, setShowButtonModal] = createSignal(false); - const [gamepadConnected, setGamepadConnected] = createSignal(false); - const [buttonPressed, setButtonPressed] = createSignal(null); - const [leftStickX, setLeftStickX] = createSignal(0); - const [leftStickY, setLeftStickY] = createSignal(0); - const [hasStream, setHasStream] = createSignal(false); - const [nestriLock, setNestriLock] = createSignal(false); - const [showOffline, setShowOffline] = createSignal(false); - - const [canvas, setCanvas] = createSignal(undefined); - let video: HTMLVideoElement; - let webrtc: WebRTCStream; - let nestriMouse: Mouse , nestriKeyboard: Keyboard; - - const initializeInputDevices = () => { - const canvasElement = canvas(); - if (!canvasElement || !webrtc) return; - try { - nestriMouse = new Mouse({ canvas: canvasElement, webrtc }); - nestriKeyboard = new Keyboard({ canvas: canvasElement, webrtc }); - console.log("Input devices initialized successfully"); - } catch (error) { - console.error("Failed to initialize input devices:", error); - } - }; - - /*const initializeGamepad = () => { - console.log("Initializing gamepad..."); - - const updateGamepadState = () => { - const gamepads = navigator.getGamepads(); - const gamepad = gamepads[0]; - if (gamepad) { - setButtonPressed(gamepad.buttons.findIndex(btn => btn.pressed) !== -1 ? "Button pressed" : null); - setLeftStickX(Number(gamepad.axes[0].toFixed(2))); - setLeftStickY(Number(gamepad.axes[1].toFixed(2))); - } - requestAnimationFrame(updateGamepadState); - }; - - window.addEventListener("gamepadconnected", () => { - setGamepadConnected(true); - console.log("Gamepad connected!"); - updateGamepadState(); - }); - - window.addEventListener("gamepaddisconnected", () => { - setGamepadConnected(false); - console.log("Gamepad disconnected!"); - }); - };*/ - - const lockPlay = async () => { - const canvasElement = canvas(); - if (!canvasElement || !hasStream()) return; - try { - await canvasElement.requestPointerLock(); - await canvasElement.requestFullscreen(); - //initializeGamepad(); - - if (document.fullscreenElement !== null) { - if ('keyboard' in navigator && 'lock' in (navigator.keyboard as any)) { - const keys = [ - "AltLeft", "AltRight", "Tab", "Escape", - "ContextMenu", "MetaLeft", "MetaRight" - ]; + const params = useParams(); + const id = params.id; - try { - await (navigator.keyboard as any).lock(keys); - setNestriLock(true); - console.log("Keyboard lock acquired"); - } catch (e) { - console.warn("Keyboard lock failed:", e); - setNestriLock(false); - } - } - } - - } catch (error) { - console.error("Error during lock sequence:", error); - } - }; - - const setupPointerLockListener = () => { - document.addEventListener("pointerlockchange", () => { - const canvasElement = canvas(); - if (!canvasElement) return; - if (document.pointerLockElement === canvasElement) { - initializeInputDevices(); - } else { - - if (!showBannerModal) { - const playing = sessionStorage.getItem("showedBanner"); - setShowBannerModal(!playing || playing !== "true"); - setShowButtonModal(playing === "false"); + const [showBannerModal, setShowBannerModal] = createSignal(false); + const [showButtonModal, setShowButtonModal] = createSignal(false); + const [gamepadConnected, setGamepadConnected] = createSignal(false); + const [buttonPressed, setButtonPressed] = createSignal(null); + const [leftStickX, setLeftStickX] = createSignal(0); + const [leftStickY, setLeftStickY] = createSignal(0); + const [hasStream, setHasStream] = createSignal(false); + const [nestriLock, setNestriLock] = createSignal(false); + const [showOffline, setShowOffline] = createSignal(false); + + const [canvas, setCanvas] = createSignal(undefined); + let video: HTMLVideoElement; + let webrtc: WebRTCStream; + let nestriMouse: Mouse, nestriKeyboard: Keyboard; + + const initializeInputDevices = () => { + const canvasElement = canvas(); + if (!canvasElement || !webrtc) return; + try { + nestriMouse = new Mouse({ canvas: canvasElement, webrtc }); + nestriKeyboard = new Keyboard({ canvas: canvasElement, webrtc }); + console.log("Input devices initialized successfully"); + } catch (error) { + console.error("Failed to initialize input devices:", error); + } + }; + + /*const initializeGamepad = () => { + console.log("Initializing gamepad..."); + + const updateGamepadState = () => { + const gamepads = navigator.getGamepads(); + const gamepad = gamepads[0]; + if (gamepad) { + setButtonPressed(gamepad.buttons.findIndex(btn => btn.pressed) !== -1 ? "Button pressed" : null); + setLeftStickX(Number(gamepad.axes[0].toFixed(2))); + setLeftStickY(Number(gamepad.axes[1].toFixed(2))); + } + requestAnimationFrame(updateGamepadState); + }; + + window.addEventListener("gamepadconnected", () => { + setGamepadConnected(true); + console.log("Gamepad connected!"); + updateGamepadState(); + }); + + window.addEventListener("gamepaddisconnected", () => { + setGamepadConnected(false); + console.log("Gamepad disconnected!"); + }); + };*/ + + const lockPlay = async () => { + const canvasElement = canvas(); + if (!canvasElement || !hasStream()) return; + try { + await canvasElement.requestPointerLock(); + await canvasElement.requestFullscreen(); + //initializeGamepad(); + + if (document.fullscreenElement !== null) { + if ('keyboard' in navigator && 'lock' in (navigator.keyboard as any)) { + const keys = [ + "AltLeft", "AltRight", "Tab", "Escape", + "ContextMenu", "MetaLeft", "MetaRight" + ]; + + try { + await (navigator.keyboard as any).lock(keys); + setNestriLock(true); + console.log("Keyboard lock acquired"); + } catch (e) { + console.warn("Keyboard lock failed:", e); + setNestriLock(false); } - - - - nestriKeyboard?.dispose(); - nestriMouse?.dispose(); } - }); - }; + } - const handleVideoInput = async () => { - const canvasElement = canvas(); - if (!video || !canvasElement) return; - - try { - - await video.play(); - if (canvasElement && video) { - canvasElement.width = video.videoWidth; - canvasElement.height = video.videoHeight; - - - const ctx = canvasElement.getContext("2d"); - const renderer = () => { - if (ctx && hasStream() && video) { - ctx.drawImage(video, 0, 0); - video.requestVideoFrameCallback(renderer); - } - }; - - video.requestVideoFrameCallback(renderer); - } - } catch (error) { - console.error("Error playing video:", error); - } - }; - - - onMount(() => { + } catch (error) { + console.error("Error during lock sequence:", error); + } + }; + + const setupPointerLockListener = () => { + document.addEventListener("pointerlockchange", () => { const canvasElement = canvas(); - if(!canvasElement) return; + if (!canvasElement) return; + if (document.pointerLockElement === canvasElement) { + initializeInputDevices(); + } else { - setupPointerLockListener(); - video = document.createElement("video"); - video.style.visibility = "hidden"; - webrtc = new WebRTCStream("http://192.168.1.200:8088", id, async (mediaStream) => { - if (video && mediaStream) { - video.srcObject = mediaStream; - setHasStream(true); - setShowOffline(false); - await handleVideoInput(); - } else if (mediaStream === null) { - console.log("MediaStream is null, Room is offline"); - setShowOffline(true); - setHasStream(false); - - const ctx = canvasElement.getContext("2d"); - if (ctx) ctx.clearRect(0, 0, canvasElement.width, canvasElement.height); - } else if (video && video.srcObject !== null) { - setHasStream(true); - setShowOffline(true); - await handleVideoInput(); + if (!showBannerModal) { + const playing = sessionStorage.getItem("showedBanner"); + setShowBannerModal(!playing || playing !== "true"); + setShowButtonModal(playing === "false"); } - }); - }); - - onCleanup(() => { - nestriKeyboard?.dispose(); - nestriMouse?.dispose(); - }); - - const { Modal, openModal } = createModal(); - return ( - <> + + + nestriKeyboard?.dispose(); + nestriMouse?.dispose(); + } + }); + }; + + const handleVideoInput = async () => { + const canvasElement = canvas(); + if (!video || !canvasElement) return; + + try { + + await video.play(); + if (canvasElement && video) { + canvasElement.width = video.videoWidth; + canvasElement.height = video.videoHeight; + + + const ctx = canvasElement.getContext("2d"); + const renderer = () => { + if (ctx && hasStream() && video) { + ctx.drawImage(video, 0, 0); + video.requestVideoFrameCallback(renderer); + } + }; + + video.requestVideoFrameCallback(renderer); + } + } catch (error) { + console.error("Error playing video:", error); + } + }; + + + onMount(() => { + const canvasElement = canvas(); + if (!canvasElement) return; + + setupPointerLockListener(); + video = document.createElement("video"); + video.style.visibility = "hidden"; + webrtc = new WebRTCStream("http://192.168.1.200:8088", id, async (mediaStream) => { + if (video && mediaStream) { + video.srcObject = mediaStream; + setHasStream(true); + setShowOffline(false); + await handleVideoInput(); + } else if (mediaStream === null) { + console.log("MediaStream is null, Room is offline"); + setShowOffline(true); + setHasStream(false); + + const ctx = canvasElement.getContext("2d"); + if (ctx) ctx.clearRect(0, 0, canvasElement.width, canvasElement.height); + } else if (video && video.srcObject !== null) { + setHasStream(true); + setShowOffline(true); + await handleVideoInput(); + } + }); + }); + + onCleanup(() => { + nestriKeyboard?.dispose(); + nestriMouse?.dispose(); + }); + + const { Modal, openModal } = createModal(); + + return ( + <> - /* - {showOffline() ? ( -
- Offline - -
- ) : ( - - )} + /* + {showOffline() ? ( +
+ Offline + +
+ ) : ( + + )} - -
*/ - ); - } + +
*/ + ); +} - interface ModalProps { - show: () => boolean; - setShow: (value: boolean) => void; - closeOnBackdropClick?: boolean; - handleVideoInput?: () => Promise; - lockPlay?: () => Promise; - } +interface ModalProps { + show: () => boolean; + setShow: (value: boolean) => void; + closeOnBackdropClick?: boolean; + handleVideoInput?: () => Promise; + lockPlay?: () => Promise; +} - function createModal() { - const [open, setOpen] = createSignal(false); - - return { - openModal() { - setOpen(true); - }, - Modal() { - return ( - - -
( + window.matchMedia("(prefers-color-scheme: dark)").matches + ? "dark" + : "light", + ); + + const darkMode = window.matchMedia("(prefers-color-scheme: dark)"); + const setColorScheme = (e: MediaQueryListEvent) => { + setTheme(e.matches ? "dark" : "light"); + }; + darkMode.addEventListener("change", setColorScheme); + onCleanup(() => { + darkMode.removeEventListener("change", setColorScheme); + }); + + + return { + openModal() { + setOpen(true); + }, + Modal() { + return ( + + +
- - Hello from modal
- -
-
-
-
- ); - }, - }; - } - - function Modal(props: ModalProps) { - return ( - - - e.stopPropagation()} // Prevent closing when clicking inside modal - > -
-
- - -
+ > + + Hello from modal
+ +
-
- ); - } \ No newline at end of file + + + ); + }, + }; +} + +function Modal(props: ModalProps) { + return ( + + + e.stopPropagation()} // Prevent closing when clicking inside modal + > +
+
+ + +
+
+
+ ); +} \ No newline at end of file diff --git a/packages/www/src/pages/test.tsx b/packages/www/src/pages/test.tsx new file mode 100644 index 00000000..f6c7c4bb --- /dev/null +++ b/packages/www/src/pages/test.tsx @@ -0,0 +1,18 @@ +import { styled } from "@macaron-css/solid"; +import { theme } from "../ui/theme"; + + +const Testing = styled("div", { + base: { + height: "100%", + width: "100%", + position: "fixed", + backgroundColor: theme.color.blue.d600 + } +}) + +export default function TestComponent() { + return ( + + ) +} \ No newline at end of file