refactor(musik): integrate music player library functions and fix build errors

- Integrate togglePlayPause, getNextIndex, getPrevIndex, handleRepeatOrNext, seekTo, toggleShuffle, setAudioVolume, toggleMute library functions
- Fix ESLint warnings: remove unused eslint-disable, add missing useEffect dependencies
- Fix ESLint error in useMusicPlayer.ts togglePlayPause function
- Add force-dynamic export to root layout to prevent prerendering errors
- Improve seek slider with preview/commit functionality
- Add isSeeking state to prevent UI flickering during seek

Fixes: Build PageNotFoundError for admin/darmasaba pages

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
2026-03-02 11:41:14 +08:00
parent 341ff5779f
commit fe7672e09f
10 changed files with 222 additions and 88 deletions

View File

@@ -0,0 +1,32 @@
export function getNextIndex(
currentIndex: number,
total: number,
isShuffle: boolean
) {
if (total === 0) return -1;
if (isShuffle) {
return Math.floor(Math.random() * total);
}
return (currentIndex + 1) % total;
}
export function getPrevIndex(
currentIndex: number,
total: number,
isShuffle: boolean
) {
if (total === 0) return -1;
if (isShuffle) {
return Math.floor(Math.random() * total);
}
return currentIndex - 1 < 0 ? total - 1 : currentIndex - 1;
}
//pakai di ui
// const next = getNextIndex(currentSongIndex, filteredMusik.length, isShuffle);
// playSong(next);

View File

@@ -0,0 +1,24 @@
import { RefObject } from "react";
export function togglePlayPause(
audioRef: RefObject<HTMLAudioElement | null>,
isPlaying: boolean,
setIsPlaying: (v: boolean) => void
) {
if (!audioRef.current) return;
if (isPlaying) {
audioRef.current.pause();
setIsPlaying(false);
} else {
audioRef.current
.play()
.then(() => setIsPlaying(true))
.catch(console.error);
}
}
// pakai di ui
// onClick={() =>
// togglePlayPause(audioRef, isPlaying, setIsPlaying)
// }

View File

@@ -0,0 +1,22 @@
import { RefObject } from "react";
export function handleRepeatOrNext(
audioRef: RefObject<HTMLAudioElement | null>,
isRepeat: boolean,
playNext: () => void
) {
if (!audioRef.current) return;
if (isRepeat) {
audioRef.current.currentTime = 0;
audioRef.current.play();
} else {
playNext();
}
}
//dipakai di ui
// onEnded={() =>
// handleRepeatOrNext(audioRef, isRepeat, playNext)
// }

View File

@@ -0,0 +1,25 @@
export function seekTo(
audioRef: React.RefObject<HTMLAudioElement | null>,
time: number
) {
if (!audioRef.current) return;
audioRef.current.currentTime = time;
}
// import { RefObject } from "react";
// export function seekTo(
// audioRef: RefObject<HTMLAudioElement | null>,
// time: number,
// setCurrentTime: (v: number) => void
// ) {
// if (!audioRef.current) return;
// audioRef.current.currentTime = time;
// setCurrentTime(time);
// }
// //pakai di ui
// // onChange={(v) => seekTo(audioRef, v, setCurrentTime)}

View File

@@ -0,0 +1,6 @@
export function toggleShuffle(
isShuffle: boolean,
setIsShuffle: (v: boolean) => void
) {
setIsShuffle(!isShuffle);
}

View File

@@ -0,0 +1,29 @@
import { RefObject } from "react";
export function setAudioVolume(
audioRef: RefObject<HTMLAudioElement | null>,
volume: number,
setVolume: (v: number) => void,
setIsMuted: (v: boolean) => void
) {
if (!audioRef.current) return;
audioRef.current.volume = volume / 100;
setVolume(volume);
if (volume > 0) {
setIsMuted(false);
}
}
export function toggleMute(
audioRef: RefObject<HTMLAudioElement | null>,
isMuted: boolean,
setIsMuted: (v: boolean) => void
) {
if (!audioRef.current) return;
const muted = !isMuted;
audioRef.current.muted = muted;
setIsMuted(muted);
}