diff --git a/apps/web/app/permissions.d.ts b/apps/web/app/permissions.d.ts index bde3019..7a68e69 100644 --- a/apps/web/app/permissions.d.ts +++ b/apps/web/app/permissions.d.ts @@ -3,18 +3,18 @@ declare global { interface PermissionDescriptor { name: - | "camera" - | "microphone" - | "geolocation" - | "notifications" - | "persistent-storage" - | "push" - | "midi" - | "midi-sysex" + | 'camera' + | 'microphone' + | 'geolocation' + | 'notifications' + | 'persistent-storage' + | 'push' + | 'midi' + | 'midi-sysex' } // Extend the PermissionName type - type ExtendedPermissionName = "camera" | "microphone" + type ExtendedPermissionName = 'camera' | 'microphone' interface Permissions { query(permissionDesc: { diff --git a/apps/web/hooks/useUserMedia.ts b/apps/web/hooks/useUserMedia.ts index e528e93..eb79ea9 100644 --- a/apps/web/hooks/useUserMedia.ts +++ b/apps/web/hooks/useUserMedia.ts @@ -12,26 +12,28 @@ export const useUserMedia = () => { const [activeStream, setActiveStream] = useState(null) const [devices, setDevices] = useState([]) const [ready, setReady] = useState(false) + const [accessGranted, setAccessGranted] = useState(false) const checkPermission = useCallback(async () => { - const videoPermission = await navigator.permissions.query({ - name: 'camera', - }) - const audioPermission = await navigator.permissions.query({ - name: 'microphone', - }) - - const permission = { - video: videoPermission.state === 'granted', - audio: audioPermission.state === 'granted', - } - - if (permission.video && permission.audio) { + try { + await navigator.mediaDevices.getUserMedia({ + video: true, + audio: true, + }) setAccessGranted(true) + return { + video: true, + audio: true, + } + } catch (error) { + console.error('Error checking permission:', error) + setAccessGranted(false) + return { + video: false, + audio: false, + } } - - return permission }, [setAccessGranted]) const stopStreaming = useCallback(async (_stream?: MediaStream) => { @@ -83,7 +85,6 @@ export const useUserMedia = () => { }, [setDevices]) const toggleMute = useCallback(async () => { - console.log({ muted: preferences.muted }) activeStream?.getAudioTracks().forEach((track) => { track.enabled = preferences.muted }) diff --git a/apps/web/tailwind.config.ts b/apps/web/tailwind.config.ts index 93673bc..ea10d50 100644 --- a/apps/web/tailwind.config.ts +++ b/apps/web/tailwind.config.ts @@ -1,85 +1,85 @@ -import type { Config } from "tailwindcss" +import type { Config } from 'tailwindcss' const config = { - darkMode: ["class"], + darkMode: ['class'], content: [ - "./pages/**/*.{ts,tsx}", - "./components/**/*.{ts,tsx}", - "./app/**/*.{ts,tsx}", - "./src/**/*.{ts,tsx}", + './pages/**/*.{ts,tsx}', + './components/**/*.{ts,tsx}', + './app/**/*.{ts,tsx}', + './src/**/*.{ts,tsx}', ], - prefix: "", + prefix: '', theme: { container: { center: true, - padding: "2rem", + padding: '2rem', screens: { - "2xl": "1400px", + '2xl': '1400px', }, }, extend: { colors: { - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", + border: 'hsl(var(--border))', + input: 'hsl(var(--input))', + ring: 'hsl(var(--ring))', + background: 'hsl(var(--background))', + foreground: 'hsl(var(--foreground))', primary: { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", + DEFAULT: 'hsl(var(--primary))', + foreground: 'hsl(var(--primary-foreground))', }, secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", + DEFAULT: 'hsl(var(--secondary))', + foreground: 'hsl(var(--secondary-foreground))', }, destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", + DEFAULT: 'hsl(var(--destructive))', + foreground: 'hsl(var(--destructive-foreground))', }, muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", + DEFAULT: 'hsl(var(--muted))', + foreground: 'hsl(var(--muted-foreground))', }, accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", + DEFAULT: 'hsl(var(--accent))', + foreground: 'hsl(var(--accent-foreground))', }, popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", + DEFAULT: 'hsl(var(--popover))', + foreground: 'hsl(var(--popover-foreground))', }, card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", + DEFAULT: 'hsl(var(--card))', + foreground: 'hsl(var(--card-foreground))', }, }, borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)', }, keyframes: { - "accordion-down": { - from: { height: "0" }, - to: { height: "var(--radix-accordion-content-height)" }, + 'accordion-down': { + from: { height: '0' }, + to: { height: 'var(--radix-accordion-content-height)' }, }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: "0" }, + 'accordion-up': { + from: { height: 'var(--radix-accordion-content-height)' }, + to: { height: '0' }, }, - "scale-in-fade": { - "0%": { transform: "scale(0)", opacity: "0" }, - "100%": { transform: "scale(1)", opacity: "1" }, + 'scale-in-fade': { + '0%': { transform: 'scale(0)', opacity: '0' }, + '100%': { transform: 'scale(1)', opacity: '1' }, }, }, animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - "scale-in-fade": "scale-in-fade 1s ease-in-out", + 'accordion-down': 'accordion-down 0.2s ease-out', + 'accordion-up': 'accordion-up 0.2s ease-out', + 'scale-in-fade': 'scale-in-fade 1s ease-in-out', }, }, }, - plugins: [require("tailwindcss-animate")], + plugins: [require('tailwindcss-animate')], } satisfies Config export default config