You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2016/04/21 10:21:20 UTC

svn commit: r1740251 [1/2] - in /openmeetings/application: branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ branches/3.2.x/openm...

Author: solomax
Date: Thu Apr 21 08:21:20 2016
New Revision: 1740251

URL: http://svn.apache.org/viewvc?rev=1740251&view=rev
Log:
[OPENMEETINGS-1045] start/stop sharing is being tracked

Added:
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.html
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.html
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java
Removed:
    openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/plugins/
Modified:
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
    openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/hibernate/hibRtmpConnection.lzx
    openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/main.lzx
    openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmButton.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/room.css
    openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
    openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmButton.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/room.css
    openmeetings/application/trunk/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java

Modified: openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java Thu Apr 21 08:21:20 2016
@@ -41,6 +41,8 @@ import org.apache.openmeetings.db.entity
 import org.apache.openmeetings.db.entity.room.Client;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.util.CalendarPatterns;
+import org.apache.openmeetings.util.message.TextRoomMessage;
+import org.apache.openmeetings.util.message.RoomMessage;
 import org.red5.logging.Red5LoggerFactory;
 import org.red5.server.api.IConnection;
 import org.red5.server.api.Red5;
@@ -94,7 +96,7 @@ public class RecordingService implements
 		try {
 			log.debug("##REC:: recordMeetingStream ::");
 
-			Long room_id = client.getRoomId();
+			Long roomId = client.getRoomId();
 
 			Date now = new Date();
 
@@ -114,7 +116,7 @@ public class RecordingService implements
 			recording.setComment(comment);
 			recording.setInterview(isInterview);
 
-			recording.setRoomId(room_id);
+			recording.setRoomId(roomId);
 			recording.setRecordStart(now);
 
 			recording.setWidth(client.getVWidth());
@@ -139,7 +141,7 @@ public class RecordingService implements
 						Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 
 						// Send every user a notification that the recording did start
-						((IServiceCapableConnection) conn).invoke("startedRecording", new Object[] { client }, this);
+						scopeApplicationAdapter.broadcastRoom(new TextRoomMessage(roomId, ownerId, RoomMessage.Type.recordingStarted, client.getPublicSID()));
 
 						// If its the recording client we need another type of Meta Data
 						if (rcl.isScreenClient()) {
@@ -304,9 +306,10 @@ public class RecordingService implements
 		}
 	}
 
-	public Long stopRecordAndSave(IScope scope, Client currentClient, Long storedRecordingId) {
+	public Long stopRecordAndSave(IScope scope, Client client, Long storedRecordingId) {
 		try {
-			log.debug("stopRecordAndSave " + currentClient.getUsername() + "," + currentClient.getUserip());
+			log.debug("stopRecordAndSave " + client.getUsername() + "," + client.getUserip());
+			scopeApplicationAdapter.broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.recordingStoped, client.getPublicSID()));
 
 			// get all stream and stop recording them
 			for (IConnection conn : scope.getClientConnections()) {
@@ -338,7 +341,7 @@ public class RecordingService implements
 				}
 			}
 			// Store to database
-			Long recordingId = currentClient.getRecordingId();
+			Long recordingId = client.getRecordingId();
 
 			// In the Case of an Interview the stopping client does not mean
 			// that its actually the recording client
@@ -350,10 +353,10 @@ public class RecordingService implements
 				recordingDao.updateEndTime(recordingId, new Date());
 
 				// Reset values
-				currentClient.setRecordingId(null);
-				currentClient.setIsRecording(false);
+				client.setRecordingId(null);
+				client.setIsRecording(false);
 
-				sessionManager.updateClientByStreamId(currentClient.getStreamid(), currentClient, false, null);
+				sessionManager.updateClientByStreamId(client.getStreamid(), client, false, null);
 				log.debug("recordingConverterTask ", recordingConverterTask);
 
 				Recording recording = recordingDao.get(recordingId);

Modified: openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java Thu Apr 21 08:21:20 2016
@@ -62,6 +62,12 @@ import org.apache.openmeetings.util.Init
 import org.apache.openmeetings.util.OmFileHelper;
 import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.util.Version;
+import org.apache.openmeetings.util.message.RoomMessage;
+import org.apache.openmeetings.util.message.TextRoomMessage;
+import org.apache.wicket.Application;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.IWebSocketConnection;
+import org.apache.wicket.protocol.ws.api.registry.IWebSocketConnectionRegistry;
 import org.red5.logging.Red5LoggerFactory;
 import org.red5.server.adapter.ApplicationAdapter;
 import org.red5.server.api.IClient;
@@ -232,6 +238,7 @@ public class ScopeApplicationAdapter ext
 					client.setStartStreaming(false);
 					//Send message to all users
 					sendMessageToCurrentScope("stopScreenSharingMessage", client, false);
+					broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
 					
 					returnMap.put("result", "stopSharingOnly");
 				}
@@ -241,8 +248,6 @@ public class ScopeApplicationAdapter ext
 					client.setIsRecording(false);
 					
 					returnMap.put("result", "stopRecordingOnly");
-					//Send message to all users
-					sendMessageToCurrentScope("stopRecordingMessage", client, false);
 
 					recordingService.stopRecordAndSave(current.getScope(), client, null);
 				}
@@ -351,6 +356,7 @@ public class ScopeApplicationAdapter ext
 						
 						//Send message to all users
 						sendMessageToCurrentScope("newScreenSharing", client, false);
+						broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStarted, client.getStreamPublishName()));
 					} else {
 						log.warn("Streaming is already started for the client id=" + client.getId() + ". Second request is ignored.");
 					}
@@ -503,50 +509,55 @@ public class ScopeApplicationAdapter ext
 	 * This function is kind of private/protected as the client won't be able 
 	 * to call it with proper values.
 	 * 
-	 * @param currentClient
-	 * @param currentScope
+	 * @param client
+	 * @param scope
 	 */
-	public void roomLeaveByScope(Client currentClient, IScope currentScope, boolean removeUserFromSessionList) {
+	public void roomLeaveByScope(Client client, IScope scope, boolean removeUserFromSessionList) {
 		try {
-			log.debug("currentClient " + currentClient);
-			Long roomId = currentClient.getRoomId();
+			log.debug("currentClient " + client);
+			Long roomId = client.getRoomId();
+			
+			if (client.isScreenClient() && client.isStartStreaming()) {
+				//TODO check others/find better way
+				broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
+			}
 
 			// Log the User
 			conferenceLogDao.add(ConferenceLog.Type.roomLeave,
-					currentClient.getUserId(), currentClient.getStreamid(),
-					roomId, currentClient.getUserip(), "");
+					client.getUserId(), client.getStreamid(),
+					roomId, client.getUserip(), "");
 
 			// Remove User from Sync List's
 			if (roomId != null) {
-				whiteBoardService.removeUserFromAllLists(currentScope, currentClient);
+				whiteBoardService.removeUserFromAllLists(scope, client);
 			}
 
-			log.debug("removing Username " + currentClient.getUsername() + " "
-					+ currentClient.getConnectedSince() + " streamid: "
-					+ currentClient.getStreamid());
+			log.debug("removing Username " + client.getUsername() + " "
+					+ client.getConnectedSince() + " streamid: "
+					+ client.getStreamid());
 
 			// stop and save any recordings
-			if (currentClient.getIsRecording()) {
+			if (client.getIsRecording()) {
 				log.debug("*** roomLeave Current Client is Recording - stop that");
-				if (currentClient.getInterviewPodId() != null) {
+				if (client.getInterviewPodId() != null) {
 					//interview, TODO need better check
-					_stopInterviewRecording(currentClient, currentScope);
+					_stopInterviewRecording(client, scope);
 				} else {
-					recordingService.stopRecordAndSave(currentScope, currentClient, null);
+					recordingService.stopRecordAndSave(scope, client, null);
 
 					// set to true and overwrite the default one cause otherwise no
 					// notification is send
-					currentClient.setIsRecording(true);
+					client.setIsRecording(true);
 				}
 			}
 
 			// Notify all clients of the same currentScope (room) with domain
 			// and room except the current disconnected cause it could throw an exception
-			log.debug("currentScope " + currentScope);
+			log.debug("currentScope " + scope);
 
-			if (currentScope != null && currentScope.getClientConnections() != null) {
+			if (scope != null && scope.getClientConnections() != null) {
 				// Notify Users of the current Scope
-				for (IConnection cons : currentScope.getClientConnections()) {
+				for (IConnection cons : scope.getClientConnections()) {
 					if (cons != null && cons instanceof IServiceCapableConnection) {
 						log.debug("sending roomDisconnect to {}  client id {}", cons, cons.getClient().getId());
 
@@ -559,16 +570,16 @@ public class ScopeApplicationAdapter ext
 						}
 						
 						//Do not send back to sender, but actually all other clients should receive this message swagner 01.10.2009
-						if (!currentClient.getStreamid().equals(rcl.getStreamid())) {
+						if (!client.getStreamid().equals(rcl.getStreamid())) {
 							// add Notification if another user isrecording
-							log.debug("###########[roomLeave]");
+							log.debug("###########[roomLeaveByScope]");
 							if (rcl.getIsRecording()) {
 								log.debug("*** roomLeave Any Client is Recording - stop that");
-								recordingService.stopRecordingShowForClient(cons, currentClient);
+								recordingService.stopRecordingShowForClient(cons, client);
 							}
 							
 							boolean isScreen = rcl.isScreenClient();
-							if (isScreen && currentClient.getPublicSID().equals(rcl.getStreamPublishName())) {
+							if (isScreen && client.getPublicSID().equals(rcl.getStreamPublishName())) {
 								//going to terminate screen sharing started by this client
 								((IServiceCapableConnection) cons).invoke("stopStream", new Object[] { },this);
 								continue;
@@ -578,7 +589,7 @@ public class ScopeApplicationAdapter ext
 							}
 							
 							// Send to all connected users
-							((IServiceCapableConnection) cons).invoke("roomDisconnect", new Object[] { currentClient },this);
+							((IServiceCapableConnection) cons).invoke("roomDisconnect", new Object[] { client },this);
 							log.debug("sending roomDisconnect to " + cons);
 						}
 					}
@@ -586,7 +597,7 @@ public class ScopeApplicationAdapter ext
 			}
 
 			if (removeUserFromSessionList) {
-				sessionManager.removeClient(currentClient.getStreamid(), null);
+				sessionManager.removeClient(client.getStreamid(), null);
 			}
 		} catch (Exception err) {
 			log.error("[roomLeaveByScope]", err);
@@ -2043,7 +2054,6 @@ public class ScopeApplicationAdapter ext
 			interviewStatus.put("action", "stop");
 
 			sendMessageToCurrentScope("interviewStatus", interviewStatus, true);
-			sendMessageToCurrentScope("stopRecordingMessage", currentClient, true);
 			return true;
 
 		} catch (Exception err) {
@@ -2200,4 +2210,16 @@ public class ScopeApplicationAdapter ext
 
 		sendMessageToCurrentScope("addNewUser", currentClient, false);
 	}
+	
+	public void broadcastRoom(RoomMessage msg) {
+		log.debug("Sending WebSocket message: {} {}", msg.getType(), msg instanceof TextRoomMessage ? ((TextRoomMessage)msg).getText() : "");
+		Application app = Application.get(OpenmeetingsVariables.wicketApplicationName);
+		WebSocketSettings settings = WebSocketSettings.Holder.get(app);
+		IWebSocketConnectionRegistry registry = settings.getConnectionRegistry();
+		for (IWebSocketConnection wc : registry.getConnections(app)) {
+			if (wc != null && wc.isOpen()) {
+				wc.sendMessage(msg);
+			}
+		}
+	}
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/hibernate/hibRtmpConnection.lzx
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/hibernate/hibRtmpConnection.lzx?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/hibernate/hibRtmpConnection.lzx (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/hibernate/hibRtmpConnection.lzx Thu Apr 21 08:21:20 2016
@@ -179,7 +179,6 @@
 		client.sendSyncCompleteFlag = this.sendSyncCompleteFlag;
 		client.sendObjectSyncFlag = this.sendObjectSyncFlag;
 		client.sendObjectSyncCompleteFlag = this.sendObjectSyncCompleteFlag;
-		client.startedRecording = this.startedRecording;
 		client.loadWmlToWhiteboardById = this.loadWmlToWhiteboardById;
 		client.newMessageByRoomAndDomain = this.newMessageByRoomAndDomain;
 		client.interviewStatus = this.interviewStatus;
@@ -190,7 +189,6 @@
 		client.setNewModeratorByList = this.setNewModeratorByList;
 		client.newScreenSharing = this.newScreenSharing;
 		client.stopScreenSharingMessage = this.stopScreenSharingMessage;
-		client.stopRecordingMessage = this.stopRecordingMessage;
 		client.stopPublishingMessage = this.stopPublishingMessage;
 		client.newRed5ScreenCursor = this.newRed5ScreenCursor;
 		client.nickNameSet = this.nickNameSet;
@@ -783,12 +781,6 @@
 		]]>
 		</method>
 		
-		<method name="stopRecordingMessage" args="value">
-			//The onResult-Handler will be called be the rtmpconnection
-			canvas._mymod.recordingUser = null;
-			canvas._mymod.setMessage();				 
-		</method>
-		
 		<method name="stopPublishingMessage" args="value">
 			//The onResult-Handler will be called be the rtmpconnection
 			canvas._mymod.publishingObj = null;
@@ -1331,12 +1323,6 @@
 		]]>
 		</method>	   
 		
-	<method name="startedRecording" args="value">
-		if ($debug) Debug.write("startedRecording: ",value);
-		canvas._mymod.recordingUser = value;
-		canvas._mymod.setMessage();
-	</method>
-	
 	<netRemoteCallHib name="checkLzRecording" funcname="recordingservice.checkLzRecording" >	  
 		<handler name="ondata" args="value">
 			if ($debug) Debug.write("checkLzRecording: ",value);

Modified: openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/main.lzx
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/main.lzx?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/main.lzx (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/main.lzx Thu Apr 21 08:21:20 2016
@@ -43,7 +43,6 @@
 	<include href="base/" /><!-- attributes,methods,datasets,are moved into /base -->
 	<include href="resources/" /> 
 	<include href="modules/" />
-	<include href="plugins/" />  
 	<include href="testVideoObject.lzx" />
 	<include href="video/" />
 	<include href="screensharing/" />

Modified: openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java Thu Apr 21 08:21:20 2016
@@ -31,9 +31,15 @@ public class RoomMessage implements IWeb
 		, roomExit
 		, roomClosed
 		, pollCreated
+		, recordingStarted
+		, recordingStoped
+		, sharingStarted
+		, sharingStoped
 		, rightUpdated
 		, activityRemove
 		, requestRightModerator
+		, requestRightWb
+		, requestRightAv
 	}
 	private final Date timestamp;
 	private final String uid;

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmButton.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmButton.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmButton.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmButton.java Thu Apr 21 08:21:20 2016
@@ -38,5 +38,5 @@ public abstract class OmButton extends B
 		});
 	}
 	
-	protected abstract void onClick(AjaxRequestTarget target); 
+	public abstract void onClick(AjaxRequestTarget target); 
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java Thu Apr 21 08:21:20 2016
@@ -106,10 +106,17 @@ public class RoomPanel extends BasePanel
 	private RoomMenuPanel menu;
 	private RoomSidebar sidebar;
 	private ActivitiesPanel activities;
+	private String sharingUser = null;
+	private String recordingUser = null;
+	private String publishingUser = null; //TODO add
 	
 	public RoomPanel(String id, Room r) {
 		super(id);
 		this.r = r;
+		//TODO check here and set 
+		//private String recordingUser = null;
+		//private String sharingUser = null;
+		//private String publishingUser = null;
 	}
 
 	@Override
@@ -214,6 +221,29 @@ public class RoomPanel extends BasePanel
 						if (getUserId() != m.getUserId()) {
 							menu.pollCreated(handler);
 						}
+						break;
+					case recordingStoped:
+						//TODO check recordingUser == ((TextRoomMessage)m).getText();
+						recordingUser = null;
+						menu.update(handler);
+						break;
+					case recordingStarted:
+					{
+						recordingUser = ((TextRoomMessage)m).getText();
+						menu.update(handler);
+					}
+						break;
+					case sharingStoped:
+						//TODO check sharingUser == ((TextRoomMessage)m).getText();
+						sharingUser = null;
+						menu.update(handler);
+						break;
+					case sharingStarted:
+					{
+						sharingUser = ((TextRoomMessage)m).getText();
+						menu.update(handler);
+					}
+						break;
 					case rightUpdated:
 						sidebar.updateUsers(handler);
 						menu.update(handler);
@@ -233,7 +263,7 @@ public class RoomPanel extends BasePanel
 						roomClosed.open(handler);
 						break;
 					case requestRightModerator:
-						if (isModerator(getUserId(), r.getId())) {
+						if (isModerator(getUserId(), r.getId()) && !isModerator(m.getUserId(), r.getId())) {
 							TextRoomMessage tm = (TextRoomMessage)m;
 							activities.add(new Activity(tm.getText(), m.getUserId(), Activity.Type.requestRightModerator), handler);
 						}
@@ -244,6 +274,12 @@ public class RoomPanel extends BasePanel
 						activities.remove(tm.getText(), handler);
 					}
 						break;
+					case requestRightAv:
+						break;
+					case requestRightWb:
+						break;
+					default:
+						break;
 				}
 			}
 		}
@@ -364,4 +400,16 @@ public class RoomPanel extends BasePanel
 	public ActivitiesPanel getActivities() {
 		return activities;
 	}
+	
+	public String getSharingUser() {
+		return sharingUser;
+	}
+
+	public String getRecordingUser() {
+		return recordingUser;
+	}
+
+	public String getPublishingUser() {
+		return publishingUser;
+	}
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js Thu Apr 21 08:21:20 2016
@@ -21,7 +21,7 @@ function activitiesClosed(activities) {
 	return activities.height() < 24;
 }
 function openActivities() {
-	var activities = $('#activitiesPanel');
+	var activities = $('#activities');
 	if (activitiesClosed(activities)) {
 		$('.control.block .ui-icon', activities).removeClass('ui-icon-carat-1-n').addClass('ui-icon-carat-1-s');
 		$('.control.block', activities).removeClass('ui-state-highlight');
@@ -29,21 +29,21 @@ function openActivities() {
 	}
 }
 function closeActivities() {
-	var activities = $('#activitiesPanel');
+	var activities = $('#activities');
 	if (!activitiesClosed(activities)) {
 		$('.control.block .ui-icon', activities).removeClass('ui-icon-carat-1-s').addClass('ui-icon-carat-1-n');
 		activities.animate({height: closedHeight}, 1000);
 	}
 }
 function toggleActivities() {
-	if (activitiesClosed($('#activitiesPanel'))) {
+	if (activitiesClosed($('#activities'))) {
 		openActivities();
 	} else {
 		closeActivities();
 	}
 }
 function hightlightActivities() {
-	var activities = $('#activitiesPanel');
+	var activities = $('#activities');
 	if (activitiesClosed(activities)) {
 		$('.control.block', activities).addClass('ui-state-highlight');
 	}

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html Thu Apr 21 08:21:20 2016
@@ -24,7 +24,6 @@
 	<div class="room menu right">
 		<span wicket:id="ask" class="icon ask"></span>
 		<span wicket:id="share" class="icon share"></span>
-		<span wicket:id="recording" class="room recording"></span>
 		<span wicket:id="roomName" class="room name"></span>
 		<span wicket:id="demo" class="ui-state-error room demo"></span>
 	</div>

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java Thu Apr 21 08:21:20 2016
@@ -25,11 +25,14 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 import static org.apache.openmeetings.web.util.OmUrlFragment.ROOMS_PUBLIC;
 
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.room.PollDao;
+import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
@@ -67,6 +70,13 @@ public class RoomMenuPanel extends Panel
 	private final PollResultsDialog pollResults;
 	private final MenuPanel menuPanel;
 	private final StartSharingButton shareBtn;
+	private final Label roomName;
+	private static ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
+		@Override
+		protected DateFormat initialValue() {
+			return new SimpleDateFormat("dd.MM.yyyy HH:mm");
+		};
+	};
 	private final OmButton askBtn = new OmButton("ask") {
 		private static final long serialVersionUID = 1L;
 		{
@@ -74,7 +84,7 @@ public class RoomMenuPanel extends Panel
 			setVisible(false);
 		}
 		@Override
-		protected void onClick(AjaxRequestTarget target) {
+		public void onClick(AjaxRequestTarget target) {
 			RoomPanel.broadcast(new TextRoomMessage(room.getRoom().getId(), getUserId(), RoomMessage.Type.requestRightModerator, room.getClient().getUid()));
 		}
 	};
@@ -106,9 +116,30 @@ public class RoomMenuPanel extends Panel
 			shareBtn.onClick(target);
 		}
 	};
-	private final RoomMenuItem applyModerMenuItem = new RoomMenuItem(Application.getString(784), Application.getString(1481), false);
-	private final RoomMenuItem applyWbMenuItem = new RoomMenuItem(Application.getString(785), Application.getString(1492), false);
-	private final RoomMenuItem applyAvMenuItem = new RoomMenuItem(Application.getString(786), Application.getString(1482), false);
+	private final RoomMenuItem applyModerMenuItem = new RoomMenuItem(Application.getString(784), Application.getString(1481), false) {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public void onClick(AjaxRequestTarget target) {
+			askBtn.onClick(target);
+		}
+	};
+	private final RoomMenuItem applyWbMenuItem = new RoomMenuItem(Application.getString(785), Application.getString(1492), false) {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public void onClick(AjaxRequestTarget target) {
+			RoomPanel.broadcast(new TextRoomMessage(room.getRoom().getId(), getUserId(), RoomMessage.Type.requestRightWb, room.getClient().getUid()));
+		}
+	};
+	private final RoomMenuItem applyAvMenuItem = new RoomMenuItem(Application.getString(786), Application.getString(1482), false) {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public void onClick(AjaxRequestTarget target) {
+			RoomPanel.broadcast(new TextRoomMessage(room.getRoom().getId(), getUserId(), RoomMessage.Type.requestRightAv, room.getClient().getUid()));
+		}
+	};
 	private final RoomMenuItem pollCreateMenuItem = new RoomMenuItem(Application.getString(24), Application.getString(1483), false) {
 		private static final long serialVersionUID = 1L;
 
@@ -146,8 +177,7 @@ public class RoomMenuPanel extends Panel
 		setVisible(!r.isHidden(RoomElement.TopBar));
 		add((menuPanel = new MenuPanel("menu", getMenu())).setVisible(isVisible()));
 		add(askBtn);
-		add(new Label("roomName", r.getName()));
-		add(new Label("recording", "Recording started").setVisible(false)); //FIXME add/remove
+		add((roomName = new Label("roomName", r.getName())).setOutputMarkupId(true));
 		add(shareBtn = new StartSharingButton("share", room.getClient()));
 		add(invite = new InvitationDialog("invite", room.getRoom().getId()));
 		add(createPoll = new CreatePollDialog("createPoll", room.getRoom().getId()));
@@ -207,7 +237,7 @@ public class RoomMenuPanel extends Panel
 		actionsMenu.getItems().add(pollResultMenuItem); //FIXME enable/disable
 		actionsMenu.getItems().add(pollVoteMenuItem); //FIXME enable/disable
 		actionsMenu.getItems().add(sipDialerMenuItem);
-		actionsMenu.getItems().add(new RoomMenuItem(Application.getString(1126), Application.getString(1490)));
+		//TODO seems need to be removed actionsMenu.getItems().add(new RoomMenuItem(Application.getString(1126), Application.getString(1490)));
 		menu.add(actionsMenu);
 		return menu;
 	}
@@ -226,7 +256,8 @@ public class RoomMenuPanel extends Panel
 		boolean moder = room.getClient().hasRight(Client.Right.moderator);
 		inviteMenuItem.setEnabled(notExternalUser && moder);
 		//TODO add check "sharing started"
-		boolean shareVisible = Room.Type.interview != r.getType() && !r.isHidden(RoomElement.ScreenSharing) && r.isAllowRecording() && moder;
+		boolean shareVisible = Room.Type.interview != r.getType() && !r.isHidden(RoomElement.ScreenSharing)
+				&& r.isAllowRecording() && room.getClient().hasRight(Client.Right.share) && room.getSharingUser() == null;
 		shareMenuItem.setEnabled(shareVisible);
 		//FIXME TODO apply* should be enabled if moder is in room
 		applyModerMenuItem.setEnabled(!moder);
@@ -238,6 +269,26 @@ public class RoomMenuPanel extends Panel
 		//TODO sip menus
 		menuPanel.update(handler);
 		//FIXME TODO askBtn should be visible if moder is in room
+		StringBuilder roomClass = new StringBuilder("room name");
+		StringBuilder roomTitle = new StringBuilder();
+		if (room.getRecordingUser() != null) {
+			org.apache.openmeetings.db.entity.room.Client recUser = getBean(ISessionManager.class).getClientByPublicSID(room.getRecordingUser(), null); //TODO check server
+			if (recUser != null) {
+				roomTitle.append(String.format("%s %s %s %s %s", getString("419")
+						, recUser.getUsername(), recUser.getFirstname(), recUser.getLastname(), df.get().format(recUser.getConnectedSince())));
+				roomClass.append(" screen");
+			}
+			org.apache.openmeetings.db.entity.room.Client pubUser = getBean(ISessionManager.class).getClientByPublicSID(room.getPublishingUser(), null); //TODO check server
+			if (pubUser != null) {
+				if (recUser != null) {
+					roomTitle.append('\n');
+				}
+				roomTitle.append(String.format("%s %s %s %s %s", getString("1504")
+						, recUser.getUsername(), pubUser.getFirstname(), pubUser.getLastname(), "URL")); //TODO add URL
+				roomClass.append(" screen");
+			}
+		}
+		handler.add(roomName.add(AttributeAppender.replace("class", roomClass), AttributeAppender.replace("title", roomTitle)));
 		handler.add(askBtn.setVisible(!moder && r.isAllowUserQuestions()));
 		handler.add(shareBtn.setVisible(shareVisible));
 	}
@@ -245,6 +296,7 @@ public class RoomMenuPanel extends Panel
 	public void pollCreated(IPartialPageRequestHandler handler) {
 		vote.updateModel(handler);
 		vote.open(handler);
+		update(handler);
 	}
 	
 	public void exit(IPartialPageRequestHandler handler) {

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java Thu Apr 21 08:21:20 2016
@@ -84,7 +84,7 @@ public class StartSharingButton extends
 	}
 	
 	@Override
-	protected void onClick(AjaxRequestTarget target) {
+	public void onClick(AjaxRequestTarget target) {
 		//TODO deny download in case other screen sharing is in progress
 		String app = "";
 		try (InputStream jnlp = getClass().getClassLoader().getResourceAsStream("APPLICATION.jnlp")) {

Added: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.html
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.html?rev=1740251&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.html (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.html Thu Apr 21 08:21:20 2016
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+  
+      http://www.apache.org/licenses/LICENSE-2.0
+    	  
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+  
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+<wicket:panel>
+	<span wicket:id="status" class="ui-icon align-right"></span>
+	<span class="ui-icon align-right clickable restart" wicket:message="title:610"></span>
+	<div wicket:id="name" class="user name"></div>
+	<span class="ui-icon align-right clickable audio-activity" wicket:message="title:372"></span>
+	<div wicket:id="actions" class="user actions">
+		<span class="ui-icon align-left clickable moderator-right" wicket:message="title:676"></span>
+		<span class="ui-icon align-left clickable wb-right" wicket:message="title:611"></span>
+		<span class="ui-icon align-left clickable screen-share-right" wicket:message="title:1067"></span>
+		<span class="ui-icon align-left clickable remote-control-right" wicket:message="title:1078"></span>
+		<span class="ui-icon align-left clickable audio-right" wicket:message="title:1604"></span>
+		<span class="ui-icon align-left clickable camera-right" wicket:message="title:683"></span>
+		<span class="ui-icon align-left clickable global-mute" wicket:message="title:1384"></span>
+		<span class="ui-icon align-left clickable exclsv-audio" wicket:message="title:1424"></span>
+		<span class="ui-icon align-left clickable kick" wicket:message="title:1213"></span>
+		<span wicket:id="privateChat" class="ui-icon align-right clickable private-chat" wicket:message="title:1493" onclick="startPrivateChat($(this));"></span>
+		<div class="clear"></div>
+	</div>
+</wicket:panel>
+</html>

Added: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java?rev=1740251&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java Thu Apr 21 08:21:20 2016
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License") +  you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openmeetings.web.room.sidebar;
+
+import static org.apache.openmeetings.web.app.Application.getBean;
+import static org.apache.openmeetings.web.app.WebSession.getUserId;
+
+import org.apache.openmeetings.db.dao.user.UserDao;
+import org.apache.openmeetings.db.entity.room.Room.RoomElement;
+import org.apache.openmeetings.db.entity.user.User;
+import org.apache.openmeetings.web.app.Client;
+import org.apache.openmeetings.web.app.Client.Right;
+import org.apache.openmeetings.web.room.RoomPanel;
+import org.apache.wicket.behavior.AttributeAppender;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public class RoomClientPanel extends Panel {
+	private static final long serialVersionUID = 1L;
+
+	public RoomClientPanel(String id, ListItem<Client> item, final RoomPanel room) {
+		super(id);
+		setRenderBodyOnly(true);
+		Client c = item.getModelObject();
+		item.setMarkupId(String.format("user%s", c.getUid()));
+		String status = null, statusTitle = null;
+		if (c.hasRight(Right.moderator)) {
+			status = "status-mod";
+			statusTitle = "679";
+		} else if (c.hasRight(Right.whiteBoard)) {
+			status = "status-wb";
+			statusTitle = "678";
+		} else {
+			status = "status-user";
+			statusTitle = "677";
+		}
+		add(new WebMarkupContainer("status").add(AttributeAppender.append("class", status), AttributeAppender.replace("title", getString(statusTitle))));
+		User u = getBean(UserDao.class).get(c.getUserId());
+		add(new Label("name", u.getFirstname() + " " + u.getLastname()));
+		add(AttributeAppender.append("data-userid", c.getUserId()));
+		WebMarkupContainer actions = new WebMarkupContainer("actions");
+		actions.add(new WebMarkupContainer("privateChat").setVisible(!room.getRoom().isHidden(RoomElement.Chat) && !getUserId().equals(c.getUserId())));
+		if (room.getClient() != null) {
+			actions.setVisible(room.getClient().hasRight(Right.moderator));
+			if (c.getUid().equals(room.getClient().getUid())) {
+				item.add(AttributeAppender.append("class", "current"));
+			}
+		} else {
+			actions.setVisible(false);
+		}
+		add(actions);
+	}
+}

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html Thu Apr 21 08:21:20 2016
@@ -25,23 +25,7 @@
 	<wicket:fragment wicket:id="user-panel">
 		<div class="user list">
 			<div wicket:id="user" class="user ui-corner-all ui-widget-content">
-				<span wicket:id="status" class="ui-icon align-right"></span>
-				<span class="ui-icon align-right clickable restart" wicket:message="title:610"></span>
-				<div wicket:id="name" class="user name"></div>
-				<span class="ui-icon align-right clickable audio-activity" wicket:message="title:372"></span>
-				<div wicket:id="actions" class="user actions">
-					<span class="ui-icon align-left clickable moderator-right" wicket:message="title:676"></span>
-					<span class="ui-icon align-left clickable wb-right" wicket:message="title:611"></span>
-					<span class="ui-icon align-left clickable screen-share-right" wicket:message="title:1067"></span>
-					<span class="ui-icon align-left clickable remote-control-right" wicket:message="title:1078"></span>
-					<span class="ui-icon align-left clickable audio-right" wicket:message="title:1604"></span>
-					<span class="ui-icon align-left clickable camera-right" wicket:message="title:683"></span>
-					<span class="ui-icon align-left clickable global-mute" wicket:message="title:1384"></span>
-					<span class="ui-icon align-left clickable exclsv-audio" wicket:message="title:1424"></span>
-					<span class="ui-icon align-left clickable kick" wicket:message="title:1213"></span>
-					<span wicket:id="privateChat" class="ui-icon align-right clickable private-chat" wicket:message="title:1493" onclick="startPrivateChat($(this));"></span>
-					<div class="clear"></div>
-				</div>
+				<div wicket:id="user"></div>
 			</div>
 		</div>
 	</wicket:fragment>

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java Thu Apr 21 08:21:20 2016
@@ -18,26 +18,18 @@
  */
 package org.apache.openmeetings.web.room.sidebar;
 
-import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.Application.getRoomUsers;
-import static org.apache.openmeetings.web.app.WebSession.getUserId;
 
-import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
 
-import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
-import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.web.app.Client;
 import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
-import org.apache.wicket.behavior.AttributeAppender;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 import org.apache.wicket.extensions.markup.html.tabs.ITab;
 import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.markup.html.panel.Fragment;
@@ -56,38 +48,12 @@ public class RoomSidebar extends Panel {
 	private final UploadDialog upload;
 	private final RoomFilePanel roomFiles;
 	private boolean showFiles;
-	private final ListView<RoomClient> users = new ListView<RoomClient>("user", new ArrayList<RoomClient>()) {
+	private final ListView<Client> users = new ListView<Client>("user", new ArrayList<Client>()) {
 		private static final long serialVersionUID = 1L;
 
 		@Override
-		protected void populateItem(ListItem<RoomClient> item) {
-			RoomClient rc = item.getModelObject();
-			item.setMarkupId(String.format("user%s", rc.c.getUid()));
-			String status = null, statusTitle = null;
-			if (rc.c.hasRight(Right.moderator)) {
-				status = "status-mod";
-				statusTitle = "679";
-			} else if (rc.c.hasRight(Right.whiteBoard)) {
-				status = "status-wb";
-				statusTitle = "678";
-			} else {
-				status = "status-user";
-				statusTitle = "677";
-			}
-			item.add(new WebMarkupContainer("status").add(AttributeAppender.append("class", status), AttributeAppender.replace("title", getString(statusTitle))));
-			item.add(new Label("name", rc.u.getFirstname() + " " + rc.u.getLastname()));
-			item.add(AttributeAppender.append("data-userid", rc.u.getId()));
-			WebMarkupContainer actions = new WebMarkupContainer("actions");
-			actions.add(new WebMarkupContainer("privateChat").setVisible(!room.getRoom().isHidden(RoomElement.Chat) && !getUserId().equals(rc.u.getId())));
-			if (room.getClient() != null) {
-				actions.setVisible(room.getClient().hasRight(Right.moderator));
-				if (rc.c.getUid().equals(room.getClient().getUid())) {
-					item.add(AttributeAppender.append("class", "current"));
-				}
-			} else {
-				actions.setVisible(false);
-			}
-			item.add(actions);
+		protected void populateItem(ListItem<Client> item) {
+			item.add(new RoomClientPanel("user", item, room));
 		}
 	};
 	
@@ -137,12 +103,19 @@ public class RoomSidebar extends Panel {
 		add(upload = new UploadDialog("upload", room, roomFiles));
 	}
 	
+	private ListView<Client> updateUsers() {
+		//TODO do we need sort??
+		users.getList().clear();
+		users.getList().addAll(getRoomUsers(room.getRoom().getId()));
+		return users;
+	}
+	
 	public class UserFragment extends Fragment {
 		private static final long serialVersionUID = 1L;
 
 		public UserFragment(String id, String markupId) {
 			super(id, markupId, RoomSidebar.this);
-			add(users.setList(getUsers()));
+			add(updateUsers());
 		}
 	}
 	
@@ -155,32 +128,13 @@ public class RoomSidebar extends Panel {
 		}
 	}
 
-	private List<RoomClient> getUsers() {
-		List<RoomClient> list = new ArrayList<>();
-		for (Client cl : getRoomUsers(room.getRoom().getId())) {
-			list.add(new RoomClient(cl));
-		}
-		return list;
-	}
-	
-	static class RoomClient implements Serializable {
-		private static final long serialVersionUID = 1L;
-		private final Client c;
-		private final User u;
-		
-		RoomClient(Client c) {
-			this.c = c;
-			this.u = getBean(UserDao.class).get(c.getUserId());
-		}
-	}
-	
 	private void updateShowFiles() {
 		showFiles = !room.getRoom().isHidden(RoomElement.Files) && room.getClient().hasRight(Right.whiteBoard);
 	}
 	
 	public void updateUsers(IPartialPageRequestHandler handler) {
 		updateShowFiles();
-		users.setList(getUsers());
+		updateUsers();
 		handler.add(tabs);
 	}
 

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/room.css
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/room.css?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/room.css (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/room.css Thu Apr 21 08:21:20 2016
@@ -52,11 +52,11 @@
 .room.menu.right .room.name {
 	font-weight: bold;
 }
-.room.menu.right .room.demo {
-}
-.room.menu.right .room.recording {
+.room.menu.right .room.name.screen {
 	color: red;
 }
+.room.menu.right .room.demo {
+}
 .room.menu.right .icon {
 	width: 30px;
 	height: 30px;
@@ -171,6 +171,7 @@
 }
 .room.sidebar.left .user.list .user.current {
 	font-weight: bold;
+	background: #00FF00;
 }
 .ui-dialog.video, .ui-dialog.video .ui-dialog-titlebar, .ui-dialog.video .video.ui-dialog-content {
 	padding: 0;

Modified: openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java Thu Apr 21 08:21:20 2016
@@ -38,6 +38,7 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 
 import org.apache.cxf.feature.Features;
+import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.db.dao.room.IInvitationManager;
 import org.apache.openmeetings.db.dao.room.InvitationDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
@@ -54,13 +55,8 @@ import org.apache.openmeetings.db.entity
 import org.apache.openmeetings.db.entity.room.Invitation.MessageType;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.util.AuthLevelUtil;
-import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.webservice.error.ServiceException;
-import org.apache.wicket.Application;
-import org.apache.wicket.protocol.ws.WebSocketSettings;
-import org.apache.wicket.protocol.ws.api.IWebSocketConnection;
-import org.apache.wicket.protocol.ws.api.registry.IWebSocketConnectionRegistry;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -92,6 +88,8 @@ public class RoomWebService {
 	private ISessionManager sessionManager;
 	@Autowired
 	private RoomDao roomDao;
+	@Autowired
+	private ScopeApplicationAdapter appAdapter;
 
 	/**
 	 * Returns an Object of Type RoomsList which contains a list of
@@ -318,15 +316,7 @@ public class RoomWebService {
 
 				roomDao.update(room, userId);
 
-				Application app = Application.get(OpenmeetingsVariables.wicketApplicationName);
-				WebSocketSettings settings = WebSocketSettings.Holder.get(app);
-				IWebSocketConnectionRegistry registry = settings.getConnectionRegistry();
-				RoomMessage cm = new RoomMessage(room.getId(),  userId,  RoomMessage.Type.roomClosed);
-				for (IWebSocketConnection wc : registry.getConnections(app)) {
-					if (wc != null && wc.isOpen()) {
-						wc.sendMessage(cm);
-					}
-				}
+				appAdapter.broadcastRoom(new RoomMessage(room.getId(),  userId,  RoomMessage.Type.roomClosed));
 
 				return new ServiceResult(1L, "Closed", Type.SUCCESS);
 			} else {

Modified: openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java (original)
+++ openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java Thu Apr 21 08:21:20 2016
@@ -41,6 +41,8 @@ import org.apache.openmeetings.db.entity
 import org.apache.openmeetings.db.entity.room.Client;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.util.CalendarPatterns;
+import org.apache.openmeetings.util.message.TextRoomMessage;
+import org.apache.openmeetings.util.message.RoomMessage;
 import org.red5.logging.Red5LoggerFactory;
 import org.red5.server.api.IConnection;
 import org.red5.server.api.Red5;
@@ -94,7 +96,7 @@ public class RecordingService implements
 		try {
 			log.debug("##REC:: recordMeetingStream ::");
 
-			Long room_id = client.getRoomId();
+			Long roomId = client.getRoomId();
 
 			Date now = new Date();
 
@@ -114,7 +116,7 @@ public class RecordingService implements
 			recording.setComment(comment);
 			recording.setInterview(isInterview);
 
-			recording.setRoomId(room_id);
+			recording.setRoomId(roomId);
 			recording.setRecordStart(now);
 
 			recording.setWidth(client.getVWidth());
@@ -139,7 +141,7 @@ public class RecordingService implements
 						Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 
 						// Send every user a notification that the recording did start
-						((IServiceCapableConnection) conn).invoke("startedRecording", new Object[] { client }, this);
+						scopeApplicationAdapter.broadcastRoom(new TextRoomMessage(roomId, ownerId, RoomMessage.Type.recordingStarted, client.getPublicSID()));
 
 						// If its the recording client we need another type of Meta Data
 						if (rcl.isScreenClient()) {
@@ -304,9 +306,10 @@ public class RecordingService implements
 		}
 	}
 
-	public Long stopRecordAndSave(IScope scope, Client currentClient, Long storedRecordingId) {
+	public Long stopRecordAndSave(IScope scope, Client client, Long storedRecordingId) {
 		try {
-			log.debug("stopRecordAndSave " + currentClient.getUsername() + "," + currentClient.getUserip());
+			log.debug("stopRecordAndSave " + client.getUsername() + "," + client.getUserip());
+			scopeApplicationAdapter.broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.recordingStoped, client.getPublicSID()));
 
 			// get all stream and stop recording them
 			for (IConnection conn : scope.getClientConnections()) {
@@ -338,7 +341,7 @@ public class RecordingService implements
 				}
 			}
 			// Store to database
-			Long recordingId = currentClient.getRecordingId();
+			Long recordingId = client.getRecordingId();
 
 			// In the Case of an Interview the stopping client does not mean
 			// that its actually the recording client
@@ -350,10 +353,10 @@ public class RecordingService implements
 				recordingDao.updateEndTime(recordingId, new Date());
 
 				// Reset values
-				currentClient.setRecordingId(null);
-				currentClient.setIsRecording(false);
+				client.setRecordingId(null);
+				client.setIsRecording(false);
 
-				sessionManager.updateClientByStreamId(currentClient.getStreamid(), currentClient, false, null);
+				sessionManager.updateClientByStreamId(client.getStreamid(), client, false, null);
 				log.debug("recordingConverterTask ", recordingConverterTask);
 
 				Recording recording = recordingDao.get(recordingId);

Modified: openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java (original)
+++ openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java Thu Apr 21 08:21:20 2016
@@ -62,6 +62,12 @@ import org.apache.openmeetings.util.Init
 import org.apache.openmeetings.util.OmFileHelper;
 import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.util.Version;
+import org.apache.openmeetings.util.message.RoomMessage;
+import org.apache.openmeetings.util.message.TextRoomMessage;
+import org.apache.wicket.Application;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.IWebSocketConnection;
+import org.apache.wicket.protocol.ws.api.registry.IWebSocketConnectionRegistry;
 import org.red5.logging.Red5LoggerFactory;
 import org.red5.server.adapter.ApplicationAdapter;
 import org.red5.server.api.IClient;
@@ -232,6 +238,7 @@ public class ScopeApplicationAdapter ext
 					client.setStartStreaming(false);
 					//Send message to all users
 					sendMessageToCurrentScope("stopScreenSharingMessage", client, false);
+					broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
 					
 					returnMap.put("result", "stopSharingOnly");
 				}
@@ -241,8 +248,6 @@ public class ScopeApplicationAdapter ext
 					client.setIsRecording(false);
 					
 					returnMap.put("result", "stopRecordingOnly");
-					//Send message to all users
-					sendMessageToCurrentScope("stopRecordingMessage", client, false);
 
 					recordingService.stopRecordAndSave(current.getScope(), client, null);
 				}
@@ -351,6 +356,7 @@ public class ScopeApplicationAdapter ext
 						
 						//Send message to all users
 						sendMessageToCurrentScope("newScreenSharing", client, false);
+						broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStarted, client.getStreamPublishName()));
 					} else {
 						log.warn("Streaming is already started for the client id=" + client.getId() + ". Second request is ignored.");
 					}
@@ -503,50 +509,55 @@ public class ScopeApplicationAdapter ext
 	 * This function is kind of private/protected as the client won't be able 
 	 * to call it with proper values.
 	 * 
-	 * @param currentClient
-	 * @param currentScope
+	 * @param client
+	 * @param scope
 	 */
-	public void roomLeaveByScope(Client currentClient, IScope currentScope, boolean removeUserFromSessionList) {
+	public void roomLeaveByScope(Client client, IScope scope, boolean removeUserFromSessionList) {
 		try {
-			log.debug("currentClient " + currentClient);
-			Long roomId = currentClient.getRoomId();
+			log.debug("currentClient " + client);
+			Long roomId = client.getRoomId();
+			
+			if (client.isScreenClient() && client.isStartStreaming()) {
+				//TODO check others/find better way
+				broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
+			}
 
 			// Log the User
 			conferenceLogDao.add(ConferenceLog.Type.roomLeave,
-					currentClient.getUserId(), currentClient.getStreamid(),
-					roomId, currentClient.getUserip(), "");
+					client.getUserId(), client.getStreamid(),
+					roomId, client.getUserip(), "");
 
 			// Remove User from Sync List's
 			if (roomId != null) {
-				whiteBoardService.removeUserFromAllLists(currentScope, currentClient);
+				whiteBoardService.removeUserFromAllLists(scope, client);
 			}
 
-			log.debug("removing Username " + currentClient.getUsername() + " "
-					+ currentClient.getConnectedSince() + " streamid: "
-					+ currentClient.getStreamid());
+			log.debug("removing Username " + client.getUsername() + " "
+					+ client.getConnectedSince() + " streamid: "
+					+ client.getStreamid());
 
 			// stop and save any recordings
-			if (currentClient.getIsRecording()) {
+			if (client.getIsRecording()) {
 				log.debug("*** roomLeave Current Client is Recording - stop that");
-				if (currentClient.getInterviewPodId() != null) {
+				if (client.getInterviewPodId() != null) {
 					//interview, TODO need better check
-					_stopInterviewRecording(currentClient, currentScope);
+					_stopInterviewRecording(client, scope);
 				} else {
-					recordingService.stopRecordAndSave(currentScope, currentClient, null);
+					recordingService.stopRecordAndSave(scope, client, null);
 
 					// set to true and overwrite the default one cause otherwise no
 					// notification is send
-					currentClient.setIsRecording(true);
+					client.setIsRecording(true);
 				}
 			}
 
 			// Notify all clients of the same currentScope (room) with domain
 			// and room except the current disconnected cause it could throw an exception
-			log.debug("currentScope " + currentScope);
+			log.debug("currentScope " + scope);
 
-			if (currentScope != null && currentScope.getClientConnections() != null) {
+			if (scope != null && scope.getClientConnections() != null) {
 				// Notify Users of the current Scope
-				for (IConnection cons : currentScope.getClientConnections()) {
+				for (IConnection cons : scope.getClientConnections()) {
 					if (cons != null && cons instanceof IServiceCapableConnection) {
 						log.debug("sending roomDisconnect to {}  client id {}", cons, cons.getClient().getId());
 
@@ -559,16 +570,16 @@ public class ScopeApplicationAdapter ext
 						}
 						
 						//Do not send back to sender, but actually all other clients should receive this message swagner 01.10.2009
-						if (!currentClient.getStreamid().equals(rcl.getStreamid())) {
+						if (!client.getStreamid().equals(rcl.getStreamid())) {
 							// add Notification if another user isrecording
-							log.debug("###########[roomLeave]");
+							log.debug("###########[roomLeaveByScope]");
 							if (rcl.getIsRecording()) {
 								log.debug("*** roomLeave Any Client is Recording - stop that");
-								recordingService.stopRecordingShowForClient(cons, currentClient);
+								recordingService.stopRecordingShowForClient(cons, client);
 							}
 							
 							boolean isScreen = rcl.isScreenClient();
-							if (isScreen && currentClient.getPublicSID().equals(rcl.getStreamPublishName())) {
+							if (isScreen && client.getPublicSID().equals(rcl.getStreamPublishName())) {
 								//going to terminate screen sharing started by this client
 								((IServiceCapableConnection) cons).invoke("stopStream", new Object[] { },this);
 								continue;
@@ -578,7 +589,7 @@ public class ScopeApplicationAdapter ext
 							}
 							
 							// Send to all connected users
-							((IServiceCapableConnection) cons).invoke("roomDisconnect", new Object[] { currentClient },this);
+							((IServiceCapableConnection) cons).invoke("roomDisconnect", new Object[] { client },this);
 							log.debug("sending roomDisconnect to " + cons);
 						}
 					}
@@ -586,7 +597,7 @@ public class ScopeApplicationAdapter ext
 			}
 
 			if (removeUserFromSessionList) {
-				sessionManager.removeClient(currentClient.getStreamid(), null);
+				sessionManager.removeClient(client.getStreamid(), null);
 			}
 		} catch (Exception err) {
 			log.error("[roomLeaveByScope]", err);
@@ -2043,7 +2054,6 @@ public class ScopeApplicationAdapter ext
 			interviewStatus.put("action", "stop");
 
 			sendMessageToCurrentScope("interviewStatus", interviewStatus, true);
-			sendMessageToCurrentScope("stopRecordingMessage", currentClient, true);
 			return true;
 
 		} catch (Exception err) {
@@ -2200,4 +2210,16 @@ public class ScopeApplicationAdapter ext
 
 		sendMessageToCurrentScope("addNewUser", currentClient, false);
 	}
+	
+	public void broadcastRoom(RoomMessage msg) {
+		log.debug("Sending WebSocket message: {} {}", msg.getType(), msg instanceof TextRoomMessage ? ((TextRoomMessage)msg).getText() : "");
+		Application app = Application.get(OpenmeetingsVariables.wicketApplicationName);
+		WebSocketSettings settings = WebSocketSettings.Holder.get(app);
+		IWebSocketConnectionRegistry registry = settings.getConnectionRegistry();
+		for (IWebSocketConnection wc : registry.getConnections(app)) {
+			if (wc != null && wc.isOpen()) {
+				wc.sendMessage(msg);
+			}
+		}
+	}
 }

Modified: openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java (original)
+++ openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java Thu Apr 21 08:21:20 2016
@@ -31,9 +31,15 @@ public class RoomMessage implements IWeb
 		, roomExit
 		, roomClosed
 		, pollCreated
+		, recordingStarted
+		, recordingStoped
+		, sharingStarted
+		, sharingStoped
 		, rightUpdated
 		, activityRemove
 		, requestRightModerator
+		, requestRightWb
+		, requestRightAv
 	}
 	private final Date timestamp;
 	private final String uid;

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmButton.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmButton.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmButton.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmButton.java Thu Apr 21 08:21:20 2016
@@ -38,5 +38,5 @@ public abstract class OmButton extends B
 		});
 	}
 	
-	protected abstract void onClick(AjaxRequestTarget target); 
+	public abstract void onClick(AjaxRequestTarget target); 
 }

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java Thu Apr 21 08:21:20 2016
@@ -123,10 +123,17 @@ public class RoomPanel extends BasePanel
 	private RoomMenuPanel menu;
 	private RoomSidebar sidebar;
 	private ActivitiesPanel activities;
+	private String sharingUser = null;
+	private String recordingUser = null;
+	private String publishingUser = null; //TODO add
 	
 	public RoomPanel(String id, Room r) {
 		super(id);
 		this.r = r;
+		//TODO check here and set 
+		//private String recordingUser = null;
+		//private String sharingUser = null;
+		//private String publishingUser = null;
 	}
 
 	@Override
@@ -233,6 +240,29 @@ public class RoomPanel extends BasePanel
 						if (getUserId() != m.getUserId()) {
 							menu.pollCreated(handler);
 						}
+						break;
+					case recordingStoped:
+						//TODO check recordingUser == ((TextRoomMessage)m).getText();
+						recordingUser = null;
+						menu.update(handler);
+						break;
+					case recordingStarted:
+					{
+						recordingUser = ((TextRoomMessage)m).getText();
+						menu.update(handler);
+					}
+						break;
+					case sharingStoped:
+						//TODO check sharingUser == ((TextRoomMessage)m).getText();
+						sharingUser = null;
+						menu.update(handler);
+						break;
+					case sharingStarted:
+					{
+						sharingUser = ((TextRoomMessage)m).getText();
+						menu.update(handler);
+					}
+						break;
 					case rightUpdated:
 						sidebar.updateUsers(handler);
 						menu.update(handler);
@@ -252,7 +282,7 @@ public class RoomPanel extends BasePanel
 						roomClosed.open(handler);
 						break;
 					case requestRightModerator:
-						if (isModerator(getUserId(), r.getId())) {
+						if (isModerator(getUserId(), r.getId()) && !isModerator(m.getUserId(), r.getId())) {
 							TextRoomMessage tm = (TextRoomMessage)m;
 							activities.add(new Activity(tm.getText(), m.getUserId(), Activity.Type.requestRightModerator), handler);
 						}
@@ -263,6 +293,12 @@ public class RoomPanel extends BasePanel
 						activities.remove(tm.getText(), handler);
 					}
 						break;
+					case requestRightAv:
+						break;
+					case requestRightWb:
+						break;
+					default:
+						break;
 				}
 			}
 		}
@@ -395,4 +431,16 @@ public class RoomPanel extends BasePanel
 	public ActivitiesPanel getActivities() {
 		return activities;
 	}
+	
+	public String getSharingUser() {
+		return sharingUser;
+	}
+
+	public String getRecordingUser() {
+		return recordingUser;
+	}
+
+	public String getPublishingUser() {
+		return publishingUser;
+	}
 }

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/activities.js Thu Apr 21 08:21:20 2016
@@ -21,7 +21,7 @@ function activitiesClosed(activities) {
 	return activities.height() < 24;
 }
 function openActivities() {
-	var activities = $('#activitiesPanel');
+	var activities = $('#activities');
 	if (activitiesClosed(activities)) {
 		$('.control.block .ui-icon', activities).removeClass('ui-icon-carat-1-n').addClass('ui-icon-carat-1-s');
 		$('.control.block', activities).removeClass('ui-state-highlight');
@@ -29,21 +29,21 @@ function openActivities() {
 	}
 }
 function closeActivities() {
-	var activities = $('#activitiesPanel');
+	var activities = $('#activities');
 	if (!activitiesClosed(activities)) {
 		$('.control.block .ui-icon', activities).removeClass('ui-icon-carat-1-s').addClass('ui-icon-carat-1-n');
 		activities.animate({height: closedHeight}, 1000);
 	}
 }
 function toggleActivities() {
-	if (activitiesClosed($('#activitiesPanel'))) {
+	if (activitiesClosed($('#activities'))) {
 		openActivities();
 	} else {
 		closeActivities();
 	}
 }
 function hightlightActivities() {
-	var activities = $('#activitiesPanel');
+	var activities = $('#activities');
 	if (activitiesClosed(activities)) {
 		$('.control.block', activities).addClass('ui-state-highlight');
 	}

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.html Thu Apr 21 08:21:20 2016
@@ -24,7 +24,6 @@
 	<div class="room menu right">
 		<span wicket:id="ask" class="icon ask"></span>
 		<span wicket:id="share" class="icon share"></span>
-		<span wicket:id="recording" class="room recording"></span>
 		<span wicket:id="roomName" class="room name"></span>
 		<span wicket:id="demo" class="ui-state-error room demo"></span>
 	</div>

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java Thu Apr 21 08:21:20 2016
@@ -25,11 +25,14 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 import static org.apache.openmeetings.web.util.OmUrlFragment.ROOMS_PUBLIC;
 
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.room.PollDao;
+import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
@@ -67,6 +70,13 @@ public class RoomMenuPanel extends Panel
 	private final PollResultsDialog pollResults;
 	private final MenuPanel menuPanel;
 	private final StartSharingButton shareBtn;
+	private final Label roomName;
+	private static ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
+		@Override
+		protected DateFormat initialValue() {
+			return new SimpleDateFormat("dd.MM.yyyy HH:mm");
+		};
+	};
 	private final OmButton askBtn = new OmButton("ask") {
 		private static final long serialVersionUID = 1L;
 		{
@@ -74,7 +84,7 @@ public class RoomMenuPanel extends Panel
 			setVisible(false);
 		}
 		@Override
-		protected void onClick(AjaxRequestTarget target) {
+		public void onClick(AjaxRequestTarget target) {
 			RoomPanel.broadcast(new TextRoomMessage(room.getRoom().getId(), getUserId(), RoomMessage.Type.requestRightModerator, room.getClient().getUid()));
 		}
 	};
@@ -106,9 +116,30 @@ public class RoomMenuPanel extends Panel
 			shareBtn.onClick(target);
 		}
 	};
-	private final RoomMenuItem applyModerMenuItem = new RoomMenuItem(Application.getString(784), Application.getString(1481), false);
-	private final RoomMenuItem applyWbMenuItem = new RoomMenuItem(Application.getString(785), Application.getString(1492), false);
-	private final RoomMenuItem applyAvMenuItem = new RoomMenuItem(Application.getString(786), Application.getString(1482), false);
+	private final RoomMenuItem applyModerMenuItem = new RoomMenuItem(Application.getString(784), Application.getString(1481), false) {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public void onClick(AjaxRequestTarget target) {
+			askBtn.onClick(target);
+		}
+	};
+	private final RoomMenuItem applyWbMenuItem = new RoomMenuItem(Application.getString(785), Application.getString(1492), false) {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public void onClick(AjaxRequestTarget target) {
+			RoomPanel.broadcast(new TextRoomMessage(room.getRoom().getId(), getUserId(), RoomMessage.Type.requestRightWb, room.getClient().getUid()));
+		}
+	};
+	private final RoomMenuItem applyAvMenuItem = new RoomMenuItem(Application.getString(786), Application.getString(1482), false) {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public void onClick(AjaxRequestTarget target) {
+			RoomPanel.broadcast(new TextRoomMessage(room.getRoom().getId(), getUserId(), RoomMessage.Type.requestRightAv, room.getClient().getUid()));
+		}
+	};
 	private final RoomMenuItem pollCreateMenuItem = new RoomMenuItem(Application.getString(24), Application.getString(1483), false) {
 		private static final long serialVersionUID = 1L;
 
@@ -146,8 +177,7 @@ public class RoomMenuPanel extends Panel
 		setVisible(!r.isHidden(RoomElement.TopBar));
 		add((menuPanel = new MenuPanel("menu", getMenu())).setVisible(isVisible()));
 		add(askBtn);
-		add(new Label("roomName", r.getName()));
-		add(new Label("recording", "Recording started").setVisible(false)); //FIXME add/remove
+		add((roomName = new Label("roomName", r.getName())).setOutputMarkupId(true));
 		add(shareBtn = new StartSharingButton("share", room.getClient()));
 		add(invite = new InvitationDialog("invite", room.getRoom().getId()));
 		add(createPoll = new CreatePollDialog("createPoll", room.getRoom().getId()));
@@ -207,7 +237,7 @@ public class RoomMenuPanel extends Panel
 		actionsMenu.getItems().add(pollResultMenuItem); //FIXME enable/disable
 		actionsMenu.getItems().add(pollVoteMenuItem); //FIXME enable/disable
 		actionsMenu.getItems().add(sipDialerMenuItem);
-		actionsMenu.getItems().add(new RoomMenuItem(Application.getString(1126), Application.getString(1490)));
+		//TODO seems need to be removed actionsMenu.getItems().add(new RoomMenuItem(Application.getString(1126), Application.getString(1490)));
 		menu.add(actionsMenu);
 		return menu;
 	}
@@ -226,7 +256,8 @@ public class RoomMenuPanel extends Panel
 		boolean moder = room.getClient().hasRight(Client.Right.moderator);
 		inviteMenuItem.setEnabled(notExternalUser && moder);
 		//TODO add check "sharing started"
-		boolean shareVisible = Room.Type.interview != r.getType() && !r.isHidden(RoomElement.ScreenSharing) && r.isAllowRecording() && moder;
+		boolean shareVisible = Room.Type.interview != r.getType() && !r.isHidden(RoomElement.ScreenSharing)
+				&& r.isAllowRecording() && room.getClient().hasRight(Client.Right.share) && room.getSharingUser() == null;
 		shareMenuItem.setEnabled(shareVisible);
 		//FIXME TODO apply* should be enabled if moder is in room
 		applyModerMenuItem.setEnabled(!moder);
@@ -238,6 +269,26 @@ public class RoomMenuPanel extends Panel
 		//TODO sip menus
 		menuPanel.update(handler);
 		//FIXME TODO askBtn should be visible if moder is in room
+		StringBuilder roomClass = new StringBuilder("room name");
+		StringBuilder roomTitle = new StringBuilder();
+		if (room.getRecordingUser() != null) {
+			org.apache.openmeetings.db.entity.room.Client recUser = getBean(ISessionManager.class).getClientByPublicSID(room.getRecordingUser(), null); //TODO check server
+			if (recUser != null) {
+				roomTitle.append(String.format("%s %s %s %s %s", getString("419")
+						, recUser.getUsername(), recUser.getFirstname(), recUser.getLastname(), df.get().format(recUser.getConnectedSince())));
+				roomClass.append(" screen");
+			}
+			org.apache.openmeetings.db.entity.room.Client pubUser = getBean(ISessionManager.class).getClientByPublicSID(room.getPublishingUser(), null); //TODO check server
+			if (pubUser != null) {
+				if (recUser != null) {
+					roomTitle.append('\n');
+				}
+				roomTitle.append(String.format("%s %s %s %s %s", getString("1504")
+						, recUser.getUsername(), pubUser.getFirstname(), pubUser.getLastname(), "URL")); //TODO add URL
+				roomClass.append(" screen");
+			}
+		}
+		handler.add(roomName.add(AttributeAppender.replace("class", roomClass), AttributeAppender.replace("title", roomTitle)));
 		handler.add(askBtn.setVisible(!moder && r.isAllowUserQuestions()));
 		handler.add(shareBtn.setVisible(shareVisible));
 	}
@@ -245,6 +296,7 @@ public class RoomMenuPanel extends Panel
 	public void pollCreated(IPartialPageRequestHandler handler) {
 		vote.updateModel(handler);
 		vote.open(handler);
+		update(handler);
 	}
 	
 	public void exit(IPartialPageRequestHandler handler) {

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java?rev=1740251&r1=1740250&r2=1740251&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java Thu Apr 21 08:21:20 2016
@@ -84,7 +84,7 @@ public class StartSharingButton extends
 	}
 	
 	@Override
-	protected void onClick(AjaxRequestTarget target) {
+	public void onClick(AjaxRequestTarget target) {
 		//TODO deny download in case other screen sharing is in progress
 		String app = "";
 		try (InputStream jnlp = getClass().getClassLoader().getResourceAsStream("APPLICATION.jnlp")) {

Added: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.html
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.html?rev=1740251&view=auto
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.html (added)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.html Thu Apr 21 08:21:20 2016
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+  
+      http://www.apache.org/licenses/LICENSE-2.0
+    	  
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+  
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+<wicket:panel>
+	<span wicket:id="status" class="ui-icon align-right"></span>
+	<span class="ui-icon align-right clickable restart" wicket:message="title:610"></span>
+	<div wicket:id="name" class="user name"></div>
+	<span class="ui-icon align-right clickable audio-activity" wicket:message="title:372"></span>
+	<div wicket:id="actions" class="user actions">
+		<span class="ui-icon align-left clickable moderator-right" wicket:message="title:676"></span>
+		<span class="ui-icon align-left clickable wb-right" wicket:message="title:611"></span>
+		<span class="ui-icon align-left clickable screen-share-right" wicket:message="title:1067"></span>
+		<span class="ui-icon align-left clickable remote-control-right" wicket:message="title:1078"></span>
+		<span class="ui-icon align-left clickable audio-right" wicket:message="title:1604"></span>
+		<span class="ui-icon align-left clickable camera-right" wicket:message="title:683"></span>
+		<span class="ui-icon align-left clickable global-mute" wicket:message="title:1384"></span>
+		<span class="ui-icon align-left clickable exclsv-audio" wicket:message="title:1424"></span>
+		<span class="ui-icon align-left clickable kick" wicket:message="title:1213"></span>
+		<span wicket:id="privateChat" class="ui-icon align-right clickable private-chat" wicket:message="title:1493" onclick="startPrivateChat($(this));"></span>
+		<div class="clear"></div>
+	</div>
+</wicket:panel>
+</html>