import React, { useEffect, useState } from 'react'; import { CopyToClipboard } from 'react-copy-to-clipboard'; import { api, Recording, Room, Restriction, Access, Permission } from '../Common/Api'; import EditRoom from './EditRoom'; import RecordingRow from './RecordingRow'; import EditableValue from './EditableValue'; import { AccessOptions } from '../Common/Translation'; type Props = { room: Room; restriction?: Restriction; updateRoom: (room: Room) => Promise; deleteRoom: (id: number) => void; cloneRoom: (room: Room) => void; } type RecordingsNumberProps = { recordings: null | Recording[]; showRecordings: boolean; setShowRecordings: (showRecordings: boolean) => void; } const RecordingsNumber: React.FC = ({ recordings, showRecordings, setShowRecordings }) => { if (recordings === null) { return ; } if (recordings.length > 0) { return ( setShowRecordings(!showRecordings)}> {showRecordings ? '▾' : '▸'} {recordings.length} ); } return 0; }; const RoomRow: React.FC = (props) => { const [recordings, setRecordings] = useState(null); const [showRecordings, setShowRecordings] = useState(false); const room = props.room; const areRecordingsLoaded = recordings !== null; useEffect(() => { if (areRecordingsLoaded) { return; } api.getRecordings(room.uid).then(recordings => { setRecordings(recordings); }).catch(err => { console.warn('Could not request recordings: ' + room.uid, err); setRecordings([]); }); }, [areRecordingsLoaded]); function updateRoom(key: string, value: string | boolean | number) { return props.updateRoom({ ...props.room, [key]: value, }); } function deleteRow(ev: MouseEvent) { ev.preventDefault(); OC.dialogs.confirm( t('bbb', 'Are you sure you want to delete "{name}"? This operation cannot be undone.', { name: room.name }), t('bbb', 'Delete "{name}"?', { name: room.name }), confirmed => { if (confirmed) { props.deleteRoom(room.id); } }, true ); } function storeRoom() { OC.dialogs.filepicker(t('bbb', 'Select target folder'), (path: string) => { api.storeRoom(room, path).then((filename) => { OC.dialogs.info( t('bbb', 'Room URL was stored in "{path}" as "{filename}".', { path: path + '/', filename }), t('bbb', 'Link stored'), () => undefined, ); }).catch(err => { console.warn('Could not store room', err); OC.dialogs.alert( t('bbb', 'URL to room could not be stored.'), t('bbb', 'Error'), () => undefined ); }); }, undefined, 'httpd/unix-directory'); } function storeRecording(recording: Recording) { OC.dialogs.filepicker(t('bbb', 'Select target folder'), (path: string) => { api.storeRecording(recording, path).then((filename) => { OC.dialogs.info( t('bbb', 'URL to presentation was stored in "{path}" as "{filename}".', { path: path + '/', filename }), t('bbb', 'Link stored'), () => undefined, ); }).catch(err => { console.warn('Could not store recording', err); OC.dialogs.alert( t('bbb', 'URL to presentation could not be stored.'), t('bbb', 'Error'), () => undefined ); }); }, undefined, 'httpd/unix-directory'); } function deleteRecording(recording: Recording) { OC.dialogs.confirm( t('bbb', 'Are you sure you want to delete the recording from "{startDate}"? This operation cannot be undone.', { startDate: (new Date(recording.startTime)).toLocaleString() }), t('bbb', 'Delete?'), confirmed => { if (confirmed) { api.deleteRecording(recording.id).then(success => { if (!success) { OC.dialogs.info( t('bbb', 'Could not delete record'), t('bbb', 'Error'), () => undefined, ); return; } if (recordings === null) { return; } setRecordings(recordings.filter(r => r.id !== recording.id)); }).catch(err => { console.warn('Could not delete recording', err); OC.dialogs.info( t('bbb', 'Could not delete record'), t('bbb', 'Server error'), () => undefined, ); }); } }, true ); } function publishRecording(recording: Recording, publish: boolean) { api.publishRecording(recording.id, publish).then(success=> { if (recordings === null) { return; } setRecordings(recordings.map(recordItem => { if (recordItem.id === recording.id) { recordItem.published = success; recordItem.state = success ? 'published' : 'unpublished'; } return recordItem; })); }).catch(err => { console.warn('Could not modify publishing state', err); OC.dialogs.info( t('bbb', 'Could not modify publishing state'), t('bbb', 'Server error'), () => undefined, ); }); } function accessToIcon(access: string) { switch(access) { case Access.Public: return ; case Access.Password: return ; case Access.Internal: return ; case Access.InternalRestricted: return ; case Access.WaitingRoom: return ; } return ; } function edit(field: string, type: 'text' | 'number' = 'text', canEdit = true, options?) { return canEdit ? : {room[field]}; } function cloneRow() { props.cloneRoom({...props.room}); } const avatarUrl = OC.generateUrl('/avatar/' + encodeURIComponent(room.userId) + '/' + 24, { user: room.userId, size: 24, requesttoken: OC.requestToken, }); const maxParticipantsLimit = props.restriction?.maxParticipants || -1; const minParticipantsLimit = (props.restriction?.maxParticipants || -1) < 1 ? 0 : 1; const adminRoom = room.permission === null || room.permission === Permission.Admin; return ( <> {room.running ? t('bbb', 'Join') : t('bbb', 'Start')} {edit('name', 'text', adminRoom)} {room.userId !== OC.currentUser && Avatar} {(room.userId === OC.currentUser && room.shared) && } {accessToIcon(room.access)} {edit('maxParticipants', 'number', adminRoom, {min: minParticipantsLimit, max: maxParticipantsLimit < 0 ? undefined : maxParticipantsLimit})} updateRoom('record', event.target.checked)} /> {} {adminRoom && } {adminRoom && } {adminRoom && } {showRecordings && {recordings?.sort((r1, r2) => r1.startTime - r2.startTime).map(recording => )}
} ); }; export default RoomRow;