173 lines
5.0 KiB
JavaScript
173 lines
5.0 KiB
JavaScript
import { useAudioStore } from '~/stores/audio'
|
|
import { useUserStore } from '~/stores/user'
|
|
import tracksConfig, { getSoundcapeList } from '~/tracks.config'
|
|
import { useArtWorkManager } from '~/composables/useArtWorkManager'
|
|
|
|
export const usePlayerControls = () => {
|
|
// State Management
|
|
const audio = useAudioStore()
|
|
const userStore = useUserStore()
|
|
const { $changeTrack } = useNuxtApp()
|
|
|
|
const currentIndex = computed(() => getSoundcapeList().indexOf(userStore.user.settings.soundscape))
|
|
const currentSoundscape = computed(() => useUserStore().user.settings.soundscape)
|
|
const playing = computed(() => audio.getPlaying)
|
|
|
|
const togglePlayingState = () => {
|
|
if (playing.value) {
|
|
audio.setPlaying(false)
|
|
} else {
|
|
audio.setPlaying(true)
|
|
}
|
|
}
|
|
|
|
// Listeners
|
|
|
|
const addSpaceListener = () => {
|
|
window.addEventListener('keydown', handleSpace)
|
|
}
|
|
|
|
const removeSpaceListener = () => {
|
|
window.removeEventListener('keydown', null)
|
|
}
|
|
|
|
const addMediaControls = () => {
|
|
for (const [action, handler] of actionHandlers) {
|
|
try {
|
|
navigator.mediaSession.setActionHandler(action, handler)
|
|
} catch (error) {
|
|
useNuxtApp().$logger.error(error)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Helper functions
|
|
const getNextSoundscape = () => {
|
|
const list = getSoundcapeList()
|
|
const current = currentSoundscape.value
|
|
const index = list.indexOf(current)
|
|
|
|
return list[(index + 1) % list.length]
|
|
}
|
|
const getPreviousSoundscape = () => {
|
|
const list = getSoundcapeList()
|
|
const current = currentSoundscape.value
|
|
|
|
const index = list.indexOf(current)
|
|
return list[(index - 1) % list.length]
|
|
}
|
|
|
|
// Handlers
|
|
const handleSpace = (e) => {
|
|
const activeElement = document.activeElement
|
|
const tagName = activeElement.tagName.toLowerCase()
|
|
|
|
// List of elements where spacebar interaction should be preserved
|
|
const interactiveElements = [
|
|
'input', 'textarea', 'button', 'select', 'option',
|
|
'video', 'audio', 'a', 'summary'
|
|
]
|
|
|
|
// Check for contenteditable attribute
|
|
const isContentEditable = activeElement.getAttribute('contenteditable') === 'true'
|
|
|
|
// Check for custom data attribute that might indicate spacebar interaction
|
|
const usesSpacebar = activeElement.getAttribute('data-uses-spacebar') === 'true'
|
|
|
|
if (e.code === 'Space' &&
|
|
!interactiveElements.includes(tagName) &&
|
|
!isContentEditable &&
|
|
!usesSpacebar) {
|
|
e.preventDefault() // Prevent the default action (scrolling)
|
|
|
|
navigator.mediaSession.playbackState = computed(() => (audio.getPlaying || false) ? 'playing' : 'paused').value
|
|
togglePlayingState()
|
|
}
|
|
}
|
|
const handlePlay = () => {
|
|
if (!playing.value) { togglePlayingState() }
|
|
}
|
|
const handlePause = () => {
|
|
if (playing.value) { togglePlayingState() }
|
|
}
|
|
const handleStop = () => {
|
|
if (playing.value) { togglePlayingState() }
|
|
}
|
|
const handleNext = () => {
|
|
if ('mediaSession' in navigator) {
|
|
navigator.mediaSession.setActionHandler('nexttrack', async () => {
|
|
const nextTrack = getNextSoundscape()
|
|
|
|
await $changeTrack(nextTrack)
|
|
useArtWorkManager().addMusicArtWork(nextTrack)
|
|
})
|
|
}
|
|
}
|
|
const handlePrev = () => {
|
|
if ('mediaSession' in navigator) {
|
|
// Set the handler for the next track action
|
|
navigator.mediaSession.setActionHandler('previoustrack', async () => {
|
|
const nextTrack = getNextSoundscape()
|
|
await $changeTrack(nextTrack)
|
|
useArtWorkManager().addMusicArtWork(nextTrack)
|
|
})
|
|
}
|
|
}
|
|
// Set the handler for the previous track action
|
|
const actionHandlers = [
|
|
[
|
|
'play', handlePlay
|
|
],
|
|
[
|
|
'pause', handlePause
|
|
],
|
|
[
|
|
'stop', handleStop
|
|
],
|
|
[
|
|
'nexttrack', handleNext
|
|
],
|
|
[
|
|
'previoustrack', handlePrev
|
|
]
|
|
]
|
|
|
|
const removeMediaNavigationHandling = () => {
|
|
if ('mediaSession' in navigator) {
|
|
// Remove Play action handler
|
|
navigator.mediaSession.setActionHandler('play', null)
|
|
|
|
// Remove Pause action handler
|
|
navigator.mediaSession.setActionHandler('pause', null)
|
|
|
|
// Remove Previous track action handler
|
|
navigator.mediaSession.setActionHandler('previoustrack', null)
|
|
|
|
// Remove Next track action handler
|
|
navigator.mediaSession.setActionHandler('nexttrack', null)
|
|
}
|
|
}
|
|
const addPlayPauseHandling = () => {
|
|
if ('mediaSession' in navigator) {
|
|
// Previous track action
|
|
navigator.mediaSession.setActionHandler('previoustrack', () => {
|
|
this.skipTo(this.playlist.index - 1)
|
|
// useNuxtApp().$logger.log('Previous track button pressed')
|
|
})
|
|
// Next track action
|
|
navigator.mediaSession.setActionHandler('nexttrack', () => {
|
|
// Your next track action here
|
|
this.skipTo(this.playlist.index + 1)
|
|
// useNuxtApp().$logger.log('Next track button pressed')
|
|
})
|
|
}
|
|
}
|
|
|
|
return {
|
|
addSpaceListener,
|
|
addMediaControls,
|
|
getNextSoundscape,
|
|
getPreviousSoundscape
|
|
}
|
|
}
|