feat: add opt-in procedural drive audio
This commit is contained in:
@@ -1,18 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { AudioUiState } from '@/audio/types';
|
||||
import type { MotionPolicy, QualityTier } from '@/journey/motion-policy';
|
||||
|
||||
const props = defineProps<{
|
||||
const props = withDefaults(defineProps<{
|
||||
policy: MotionPolicy;
|
||||
maximumQuality: QualityTier;
|
||||
sceneStatus: string;
|
||||
}>();
|
||||
audioState?: AudioUiState;
|
||||
audioMuted?: boolean;
|
||||
audioVolume?: number;
|
||||
}>(), {
|
||||
audioState: () => ({ kind: 'idle' }),
|
||||
audioMuted: false,
|
||||
audioVolume: 0.4,
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
pause: [];
|
||||
resume: [];
|
||||
enable: [];
|
||||
qualityChange: [quality: QualityTier];
|
||||
audioStart: [];
|
||||
audioResume: [];
|
||||
audioMuteToggle: [];
|
||||
audioVolumeChange: [volume: number];
|
||||
}>();
|
||||
|
||||
const action = computed(() => {
|
||||
@@ -45,11 +57,51 @@ const changeQuality = (event: Event): void => {
|
||||
emit('qualityChange', value);
|
||||
}
|
||||
};
|
||||
|
||||
const changeVolume = (event: Event): void => {
|
||||
emit('audioVolumeChange', Number((event.currentTarget as HTMLInputElement).value));
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="drive-controls">
|
||||
<button v-if="action" type="button" @click="runAction">{{ action.label }}</button>
|
||||
<div v-if="audioState.kind === 'idle'" class="drive-controls__audio-start">
|
||||
<button type="button" @click="emit('audioStart')">START THE DRIVE</button>
|
||||
<span>Enables the interactive soundtrack.</span>
|
||||
</div>
|
||||
<div v-else-if="audioState.kind === 'starting'" class="drive-controls__audio-start" aria-live="polite">
|
||||
<button type="button" disabled>Starting drive…</button>
|
||||
<span>Preparing the interactive soundtrack.</span>
|
||||
</div>
|
||||
<p v-else-if="audioState.kind === 'failed'" class="drive-controls__audio-status" role="status">
|
||||
Audio unavailable. Continue without sound.
|
||||
</p>
|
||||
<div
|
||||
v-else-if="audioState.kind === 'running' || audioState.kind === 'suspended'"
|
||||
class="drive-controls__audio"
|
||||
>
|
||||
<button
|
||||
v-if="audioState.kind === 'suspended' && audioState.resumeRequiresGesture"
|
||||
type="button"
|
||||
@click="emit('audioResume')"
|
||||
>Resume sound</button>
|
||||
<button type="button" @click="emit('audioMuteToggle')">
|
||||
{{ audioMuted ? 'Unmute sound' : 'Mute sound' }}
|
||||
</button>
|
||||
<label>
|
||||
<span>Sound volume</span>
|
||||
<input
|
||||
aria-label="Sound volume"
|
||||
type="range"
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.05"
|
||||
:value="audioVolume"
|
||||
@input="changeVolume"
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
<label>
|
||||
<span>Quality</span>
|
||||
<select :value="maximumQuality" aria-label="Quality control" @change="changeQuality">
|
||||
|
||||
Reference in New Issue
Block a user