music-app/mobile/app/now-playing.tsx
2026-07-03 01:06:35 +00:00

86 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { View, Text, TouchableOpacity, PanResponder } from 'react-native'
import { useRouter } from 'expo-router'
import { useState, useCallback } from 'react'
import { usePlayerStore } from '../src/store/playerStore'
export default function NowPlayingScreen() {
const router = useRouter()
const currentSong = usePlayerStore(s => s.currentSong)
const isPlaying = usePlayerStore(s => s.isPlaying)
const progress = usePlayerStore(s => s.progress)
const togglePlay = usePlayerStore(s => s.togglePlay)
const toggleShuffle = usePlayerStore(s => s.toggleShuffle)
const next = usePlayerStore(s => s.next)
const previous = usePlayerStore(s => s.previous)
const seek = usePlayerStore(s => s.seek)
const shuffle = usePlayerStore(s => s.shuffle)
const progressPercent = currentSong ? (progress / currentSong.duration) * 100 : 0
const panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onMoveShouldSetPanResponder: () => true,
onPanResponderMove: (evt) => {
if (!currentSong) return
const x = evt.nativeEvent.locationX
const ratio = Math.max(0, Math.min(x / 375, 1))
seek(currentSong.duration * ratio)
},
})
return (
<View className="flex-1 bg-music-black justify-between py-8 px-6" {...panResponder.panHandlers}>
<TouchableOpacity onPress={() => router.back()} className="self-start">
<Text className="text-music-muted text-2xl"></Text>
</TouchableOpacity>
<View className="w-64 h-64 rounded-2xl bg-music-vinyl items-center justify-center self-center">
<Text className="text-6xl">🎵</Text>
</View>
<View className="items-center">
<Text className="text-2xl font-semibold text-music-text">{currentSong?.title || 'No song'}</Text>
<Text className="text-music-muted mt-1">{currentSong?.artist}</Text>
</View>
<View className="w-full">
<View className="h-1 bg-music-border rounded-full">
<View className="h-full bg-music-accent rounded-full" style={{ width: `${progressPercent}%` }} />
</View>
<View className="flex-row justify-between mt-2">
<Text className="text-xs text-music-muted">{formatTime(progress)}</Text>
<Text className="text-xs text-music-muted">{currentSong ? formatTime(currentSong.duration) : '0:00'}</Text>
</View>
</View>
<View className="flex-row items-center justify-center gap-6">
<TouchableOpacity onPress={toggleShuffle}>
<Text className={`${shuffle ? 'text-music-accent' : 'text-music-muted'} text-2xl`}>🔀</Text>
</TouchableOpacity>
<TouchableOpacity onPress={previous}>
<Text className="text-3xl"></Text>
</TouchableOpacity>
<TouchableOpacity onPress={togglePlay}>
<Text className="text-5xl text-music-accent">{isPlaying ? '⏸' : '▶️'}</Text>
</TouchableOpacity>
<TouchableOpacity onPress={next}>
<Text className="text-3xl"></Text>
</TouchableOpacity>
<Text className="text-music-muted text-2xl"></Text>
</View>
<View className="flex-row items-center justify-center gap-2">
<TouchableOpacity onPress={() => router.push('/shareplay' as any)}>
<Text className="text-music-muted">📢</Text>
</TouchableOpacity>
<Text className="text-xs text-music-muted">Speaker</Text>
</View>
</View>
)
}
function formatTime(sec: number): string {
const m = Math.floor(sec / 60)
const s = Math.floor(sec % 60)
return `${m}:${s.toString().padStart(2, '0')}`
}