Initial commit
This commit is contained in:
172
composables/usePlayerControls.js
Normal file
172
composables/usePlayerControls.js
Normal file
@@ -0,0 +1,172 @@
|
||||
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
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user