UNPKG

@selfcommunity/react-ui

Version:

React UI Components to integrate a Community created with SelfCommunity Platform.

196 lines (195 loc) • 9.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useLivestreamCheck = void 0; const react_1 = require("react"); const api_services_1 = require("@selfcommunity/api-services"); const components_react_1 = require("@livekit/components-react"); const LiveStreamProvider_1 = require("./LiveStreamProvider"); const notistack_1 = require("notistack"); const react_intl_1 = require("react-intl"); const react_core_1 = require("@selfcommunity/react-core"); const constants_1 = require("../constants"); const livekit_client_1 = require("livekit-client"); const _INITIAL_STATE = { checkStarted: false, timeRemaining: 60, isExpiringSoonAloneInRoom: false, isExpiringSoonMissingHost: false, isExpiringSoonFewMinutesRemaining: false, isExpiredSoonAloneInRoom: false, isExpiredSoonMissingHost: false, isExpiredSoonFewMinutesRemaining: false }; const reducer = (state, action) => { switch (action.type) { case 'startChecking': return Object.assign(Object.assign({}, _INITIAL_STATE), { checkStarted: true }); case 'stopChecking': return Object.assign(Object.assign({}, _INITIAL_STATE), { checkStarted: false }); case 'reset': return Object.assign({}, _INITIAL_STATE); case 'isExpiringSoonAloneInRoom': return Object.assign(Object.assign({}, state), { isExpiringSoonAloneInRoom: action.value }); case 'isExpiringSoonMissingHost': return Object.assign(Object.assign({}, state), { isExpiringSoonMissingHost: action.value }); case 'isExpiringSoonFewMinutesRemaining': return Object.assign(Object.assign({}, state), { isExpiringSoonFewMinutesRemaining: action.value }); case 'isExpiredAloneInRoom': return Object.assign(Object.assign({}, state), { isExpiredAloneInRoom: action.value }); case 'isExpiredSoonMissingHost': return Object.assign(Object.assign({}, state), { isExpiredSoonMissingHost: action.value }); case 'isExpiredSoonFewMinutesRemaining': return Object.assign(Object.assign({}, state), { isExpiredSoonFewMinutesRemaining: action.value }); case 'timeRemaining': return Object.assign(Object.assign({}, state), { timeRemaining: action.value }); default: return Object.assign(Object.assign({}, state), { [action.type]: action.value }); } }; /** * Custom hook for monitoring livestream. * @param {number} warningThreshold * @param showWarnings * @param performDisconnect */ function useLivestreamCheck(warningThreshold = constants_1.WARNING_THRESHOLD_EXPIRING_SOON, showWarnings = true, performDisconnect = true) { // STATE const [state, dispatch] = (0, react_1.useReducer)(reducer, _INITIAL_STATE); const intervalRef = (0, react_1.useRef)(null); // HOOKS const scUserContext = (0, react_core_1.useSCUser)(); const participants = (0, components_react_1.useParticipants)({ updateOnlyOn: [ livekit_client_1.RoomEvent.ParticipantConnected, livekit_client_1.RoomEvent.ParticipantDisconnected, livekit_client_1.RoomEvent.ConnectionStateChanged, livekit_client_1.RoomEvent.Connected, livekit_client_1.RoomEvent.Disconnected, livekit_client_1.RoomEvent.TrackSubscribed, livekit_client_1.RoomEvent.TrackUnsubscribed ] }); const { liveStream } = (0, LiveStreamProvider_1.useLiveStream)(); const { buttonProps } = (0, components_react_1.useDisconnectButton)({}); const { enqueueSnackbar } = (0, notistack_1.useSnackbar)(); const __DEBUG = (0, react_1.useRef)(true); // INTL const intl = (0, react_intl_1.useIntl)(); /** * fetchLivestreamStatus */ const fetchLivestreamStatus = () => { api_services_1.LiveStreamApiClient.getMonthlyDuration() .then((r) => { dispatch({ type: 'timeRemaining', value: r.remaining_minutes }); if (r.remaining_minutes > 0 && r.remaining_minutes <= warningThreshold) { if (!state.isExpiringSoonFewMinutesRemaining && !state.isExpiredSoonFewMinutesRemaining && liveStream.host.id === scUserContext.user.id && showWarnings) { __DEBUG && console.log('Warning: '); enqueueSnackbar(intl.formatMessage({ id: 'ui.liveStreamRoom.check.fewMinutesRemaining', defaultMessage: 'ui.liveStreamRoom.check.fewMinutesRemaining' }), { variant: 'warning', autoHideDuration: 30000 }); dispatch({ type: 'isExpiringSoonFewMinutesRemaining', value: true }); } } else if (r.remaining_minutes <= 0) { __DEBUG && console.log('Livestream expired'); dispatch({ type: 'isExpiredFewMinutesRemaining', value: true }); } else if (state.isExpiredFewMinutesRemaining) { dispatch({ type: 'isExpiringSoonFewMinutesRemaining', value: false }); } }) .catch((error) => { console.error('Error fetching live status:', error); }); }; /** * Check live */ const check = (0, react_1.useCallback)(() => { if (__DEBUG) { console.log('Checking live status'); console.log('Status: ', state); console.log('Checking participants...', participants.length); console.log(participants); } if (participants.length <= 1) { if (!state.isExpiringSoonAloneInRoom && !state.isExpiredAloneInRoom && showWarnings) { __DEBUG && console.log('Set expire soon: you are alone in the room'); enqueueSnackbar(intl.formatMessage({ id: 'ui.liveStreamRoom.check.youAreAloneInTheRoom', defaultMessage: 'ui.liveStreamRoom.check.youAreAloneInTheRoom' }), { variant: 'warning', autoHideDuration: 10000 }); state.isExpiringSoonAloneInRoom ? dispatch({ type: 'isExpiredAloneInRoom', value: true }) : dispatch({ type: 'isExpiringSoonAloneInRoom', value: true }); } else if (performDisconnect && (state.isExpiringSoonAloneInRoom || state.isExpiredAloneInRoom)) { // Leave the room __DEBUG && console.log('Leave the room: no participants'); buttonProps.onClick(); } return; } else if (state.isExpiringSoonAloneInRoom) { __DEBUG && console.log('Reset expire soon'); dispatch({ type: 'isExpiringSoonAloneInRoom', value: false }); } __DEBUG && console.log('Checking live speaker...'); const speaker = participants.find((pt) => { return pt.name === liveStream.host.username; }); if (!speaker) { if (!state.isExpiredSoonMissingHost && !state.isExpiringSoonMissingHost && liveStream.host.id !== scUserContext.user.id && showWarnings) { enqueueSnackbar(intl.formatMessage({ id: 'ui.liveStreamRoom.check.hostMissing', defaultMessage: 'ui.liveStreamRoom.check.hostMissing' }), { variant: 'warning', autoHideDuration: 10000 }); state.isExpiringSoonMissingHost ? dispatch({ type: 'isExpiredSoonMissingHost', value: true }) : dispatch({ type: 'isExpiringSoonMissingHost', value: true }); } else if (performDisconnect && (state.isExpiredSoonMissingHost || state.isExpiringSoonMissingHost)) { // Leave the room __DEBUG && console.log('Leave the room: no host'); buttonProps.onClick(); } } else if (state.isExpiringSoonMissingHost) { dispatch({ type: 'isExpiringSoonMissingHost', value: false }); } __DEBUG && console.log('Checking live status resources...'); fetchLivestreamStatus(); }, [state, buttonProps, participants]); /** * Check live status */ (0, react_1.useEffect)(() => { if (state.checkStarted) { intervalRef.current = setInterval(check, constants_1.LIVE_CHECKING_INTERVAL * 60000); } return () => { intervalRef.current && clearInterval(intervalRef.current); }; }, [state, participants]); /** * Start the checking after a delay */ (0, react_1.useEffect)(() => { let _timeout; if (liveStream) { _timeout = setTimeout(() => { // Start the checking after 5 minutes dispatch({ type: 'startChecking' }); __DEBUG && console.log('Start checking'); }, (liveStream.host.id === scUserContext.user.id ? constants_1.LIVE_CHECKING_INITIAL_DELAY_HOST : constants_1.LIVE_CHECKING_INITIAL_DELAY_GUEST) * 60000); } return () => { _timeout && clearTimeout(_timeout); dispatch({ type: 'stopChecking' }); }; }, [liveStream]); return state; } exports.useLivestreamCheck = useLivestreamCheck;