207 lines
6.9 KiB
JavaScript
207 lines
6.9 KiB
JavaScript
import React, { useEffect } from 'react';
|
|
import { useAuth } from '../../context/UserAuth';
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
import { fetchUserLatencies } from '../../store/features/latencySlice';
|
|
import { toast } from 'react-toastify';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { useResponsive } from '@farfetch/react-context-responsive';
|
|
import PropTypes from 'prop-types';
|
|
import { Row, Col, Button, UncontrolledTooltip } from 'reactstrap';
|
|
|
|
import jkCustomUrlScheme from '../../helpers/jkCustomUrlScheme';
|
|
|
|
import JKUserLatencyBadge from '../profile/JKUserLatencyBadge';
|
|
import JKSessionUser from './JKSessionUser';
|
|
import useNativeAppCheck from '../../hooks/useNativeAppCheck';
|
|
import { useNativeApp } from '../../context/NativeAppContext';
|
|
import EnterIcon from '../../icons/enter.svg';
|
|
import JKInstrumentIcon from '../profile/JKInstrumentIcon';
|
|
|
|
function JKSession({ session }) {
|
|
const { currentUser } = useAuth();
|
|
const dispatch = useDispatch();
|
|
const { t } = useTranslation();
|
|
const { greaterThan } = useResponsive();
|
|
const { setNativeAppUnavailable } = useNativeApp();
|
|
|
|
useEffect(() => {
|
|
const participantIds = session.participants.map(p => p.user.id);
|
|
const options = { currentUserId: currentUser.id, participantIds };
|
|
dispatch(fetchUserLatencies(options));
|
|
}, [session.id]);
|
|
|
|
const sessionDescription = session => {
|
|
if (session.description) {
|
|
return session.description;
|
|
} else if (session.musician_access && !session.approval_required) {
|
|
return t('list.descriptions.public_open_session', { ns: 'sessions' });
|
|
} else if (session.musician_access && session.approval_required) {
|
|
return t('list.descriptions.private_session', { ns: 'sessions' });
|
|
} else if (!session.musician_access && !session.approval_required) {
|
|
return t('list.descriptions.rsvp_session', { ns: 'sessions' });
|
|
}
|
|
};
|
|
|
|
const invitedNote = session => {
|
|
if (session.invitations.find(i => i.receiver_id === currentUser.id)) {
|
|
return t('list.notes.invited', { ns: 'sessions' });
|
|
}
|
|
};
|
|
|
|
const hasFriendNote = session => {
|
|
if (session.participants.find(p => p.user.is_friend)) {
|
|
return t('list.notes.has_friend', { ns: 'sessions' });
|
|
}
|
|
};
|
|
|
|
const musicianRowStyle = {
|
|
height: '40px',
|
|
flexWrap: 'wrap',
|
|
overflow: 'hidden',
|
|
alignItems: 'center',
|
|
};
|
|
|
|
return (
|
|
<>
|
|
{greaterThan.sm ? (
|
|
<tr key={session.id}>
|
|
<td>
|
|
<div>
|
|
<u>
|
|
<small>
|
|
<strong>{invitedNote(session)}</strong>
|
|
</small>
|
|
</u>
|
|
</div>
|
|
<div>
|
|
<u>
|
|
<small>{hasFriendNote(session)}</small>
|
|
</u>
|
|
</div>
|
|
<div>{sessionDescription(session)}</div>
|
|
</td>
|
|
<td>
|
|
{session.participants.map(participant => (
|
|
<Row style={musicianRowStyle} key={participant.id}>
|
|
<Col>
|
|
<JKSessionUser user={participant.user} />
|
|
</Col>
|
|
</Row>
|
|
))}
|
|
</td>
|
|
<td className="text-center">
|
|
{session.participants.map(participant => (
|
|
<Row key={participant.id} style={musicianRowStyle}>
|
|
<Col>
|
|
<JKUserLatencyBadge key={participant.id} user={participant.user} showBadgeOnly={true} />
|
|
</Col>
|
|
</Row>
|
|
))}
|
|
</td>
|
|
<td>
|
|
{session.participants.map(participant => (
|
|
<Row style={musicianRowStyle} key={participant.id} data-testid={`Participant${participant.id}Tracks`}>
|
|
<Col>
|
|
{participant.tracks.map(track => (
|
|
<span key={track.id} className="mr-1 mb-1" title={track.instrment}>
|
|
<a id={`Participant${participant.id}Track${track.id}Instrument`} data-testid={`Track${track.id}Instrument`}>
|
|
{/* <InstrumentIcon track={track} /> */}
|
|
<JKInstrumentIcon instrumentId={track.instrument_id} instrumentName={track.instrument} />
|
|
</a>
|
|
<UncontrolledTooltip placement="top" target={`Participant${participant.id}Track${track.id}Instrument`}>
|
|
{track.instrument}
|
|
</UncontrolledTooltip>
|
|
</span>
|
|
))}
|
|
</Col>
|
|
</Row>
|
|
))}
|
|
</td>
|
|
<td className="text-center">
|
|
<JoinSessionButton session={session} />
|
|
</td>
|
|
</tr>
|
|
) : (
|
|
<Row>
|
|
<Col>
|
|
<div>
|
|
<u>
|
|
<small>
|
|
<strong>{invitedNote(session)}</strong>
|
|
</small>
|
|
</u>
|
|
</div>
|
|
<div>
|
|
<u>
|
|
<small>{hasFriendNote(session)}</small>
|
|
</u>
|
|
</div>
|
|
<div>{sessionDescription(session)}</div>
|
|
<div className="d-flex flex-row justify-content-between mt-3">
|
|
<div className="ml-2 ms-2">
|
|
<h5>{t('list.header.musicians', { ns: 'sessions' })}</h5>
|
|
</div>
|
|
<div className="ml-2 ms-2">
|
|
<strong>{t('list.header.latency', { ns: 'sessions' })}</strong>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
{session.participants.map(participant => (
|
|
<JKSessionUser key={participant.id} user={participant.user} />
|
|
))}
|
|
</div>
|
|
<div className="mt-4 d-flex flex-row justify-content-center">
|
|
<JoinSessionButton session={session} />
|
|
</div>
|
|
</Col>
|
|
</Row>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
function JoinSessionButton({ session }) {
|
|
const isNativeAppAvailable = useNativeAppCheck();
|
|
const { setNativeAppUnavailable } = useNativeApp();
|
|
const { t } = useTranslation();
|
|
|
|
async function joinSession(e) {
|
|
e.preventDefault();
|
|
if (session.musician_access && session.approval_required) {
|
|
toast.info(t('list.alerts.join_request_sent', { ns: 'sessions' }));
|
|
} else {
|
|
try {
|
|
await isNativeAppAvailable();
|
|
const q = `joinSessionId~${session.id}`;
|
|
const urlScheme = jkCustomUrlScheme('findSession', q);
|
|
window.open(urlScheme, '_blank');
|
|
return;
|
|
} catch (error) {
|
|
setNativeAppUnavailable(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<Button
|
|
data-testid="joinBtn"
|
|
color="primary"
|
|
onClick={joinSession}
|
|
className="btn-join btn-sm mr-1 mb-1 pt-1 pb-1 pl-1 pr-1"
|
|
style={{ cursor: 'pointer' }}
|
|
>
|
|
<img src={EnterIcon} alt="enter" className="mr-1" width={20} />
|
|
</Button>
|
|
<div>
|
|
<a href="#" onClick={joinSession}>Join Session</a>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
|
|
JKSession.propTypes = { session: PropTypes.object.isRequired };
|
|
|
|
export default JKSession;
|