Skip to content

Commit 68c656f

Browse files
committed
fix(attempt): media session actions and media key keybinds cause duplicate function calls
1 parent cfe75fb commit 68c656f

1 file changed

Lines changed: 40 additions & 15 deletions

File tree

resources/js/components/video/VideoPlayer.vue

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ let unSub: () => boolean; // Unsub from seek bus
100100
const emit = defineEmits(['loadedData', 'seeked', 'play', 'pause', 'ended', 'loadedMetadata']);
101101
102102
// Global State
103+
// So isAutoPlay determines if the video should auto start, and has no ui toggle
104+
// But isPlaylist determines if should navigate to next video at the end of current video and has a ui toggle called Autoplay ????????????
103105
const { contextMenuItems, contextMenuStyle, contextMenuItemStyle, playbackHeatmap, ambientMode, lightMode, isAutoPlay, isPlaylist } = storeToRefs(useAppStore());
104106
const { updateViewCount } = useContentStore();
105107
const { setContextMenu } = useAppStore();
@@ -320,8 +322,8 @@ const videoPopoverItems = computed(() => {
320322
},
321323
},
322324
{
323-
text: 'Autoplay',
324-
title: 'Toggle Autoplay',
325+
text: 'Playlist',
326+
title: `Toggle auto-playing the next ${isAudio.value ? 'track' : 'video'}`,
325327
icon: MagePlaylist,
326328
selectedIcon: ProiconsCheckmark,
327329
selected: isPlaylist.value ?? false,
@@ -477,7 +479,6 @@ const onPlayerPlay = async (override = false, recordProgress = true) => {
477479
onPlayerPause();
478480
return;
479481
} */
480-
481482
const playRequestId = ++latestPlayRequestId.value;
482483
try {
483484
isAutoPlay.value = false;
@@ -869,23 +870,42 @@ const handleLoadUrlTime = async () => {
869870
handleManualSeek(seconds);
870871
};
871872
872-
const handleNext = (useAutoPlay = isAudio.value) => {
873+
const handleNext = (useAutoPlay = isAudio.value || (!!isPlaylist.value && !isPaused.value)) => {
873874
if (!nextVideoURL.value) {
875+
console.trace('end of list');
874876
toast('Reached end of playlist');
875877
return;
876878
}
877879
isAutoPlay.value = useAutoPlay;
878880
router.push(nextVideoURL.value);
879881
};
880882
881-
const handlePrevious = (useAutoPlay = isAudio.value) => {
882-
if (!previousVideoURL.value) return;
883+
const handlePrevious = (useAutoPlay = isAudio.value || (!!isPlaylist.value && !isPaused.value)) => {
884+
if (!previousVideoURL.value) {
885+
toast('Reached start of playlist');
886+
return;
887+
}
883888
isAutoPlay.value = useAutoPlay;
884889
router.push(previousVideoURL.value);
885890
};
886891
892+
/**
893+
* Media key handler for playing and pausing the player.
894+
* @param explicitAction depending on the source (keybind or media session) explictly play / pause or simply toggle
895+
*/
896+
const handlePlayPause = (explicitAction?: 'play' | 'pause') => {
897+
if (explicitAction === 'play') onPlayerPlay();
898+
else if (explicitAction === 'pause') onPlayerPause();
899+
else handlePlayerToggle();
900+
};
901+
902+
// Debounced actions shared by keybinds and media session action handlers
903+
const debouncedHandleNext = debounce(handleNext, 50, { leading: true, trailing: false });
904+
const debouncedHandlePrevious = debounce(handlePrevious, 50, { leading: true, trailing: false });
905+
const debouncedHandlePlayPause = debounce(handlePlayPause, 50, { leading: true, trailing: false });
906+
887907
const handleKeyBinds = (event: KeyboardEvent, override = false) => {
888-
const keyBinds = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'l', 'N', 'j', 'k', 'm', 'c', ' ', 'f', 'MediaTrackNext', 'MediaTrackPrevious', 'MediaPlayPause'];
908+
const keyBinds = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'l', 'N', 'P', 'j', 'k', 'm', 'c', ' ', 'f', 'MediaTrackNext', 'MediaTrackPrevious', 'MediaPlayPause'];
889909
890910
if (!keyBinds.includes(event.key)) return;
891911
if (isInputLikeElement(event.target, event.key) && !override) return;
@@ -901,7 +921,11 @@ const handleKeyBinds = (event: KeyboardEvent, override = false) => {
901921
break;
902922
case 'N':
903923
if (!event.shiftKey) return;
904-
handleNext(false);
924+
handleNext();
925+
break;
926+
case 'P':
927+
if (!event.shiftKey) return;
928+
handlePrevious();
905929
break;
906930
case 'm':
907931
handleMute();
@@ -913,7 +937,7 @@ const handleKeyBinds = (event: KeyboardEvent, override = false) => {
913937
case ' ':
914938
case 'MediaPlayPause':
915939
event.preventDefault();
916-
handlePlayerToggle();
940+
debouncedHandlePlayPause();
917941
break;
918942
case 'f':
919943
handleFullScreen();
@@ -928,11 +952,11 @@ const handleKeyBinds = (event: KeyboardEvent, override = false) => {
928952
break;
929953
case 'MediaTrackNext':
930954
event.preventDefault();
931-
handleNext();
955+
debouncedHandleNext();
932956
break;
933957
case 'MediaTrackPrevious':
934958
event.preventDefault();
935-
handlePrevious();
959+
debouncedHandlePrevious();
936960
break;
937961
default:
938962
break;
@@ -942,15 +966,16 @@ const handleKeyBinds = (event: KeyboardEvent, override = false) => {
942966
const handleMediaSessionEvents = () => {
943967
if (!('mediaSession' in navigator)) {
944968
console.warn('Media Session API is not supported in this browser.');
969+
isMediaSession.value = false;
945970
return;
946971
}
947972
isMediaSession.value = true;
948973
navigator.mediaSession.setActionHandler('play', () => {
949-
onPlayerPlay();
974+
debouncedHandlePlayPause('play');
950975
});
951976
952977
navigator.mediaSession.setActionHandler('pause', () => {
953-
onPlayerPause();
978+
debouncedHandlePlayPause('pause');
954979
});
955980
956981
navigator.mediaSession.setActionHandler('seekbackward', () => {
@@ -962,11 +987,11 @@ const handleMediaSessionEvents = () => {
962987
});
963988
964989
navigator.mediaSession.setActionHandler('previoustrack', () => {
965-
handlePrevious();
990+
debouncedHandlePrevious();
966991
});
967992
968993
navigator.mediaSession.setActionHandler('nexttrack', () => {
969-
handleNext();
994+
debouncedHandleNext();
970995
});
971996
972997
navigator.mediaSession.setActionHandler('seekto', (details: MediaSessionActionDetails) => {

0 commit comments

Comments
 (0)