added more actions and connection list to proctor rooms
This commit is contained in:
		
							parent
							
								
									1d7d15c02c
								
							
						
					
					
						commit
						daebd9b5f7
					
				
					 7 changed files with 221 additions and 86 deletions
				
			
		|  | @ -84,4 +84,29 @@ public class RemoteProctoringRoom { | |||
|         return builder.toString(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int hashCode() { | ||||
|         final int prime = 31; | ||||
|         int result = 1; | ||||
|         result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean equals(final Object obj) { | ||||
|         if (this == obj) | ||||
|             return true; | ||||
|         if (obj == null) | ||||
|             return false; | ||||
|         if (getClass() != obj.getClass()) | ||||
|             return false; | ||||
|         final RemoteProctoringRoom other = (RemoteProctoringRoom) obj; | ||||
|         if (this.id == null) { | ||||
|             if (other.id != null) | ||||
|                 return false; | ||||
|         } else if (!this.id.equals(other.id)) | ||||
|             return false; | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ import org.eclipse.swt.SWT; | |||
| import org.eclipse.swt.layout.GridData; | ||||
| import org.eclipse.swt.layout.GridLayout; | ||||
| import org.eclipse.swt.widgets.Composite; | ||||
| import org.eclipse.swt.widgets.Tree; | ||||
| import org.eclipse.swt.widgets.TreeItem; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | @ -90,6 +91,7 @@ public class MonitoringRunningExam implements TemplateComposer { | |||
|             "}"; | ||||
|     // @formatter:on | ||||
| 
 | ||||
|     private static final String SHOW_CONNECTION_ACTION_APPLIED = "SHOW_CONNECTION_ACTION_APPLIED"; | ||||
|     private static final LocTextKey EMPTY_SELECTION_TEXT_KEY = | ||||
|             new LocTextKey("sebserver.monitoring.exam.connection.emptySelection"); | ||||
|     private static final LocTextKey EMPTY_ACTIVE_SELECTION_TEXT_KEY = | ||||
|  | @ -108,12 +110,14 @@ public class MonitoringRunningExam implements TemplateComposer { | |||
|     private final GuiServiceInfo guiServiceInfo; | ||||
|     private final long pollInterval; | ||||
|     private final String remoteProctoringEndpoint; | ||||
|     private final ProctorRoomConnectionsPopup proctorRoomConnectionsPopup; | ||||
| 
 | ||||
|     protected MonitoringRunningExam( | ||||
|             final ServerPushService serverPushService, | ||||
|             final PageService pageService, | ||||
|             final InstructionProcessor instructionProcessor, | ||||
|             final GuiServiceInfo guiServiceInfo, | ||||
|             final ProctorRoomConnectionsPopup proctorRoomConnectionsPopup, | ||||
|             @Value("${sebserver.gui.webservice.poll-interval:1000}") final long pollInterval, | ||||
|             @Value("${sebserver.gui.remote.proctoring.entrypoint:/remote-proctoring}") final String remoteProctoringEndpoint) { | ||||
| 
 | ||||
|  | @ -124,6 +128,7 @@ public class MonitoringRunningExam implements TemplateComposer { | |||
|         this.guiServiceInfo = guiServiceInfo; | ||||
|         this.pollInterval = pollInterval; | ||||
|         this.remoteProctoringEndpoint = remoteProctoringEndpoint; | ||||
|         this.proctorRoomConnectionsPopup = proctorRoomConnectionsPopup; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -315,10 +320,11 @@ public class MonitoringRunningExam implements TemplateComposer { | |||
|                 .getOr(null); | ||||
| 
 | ||||
|         if (proctoringSettings != null && proctoringSettings.enableProctoring) { | ||||
|             final Map<String, TreeItem> availableRoomNames = new HashMap<>(); | ||||
|             final Map<RemoteProctoringRoom, TreeItem> availableRooms = new HashMap<>(); | ||||
|             updateRoomActions( | ||||
|                     entityKey, | ||||
|                     availableRoomNames, | ||||
|                     pageContext, | ||||
|                     availableRooms, | ||||
|                     actionBuilder, | ||||
|                     proctoringSettings); | ||||
|             this.serverPushService.runServerPush( | ||||
|  | @ -326,7 +332,8 @@ public class MonitoringRunningExam implements TemplateComposer { | |||
|                     5000, | ||||
|                     context -> updateRoomActions( | ||||
|                             entityKey, | ||||
|                             availableRoomNames, | ||||
|                             pageContext, | ||||
|                             availableRooms, | ||||
|                             actionBuilder, | ||||
|                             proctoringSettings)); | ||||
|         } | ||||
|  | @ -334,7 +341,8 @@ public class MonitoringRunningExam implements TemplateComposer { | |||
| 
 | ||||
|     private void updateRoomActions( | ||||
|             final EntityKey entityKey, | ||||
|             final Map<String, TreeItem> rooms, | ||||
|             final PageContext pageContext, | ||||
|             final Map<RemoteProctoringRoom, TreeItem> rooms, | ||||
|             final PageActionBuilder actionBuilder, | ||||
|             final ProctoringSettings proctoringSettings) { | ||||
| 
 | ||||
|  | @ -345,9 +353,9 @@ public class MonitoringRunningExam implements TemplateComposer { | |||
|                 .getOrThrow() | ||||
|                 .stream() | ||||
|                 .forEach(room -> { | ||||
|                     if (rooms.containsKey(room.name)) { | ||||
|                     if (rooms.containsKey(room)) { | ||||
|                         // update action | ||||
|                         final TreeItem treeItem = rooms.get(room.name); | ||||
|                         final TreeItem treeItem = rooms.get(room); | ||||
|                         treeItem.setText(i18nSupport.getText(new LocTextKey( | ||||
|                                 ActionDefinition.MONITOR_EXAM_VIEW_PROCTOR_ROOM.title.name, | ||||
|                                 room.subject, | ||||
|  | @ -367,10 +375,36 @@ public class MonitoringRunningExam implements TemplateComposer { | |||
|                                         .noEventPropagation() | ||||
|                                         .create(); | ||||
| 
 | ||||
|                         this.pageService.publishAction(action, treeItem -> rooms.put(room.name, treeItem)); | ||||
|                         this.pageService.publishAction(action, treeItem -> rooms.put(room, treeItem)); | ||||
| 
 | ||||
|                         // check and add show connections in room action adaptation | ||||
|                         if (!rooms.isEmpty()) { | ||||
|                             final TreeItem treeItem = rooms.values().iterator().next(); | ||||
|                             final Tree tree = treeItem.getParent(); | ||||
|                             if (tree.getData(SHOW_CONNECTION_ACTION_APPLIED) == null) { | ||||
|                                 tree.addListener(SWT.Selection, event -> { | ||||
|                                     final TreeItem item = (TreeItem) event.item; | ||||
|                                     treeItem.getParent().deselectAll(); | ||||
|                                     if (event.button == 3) { | ||||
|                                         rooms.entrySet() | ||||
|                                                 .stream() | ||||
|                                                 .filter(e -> e.getValue().equals(item)) | ||||
|                                                 .findFirst() | ||||
|                                                 .ifPresent(e -> { | ||||
|                                                     final PageContext pc = pageContext.copy() | ||||
|                                                             .clearAttributes() | ||||
|                                                             .withEntityKey(new EntityKey(e.getKey().getName(), | ||||
|                                                                     EntityType.REMOTE_PROCTORING_ROOM)) | ||||
|                                                             .withParentEntityKey(entityKey); | ||||
|                                                     this.proctorRoomConnectionsPopup.show(pc, e.getKey().getSubject()); | ||||
|                                                 }); | ||||
|                                     } | ||||
|                                 }); | ||||
|                                 tree.setData(SHOW_CONNECTION_ACTION_APPLIED, true); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private PageAction showExamProctoringRoom( | ||||
|  |  | |||
|  | @ -0,0 +1,70 @@ | |||
| /* | ||||
|  * Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET) | ||||
|  * | ||||
|  * This Source Code Form is subject to the terms of the Mozilla Public | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| 
 | ||||
| package ch.ethz.seb.sebserver.gui.content; | ||||
| 
 | ||||
| import org.eclipse.swt.SWT; | ||||
| import org.eclipse.swt.widgets.Composite; | ||||
| import org.eclipse.swt.widgets.Label; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.stereotype.Component; | ||||
| 
 | ||||
| import ch.ethz.seb.sebserver.gbl.api.API; | ||||
| import ch.ethz.seb.sebserver.gbl.model.Domain; | ||||
| import ch.ethz.seb.sebserver.gbl.model.EntityKey; | ||||
| import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; | ||||
| import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; | ||||
| import ch.ethz.seb.sebserver.gui.service.page.PageContext; | ||||
| import ch.ethz.seb.sebserver.gui.service.page.PageService; | ||||
| import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog; | ||||
| import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetProctorRoomConnections; | ||||
| 
 | ||||
| @Lazy | ||||
| @Component | ||||
| @GuiProfile | ||||
| public class ProctorRoomConnectionsPopup { | ||||
| 
 | ||||
|     private static final LocTextKey TITLE_TEXT_KEY = | ||||
|             new LocTextKey("sebserver.monitoring.exam.proctoring.room.connections.title"); | ||||
| 
 | ||||
|     private final PageService pageService; | ||||
| 
 | ||||
|     protected ProctorRoomConnectionsPopup(final PageService pageService) { | ||||
|         this.pageService = pageService; | ||||
|     } | ||||
| 
 | ||||
|     public void show(final PageContext pageContext, final String roomSubject) { | ||||
|         final ModalInputDialog<Void> dialog = new ModalInputDialog<>( | ||||
|                 pageContext.getParent().getShell(), | ||||
|                 this.pageService.getWidgetFactory()); | ||||
|         dialog.setLargeDialogWidth(); | ||||
|         dialog.open( | ||||
|                 new LocTextKey(TITLE_TEXT_KEY.name, roomSubject), | ||||
|                 pageContext, | ||||
|                 this::compose); | ||||
|     } | ||||
| 
 | ||||
|     private void compose(final PageContext pageContext) { | ||||
|         final Composite parent = pageContext.getParent(); | ||||
|         final Composite grid = this.pageService.getWidgetFactory().createPopupScrollComposite(parent); | ||||
|         final EntityKey entityKey = pageContext.getEntityKey(); | ||||
|         final EntityKey parentEntityKey = pageContext.getParentEntityKey(); | ||||
| 
 | ||||
|         this.pageService.getRestService().getBuilder(GetProctorRoomConnections.class) | ||||
|                 .withURIVariable(API.PARAM_MODEL_ID, parentEntityKey.modelId) | ||||
|                 .withQueryParam(Domain.REMOTE_PROCTORING_ROOM.ATTR_ID, entityKey.modelId) | ||||
|                 .call() | ||||
|                 .getOrThrow() | ||||
|                 .stream() | ||||
|                 .forEach(connection -> { | ||||
|                     final Label label = new Label(grid, SWT.NONE); | ||||
|                     label.setText(connection.userSessionId); | ||||
|                 }); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -42,19 +42,19 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; | |||
| public class JitsiMeetProctoringView implements RemoteProctoringView { | ||||
| 
 | ||||
|     private static final LocTextKey CLOSE_WINDOW_TEXT_KEY = | ||||
|             new LocTextKey("sebserver.monitoring.exam.action.close"); | ||||
|             new LocTextKey("sebserver.monitoring.exam.proctoring.action.close"); | ||||
|     private static final LocTextKey BROADCAST_AUDIO_ON_TEXT_KEY = | ||||
|             new LocTextKey("sebserver.monitoring.exam.action.broadcaston.audio"); | ||||
|             new LocTextKey("sebserver.monitoring.exam.proctoring.action.broadcaston.audio"); | ||||
|     private static final LocTextKey BROADCAST_AUDIO_OFF_TEXT_KEY = | ||||
|             new LocTextKey("sebserver.monitoring.exam.action.broadcastoff.audio"); | ||||
|             new LocTextKey("sebserver.monitoring.exam.proctoring.action.broadcastoff.audio"); | ||||
|     private static final LocTextKey BROADCAST_VIDEO_ON_TEXT_KEY = | ||||
|             new LocTextKey("sebserver.monitoring.exam.action.broadcaston.video"); | ||||
|             new LocTextKey("sebserver.monitoring.exam.proctoring.action.broadcaston.video"); | ||||
|     private static final LocTextKey BROADCAST_VIDEO_OFF_TEXT_KEY = | ||||
|             new LocTextKey("sebserver.monitoring.exam.action.broadcastoff.video"); | ||||
|             new LocTextKey("sebserver.monitoring.exam.proctoring.action.broadcastoff.video"); | ||||
|     private static final LocTextKey CHAT_ON_TEXT_KEY = | ||||
|             new LocTextKey("sebserver.monitoring.exam.action.broadcaston.chat"); | ||||
|             new LocTextKey("sebserver.monitoring.exam.proctoring.action.broadcaston.chat"); | ||||
|     private static final LocTextKey CHAT_OFF_TEXT_KEY = | ||||
|             new LocTextKey("sebserver.monitoring.exam.action.broadcastoff.chat"); | ||||
|             new LocTextKey("sebserver.monitoring.exam.proctoring.action.broadcastoff.chat"); | ||||
| 
 | ||||
|     private final PageService pageService; | ||||
|     private final GuiServiceInfo guiServiceInfo; | ||||
|  | @ -132,7 +132,8 @@ public class JitsiMeetProctoringView implements RemoteProctoringView { | |||
|         broadcastVideoAction.addListener(SWT.Selection, event -> toggleBroadcastVideo( | ||||
|                 proctoringWindowData.examId, | ||||
|                 proctoringWindowData.connectionData.roomName, | ||||
|                 broadcastVideoAction)); | ||||
|                 broadcastVideoAction, | ||||
|                 broadcastAudioAction)); | ||||
|         broadcastVideoAction.setData(BroadcastActionState.KEY_NAME, broadcastActionState); | ||||
| 
 | ||||
|         final Button chatAction = widgetFactory.buttonLocalized(footer, CHAT_ON_TEXT_KEY); | ||||
|  | @ -172,24 +173,37 @@ public class JitsiMeetProctoringView implements RemoteProctoringView { | |||
|         state.audio = !state.audio; | ||||
|     } | ||||
| 
 | ||||
|     private void toggleBroadcastVideo(final String examId, final String roomName, final Button broadcastAction) { | ||||
|     private void toggleBroadcastVideo( | ||||
|             final String examId, | ||||
|             final String roomName, | ||||
|             final Button videoAction, | ||||
|             final Button audioAction) { | ||||
|         final BroadcastActionState state = | ||||
|                 (BroadcastActionState) broadcastAction.getData(BroadcastActionState.KEY_NAME); | ||||
|                 (BroadcastActionState) videoAction.getData(BroadcastActionState.KEY_NAME); | ||||
|         if (state.video) { | ||||
|             this.pageService.getPolyglotPageService().injectI18n(broadcastAction, BROADCAST_VIDEO_ON_TEXT_KEY); | ||||
|             this.pageService.getPolyglotPageService().injectI18n(audioAction, BROADCAST_AUDIO_ON_TEXT_KEY); | ||||
|             this.pageService.getPolyglotPageService().injectI18n(videoAction, BROADCAST_VIDEO_ON_TEXT_KEY); | ||||
| 
 | ||||
|             this.pageService.getRestService().getBuilder(SendProctoringBroadcastOffInstruction.class) | ||||
|                     .withURIVariable(API.PARAM_MODEL_ID, examId) | ||||
|                     .withFormParam(Domain.REMOTE_PROCTORING_ROOM.ATTR_ID, roomName) | ||||
|                     .withFormParam( | ||||
|                             ClientInstruction.SEB_INSTRUCTION_ATTRIBUTES.SEB_RECONFIGURE_SETTINGS.JITSI_RECEIVE_AUDIO, | ||||
|                             Constants.TRUE_STRING) | ||||
|                     .withFormParam( | ||||
|                             ClientInstruction.SEB_INSTRUCTION_ATTRIBUTES.SEB_RECONFIGURE_SETTINGS.JITSI_RECEIVE_VIDEO, | ||||
|                             Constants.TRUE_STRING) | ||||
|                     .call() | ||||
|                     .getOrThrow(); | ||||
|         } else { | ||||
|             this.pageService.getPolyglotPageService().injectI18n(broadcastAction, BROADCAST_VIDEO_OFF_TEXT_KEY); | ||||
|             this.pageService.getPolyglotPageService().injectI18n(audioAction, BROADCAST_AUDIO_OFF_TEXT_KEY); | ||||
|             this.pageService.getPolyglotPageService().injectI18n(videoAction, BROADCAST_VIDEO_OFF_TEXT_KEY); | ||||
|             this.pageService.getRestService().getBuilder(SendProctoringBroadcastOnInstruction.class) | ||||
|                     .withURIVariable(API.PARAM_MODEL_ID, examId) | ||||
|                     .withFormParam(Domain.REMOTE_PROCTORING_ROOM.ATTR_ID, roomName) | ||||
|                     .withFormParam( | ||||
|                             ClientInstruction.SEB_INSTRUCTION_ATTRIBUTES.SEB_RECONFIGURE_SETTINGS.JITSI_RECEIVE_AUDIO, | ||||
|                             Constants.TRUE_STRING) | ||||
|                     .withFormParam( | ||||
|                             ClientInstruction.SEB_INSTRUCTION_ATTRIBUTES.SEB_RECONFIGURE_SETTINGS.JITSI_RECEIVE_VIDEO, | ||||
|                             Constants.TRUE_STRING) | ||||
|  | @ -197,6 +211,7 @@ public class JitsiMeetProctoringView implements RemoteProctoringView { | |||
|                     .getOrThrow(); | ||||
|         } | ||||
|         state.video = !state.video; | ||||
|         state.audio = state.video; | ||||
|     } | ||||
| 
 | ||||
|     private void toggleChat(final String examId, final String roomName, final Button broadcastAction) { | ||||
|  |  | |||
|  | @ -0,0 +1,45 @@ | |||
| /* | ||||
|  * Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET) | ||||
|  * | ||||
|  * This Source Code Form is subject to the terms of the Mozilla Public | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| 
 | ||||
| package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| 
 | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.http.HttpMethod; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.stereotype.Component; | ||||
| 
 | ||||
| import com.fasterxml.jackson.core.type.TypeReference; | ||||
| 
 | ||||
| import ch.ethz.seb.sebserver.gbl.api.API; | ||||
| import ch.ethz.seb.sebserver.gbl.api.EntityType; | ||||
| import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection; | ||||
| import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; | ||||
| import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; | ||||
| 
 | ||||
| @Lazy | ||||
| @Component | ||||
| @GuiProfile | ||||
| public class GetProctorRoomConnections extends RestCall<Collection<ClientConnection>> { | ||||
| 
 | ||||
|     public GetProctorRoomConnections() { | ||||
|         super(new TypeKey<>( | ||||
|                 CallType.GET_LIST, | ||||
|                 EntityType.CLIENT_CONNECTION, | ||||
|                 new TypeReference<Collection<ClientConnection>>() { | ||||
|                 }), | ||||
|                 HttpMethod.GET, | ||||
|                 MediaType.APPLICATION_FORM_URLENCODED, | ||||
|                 API.EXAM_MONITORING_ENDPOINT | ||||
|                         + API.MODEL_ID_VAR_PATH_SEGMENT | ||||
|                         + API.PROCTORING_PATH_SEGMENT | ||||
|                         + API.PROCTORING_ROOM_CONNECTIONS_PATH_SEGMENT); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -360,7 +360,7 @@ public class ExamMonitoringController { | |||
|             @PathVariable(name = API.PARAM_MODEL_ID) final Long examId, | ||||
|             @RequestParam( | ||||
|                     name = Domain.REMOTE_PROCTORING_ROOM.ATTR_ID, | ||||
|                     required = true) final Long roomId) { | ||||
|                     required = true) final String roomName) { | ||||
| 
 | ||||
|         this.authorization.check( | ||||
|                 PrivilegeType.READ, | ||||
|  | @ -370,7 +370,7 @@ public class ExamMonitoringController { | |||
|         this.authorization.checkRead( | ||||
|                 this.examSessionService.getExamDAO().byPK(examId).getOrThrow()); | ||||
| 
 | ||||
|         return this.examProcotringRoomService.getRoomConnections(roomId) | ||||
|         return this.examProcotringRoomService.getRoomConnections(examId, roomName) | ||||
|                 .getOrThrow(); | ||||
|     } | ||||
| 
 | ||||
|  | @ -639,62 +639,6 @@ public class ExamMonitoringController { | |||
|                 .getOrThrow(); | ||||
|     } | ||||
| 
 | ||||
| //    @RequestMapping( | ||||
| //            path = API.MODEL_ID_VAR_PATH_SEGMENT | ||||
| //                    + API.PROCTORING_PATH_SEGMENT | ||||
| //                    + API.PROCTORING_LEAVE_ROOM_PATH_SEGMENT, | ||||
| //            method = RequestMethod.POST, | ||||
| //            produces = MediaType.APPLICATION_JSON_UTF8_VALUE) | ||||
| //    public List<SEBProctoringConnectionData> leaveProctoringRoom( | ||||
| //            @RequestParam( | ||||
| //                    name = API.PARAM_INSTITUTION_ID, | ||||
| //                    required = true, | ||||
| //                    defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId, | ||||
| //            @PathVariable(name = API.PARAM_MODEL_ID) final Long examId, | ||||
| //            @RequestParam( | ||||
| //                    name = SEBProctoringConnectionData.ATTR_ROOM_NAME, | ||||
| //                    required = true) final String roomName, | ||||
| //            @RequestParam( | ||||
| //                    name = API.EXAM_API_SEB_CONNECTION_TOKEN, | ||||
| //                    required = true) final String connectionTokens) { | ||||
| // | ||||
| //        this.authorization.check( | ||||
| //                PrivilegeType.READ, | ||||
| //                EntityType.EXAM, | ||||
| //                institutionId); | ||||
| // | ||||
| //        final ProctoringSettings settings = this.examSessionService | ||||
| //                .getRunningExam(examId) | ||||
| //                .flatMap(this.authorization::checkRead) | ||||
| //                .flatMap(this.examAdminService::getExamProctoring) | ||||
| //                .getOrThrow(); | ||||
| // | ||||
| //        final ExamProctoringService examProctoringService = this.examAdminService | ||||
| //                .getExamProctoringService(settings.serverType) | ||||
| //                .getOrThrow(); | ||||
| // | ||||
| //        if (StringUtils.isNotBlank(connectionTokens)) { | ||||
| //            return (connectionTokens.contains(Constants.LIST_SEPARATOR) | ||||
| //                    ? Arrays.asList(StringUtils.split(connectionTokens, Constants.LIST_SEPARATOR)) | ||||
| //                    : Arrays.asList(connectionTokens)) | ||||
| //                            .stream() | ||||
| //                            .map(connectionToken -> { | ||||
| //                                final SEBProctoringConnectionData data = examProctoringService | ||||
| //                                        .createClientPublicRoomConnection(settings, connectionToken, roomName, roomName) | ||||
| //                                        .getOrThrow(); | ||||
| // | ||||
| //                                sendLeaveInstruction(examId, connectionTokens, data) | ||||
| //                                        .onError(error -> log.error( | ||||
| //                                                "Failed to send proctoring leave instruction for common room to client: {} ", | ||||
| //                                                connectionToken, error)); | ||||
| //                                return data; | ||||
| // | ||||
| //                            }).collect(Collectors.toList()); | ||||
| //        } | ||||
| // | ||||
| //        return Collections.emptyList(); | ||||
| //    } | ||||
| 
 | ||||
|     //**** Proctoring | ||||
|     //*********************************************************************************************** | ||||
| 
 | ||||
|  |  | |||
|  | @ -1437,17 +1437,19 @@ sebserver.monitoring.exam.list.title=Running Exams | |||
| sebserver.monitoring.exam.list.actions= | ||||
| sebserver.monitoring.exam.action.detail.view=Back To Monitoring | ||||
| sebserver.monitoring.exam.action.list.view=Monitoring | ||||
| sebserver.monitoring.exam.action.close=Close Window | ||||
| sebserver.monitoring.exam.action.broadcaston.audio=Start Audio Broadcast | ||||
| sebserver.monitoring.exam.action.broadcastoff.audio=End Audio Broadcast | ||||
| sebserver.monitoring.exam.action.broadcaston.video=Start Video Broadcast | ||||
| sebserver.monitoring.exam.action.broadcastoff.video=End Video Broadcast | ||||
| sebserver.monitoring.exam.action.broadcaston.chat=Enable Chat | ||||
| sebserver.monitoring.exam.action.broadcastoff.chat=Disable Chat | ||||
| sebserver.monitoring.exam.action.viewroom=View {0} | {1} / {2} | ||||
| sebserver.monitoring.exam.action.viewroom=View {0}  ( {1} / {2} ) | ||||
| sebserver.exam.monitoring.action.category.filter=Filter | ||||
| sebserver.exam.overall.action.category.proctoring=Proctoring | ||||
| 
 | ||||
| sebserver.monitoring.exam.proctoring.action.close=Close Window | ||||
| sebserver.monitoring.exam.proctoring.action.broadcaston.audio=Start Audio Broadcast | ||||
| sebserver.monitoring.exam.proctoring.action.broadcastoff.audio=End Audio Broadcast | ||||
| sebserver.monitoring.exam.proctoring.action.broadcaston.video=Start Video Broadcast | ||||
| sebserver.monitoring.exam.proctoring.action.broadcastoff.video=End Video Broadcast | ||||
| sebserver.monitoring.exam.proctoring.action.broadcaston.chat=Enable Chat | ||||
| sebserver.monitoring.exam.proctoring.action.broadcastoff.chat=Disable Chat | ||||
| sebserver.monitoring.exam.proctoring.room.connections.title=SEB Connections in {0} | ||||
| 
 | ||||
| 
 | ||||
| sebserver.monitoring.exam.info.pleaseSelect=At first please select an Exam from the list | ||||
| sebserver.monitoring.exam.list.empty=There are currently no running exams | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 anhefti
						anhefti