diff --git a/src/app/routes/__root.tsx b/src/app/routes/__root.tsx index 485b9f9..64ce625 100644 --- a/src/app/routes/__root.tsx +++ b/src/app/routes/__root.tsx @@ -37,7 +37,7 @@ export const Route = createRootRouteWithContext<{ { name: "viewport", content: - "width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, interactive-widget=overlays-content", + "width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, interactive-widget=resizes-content", }, ], links: [ @@ -122,8 +122,7 @@ function RootDocument({ children }: { children: React.ReactNode }) { {...mantineHtmlProps} style={{ overflowX: "hidden", - overflowY: "hidden", - position: "fixed", + height: "100%", width: "100%", }} > @@ -135,9 +134,10 @@ function RootDocument({ children }: { children: React.ReactNode }) {
{children}
diff --git a/src/app/routes/api/events.$.ts b/src/app/routes/api/events.$.ts index 073015c..0f5b8f7 100644 --- a/src/app/routes/api/events.$.ts +++ b/src/app/routes/api/events.$.ts @@ -17,6 +17,10 @@ export const Route = createFileRoute("/api/events/$")({ logger.info("ServerEvents | Event received", event); const message = `data: ${JSON.stringify(event)}\n\n`; try { + if (!controller.desiredSize || controller.desiredSize <= 0) { + logger.warn("ServerEvents | Stream closed, skipping event"); + return; + } controller.enqueue(new TextEncoder().encode(message)); } catch (error) { logger.error("ServerEvents | Error sending SSE message", error); @@ -29,9 +33,14 @@ export const Route = createFileRoute("/api/events/$")({ const pingInterval = setInterval(() => { try { + if (!controller.desiredSize || controller.desiredSize <= 0) { + clearInterval(pingInterval); + return; + } const pingMessage = `data: ${JSON.stringify({ type: "ping" })}\n\n`; controller.enqueue(new TextEncoder().encode(pingMessage)); } catch (e) { + logger.error("ServerEvents | Ping interval error", e); clearInterval(pingInterval); } }, 30000); @@ -49,10 +58,11 @@ export const Route = createFileRoute("/api/events/$")({ return new Response(stream, { headers: { "Content-Type": "text/event-stream", - "Cache-Control": "no-cache", - Connection: "keep-alive", + "Cache-Control": "no-cache, no-store, must-revalidate", + "Connection": "keep-alive", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Cache-Control", + "X-Accel-Buffering": "no", }, }); }, diff --git a/src/features/core/components/layout.tsx b/src/features/core/components/layout.tsx index f0a457a..6e293b5 100644 --- a/src/features/core/components/layout.tsx +++ b/src/features/core/components/layout.tsx @@ -31,7 +31,11 @@ const Layout: React.FC = ({ children }) => { pos='relative' h='100dvh' mah='100dvh' - // style={{ top: viewport.top }} //, transition: 'top 0.1s ease-in-out' }} + style={{ + height: `${viewport.height}px`, + minHeight: '100dvh', + // top: viewport.top + }} >
{ useEffect(() => { if (!windowExists) return; + + setSize(); + window.visualViewport?.addEventListener('resize', setSize, eventListerOptions); + window.visualViewport?.addEventListener('scroll', setSize, eventListerOptions); + return () => { window.visualViewport?.removeEventListener('resize', setSize); + window.visualViewport?.removeEventListener('scroll', setSize); } - }, []); + }, [setSize]); return windowSize; } diff --git a/src/lib/supertokens/server.ts b/src/lib/supertokens/server.ts index 50d51df..3b4a535 100644 --- a/src/lib/supertokens/server.ts +++ b/src/lib/supertokens/server.ts @@ -17,7 +17,8 @@ export const backendConfig = (): TypeInput => { }, appInfo, recipeList: [ - passwordlessTwilioVerify.init(), + //passwordlessTwilioVerify.init(), + PasswordlessDevelopmentMode.init(), Session.init({ cookieSameSite: "lax", cookieSecure: import.meta.env.NODE_ENV === "production", diff --git a/src/lib/twilio/index.ts b/src/lib/twilio/index.ts index 3efe179..0cf009f 100644 --- a/src/lib/twilio/index.ts +++ b/src/lib/twilio/index.ts @@ -1,21 +1,33 @@ import twilio, { type Twilio } from "twilio"; -const accountSid = process.env.TWILIO_ACCOUNT_SID!; -const authToken = process.env.TWILIO_AUTH_TOKEN!; -const serviceSid = process.env.TWILIO_SERVICE_SID!; - let client: Twilio; +function getEnvVars() { + const accountSid = process.env.TWILIO_ACCOUNT_SID; + const authToken = process.env.TWILIO_AUTH_TOKEN; + const serviceSid = process.env.TWILIO_SERVICE_SID; + + if (!accountSid || !authToken || !serviceSid) { + throw new Error(`Missing env vars. accountSid: ${!!accountSid}, authToken: ${!!authToken}, serviceSid: ${!!serviceSid}`); + } + + return { accountSid, authToken, serviceSid }; +} + function getTwilioClient() { if (!client) { + const { accountSid, authToken } = getEnvVars(); client = twilio(accountSid, authToken); } return client; } + export async function sendVerifyCode(phoneNumber: string, code: string) { + const { serviceSid } = getEnvVars(); + const twilioClient = getTwilioClient(); - + const verification = await twilioClient!.verify.v2 .services(serviceSid) .verifications.create({ @@ -32,8 +44,9 @@ export async function sendVerifyCode(phoneNumber: string, code: string) { } export async function updateVerify(sid: string) { + const { serviceSid } = getEnvVars(); const twilioClient = getTwilioClient(); - + const verification = await twilioClient!.verify.v2 .services(serviceSid) .verifications(sid)