feat: offline content

This commit is contained in:
gosangam
2026-07-02 21:32:22 +05:30
parent 0b67a1142f
commit 380c23e469
13 changed files with 969 additions and 14 deletions
+25 -5
View File
@@ -18,6 +18,19 @@ import {
syncLocalToRemote,
type ProgressEntry,
} from "@/lib/audio-progress";
import {
primeOfflineAudio,
offlineAudioURL,
releaseOfflineAudio,
} from "@/lib/offline";
/**
* Resolve the media source for a track: prefer a saved offline object URL
* (works with no network + full seeking) and fall back to the remote URL.
*/
function resolveSrc(url: string): string {
return offlineAudioURL(trackKey(url)) ?? url;
}
// ---------------------------------------------------------------------------
// Types
@@ -242,6 +255,13 @@ export function AudioPlayerProvider({ children }: { children: ReactNode }) {
currentIndexRef.current = currentIndex;
}, [currentIndex]);
// Build object URLs for any audio saved offline so `resolveSrc` can prefer
// them synchronously at play time (offline playback + full seeking).
useEffect(() => {
void primeOfflineAudio();
return () => releaseOfflineAudio();
}, []);
// --- Sync volume/muted to the <audio> element ---
useEffect(() => {
const audio = audioRef.current;
@@ -334,7 +354,7 @@ export function AudioPlayerProvider({ children }: { children: ReactNode }) {
setDuration(0);
setIsLoading(true);
if (audio) {
audio.src = nextTrack.url;
audio.src = resolveSrc(nextTrack.url);
audio.load();
audio.play().catch((err) => {
console.error("[AudioPlayer] Auto-play next failed:", err);
@@ -409,7 +429,7 @@ export function AudioPlayerProvider({ children }: { children: ReactNode }) {
setDuration(0);
setIsLoading(true);
audio.src = track.url;
audio.src = resolveSrc(track.url);
audio.load();
audio.play().catch((err) => {
console.error("[AudioPlayer] Play failed:", err);
@@ -438,7 +458,7 @@ export function AudioPlayerProvider({ children }: { children: ReactNode }) {
setDuration(0);
setIsLoading(true);
audio.src = track.url;
audio.src = resolveSrc(track.url);
audio.load();
audio.play().catch((err) => {
console.error("[AudioPlayer] PlayPlaylist failed:", err);
@@ -545,7 +565,7 @@ export function AudioPlayerProvider({ children }: { children: ReactNode }) {
setDuration(0);
setIsLoading(true);
audio.src = nextTrack.url;
audio.src = resolveSrc(nextTrack.url);
audio.load();
audio.play().catch((err) => {
console.error("[AudioPlayer] Next failed:", err);
@@ -587,7 +607,7 @@ export function AudioPlayerProvider({ children }: { children: ReactNode }) {
setDuration(0);
setIsLoading(true);
audio.src = prevTrack.url;
audio.src = resolveSrc(prevTrack.url);
audio.load();
audio.play().catch((err) => {
console.error("[AudioPlayer] Previous failed:", err);