cookie and pwa stuff

This commit is contained in:
yohlo
2026-02-14 12:59:01 -06:00
parent 236fcda671
commit 6e9e014fcc
11 changed files with 180 additions and 24 deletions

View File

@@ -0,0 +1,59 @@
import { useEffect, useState } from 'react'
import { Box, Paper, Group, Text, ActionIcon } from '@mantine/core'
import { DownloadIcon, XIcon } from '@phosphor-icons/react'
export function IOSInstallPrompt() {
const [show, setShow] = useState(false)
const [platform, setPlatform] = useState<'ios' | 'android' | null>(null)
useEffect(() => {
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent)
const isAndroid = /Android/.test(navigator.userAgent)
const isInStandaloneMode =
window.matchMedia('(display-mode: standalone)').matches ||
('standalone' in window.navigator && (window.navigator as any).standalone)
const hasBeenDismissed = localStorage.getItem('pwa-install-prompt-dismissed') === 'true'
if ((isIOS || isAndroid) && !isInStandaloneMode && !hasBeenDismissed) {
setPlatform(isIOS ? 'ios' : 'android')
const timer = setTimeout(() => setShow(true), 3000)
return () => clearTimeout(timer)
}
}, [])
const handleDismiss = () => {
localStorage.setItem('pwa-install-prompt-dismissed', 'true')
setShow(false)
}
if (!show || !platform) return null
const instructions = platform === 'ios'
? 'Tap Share → Add to Home Screen'
: 'Tap Menu (⋮) → Add to Home screen'
return (
<Box style={{ position: 'fixed', bottom: 0, left: 0, right: 0, zIndex: 1000, padding: '8px' }}>
<Paper shadow="lg" p="sm" style={{ background: 'var(--mantine-color-blue-9)', color: 'white' }}>
<Group justify="space-between" wrap="nowrap">
<Group gap="xs" wrap="nowrap" style={{ flex: 1 }}>
<DownloadIcon size={20} style={{ flexShrink: 0 }} />
<Box style={{ flex: 1, minWidth: 0 }}>
<Text size="sm" fw={500} style={{ lineHeight: 1.3 }}>
Please install FLXN This will save me Twilio credits as you won't be signed out!
</Text>
<Text size="xs" opacity={0.9} style={{ lineHeight: 1.2 }}>
{instructions}
</Text>
</Box>
</Group>
<ActionIcon variant="subtle" color="white" onClick={handleDismiss}>
<XIcon size={18} />
</ActionIcon>
</Group>
</Paper>
</Box>
)
}

View File

@@ -1,10 +1,12 @@
import { useEffect, useRef } from 'react';
import { useNavigate } from '@tanstack/react-router';
import { doesSessionExist } from 'supertokens-web-js/recipe/session';
import { getOrCreateRefreshPromise } from '@/lib/supertokens/client';
import { attemptRefreshingSession } from 'supertokens-web-js/recipe/session';
import { logger } from '@/lib/supertokens';
export function SessionMonitor() {
const navigate = useNavigate();
const lastRefreshTimeRef = useRef<number>(0);
const REFRESH_COOLDOWN = 30 * 1000;
@@ -49,12 +51,14 @@ export function SessionMonitor() {
}
};
handleVisibilityChange();
document.addEventListener('visibilitychange', handleVisibilityChange);
return () => {
document.removeEventListener('visibilitychange', handleVisibilityChange);
};
}, []);
}, [navigate]);
return null;
}