Spaces:
Sleeping
Sleeping
copilot-swe-agent[bot]
ArnavSingh76533
commited on
Commit
·
3c9a7c2
1
Parent(s):
3e45585
Address code review comments: improve audio context handling and extract media creation helper
Browse files- components/chat/ChatPanel.tsx +25 -9
- pages/api/socketio.ts +11 -13
components/chat/ChatPanel.tsx
CHANGED
|
@@ -16,6 +16,22 @@ interface Props {
|
|
| 16 |
className?: string
|
| 17 |
}
|
| 18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
const ChatPanel: FC<Props> = ({ socket, className }) => {
|
| 20 |
const [messages, _setMessages] = useState<ChatMessage[]>([])
|
| 21 |
const [text, setText] = useState("")
|
|
@@ -33,21 +49,21 @@ const ChatPanel: FC<Props> = ({ socket, className }) => {
|
|
| 33 |
setMessages([...messagesRef.current, msg].slice(-200))
|
| 34 |
// Play notification sound using Web Audio API
|
| 35 |
try {
|
| 36 |
-
const
|
| 37 |
-
const oscillator =
|
| 38 |
-
const gainNode =
|
| 39 |
|
| 40 |
oscillator.connect(gainNode)
|
| 41 |
-
gainNode.connect(
|
| 42 |
|
| 43 |
-
oscillator.frequency.value =
|
| 44 |
oscillator.type = 'sine'
|
| 45 |
|
| 46 |
-
gainNode.gain.setValueAtTime(
|
| 47 |
-
gainNode.gain.exponentialRampToValueAtTime(
|
| 48 |
|
| 49 |
-
oscillator.start(
|
| 50 |
-
oscillator.stop(
|
| 51 |
} catch (err) {
|
| 52 |
console.log("Audio notification failed:", err)
|
| 53 |
}
|
|
|
|
| 16 |
className?: string
|
| 17 |
}
|
| 18 |
|
| 19 |
+
// Audio notification constants
|
| 20 |
+
const NOTIFICATION_FREQUENCY = 800
|
| 21 |
+
const NOTIFICATION_VOLUME = 0.3
|
| 22 |
+
const NOTIFICATION_VOLUME_END = 0.01
|
| 23 |
+
const NOTIFICATION_DURATION = 0.1
|
| 24 |
+
|
| 25 |
+
// Reusable audio context for notifications
|
| 26 |
+
let audioContext: AudioContext | null = null
|
| 27 |
+
|
| 28 |
+
const getAudioContext = () => {
|
| 29 |
+
if (!audioContext) {
|
| 30 |
+
audioContext = new (window.AudioContext || (window as any).webkitAudioContext)()
|
| 31 |
+
}
|
| 32 |
+
return audioContext
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
const ChatPanel: FC<Props> = ({ socket, className }) => {
|
| 36 |
const [messages, _setMessages] = useState<ChatMessage[]>([])
|
| 37 |
const [text, setText] = useState("")
|
|
|
|
| 49 |
setMessages([...messagesRef.current, msg].slice(-200))
|
| 50 |
// Play notification sound using Web Audio API
|
| 51 |
try {
|
| 52 |
+
const ctx = getAudioContext()
|
| 53 |
+
const oscillator = ctx.createOscillator()
|
| 54 |
+
const gainNode = ctx.createGain()
|
| 55 |
|
| 56 |
oscillator.connect(gainNode)
|
| 57 |
+
gainNode.connect(ctx.destination)
|
| 58 |
|
| 59 |
+
oscillator.frequency.value = NOTIFICATION_FREQUENCY
|
| 60 |
oscillator.type = 'sine'
|
| 61 |
|
| 62 |
+
gainNode.gain.setValueAtTime(NOTIFICATION_VOLUME, ctx.currentTime)
|
| 63 |
+
gainNode.gain.exponentialRampToValueAtTime(NOTIFICATION_VOLUME_END, ctx.currentTime + NOTIFICATION_DURATION)
|
| 64 |
|
| 65 |
+
oscillator.start(ctx.currentTime)
|
| 66 |
+
oscillator.stop(ctx.currentTime + NOTIFICATION_DURATION)
|
| 67 |
} catch (err) {
|
| 68 |
console.log("Audio notification failed:", err)
|
| 69 |
}
|
pages/api/socketio.ts
CHANGED
|
@@ -11,10 +11,16 @@ import {
|
|
| 11 |
setRoom,
|
| 12 |
} from "../../lib/cache"
|
| 13 |
import { createNewRoom, createNewUser, updateLastSync } from "../../lib/room"
|
| 14 |
-
import { Playlist, RoomState, UserState, ChatMessage } from "../../lib/types"
|
| 15 |
import { isUrl } from "../../lib/utils"
|
| 16 |
import { getDefaultImg, getDefaultSrc } from "../../lib/env"
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
const ioHandler = (_: NextApiRequest, res: NextApiResponse) => {
|
| 19 |
// @ts-ignore
|
| 20 |
if (res.socket !== null && "server" in res.socket && !res.socket.server.io) {
|
|
@@ -314,15 +320,10 @@ const ioHandler = (_: NextApiRequest, res: NextApiResponse) => {
|
|
| 314 |
}
|
| 315 |
|
| 316 |
// Add new video to playlist at position 0
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
sub: [],
|
| 320 |
-
})
|
| 321 |
|
| 322 |
-
room.targetState.playing =
|
| 323 |
-
src: [{ src: url, resolution: "" }],
|
| 324 |
-
sub: [],
|
| 325 |
-
}
|
| 326 |
room.targetState.playlist.currentIndex = 0
|
| 327 |
room.targetState.progress = 0
|
| 328 |
room.targetState.lastSync = new Date().getTime() / 1000
|
|
@@ -341,10 +342,7 @@ const ioHandler = (_: NextApiRequest, res: NextApiResponse) => {
|
|
| 341 |
if (!isUrl(url)) return log("addToPlaylist invalid url", url)
|
| 342 |
log("add to playlist", url)
|
| 343 |
|
| 344 |
-
room.targetState.playlist.items.push(
|
| 345 |
-
src: [{ src: url, resolution: "" }],
|
| 346 |
-
sub: [],
|
| 347 |
-
})
|
| 348 |
|
| 349 |
await broadcast(room)
|
| 350 |
})
|
|
|
|
| 11 |
setRoom,
|
| 12 |
} from "../../lib/cache"
|
| 13 |
import { createNewRoom, createNewUser, updateLastSync } from "../../lib/room"
|
| 14 |
+
import { Playlist, RoomState, UserState, ChatMessage, MediaElement } from "../../lib/types"
|
| 15 |
import { isUrl } from "../../lib/utils"
|
| 16 |
import { getDefaultImg, getDefaultSrc } from "../../lib/env"
|
| 17 |
|
| 18 |
+
// Helper function to create a media element from a URL
|
| 19 |
+
const createMediaElement = (url: string): MediaElement => ({
|
| 20 |
+
src: [{ src: url, resolution: "" }],
|
| 21 |
+
sub: [],
|
| 22 |
+
})
|
| 23 |
+
|
| 24 |
const ioHandler = (_: NextApiRequest, res: NextApiResponse) => {
|
| 25 |
// @ts-ignore
|
| 26 |
if (res.socket !== null && "server" in res.socket && !res.socket.server.io) {
|
|
|
|
| 320 |
}
|
| 321 |
|
| 322 |
// Add new video to playlist at position 0
|
| 323 |
+
const newMedia = createMediaElement(url)
|
| 324 |
+
room.targetState.playlist.items.unshift(newMedia)
|
|
|
|
|
|
|
| 325 |
|
| 326 |
+
room.targetState.playing = newMedia
|
|
|
|
|
|
|
|
|
|
| 327 |
room.targetState.playlist.currentIndex = 0
|
| 328 |
room.targetState.progress = 0
|
| 329 |
room.targetState.lastSync = new Date().getTime() / 1000
|
|
|
|
| 342 |
if (!isUrl(url)) return log("addToPlaylist invalid url", url)
|
| 343 |
log("add to playlist", url)
|
| 344 |
|
| 345 |
+
room.targetState.playlist.items.push(createMediaElement(url))
|
|
|
|
|
|
|
|
|
|
| 346 |
|
| 347 |
await broadcast(room)
|
| 348 |
})
|