jeffsi-meet/react/features/shared-music/components/web/SharedMusicTile.tsx

110 lines
3.8 KiB
TypeScript

import React, { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { IReduxState } from '../../../app/types';
import { IconPlay, IconStop } from '../../../base/icons/svg';
import { getLocalParticipant } from '../../../base/participants/functions';
import { setSharedMusicStatus } from '../../actions';
import { PLAYBACK_STATUSES, SOURCE_TYPES } from '../../constants';
import { isSharingStatus } from '../../functions';
import SharedMusicPlayer from './SharedMusicPlayer';
interface IProps {
/**
* The participant ID (music URL).
*/
participantId: string;
}
/**
* Component that renders a shared music tile with the actual video player.
* This is displayed in the filmstrip thumbnail for shared music.
*
* @param {IProps} props - The component props.
* @returns {React.ReactElement | null}
*/
const SharedMusicTile: React.FC<IProps> = ({ participantId }) => {
const dispatch = useDispatch();
const { musicUrl, ownerId, status, sourceType, time, title } = useSelector(
(state: IReduxState) => state['features/shared-music']
);
const localParticipant = useSelector((state: IReduxState) => getLocalParticipant(state));
const isOwner = ownerId === localParticipant?.id;
const isMusicShared = isSharingStatus(status ?? '');
const isPlaying = status === PLAYBACK_STATUSES.PLAYING;
const isYouTube = sourceType === SOURCE_TYPES.YOUTUBE;
const handlePlayPause = useCallback((e: React.MouseEvent) => {
e.stopPropagation(); // Prevent thumbnail click from pinning
if (!isOwner || !musicUrl) {
return; // Only owner can control playback, and musicUrl must exist
}
const newStatus = isPlaying ? PLAYBACK_STATUSES.PAUSED : PLAYBACK_STATUSES.PLAYING;
dispatch(setSharedMusicStatus({
musicUrl,
status: newStatus,
time: time ?? 0,
ownerId,
sourceType
}));
}, [ dispatch, isOwner, isPlaying, musicUrl, ownerId, sourceType, time ]);
if (!isMusicShared || participantId !== musicUrl) {
return null;
}
return (
<div className = 'shared-music-tile'>
{/* Render the actual player for YouTube videos */}
{isYouTube ? (
<div className = 'shared-music-player-wrapper'>
<SharedMusicPlayer />
</div>
) : (
/* For audio-only, show a background with controls */
<div className = 'shared-music-audio-bg'>
<SharedMusicPlayer />
</div>
)}
{/* Overlay with title and controls for non-owners */}
<div className = 'shared-music-controls-overlay'>
{/* Title */}
<div className = 'shared-music-title'>
{title || 'Shared Music'}
</div>
{/* Play/Pause button (owner only, shown when YouTube controls are hidden) */}
{isOwner && !isYouTube && (
<button
aria-label = { isPlaying ? 'Pause' : 'Play' }
className = 'shared-music-control-button'
onClick = { handlePlayPause }
type = 'button'>
{isPlaying ? (
<IconStop />
) : (
<IconPlay />
)}
</button>
)}
{/* Status indicator for non-owners when not YouTube */}
{!isOwner && !isYouTube && (
<div className = 'shared-music-status'>
{isPlaying ? 'Playing' : 'Paused'}
</div>
)}
</div>
</div>
);
};
export default SharedMusicTile;