fix: Resolve scrolling and audio playback issues
- Fix scrolling on Music Storage page by adding proper overflow handling - Add height constraints and flex layout for better tab panel scrolling - Update streaming endpoint to use presigned URLs instead of direct URLs - Improve audio error handling with better error messages - Update MusicPlayer component with dark theme styling - Add loading indicators and error states for better UX - Fix audio playback for files synced from S3 subdirectories The Music Storage page now has proper scrolling behavior and audio playback should work correctly for all music files.
This commit is contained in:
parent
3317a69004
commit
1bb1f7d0d5
@ -235,10 +235,11 @@ router.get('/:id/stream', async (req, res) => {
|
||||
return res.status(404).json({ error: 'Music file not found' });
|
||||
}
|
||||
|
||||
const streamingUrl = await s3Service.getStreamingUrl(musicFile.s3Key);
|
||||
// Use presigned URL for secure access instead of direct URL
|
||||
const presignedUrl = await s3Service.getPresignedUrl(musicFile.s3Key, 3600); // 1 hour expiry
|
||||
|
||||
res.json({
|
||||
streamingUrl,
|
||||
streamingUrl: presignedUrl,
|
||||
musicFile,
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@ -185,7 +185,7 @@ export const MusicPlayer: React.FC<MusicPlayerProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<VStack spacing={4} align="stretch" w="full" p={4} bg="gray.50" borderRadius="lg">
|
||||
<VStack spacing={4} align="stretch" w="full" p={4} bg="gray.800" borderRadius="lg" borderColor="gray.700" borderWidth="1px">
|
||||
{/* Audio element */}
|
||||
<audio
|
||||
ref={audioRef}
|
||||
@ -197,21 +197,23 @@ export const MusicPlayer: React.FC<MusicPlayerProps> = ({
|
||||
console.error('Audio error:', e);
|
||||
toast({
|
||||
title: 'Playback Error',
|
||||
description: 'Failed to play audio file',
|
||||
description: 'Failed to play audio file. The file may be corrupted or the streaming URL may have expired.',
|
||||
status: 'error',
|
||||
duration: 3000,
|
||||
duration: 5000,
|
||||
isClosable: true,
|
||||
});
|
||||
}}
|
||||
onLoadStart={() => setIsLoading(true)}
|
||||
onCanPlay={() => setIsLoading(false)}
|
||||
/>
|
||||
|
||||
{/* Track info */}
|
||||
<VStack spacing={1} align="center">
|
||||
<Text fontWeight="bold" fontSize="lg" noOfLines={1}>
|
||||
<Text fontWeight="bold" fontSize="lg" noOfLines={1} color="white">
|
||||
{musicFile.title || musicFile.originalName}
|
||||
</Text>
|
||||
{musicFile.artist && (
|
||||
<Text fontSize="sm" color="gray.600" noOfLines={1}>
|
||||
<Text fontSize="sm" color="gray.400" noOfLines={1}>
|
||||
{musicFile.artist}
|
||||
</Text>
|
||||
)}
|
||||
@ -230,13 +232,14 @@ export const MusicPlayer: React.FC<MusicPlayerProps> = ({
|
||||
onChange={handleSeek}
|
||||
isDisabled={isLoading}
|
||||
size="sm"
|
||||
colorScheme="blue"
|
||||
>
|
||||
<SliderTrack>
|
||||
<SliderFilledTrack />
|
||||
<SliderTrack bg="gray.700">
|
||||
<SliderFilledTrack bg="blue.400" />
|
||||
</SliderTrack>
|
||||
<SliderThumb />
|
||||
<SliderThumb bg="blue.400" />
|
||||
</Slider>
|
||||
<HStack justify="space-between" w="full" fontSize="xs" color="gray.600">
|
||||
<HStack justify="space-between" w="full" fontSize="xs" color="gray.400">
|
||||
<Text>{formatTime(currentTime)}</Text>
|
||||
<Text>{formatTime(duration)}</Text>
|
||||
</HStack>
|
||||
@ -250,6 +253,8 @@ export const MusicPlayer: React.FC<MusicPlayerProps> = ({
|
||||
onClick={skipBackward}
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
color="gray.400"
|
||||
_hover={{ bg: "gray.700" }}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
@ -260,6 +265,7 @@ export const MusicPlayer: React.FC<MusicPlayerProps> = ({
|
||||
colorScheme="blue"
|
||||
isLoading={isLoading}
|
||||
isDisabled={!streamingUrl}
|
||||
_hover={{ bg: "blue.700" }}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
@ -268,6 +274,8 @@ export const MusicPlayer: React.FC<MusicPlayerProps> = ({
|
||||
onClick={skipForward}
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
color="gray.400"
|
||||
_hover={{ bg: "gray.700" }}
|
||||
/>
|
||||
</HStack>
|
||||
|
||||
@ -279,21 +287,40 @@ export const MusicPlayer: React.FC<MusicPlayerProps> = ({
|
||||
onClick={toggleMute}
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
color="gray.400"
|
||||
_hover={{ bg: "gray.700" }}
|
||||
/>
|
||||
|
||||
<Slider
|
||||
value={isMuted ? 0 : volume}
|
||||
onChange={handleVolumeChange}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.1}
|
||||
onChange={handleVolumeChange}
|
||||
size="sm"
|
||||
w="100px"
|
||||
colorScheme="blue"
|
||||
>
|
||||
<SliderTrack>
|
||||
<SliderFilledTrack />
|
||||
<SliderTrack bg="gray.700">
|
||||
<SliderFilledTrack bg="blue.400" />
|
||||
</SliderTrack>
|
||||
<SliderThumb />
|
||||
<SliderThumb bg="blue.400" />
|
||||
</Slider>
|
||||
</HStack>
|
||||
|
||||
{/* Loading indicator */}
|
||||
{isLoading && (
|
||||
<Text fontSize="sm" color="gray.500" textAlign="center">
|
||||
Loading audio...
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{/* Error state */}
|
||||
{!streamingUrl && (
|
||||
<Text fontSize="sm" color="red.400" textAlign="center">
|
||||
Unable to load audio file
|
||||
</Text>
|
||||
)}
|
||||
</VStack>
|
||||
);
|
||||
};
|
||||
@ -178,6 +178,8 @@ export const MusicStorage: React.FC = () => {
|
||||
minH="100vh"
|
||||
bg="gray.900"
|
||||
color="gray.100"
|
||||
overflowY="auto"
|
||||
height="100vh"
|
||||
>
|
||||
<VStack spacing={6} align="stretch">
|
||||
<Heading size="lg" textAlign="center" color="white">
|
||||
@ -195,8 +197,8 @@ export const MusicStorage: React.FC = () => {
|
||||
</Box>
|
||||
</Alert>
|
||||
|
||||
<Tabs variant="enclosed" colorScheme="blue">
|
||||
<TabList bg="gray.800" borderColor="gray.700">
|
||||
<Tabs variant="enclosed" colorScheme="blue" height="calc(100vh - 200px)" display="flex" flexDirection="column">
|
||||
<TabList bg="gray.800" borderColor="gray.700" flexShrink={0}>
|
||||
<Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
|
||||
Upload Music
|
||||
</Tab>
|
||||
@ -211,9 +213,9 @@ export const MusicStorage: React.FC = () => {
|
||||
</Tab>
|
||||
</TabList>
|
||||
|
||||
<TabPanels>
|
||||
<TabPanels flex={1} overflow="hidden">
|
||||
{/* Upload Tab */}
|
||||
<TabPanel bg="gray.900">
|
||||
<TabPanel bg="gray.900" height="100%" overflowY="auto">
|
||||
<VStack spacing={6} align="stretch">
|
||||
<Box>
|
||||
<Heading size="md" mb={4} color="white">
|
||||
@ -229,7 +231,7 @@ export const MusicStorage: React.FC = () => {
|
||||
</TabPanel>
|
||||
|
||||
{/* Library Tab */}
|
||||
<TabPanel bg="gray.900">
|
||||
<TabPanel bg="gray.900" height="100%" overflowY="auto">
|
||||
<VStack spacing={4} align="stretch">
|
||||
<HStack justify="space-between">
|
||||
<Heading size="md" color="white">Music Library</Heading>
|
||||
@ -335,12 +337,12 @@ export const MusicStorage: React.FC = () => {
|
||||
</TabPanel>
|
||||
|
||||
{/* Song Matching Tab */}
|
||||
<TabPanel bg="gray.900">
|
||||
<TabPanel bg="gray.900" height="100%" overflowY="auto">
|
||||
<SongMatching />
|
||||
</TabPanel>
|
||||
|
||||
{/* Player Tab */}
|
||||
<TabPanel bg="gray.900">
|
||||
<TabPanel bg="gray.900" height="100%" overflowY="auto">
|
||||
<VStack spacing={4} align="stretch">
|
||||
<Heading size="md" color="white">Music Player</Heading>
|
||||
{selectedFile ? (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user