generated from VLADIMIR/template_frontend
up
This commit is contained in:
Binary file not shown.
+20
-19
@@ -44,6 +44,7 @@ import type {
|
||||
TeamResult,
|
||||
Ticket,
|
||||
} from '@/api/generated/crabs/evening_detective_server'
|
||||
import notificationSoundURL from '@/assets/icq-uh-oh.wav'
|
||||
import GameMapPanel from '@/components/GameMapPanel.vue'
|
||||
import GameScreensPanel from '@/components/GameScreensPanel.vue'
|
||||
import GameStatePanel from '@/components/GameStatePanel.vue'
|
||||
@@ -134,6 +135,7 @@ let appliedGameRequestVersion = 0
|
||||
let hasLoadedGame = false
|
||||
let isDisposed = false
|
||||
let notificationAudio: AudioContext | undefined
|
||||
let notificationSound: Promise<AudioBuffer> | undefined
|
||||
let hasReportedSoundError = false
|
||||
const canViewState = computed(
|
||||
() =>
|
||||
@@ -239,30 +241,29 @@ async function enableNotificationSound() {
|
||||
try {
|
||||
notificationAudio ??= new AudioContext()
|
||||
if (notificationAudio.state === 'suspended') await notificationAudio.resume()
|
||||
const audio = notificationAudio
|
||||
notificationSound ??= fetch(notificationSoundURL).then(async (response) => {
|
||||
if (!response.ok) throw new Error('Не удалось загрузить звук уведомления')
|
||||
return audio.decodeAudioData(await response.arrayBuffer())
|
||||
})
|
||||
await notificationSound
|
||||
} catch (error) {
|
||||
notificationSound = undefined
|
||||
reportSoundError(error)
|
||||
}
|
||||
}
|
||||
|
||||
function playApplicationNotification() {
|
||||
async function playApplicationNotification() {
|
||||
// До первого взаимодействия браузер блокирует звук; пропущенные сигналы не накапливаем.
|
||||
if (!notificationAudio || notificationAudio.state !== 'running') return
|
||||
if (!notificationAudio || notificationAudio.state !== 'running' || !notificationSound) return
|
||||
try {
|
||||
const oscillator = notificationAudio.createOscillator()
|
||||
const gain = notificationAudio.createGain()
|
||||
const now = notificationAudio.currentTime
|
||||
oscillator.frequency.value = 880
|
||||
gain.gain.setValueAtTime(0, now)
|
||||
gain.gain.linearRampToValueAtTime(0.1, now + 0.02)
|
||||
gain.gain.linearRampToValueAtTime(0, now + 0.3)
|
||||
oscillator.connect(gain)
|
||||
gain.connect(notificationAudio.destination)
|
||||
oscillator.onended = () => {
|
||||
oscillator.disconnect()
|
||||
gain.disconnect()
|
||||
}
|
||||
oscillator.start(now)
|
||||
oscillator.stop(now + 0.3)
|
||||
const buffer = await notificationSound
|
||||
if (isDisposed || notificationAudio.state !== 'running') return
|
||||
const source = notificationAudio.createBufferSource()
|
||||
source.buffer = buffer
|
||||
source.connect(notificationAudio.destination)
|
||||
source.onended = () => source.disconnect()
|
||||
source.start()
|
||||
} catch (error) {
|
||||
reportSoundError(error)
|
||||
}
|
||||
@@ -270,7 +271,7 @@ function playApplicationNotification() {
|
||||
|
||||
async function testNotificationSound() {
|
||||
await enableNotificationSound()
|
||||
playApplicationNotification()
|
||||
await playApplicationNotification()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@@ -303,7 +304,7 @@ async function getGame(id: number) {
|
||||
hasLoadedGame &&
|
||||
hasNewTeamApplications(game.value.teams || [], res.game?.teams || [])
|
||||
) {
|
||||
playApplicationNotification()
|
||||
void playApplicationNotification()
|
||||
}
|
||||
hasLoadedGame = true
|
||||
game.value = res.game!
|
||||
|
||||
Reference in New Issue
Block a user