diff options
| author | Frank <[email protected]> | 2025-05-23 15:57:33 -0400 |
|---|---|---|
| committer | Dax Raad <[email protected]> | 2025-05-26 12:40:17 -0400 |
| commit | d51b4263aba59f60277766fc024f2931fc8874ec (patch) | |
| tree | a9dfed63563a88bc26cb2d37d582e2c14a5d9331 /app/packages/web/src | |
| parent | 34a2dcb80a28e208c986d39ce1e145f245691f62 (diff) | |
| download | opencode-d51b4263aba59f60277766fc024f2931fc8874ec.tar.gz opencode-d51b4263aba59f60277766fc024f2931fc8874ec.zip | |
Share: sync
Diffstat (limited to 'app/packages/web/src')
| -rw-r--r-- | app/packages/web/src/App.module.css | 33 | ||||
| -rw-r--r-- | app/packages/web/src/app.css | 39 | ||||
| -rw-r--r-- | app/packages/web/src/app.tsx | 164 | ||||
| -rw-r--r-- | app/packages/web/src/assets/favicon.ico | bin | 0 -> 15086 bytes | |||
| -rw-r--r-- | app/packages/web/src/entry-client.tsx | 4 | ||||
| -rw-r--r-- | app/packages/web/src/entry-server.tsx | 21 | ||||
| -rw-r--r-- | app/packages/web/src/global.d.ts | 1 | ||||
| -rw-r--r-- | app/packages/web/src/index.css | 13 | ||||
| -rw-r--r-- | app/packages/web/src/index.tsx | 24 | ||||
| -rw-r--r-- | app/packages/web/src/logo.svg | 1 | ||||
| -rw-r--r-- | app/packages/web/src/routes/[...404].tsx | 19 | ||||
| -rw-r--r-- | app/packages/web/src/routes/index.tsx | 14 | ||||
| -rw-r--r-- | app/packages/web/src/routes/share/[id].tsx | 150 | ||||
| -rw-r--r-- | app/packages/web/src/sst-env.d.ts | 10 |
14 files changed, 230 insertions, 263 deletions
diff --git a/app/packages/web/src/App.module.css b/app/packages/web/src/App.module.css new file mode 100644 index 000000000..48308b24a --- /dev/null +++ b/app/packages/web/src/App.module.css @@ -0,0 +1,33 @@ +.App { + text-align: center; +} + +.logo { + animation: logo-spin infinite 20s linear; + height: 40vmin; + pointer-events: none; +} + +.header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.link { + color: #b318f0; +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/app/packages/web/src/app.css b/app/packages/web/src/app.css deleted file mode 100644 index 8596998a4..000000000 --- a/app/packages/web/src/app.css +++ /dev/null @@ -1,39 +0,0 @@ -body { - font-family: Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; -} - -a { - margin-right: 1rem; -} - -main { - text-align: center; - padding: 1em; - margin: 0 auto; -} - -h1 { - color: #335d92; - text-transform: uppercase; - font-size: 4rem; - font-weight: 100; - line-height: 1.1; - margin: 4rem auto; - max-width: 14rem; -} - -p { - max-width: 14rem; - margin: 2rem auto; - line-height: 1.35; -} - -@media (min-width: 480px) { - h1 { - max-width: none; - } - - p { - max-width: none; - } -} diff --git a/app/packages/web/src/app.tsx b/app/packages/web/src/app.tsx index e6ad8f9df..ee09bc954 100644 --- a/app/packages/web/src/app.tsx +++ b/app/packages/web/src/app.tsx @@ -1,20 +1,154 @@ -import { MetaProvider, Title } from "@solidjs/meta" -import { Router } from "@solidjs/router" -import { FileRoutes } from "@solidjs/start/router" -import { Suspense } from "solid-js" -import "./app.css" +import { createSignal, onCleanup, onMount, Show, For } from "solid-js" +import { useParams } from "@solidjs/router" + +type Message = { + key: string + content: string +} export default function App() { + const params = useParams<{ id: string }>() + const [messages, setMessages] = createSignal<Message[]>([]) + const [connectionStatus, setConnectionStatus] = createSignal("Disconnected") + + onMount(() => { + // Get the API URL from environment + const apiUrl = import.meta.env.VITE_API_URL + const shareId = params.id + + console.log("Mounting Share component with ID:", shareId) + console.log("API URL:", apiUrl) + + if (!shareId) { + console.error("Share ID not found in environment variables") + setConnectionStatus("Error: Share ID not found") + return + } + + if (!apiUrl) { + console.error("API URL not found in environment variables") + setConnectionStatus("Error: API URL not found") + return + } + + let reconnectTimer: number | undefined + let socket: WebSocket | null = null + + // Function to create and set up WebSocket with auto-reconnect + const setupWebSocket = () => { + // Close any existing connection + if (socket) { + socket.close() + } + + setConnectionStatus("Connecting...") + + // Always use secure WebSocket protocol (wss) + const wsBaseUrl = apiUrl.replace(/^https?:\/\//, "wss://") + const wsUrl = `${wsBaseUrl}/share_poll?share_id=${shareId}` + console.log("Connecting to WebSocket URL:", wsUrl) + + // Create WebSocket connection + socket = new WebSocket(wsUrl) + + // Handle connection opening + socket.onopen = () => { + setConnectionStatus("Connected") + console.log("WebSocket connection established") + } + + // Handle incoming messages + socket.onmessage = (event) => { + console.log("WebSocket message received") + try { + const data = JSON.parse(event.data) as Message + setMessages((prev) => [...prev, data]) + } catch (error) { + console.error("Error parsing WebSocket message:", error) + } + } + + // Handle errors + socket.onerror = (error) => { + console.error("WebSocket error:", error) + setConnectionStatus("Error: Connection failed") + } + + // Handle connection close and reconnection + socket.onclose = (event) => { + console.log(`WebSocket closed: ${event.code} ${event.reason}`) + setConnectionStatus("Disconnected, reconnecting...") + + // Try to reconnect after 2 seconds + clearTimeout(reconnectTimer) + reconnectTimer = window.setTimeout( + setupWebSocket, + 2000, + ) as unknown as number + } + } + + // Initial connection + setupWebSocket() + + // Clean up on component unmount + onCleanup(() => { + console.log("Cleaning up WebSocket connection") + if (socket) { + socket.close() + } + clearTimeout(reconnectTimer) + }) + }) + return ( - <Router - root={(props) => ( - <MetaProvider> - <Title>SolidStart - Basic</Title> - <Suspense>{props.children}</Suspense> - </MetaProvider> - )} - > - <FileRoutes /> - </Router> + <main> + <h1>Share: {params.id}</h1> + + <div style={{ margin: "2rem 0" }}> + <h2>WebSocket Connection</h2> + <p> + Status: <strong>{connectionStatus()}</strong> + </p> + + <h3>Live Updates</h3> + <div + style={{ + border: "1px solid #ccc", + padding: "1rem", + borderRadius: "0.5rem", + maxHeight: "500px", + overflowY: "auto", + }} + > + <Show + when={messages().length > 0} + fallback={<p>Waiting for messages...</p>} + > + <ul style={{ listStyleType: "none", padding: 0 }}> + <For each={messages()}> + {(msg) => ( + <li + style={{ + padding: "0.5rem", + margin: "0.5rem 0", + backgroundColor: "#f5f5f5", + borderRadius: "0.25rem", + }} + > + <div> + <strong>Key:</strong> {msg.key} + </div> + <div> + <strong>Content:</strong> {msg.content} + </div> + </li> + )} + </For> + </ul> + </Show> + </div> + </div> + </main> ) } diff --git a/app/packages/web/src/assets/favicon.ico b/app/packages/web/src/assets/favicon.ico Binary files differnew file mode 100644 index 000000000..b836b2bcc --- /dev/null +++ b/app/packages/web/src/assets/favicon.ico diff --git a/app/packages/web/src/entry-client.tsx b/app/packages/web/src/entry-client.tsx deleted file mode 100644 index 0ca4e3c30..000000000 --- a/app/packages/web/src/entry-client.tsx +++ /dev/null @@ -1,4 +0,0 @@ -// @refresh reload -import { mount, StartClient } from "@solidjs/start/client"; - -mount(() => <StartClient />, document.getElementById("app")!); diff --git a/app/packages/web/src/entry-server.tsx b/app/packages/web/src/entry-server.tsx deleted file mode 100644 index 401eff83f..000000000 --- a/app/packages/web/src/entry-server.tsx +++ /dev/null @@ -1,21 +0,0 @@ -// @refresh reload -import { createHandler, StartServer } from "@solidjs/start/server"; - -export default createHandler(() => ( - <StartServer - document={({ assets, children, scripts }) => ( - <html lang="en"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <link rel="icon" href="/favicon.ico" /> - {assets} - </head> - <body> - <div id="app">{children}</div> - {scripts} - </body> - </html> - )} - /> -)); diff --git a/app/packages/web/src/global.d.ts b/app/packages/web/src/global.d.ts deleted file mode 100644 index dc6f10c22..000000000 --- a/app/packages/web/src/global.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// <reference types="@solidjs/start/env" /> diff --git a/app/packages/web/src/index.css b/app/packages/web/src/index.css new file mode 100644 index 000000000..85e778f43 --- /dev/null +++ b/app/packages/web/src/index.css @@ -0,0 +1,13 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', + 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', + 'Helvetica Neue', sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} diff --git a/app/packages/web/src/index.tsx b/app/packages/web/src/index.tsx new file mode 100644 index 000000000..823bf0fb8 --- /dev/null +++ b/app/packages/web/src/index.tsx @@ -0,0 +1,24 @@ +/* @refresh reload */ +import { render } from "solid-js/web" +import { Router, Route } from "@solidjs/router" + +import "./index.css" +import App from "./App" + +const root = document.getElementById("root") + +if (import.meta.env.DEV && !(root instanceof HTMLElement)) { + throw new Error( + "Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?", + ) +} + +render( + () => ( + <Router> + <Route path="/share/:id" component={App} /> + <Route path="/" component={App} /> + </Router> + ), + root!, +) diff --git a/app/packages/web/src/logo.svg b/app/packages/web/src/logo.svg new file mode 100644 index 000000000..025aa303c --- /dev/null +++ b/app/packages/web/src/logo.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 166 155.3"><path d="M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z" fill="#76b3e1"/><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="27.5" y1="3" x2="152" y2="63.5"><stop offset=".1" stop-color="#76b3e1"/><stop offset=".3" stop-color="#dcf2fd"/><stop offset="1" stop-color="#76b3e1"/></linearGradient><path d="M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z" opacity=".3" fill="url(#a)"/><path d="M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z" fill="#518ac8"/><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="95.8" y1="32.6" x2="74" y2="105.2"><stop offset="0" stop-color="#76b3e1"/><stop offset=".5" stop-color="#4377bb"/><stop offset="1" stop-color="#1f3b77"/></linearGradient><path d="M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z" opacity=".3" fill="url(#b)"/><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="18.4" y1="64.2" x2="144.3" y2="149.8"><stop offset="0" stop-color="#315aa9"/><stop offset=".5" stop-color="#518ac8"/><stop offset="1" stop-color="#315aa9"/></linearGradient><path d="M134 80a45 45 0 00-48-15L24 85 4 120l112 19 20-36c4-7 3-15-2-23z" fill="url(#c)"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="75.2" y1="74.5" x2="24.4" y2="260.8"><stop offset="0" stop-color="#4377bb"/><stop offset=".5" stop-color="#1a336b"/><stop offset="1" stop-color="#1a336b"/></linearGradient><path d="M114 115a45 45 0 00-48-15L4 120s53 40 94 30l3-1c17-5 23-21 13-34z" fill="url(#d)"/></svg>
\ No newline at end of file diff --git a/app/packages/web/src/routes/[...404].tsx b/app/packages/web/src/routes/[...404].tsx deleted file mode 100644 index 4ea71ec7f..000000000 --- a/app/packages/web/src/routes/[...404].tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { Title } from "@solidjs/meta"; -import { HttpStatusCode } from "@solidjs/start"; - -export default function NotFound() { - return ( - <main> - <Title>Not Found</Title> - <HttpStatusCode code={404} /> - <h1>Page Not Found</h1> - <p> - Visit{" "} - <a href="https://start.solidjs.com" target="_blank"> - start.solidjs.com - </a>{" "} - to learn how to build SolidStart apps. - </p> - </main> - ); -} diff --git a/app/packages/web/src/routes/index.tsx b/app/packages/web/src/routes/index.tsx deleted file mode 100644 index 415b32744..000000000 --- a/app/packages/web/src/routes/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { Title } from "@solidjs/meta" -import { A } from "@solidjs/router" - -export default function Home() { - return ( - <main> - <Title>Share Demo</Title> - <h1>Share Demo</h1> - <p> - <A href="/share/test-share-id">Go to test share</A> - </p> - </main> - ) -} diff --git a/app/packages/web/src/routes/share/[id].tsx b/app/packages/web/src/routes/share/[id].tsx deleted file mode 100644 index 851197de7..000000000 --- a/app/packages/web/src/routes/share/[id].tsx +++ /dev/null @@ -1,150 +0,0 @@ -import { Title } from "@solidjs/meta" -import { createSignal, onCleanup, onMount, Show, For } from "solid-js" -import { useParams } from "@solidjs/router" - -type Message = { - key: string - content: string -} - -export default function SharePage() { - const params = useParams<{ id: string }>() - const [messages, setMessages] = createSignal<Message[]>([]) - const [connectionStatus, setConnectionStatus] = createSignal("Disconnected") - - onMount(() => { - // Get the API URL from environment - const apiUrl = import.meta.env.VITE_API_URL - const shareId = params.id - - console.log("Mounting Share component with ID:", shareId) - console.log("API URL:", apiUrl) - - if (!apiUrl) { - console.error("API URL not found in environment variables") - setConnectionStatus("Error: API URL not found") - return - } - - let reconnectTimer: number | undefined - let socket: WebSocket | null = null - - // Function to create and set up WebSocket with auto-reconnect - const setupWebSocket = () => { - // Close any existing connection - if (socket) { - socket.close() - } - - setConnectionStatus("Connecting...") - - // Always use secure WebSocket protocol (wss) - const wsBaseUrl = apiUrl.replace(/^https?:\/\//, "wss://") - const wsUrl = `${wsBaseUrl}/share_poll?share_id=${shareId}` - console.log("Connecting to WebSocket URL:", wsUrl) - - // Create WebSocket connection - socket = new WebSocket(wsUrl) - - // Handle connection opening - socket.onopen = () => { - setConnectionStatus("Connected") - console.log("WebSocket connection established") - } - - // Handle incoming messages - socket.onmessage = (event) => { - console.log("WebSocket message received") - try { - const data = JSON.parse(event.data) as Message - setMessages((prev) => [...prev, data]) - } catch (error) { - console.error("Error parsing WebSocket message:", error) - } - } - - // Handle errors - socket.onerror = (error) => { - console.error("WebSocket error:", error) - setConnectionStatus("Error: Connection failed") - } - - // Handle connection close and reconnection - socket.onclose = (event) => { - console.log(`WebSocket closed: ${event.code} ${event.reason}`) - setConnectionStatus("Disconnected, reconnecting...") - - // Try to reconnect after 2 seconds - clearTimeout(reconnectTimer) - reconnectTimer = window.setTimeout( - setupWebSocket, - 2000, - ) as unknown as number - } - } - - // Initial connection - setupWebSocket() - - // Clean up on component unmount - onCleanup(() => { - console.log("Cleaning up WebSocket connection") - if (socket) { - socket.close() - } - clearTimeout(reconnectTimer) - }) - }) - - return ( - <main> - <Title>Share: {params.id}</Title> - <h1>Share: {params.id}</h1> - - <div style={{ margin: "2rem 0" }}> - <h2>WebSocket Connection</h2> - <p> - Status: <strong>{connectionStatus()}</strong> - </p> - - <h3>Live Updates</h3> - <div - style={{ - border: "1px solid #ccc", - padding: "1rem", - borderRadius: "0.5rem", - maxHeight: "500px", - overflowY: "auto", - }} - > - <Show - when={messages().length > 0} - fallback={<p>Waiting for messages...</p>} - > - <ul style={{ listStyleType: "none", padding: 0 }}> - <For each={messages()}> - {(msg) => ( - <li - style={{ - padding: "0.5rem", - margin: "0.5rem 0", - backgroundColor: "#f5f5f5", - borderRadius: "0.25rem", - }} - > - <div> - <strong>Key:</strong> {msg.key} - </div> - <div> - <strong>Content:</strong> {msg.content} - </div> - </li> - )} - </For> - </ul> - </Show> - </div> - </div> - </main> - ) -} diff --git a/app/packages/web/src/sst-env.d.ts b/app/packages/web/src/sst-env.d.ts new file mode 100644 index 000000000..4addc8ef9 --- /dev/null +++ b/app/packages/web/src/sst-env.d.ts @@ -0,0 +1,10 @@ +/* This file is auto-generated by SST. Do not edit. */ +/* tslint:disable */ +/* eslint-disable */ +/// <reference types="vite/client" /> +interface ImportMetaEnv { + readonly VITE_API_URL: string +} +interface ImportMeta { + readonly env: ImportMetaEnv +}
\ No newline at end of file |
