refactor: split soundtrack chapter and drive commands
This commit is contained in:
@@ -14,6 +14,7 @@ import SiteNavigation from './SiteNavigation.vue';
|
||||
import ToolkitGrid from './ToolkitGrid.vue';
|
||||
import { useAdaptiveQuality } from '@/composables/useAdaptiveQuality';
|
||||
import { useAudioEngine } from '@/composables/useAudioEngine';
|
||||
import { useAudioIntent } from '@/composables/useAudioIntent';
|
||||
import { useJourneySections } from '@/composables/useJourneySections';
|
||||
import { useKeyboardNavigation } from '@/composables/useKeyboardNavigation';
|
||||
import { useMotionPreferences } from '@/composables/useMotionPreferences';
|
||||
@@ -21,7 +22,7 @@ import { assetUrl } from '@/content/asset-url';
|
||||
import type { PortfolioContent, PublicAssetManifest, SectionId, SectionLayout } from '@/content/types';
|
||||
import type { SceneHostState } from '@/composables/useSceneController';
|
||||
import type { MotionPolicy } from '@/journey/motion-policy';
|
||||
import type { SoundtrackSources } from '@/audio/types';
|
||||
import type { AudioSourceVariant, SoundtrackSources } from '@/audio/types';
|
||||
|
||||
declare const __PORTFOLIO_TEST_BUILD__: boolean;
|
||||
const TEST_BUILD = typeof __PORTFOLIO_TEST_BUILD__ !== 'undefined' && __PORTFOLIO_TEST_BUILD__;
|
||||
@@ -65,43 +66,30 @@ const journeyBinding = useJourneySections(
|
||||
computed(() => motion.policy.value.allowSceneRequest),
|
||||
);
|
||||
const journey = journeyBinding.snapshot;
|
||||
const pendingAudioDestination = shallowRef<SectionId | null>(null);
|
||||
let audioNavigationEpoch = -1;
|
||||
watch(
|
||||
[navigation.state, () => journey.value.activeSectionId],
|
||||
([navigationState, activeSectionId]) => {
|
||||
if (navigationState.epoch !== audioNavigationEpoch) {
|
||||
audioNavigationEpoch = navigationState.epoch;
|
||||
pendingAudioDestination.value = navigationState.source === 'passive-scroll'
|
||||
? null
|
||||
: navigationState.destinationId;
|
||||
}
|
||||
if (pendingAudioDestination.value === activeSectionId) {
|
||||
pendingAudioDestination.value = null;
|
||||
}
|
||||
},
|
||||
{ flush: 'sync', immediate: true },
|
||||
);
|
||||
const audioSectionId = computed(() => (
|
||||
pendingAudioDestination.value ?? journey.value.activeSectionId
|
||||
));
|
||||
const audioIntent = useAudioIntent({
|
||||
canonicalIds: canonicalSectionIds,
|
||||
journey: journeyBinding,
|
||||
navigation: navigation.state,
|
||||
});
|
||||
const variants = (
|
||||
sources: { readonly opusAssetId: string; readonly mp3AssetId: string },
|
||||
): readonly AudioSourceVariant[] => [
|
||||
{ url: assetUrl(props.manifest, sources.opusAssetId), mediaType: 'audio/ogg' },
|
||||
{ url: assetUrl(props.manifest, sources.mp3AssetId), mediaType: 'audio/mpeg' },
|
||||
];
|
||||
const soundtrackSources = computed<SoundtrackSources | null>(() => {
|
||||
const soundtrack = props.content.soundtrack;
|
||||
if (soundtrack === undefined) return null;
|
||||
return {
|
||||
intro: [
|
||||
{ url: assetUrl(props.manifest, soundtrack.intro.opusAssetId), mediaType: 'audio/ogg' },
|
||||
{ url: assetUrl(props.manifest, soundtrack.intro.mp3AssetId), mediaType: 'audio/mpeg' },
|
||||
],
|
||||
main: [
|
||||
{ url: assetUrl(props.manifest, soundtrack.main.opusAssetId), mediaType: 'audio/ogg' },
|
||||
{ url: assetUrl(props.manifest, soundtrack.main.mp3AssetId), mediaType: 'audio/mpeg' },
|
||||
],
|
||||
intro: variants(soundtrack.intro),
|
||||
main: variants(soundtrack.main),
|
||||
afterglow: variants(soundtrack.afterglow),
|
||||
driveLift: variants(soundtrack.driveLift),
|
||||
};
|
||||
});
|
||||
const audio = useAudioEngine({
|
||||
activeSectionId: audioSectionId,
|
||||
intensity: computed(() => journey.value.acceleration),
|
||||
chapter: audioIntent.chapter,
|
||||
drive: audioIntent.drive,
|
||||
soundtrack: soundtrackSources,
|
||||
volume: motion.volume,
|
||||
setVolume: motion.setVolume,
|
||||
|
||||
Reference in New Issue
Block a user