diff --git a/app/components/app/CodeInput.vue b/app/components/app/CodeInput.vue index 40d08f6..ef24be7 100644 --- a/app/components/app/CodeInput.vue +++ b/app/components/app/CodeInput.vue @@ -1,20 +1,46 @@ - + @@ -22,8 +48,41 @@ const viewerStore = useViewerStore() v-for="(id, index) in 6" :key="id" :index="index" + class="h-14 w-10 sm:h-16 sm:w-12 text-lg sm:text-xl" /> + + + + + {{ n }} + + + + + + 0 + + + + + + - \ No newline at end of file + diff --git a/app/lib/types/PresetShareResponse.ts b/app/lib/types/PresetShareResponse.ts index 24d2c9a..007a22f 100644 --- a/app/lib/types/PresetShareResponse.ts +++ b/app/lib/types/PresetShareResponse.ts @@ -18,6 +18,7 @@ export interface PresetAuthor { fullName: string | null; profileImageUrl: string | null; username: string | null; + email: string | null; } export interface PresetShareResponse { diff --git a/app/lib/utils/presetsDb.ts b/app/lib/utils/presetsDb.ts index 3e9002d..cde3e4c 100644 --- a/app/lib/utils/presetsDb.ts +++ b/app/lib/utils/presetsDb.ts @@ -160,5 +160,6 @@ export async function getPresetAuthorData(event: H3Event, presetId: string) { fullName: user.fullName, profileImageUrl: user.imageUrl, username: user.username, + email: user.primaryEmailAddress?.emailAddress || null, }; } diff --git a/app/pages/index.vue b/app/pages/index.vue index 2bfe27a..49d7177 100644 --- a/app/pages/index.vue +++ b/app/pages/index.vue @@ -1,27 +1,84 @@ - - helium - effortless screensharing powered by webrtc - + + + + helium + effortless screensharing powered by webrtc + + + + + + + host instead? + + + - + + - {{ viewerStore.connectionStatus }} + + stream ended + + Enter another code + + + + + {{ viewerStore.connectionStatus }} + + + enter code to join stream + + + - - host instead? + + + + + Disconnect + + + + + Fullscreen + + + @@ -30,11 +87,14 @@ import { useWebSocket } from "@vueuse/core"; import { useViewerStore } from "~/state/viewer"; import { Button } from "@/components/ui/button"; import { useWebSocketUrl } from "~/composables/useWebSocketUrl"; +import { LogOut, Maximize } from "lucide-vue-next"; const isConnected = ref(false); const viewerStore = useViewerStore(); const { code: codeRef } = storeToRefs(viewerStore); const wsUrl = useWebSocketUrl(); +const videofeedRef = ref(null); + const { send, close: closeWebSocket } = useWebSocket(wsUrl, { autoReconnect: true, heartbeat: { @@ -90,7 +150,11 @@ const { send, close: closeWebSocket } = useWebSocket(wsUrl, { viewerStore.setConnectionStatus( `connection ${peerConnection.connectionState}`, ); - isConnected.value = false; + // Don't set isConnected = false immediately here to avoid flickering if it's a temp glitch, + // but usually disconnected means it's over. + if (peerConnection.connectionState !== "connected") { + isConnected.value = false; + } } }; @@ -161,8 +225,6 @@ const { send, close: closeWebSocket } = useWebSocket(wsUrl, { }, }); -const videofeedRef = ref(null); - const startWebRTCConnection = async () => { send( JSON.stringify({ @@ -190,10 +252,35 @@ function cleanupViewing() { if (videofeedRef.value) { videofeedRef.value.srcObject = null; } + + // Clear code + viewerStore.code = ''; // Reset connection status viewerStore.setConnectionStatus("disconnected"); isConnected.value = false; + + // Exit fullscreen if active + if (document.fullscreenElement) { + document.exitFullscreen().catch(() => {}); + } +} + +function toggleFullscreen() { + if (!videofeedRef.value) return; + + if (!document.fullscreenElement) { + videofeedRef.value.requestFullscreen().catch((err) => { + console.error(`Error attempting to enable fullscreen: ${err.message}`); + }); + } else { + document.exitFullscreen(); + } +} + +function handleReset() { + viewerStore.resetDisconnected(); + viewerStore.setConnectionStatus('waiting for a code'); } // Cleanup on component unmount @@ -214,4 +301,4 @@ onMounted(() => { window.removeEventListener("beforeunload", handleBeforeUnload); }); }); - + \ No newline at end of file diff --git a/app/pages/presets/shared/[id].vue b/app/pages/presets/shared/[id].vue index 3c9259b..da98973 100644 --- a/app/pages/presets/shared/[id].vue +++ b/app/pages/presets/shared/[id].vue @@ -22,6 +22,7 @@ {{ (response.author?.fullName || response.author?.username || + response.author?.email || "?")[0]!.toUpperCase() }} @@ -68,7 +69,7 @@ Cancel - {{ isImporting ? 'Importing...' : 'Import Preset' }} + {{ isImporting ? "Importing..." : "Import Preset" }} diff --git a/app/state/viewer.ts b/app/state/viewer.ts index c579f3e..9c85238 100644 --- a/app/state/viewer.ts +++ b/app/state/viewer.ts @@ -5,6 +5,7 @@ export const useViewerStore = defineStore('viewer', { code: '', peerConnection: null as RTCPeerConnection | null, connectionStatus: 'waiting for a code', + isDisconnected: false, }), actions: { setCode(code: string) { @@ -18,6 +19,12 @@ export const useViewerStore = defineStore('viewer', { console.log('pinia connection status debug:', status); } this.connectionStatus = status; + if (status === 'disconnected') { + this.isDisconnected = true; + } + }, + resetDisconnected() { + this.isDisconnected = false; } }, }); \ No newline at end of file
effortless screensharing powered by webrtc
stream ended
{{ viewerStore.connectionStatus }}
+ enter code to join stream +