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)