{"version":3,"file":"DAudioSongPlayer.vue_vue_type_script_setup_true_lang-6b7954db.js","sources":["../../client/packages/design-system/src/composables/useAudioPlayer.ts","../../client/packages/design-system/src/atoms/DAudioSongPlayer.vue"],"sourcesContent":["import {reactive, inject, ref, onUnmounted, type Ref, nextTick} from \"vue\";\n\nimport {logError} from \"@songfinch/utils/src/error\";\n\nimport type {\n SongTrackingDataType,\n InjectedAudioTrackEvent,\n} from \"@songfinch/types\";\n\n\nconst audioPlayerState = reactive<{\n instances: Map, Ref>;\n}>({\n instances: new Map(),\n});\n\nlet intervalId: number | undefined;\n\nexport type SongMetaObjectType = {\n artist: string;\n genres: string;\n title: string;\n};\n\nexport function useAudioPlayer(src: string, songMetaData: SongMetaObjectType) {\n const audioTrackEvent = inject(\"audioTrackEvent\", null);\n \n const audio = ref(null);\n const isPlaying = ref(false);\n const currentTime = ref(0);\n\n const initAudio = async () => {\n if (!audio.value) {\n audio.value = new Audio(src);\n audio.value.preload = \"auto\";\n audio.value.addEventListener(\"timeupdate\", () => {\n if (audio.value) currentTime.value = audio.value.currentTime;\n });\n }\n };\n\n const hasAudioTrackingEvent = (value: InjectedAudioTrackEvent | null): value is InjectedAudioTrackEvent => {\n if (!value) {\n // TODO hanlde tracking for this commponent (ignore this for now cause its never been setup)\n // logError(\"audioTrackEvent is missing\", {\n // level: \"warning\",\n // extra: {file: \"useAudioPlayer.ts\"},\n // });\n return false;\n }\n return true;\n };\n\n const handlePauseAudioTrackingEvent = (e: MouseEvent | TouchEvent) => {\n if (hasAudioTrackingEvent(audioTrackEvent)) {\n let percentagePlayed;\n if (audio.value?.currentTime && audio.value?.duration) {\n percentagePlayed = Math.round(\n (audio.value?.currentTime / audio.value?.duration) * 100,\n );\n }\n \n const trackingObject: SongTrackingDataType = {\n ...songMetaData,\n time_played: audio.value?.currentTime.toFixed(2) || undefined,\n audio_duration: audio.value?.duration.toFixed(2) || undefined,\n percentage_played: percentagePlayed ? `${percentagePlayed}%` : undefined,\n };\n audioTrackEvent(e, \"audio_paused\", trackingObject);\n }\n };\n \n const handleAudioPlayedTrackingEvent = (e: MouseEvent | TouchEvent) => {\n if (hasAudioTrackingEvent(audioTrackEvent)) {\n audioTrackEvent(e, \"audio_played\", songMetaData);\n }\n };\n\n const play = async (e: MouseEvent | TouchEvent, startTime?: number = 0, endTime?: number) => {\n try {\n await initAudio();\n await nextTick();\n if (!audio.value) return;\n // Stop all other playing instances\n audioPlayerState.instances.forEach((playingRef, audioRef) => {\n if (audioRef.value && audioRef.value !== audio.value && playingRef.value) {\n audioRef.value.pause();\n audioRef.value.currentTime = 0;\n playingRef.value = false;\n }\n });\n\n audio.value.currentTime = startTime;\n await nextTick();\n\n await audio.value.play();\n isPlaying.value = true;\n audioPlayerState.instances.set(audio, isPlaying);\n handleAudioPlayedTrackingEvent(e);\n\n if (endTime !== undefined) {\n if (intervalId !== undefined) {\n clearIntervalAndId();\n }\n\n intervalId = setInterval(() => {\n if (audio.value && audio.value.currentTime >= endTime) {\n audio.value.pause();\n isPlaying.value = false;\n }\n }, 200);\n }\n } catch (error) {\n logError(error, {\n extra: {src, songMetaData}\n });\n }\n };\n\n const clearIntervalAndId = () => {\n if (intervalId !== undefined) {\n clearInterval(intervalId);\n intervalId = undefined;\n }\n };\n\n const pause = (e: MouseEvent | TouchEvent) => {\n if (audio.value && !audio.value.paused) {\n audio.value.pause();\n isPlaying.value = false;\n audioPlayerState.instances.delete(audio);\n handlePauseAudioTrackingEvent(e);\n clearIntervalAndId();\n }\n };\n\n const stop = () => {\n if (audio.value) {\n audio.value.pause();\n audio.value.currentTime = 0;\n isPlaying.value = false;\n audioPlayerState.instances.delete(audio);\n clearIntervalAndId();\n }\n };\n\n \n const playPauseAudio = (e: MouseEvent, startTime?: number, endTime?: endTime) => {\n if (isPlaying.value) {\n pause(e);}\n else {\n play(e, startTime, endTime);\n } \n };\n \n\n onUnmounted(() => {\n if (audio.value) {\n audio.value.pause();\n audio.value.src = \"\";\n audio.value.load();\n }\n\n audioPlayerState.instances.delete(audio);\n });\n\n return {\n play, \n pause, \n playPauseAudio,\n stop, \n isPlaying\n };\n}\n","\n\n"],"names":["audioPlayerState","reactive","intervalId","useAudioPlayer","src","songMetaData","audioTrackEvent","inject","audio","ref","isPlaying","currentTime","initAudio","hasAudioTrackingEvent","value","handlePauseAudioTrackingEvent","e","percentagePlayed","_a","_b","_c","_d","trackingObject","_e","_f","handleAudioPlayedTrackingEvent","play","startTime","endTime","nextTick","playingRef","audioRef","clearIntervalAndId","error","logError","pause","stop","playPauseAudio","onUnmounted","props","__props","normalizedSongMetaObject","genres","isString","isArray","__expose"],"mappings":"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"}