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 2018/03/06 17:42:56 UTC

[openmeetings] branch 4.0.x updated: [OPENMEETINGS-1836] initial attempt to fix performance

This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch 4.0.x
in repository https://gitbox.apache.org/repos/asf/openmeetings.git


The following commit(s) were added to refs/heads/4.0.x by this push:
     new d6ea627  [OPENMEETINGS-1836] initial attempt to fix performance
d6ea627 is described below

commit d6ea6279db4afd878337ad3476b9861901c009ce
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Wed Mar 7 00:42:46 2018 +0700

    [OPENMEETINGS-1836] initial attempt to fix performance
---
 .../openmeetings/core/util/WebSocketHelper.java    |  22 ++--
 .../apache/openmeetings/web/common/BasePanel.java  |  11 ++
 .../apache/openmeetings/web/common/MainPanel.java  |  12 ++
 .../org/apache/openmeetings/web/common/main.js     |   4 +
 .../apache/openmeetings/web/room/RoomPanel.html    |   3 +
 .../apache/openmeetings/web/room/RoomPanel.java    | 140 +++++++++++----------
 .../web/room/sidebar/ClientIconsPanel.java         |  19 ++-
 .../web/room/sidebar/RoomClientPanel.java          |  10 +-
 .../openmeetings/web/room/sidebar/RoomSidebar.java |   4 +-
 .../web/room/sidebar/SelfIconsPanel.java           |  11 +-
 .../web/room/sidebar/icon/ClientIcon.java          |  33 ++++-
 .../web/room/sidebar/icon/KickIcon.java            |   7 +-
 .../web/room/sidebar/icon/RefreshIcon.java         |   5 +-
 .../web/room/sidebar/icon/SettingsIcon.java        |   6 +-
 .../web/room/sidebar/icon/UserSpeaksIcon.java      |   7 +-
 .../sidebar/icon/activity/CamActivityIcon.java     |   5 +-
 .../sidebar/icon/activity/MicActivityIcon.java     |   5 +-
 .../sidebar/icon/activity/RoomActivityIcon.java    |  10 +-
 .../room/sidebar/icon/right/AudioRightIcon.java    |   5 +-
 .../sidebar/icon/right/ExclusiveRightIcon.java     |   5 +-
 .../sidebar/icon/right/ModeratorRightIcon.java     |   5 +-
 .../sidebar/icon/right/PresenterRightIcon.java     |   9 +-
 .../sidebar/icon/right/RemoteControlRightIcon.java |   7 +-
 .../web/room/sidebar/icon/right/RoomRightIcon.java |  15 ++-
 .../sidebar/icon/right/ScreenShareRightIcon.java   |   7 +-
 .../room/sidebar/icon/right/VideoRightIcon.java    |   7 +-
 .../sidebar/icon/right/WhiteboardRightIcon.java    |   7 +-
 .../openmeetings/web/user/chat/ChatPanel.java      |   7 +-
 .../main/webapp/WEB-INF/classes/logback-config.xml |   2 +-
 29 files changed, 215 insertions(+), 175 deletions(-)

diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
index a0ede37..d15fb17 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
@@ -239,17 +239,19 @@ public class WebSocketHelper {
 			, BiConsumer<IWebSocketConnection, Client> consumer
 			, Predicate<Client> check)
 	{
-		Application app = (Application)getApp();
-		WebSocketSettings settings = WebSocketSettings.Holder.get(app);
-		IWebSocketConnectionRegistry reg = settings.getConnectionRegistry();
-		Executor executor = settings.getWebSocketPushMessageExecutor();
-		for (Client c : func.apply(app)) {
-			if (check == null || check.test(c)) {
-				final IWebSocketConnection wc = reg.getConnection(app, c.getSessionId(), new PageIdKey(c.getPageId()));
-				if (wc != null && wc.isOpen()) {
-					executor.run(() -> consumer.accept(wc, c));
+		new Thread(() -> {
+			Application app = (Application)getApp();
+			WebSocketSettings settings = WebSocketSettings.Holder.get(app);
+			IWebSocketConnectionRegistry reg = settings.getConnectionRegistry();
+			Executor executor = settings.getWebSocketPushMessageExecutor();
+			for (Client c : func.apply(app)) {
+				if (check == null || check.test(c)) {
+					final IWebSocketConnection wc = reg.getConnection(app, c.getSessionId(), new PageIdKey(c.getPageId()));
+					if (wc != null && wc.isOpen()) {
+						executor.run(() -> consumer.accept(wc, c));
+					}
 				}
 			}
-		}
+		}).start();
 	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/BasePanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/BasePanel.java
index d870642..2854de5 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/BasePanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/BasePanel.java
@@ -27,6 +27,8 @@ import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 
+import com.github.openjson.JSONObject;
+
 public abstract class BasePanel extends Panel {
 	private static final long serialVersionUID = 1L;
 	public static final String EVT_CLICK = "click";
@@ -82,4 +84,13 @@ public abstract class BasePanel extends Panel {
 	 */
 	public void onNewMessageClose(IPartialPageRequestHandler handler) {
 	}
+
+	/**
+	 * Handler for WebSocket messages
+	 *
+	 * @param handler - handler to perform update
+	 * @param o - message to process
+	 */
+	protected void process(IPartialPageRequestHandler handler, JSONObject o) {
+	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
index 10eb391..dca6991 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
@@ -90,6 +90,7 @@ import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.wicketstuff.urlfragment.UrlFragment;
 
+import com.github.openjson.JSONObject;
 import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
 import com.googlecode.wicket.jquery.ui.widget.menu.IMenuItem;
 
@@ -150,6 +151,17 @@ public class MainPanel extends Panel {
 					}
 					log.debug("WebSocketBehavior:: pingTimer is attached");
 					pingTimer.restart(handler);
+				} else {
+					final JSONObject m;
+					try {
+						m = new JSONObject(msg.getText());
+						BasePanel p = getCurrentPanel();
+						if (p != null) {
+							p.process(handler, m);
+						}
+					} catch (Exception e) {
+						//no-op
+					}
 				}
 			}
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
index a6536e0..1745c0c 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
@@ -52,6 +52,10 @@ var OmUtil = (function() {
 
 	self.confirmDlg = _confirmDlg;
 	self.tmpl = _tmpl;
+	self.sendMessage = function(m) {
+		const msg = JSON.stringify(m || {});
+		Wicket.WebSocket.send(msg);
+	};
 	return self;
 })();
 Wicket.BrowserInfo.collectExtraInfo = function(info) {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
index d6c38c8..5b66475 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
@@ -85,5 +85,8 @@
 			</div>
 		</div>
 	</div>
+	<script type="text/javascript">
+		OmUtil.sendMessage({area: 'room', type: 'room', action: 'roomEnter'});
+	</script>
 </wicket:panel>
 </html>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 2da8a6c..f6942a3 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -72,7 +72,6 @@ import org.apache.openmeetings.web.room.wb.WbPanel;
 import org.apache.openmeetings.web.util.ExtendedClientProperties;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
-import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
@@ -80,7 +79,6 @@ import org.apache.wicket.event.IEvent;
 import org.apache.wicket.extensions.ajax.AjaxDownloadBehavior;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.JavaScriptHeaderItem;
-import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
 import org.apache.wicket.markup.head.PriorityHeaderItem;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.protocol.ws.api.event.WebSocketPushPayload;
@@ -116,69 +114,6 @@ public class RoomPanel extends BasePanel {
 	private final Room r;
 	private final boolean interview;
 	private final WebMarkupContainer room = new WebMarkupContainer("roomContainer");
-	private final AbstractDefaultAjaxBehavior roomEnter = new AbstractDefaultAjaxBehavior() {
-		private static final long serialVersionUID = 1L;
-
-		@Override
-		protected void respond(AjaxRequestTarget target) {
-			WebSession ws = WebSession.get();
-			ExtendedClientProperties cp = ws.getExtendedProperties();
-			getBean(ConferenceLogDao.class).add(
-					ConferenceLog.Type.roomEnter
-					, getUserId(), "0", r.getId()
-					, cp.getRemoteAddress()
-					, "" + r.getId());
-			Client _c = getClient();
-			JSONObject options = VideoSettings.getInitJson(cp, r.getId(), _c.getSid())
-					.put("uid", _c.getUid())
-					.put("rights", _c.toJson(true).getJSONArray("rights"))
-					.put("interview", interview)
-					.put("showMicStatus", !r.getHiddenElements().contains(RoomElement.MicrophoneStatus))
-					.put("exclusiveTitle", getString("1386"));
-			if (!Strings.isEmpty(r.getRedirectURL()) && (ws.getSoapLogin() != null || ws.getInvitation() != null)) {
-				options.put("reloadUrl", r.getRedirectURL());
-			}
-			StringBuilder sb = new StringBuilder("Room.init(").append(options.toString(new NullStringer())).append(");")
-					.append(wb.getInitScript())
-					.append("Room.setSize();")
-					.append(getQuickPollJs());
-			target.appendJavaScript(sb);
-			WebSocketHelper.sendRoom(new RoomMessage(r.getId(), _c, RoomMessage.Type.roomEnter));
-			// play video from other participants
-			initVideos(target);
-			getMainPanel().getChat().roomEnter(r, target);
-			if (r.isFilesOpened()) {
-				sidebar.setFilesActive(target);
-			}
-			if (Room.Type.presentation != r.getType()) {
-				List<Client> mods = getBean(ClientManager.class).listByRoom(r.getId(), c -> c.hasRight(Room.Right.moderator));
-				if (mods.isEmpty()) {
-					waitApplyModeration.open(target);
-				}
-			}
-			wb.update(target);
-		}
-
-		private void initVideos(AjaxRequestTarget target) {
-			StringBuilder sb = new StringBuilder();
-			boolean hasStreams = false;
-			Client _c = getClient();
-			for (Client c: getBean(ClientManager.class).listByRoom(getRoom().getId())) {
-				boolean self = _c.getUid().equals(c.getUid());
-				for (String uid : c.getStreams()) {
-					JSONObject jo = videoJson(c, self, c.getSid(), getBean(StreamClientManager.class), uid);
-					sb.append(String.format("VideoManager.play(%s);", jo));
-					hasStreams = true;
-				}
-			}
-			if (interview && recordingUser == null && hasStreams && _c.hasRight(Right.moderator)) {
-				sb.append("WbArea.setRecStartEnabled(true);");
-			}
-			if (!Strings.isEmpty(sb)) {
-				target.appendJavaScript(sb);
-			}
-		}
-	};
 	private RedirectMessageDialog roomClosed;
 	private MessageDialog clientKicked, waitForModerator, waitApplyModeration;
 
@@ -276,7 +211,6 @@ public class RoomPanel extends BasePanel {
 			};
 			room.add(wbArea.add(wb));
 		}
-		room.add(roomEnter);
 		room.add(sidebar = new RoomSidebar("sidebar", this));
 		add(roomClosed = new RedirectMessageDialog("room-closed", "1098", r.isClosed(), r.getRedirectURL()));
 		if (r.isClosed()) {
@@ -733,9 +667,6 @@ public class RoomPanel extends BasePanel {
 		super.renderHead(response);
 		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(interview ? INTERVIEWWB_JS_REFERENCE : WB_JS_REFERENCE)));
 		response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(RoomPanel.class, "room.js"))));
-		if (room.isVisible()) {
-			response.render(OnDomReadyHeaderItem.forScript(roomEnter.getCallbackScript()));
-		}
 	}
 
 	public void requestRight(Right right, IPartialPageRequestHandler handler) {
@@ -814,6 +745,77 @@ public class RoomPanel extends BasePanel {
 		WebSocketHelper.sendRoom(new TextRoomMessage(getRoom().getId(), getClient(), RoomMessage.Type.rightUpdated, client.getUid()));
 	}
 
+	@Override
+	protected void process(IPartialPageRequestHandler handler, JSONObject o) {
+		if (room.isVisible() && "room".equals(o.optString("area"))) {
+			final String type = o.optString("type");
+			if ("room".equals(type)) {
+				if ("roomEnter".equals(o.optString("action"))) {
+					onRoomEnter(handler);
+				}
+			}
+		}
+	}
+
+	private void onRoomEnter(IPartialPageRequestHandler handler) {
+		WebSession ws = WebSession.get();
+		ExtendedClientProperties cp = ws.getExtendedProperties();
+		getBean(ConferenceLogDao.class).add(
+				ConferenceLog.Type.roomEnter
+				, getUserId(), "0", r.getId()
+				, cp.getRemoteAddress()
+				, "" + r.getId());
+		Client _c = getClient();
+		JSONObject options = VideoSettings.getInitJson(cp, r.getId(), _c.getSid())
+				.put("uid", _c.getUid())
+				.put("rights", _c.toJson(true).getJSONArray("rights"))
+				.put("interview", interview)
+				.put("showMicStatus", !r.getHiddenElements().contains(RoomElement.MicrophoneStatus))
+				.put("exclusiveTitle", getString("1386"));
+		if (!Strings.isEmpty(r.getRedirectURL()) && (ws.getSoapLogin() != null || ws.getInvitation() != null)) {
+			options.put("reloadUrl", r.getRedirectURL());
+		}
+		StringBuilder sb = new StringBuilder("Room.init(").append(options.toString(new NullStringer())).append(");")
+				.append(wb.getInitScript())
+				.append("Room.setSize();")
+				.append(getQuickPollJs());
+		handler.appendJavaScript(sb);
+		WebSocketHelper.sendRoom(new RoomMessage(r.getId(), _c, RoomMessage.Type.roomEnter));
+		// play video from other participants
+		initVideos(handler);
+		getMainPanel().getChat().roomEnter(r, handler);
+		if (r.isFilesOpened()) {
+			sidebar.setFilesActive(handler);
+		}
+		if (Room.Type.presentation != r.getType()) {
+			List<Client> mods = getBean(ClientManager.class).listByRoom(r.getId(), c -> c.hasRight(Room.Right.moderator));
+			if (mods.isEmpty()) {
+				waitApplyModeration.open(handler);
+			}
+		}
+		wb.update(handler);
+	}
+
+	private void initVideos(IPartialPageRequestHandler handler) {
+		StringBuilder sb = new StringBuilder();
+		boolean hasStreams = false;
+		Client _c = getClient();
+		for (Client c: getBean(ClientManager.class).listByRoom(getRoom().getId())) {
+			boolean self = _c.getUid().equals(c.getUid());
+			for (String uid : c.getStreams()) {
+				JSONObject jo = videoJson(c, self, c.getSid(), getBean(StreamClientManager.class), uid);
+				sb.append(String.format("VideoManager.play(%s);", jo));
+				hasStreams = true;
+			}
+		}
+		if (interview && recordingUser == null && hasStreams && _c.hasRight(Right.moderator)) {
+			sb.append("WbArea.setRecStartEnabled(true);");
+		}
+		if (!Strings.isEmpty(sb)) {
+			handler.appendJavaScript(sb);
+		}
+	}
+
 	public Room getRoom() {
 		return r;
 	}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/ClientIconsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/ClientIconsPanel.java
index 8cb8633..00779d8 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/ClientIconsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/ClientIconsPanel.java
@@ -18,7 +18,6 @@
  */
 package org.apache.openmeetings.web.room.sidebar;
 
-import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.sidebar.icon.right.AudioRightIcon;
 import org.apache.openmeetings.web.room.sidebar.icon.right.ExclusiveRightIcon;
 import org.apache.openmeetings.web.room.sidebar.icon.right.ModeratorRightIcon;
@@ -41,18 +40,18 @@ public class ClientIconsPanel extends Panel {
 	private final VideoRightIcon rightVideo;
 	private final ExclusiveRightIcon rightExclsv;
 
-	public ClientIconsPanel(String id, String uid, RoomPanel room) {
+	public ClientIconsPanel(String id, String uid) {
 		super(id);
 		setOutputMarkupId(true);
 		setOutputMarkupPlaceholderTag(true);
-		add(rightModer = new ModeratorRightIcon("right-moder", uid, room));
-		add(rightPresenter = new PresenterRightIcon("right-presenter", uid, room));
-		add(rightWb = new WhiteboardRightIcon("right-wb", uid, room));
-		add(rightScreen = new ScreenShareRightIcon("right-screen-share", uid, room));
-		add(rightRemote = new RemoteControlRightIcon("right-remote-control", uid, room));
-		add(rightAudio = new AudioRightIcon("right-audio", uid, room));
-		add(rightVideo = new VideoRightIcon("right-video", uid, room));
-		add(rightExclsv = new ExclusiveRightIcon("right-exclsv", uid, room));
+		add(rightModer = new ModeratorRightIcon("right-moder", uid));
+		add(rightPresenter = new PresenterRightIcon("right-presenter", uid));
+		add(rightWb = new WhiteboardRightIcon("right-wb", uid));
+		add(rightScreen = new ScreenShareRightIcon("right-screen-share", uid));
+		add(rightRemote = new RemoteControlRightIcon("right-remote-control", uid));
+		add(rightAudio = new AudioRightIcon("right-audio", uid));
+		add(rightVideo = new VideoRightIcon("right-video", uid));
+		add(rightExclsv = new ExclusiveRightIcon("right-exclsv", uid));
 	}
 
 	@Override
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java
index 7b586a6..9bcb491 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java
@@ -51,20 +51,20 @@ public class RoomClientPanel extends Panel {
 		item.setMarkupId(String.format("user%s", c.getUid()));
 		item.add(AttributeModifier.append("style", String.format("background-image: url(profile/%s);", c.getUserId())));
 		item.add(AttributeModifier.append("data-userid", c.getUserId()));
-		add(new RefreshIcon("refresh", uid, room));
+		add(new RefreshIcon("refresh", uid));
 		final String name = getName(c);
 		add(new Label("name", name));
-		add(new UserSpeaksIcon("user-speaks", uid, room));
+		add(new UserSpeaksIcon("user-speaks", uid));
 		item.add(AttributeModifier.replace(ATTR_TITLE, name));
 		WebMarkupContainer actions = new WebMarkupContainer("actions");
-		actions.add(new KickIcon("kick", uid, room));
+		actions.add(new KickIcon("kick", uid));
 		actions.add(new WebMarkupContainer("privateChat").setVisible(!room.getRoom().isHidden(RoomElement.Chat) && !getUserId().equals(c.getUserId())));
 		actions.setVisible(room.getClient().hasRight(Right.moderator));
 		if (c.getUid().equals(room.getClient().getUid())) {
-			actions.add(new SelfIconsPanel("icons", uid, room, false));
+			actions.add(new SelfIconsPanel("icons", uid, false));
 			item.add(AttributeModifier.append(ATTR_CLASS, "current"));
 		} else {
-			actions.add(new ClientIconsPanel("icons", uid, room));
+			actions.add(new ClientIconsPanel("icons", uid));
 		}
 		add(actions);
 	}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
index c16b630..f38bc57 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
@@ -235,7 +235,7 @@ public class RoomSidebar extends Panel {
 	public RoomSidebar(String id, final RoomPanel room) {
 		super(id);
 		this.room = room;
-		selfRights = new SelfIconsPanel("icons", room.getUid(), room, true);
+		selfRights = new SelfIconsPanel("icons", room.getUid(), true);
 	}
 
 	@Override
@@ -286,7 +286,7 @@ public class RoomSidebar extends Panel {
 	}
 
 	private void updateShowFiles(IPartialPageRequestHandler handler) {
-		if (room.isInterview()) {
+		if (room.isInterview() || room.getRoom() == null) {
 			return;
 		}
 		showFiles = !room.getRoom().isHidden(RoomElement.Files) && room.getClient().hasRight(Right.presenter);
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/SelfIconsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/SelfIconsPanel.java
index cadcfd3..daea549 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/SelfIconsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/SelfIconsPanel.java
@@ -18,7 +18,6 @@
  */
 package org.apache.openmeetings.web.room.sidebar;
 
-import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.sidebar.icon.SettingsIcon;
 import org.apache.openmeetings.web.room.sidebar.icon.activity.CamActivityIcon;
 import org.apache.openmeetings.web.room.sidebar.icon.activity.MicActivityIcon;
@@ -31,12 +30,12 @@ public class SelfIconsPanel extends ClientIconsPanel {
 	private final MicActivityIcon mic;
 	private final boolean header;
 
-	public SelfIconsPanel(String id, String uid, RoomPanel room, boolean header) {
-		super(id, uid, room);
+	public SelfIconsPanel(String id, String uid, boolean header) {
+		super(id, uid);
 		this.header = header;
-		add(settings = new SettingsIcon("settings", uid, room)
-			, cam = new CamActivityIcon("cam", uid, room)
-			, mic = new MicActivityIcon("mic", uid, room));
+		add(settings = new SettingsIcon("settings", uid)
+			, cam = new CamActivityIcon("cam", uid)
+			, mic = new MicActivityIcon("mic", uid));
 	}
 
 	@Override
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ClientIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ClientIcon.java
index 0dd3191..5d7637f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ClientIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ClientIcon.java
@@ -26,6 +26,8 @@ import static org.apache.openmeetings.web.pages.BasePage.ALIGN_RIGHT;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.addOnClick;
 
 import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.web.app.ClientManager;
 import org.apache.openmeetings.web.pages.BasePage;
 import org.apache.openmeetings.web.room.RoomPanel;
@@ -37,17 +39,16 @@ public abstract class ClientIcon extends WebMarkupContainer {
 	private static final long serialVersionUID = 1L;
 	protected static final String ICON_CLASS = "ui-icon ";
 	protected static final String CLS_CLICKABLE = "clickable ";
-	protected final RoomPanel room;
 	protected final boolean self;
 	protected final String uid;
 	protected String mainCssClass;
 	protected final StringBuilder cssClass = new StringBuilder(ICON_CLASS);
 
-	public ClientIcon(String id, String uid, RoomPanel room) {
+	public ClientIcon(String id, String uid) {
 		super(id);
-		this.room = room;
 		this.uid = uid;
-		self = room.getClient().getUid().equals(uid);
+		Client rc = getRoomClient();
+		self = rc == null ? false : rc.getUid().equals(uid);
 		setOutputMarkupId(true);
 		setOutputMarkupPlaceholderTag(true);
 	}
@@ -93,4 +94,28 @@ public abstract class ClientIcon extends WebMarkupContainer {
 	protected Client getClient() {
 		return getBean(ClientManager.class).get(uid);
 	}
+
+	protected boolean hasRight(Right right) {
+		Client c = getClient();
+		return c == null ? false : c.hasRight(right);
+	}
+
+	protected boolean roomHasRight(Right right) {
+		Client rc = getRoomClient();
+		return rc == null ? false : rc.hasRight(right);
+	}
+
+	protected Client getRoomClient() {
+		RoomPanel rp = getRoomPanel();
+		return rp == null ? null : rp.getClient();
+	}
+
+	protected RoomPanel getRoomPanel() {
+		return findParent(RoomPanel.class);
+	}
+
+	protected Room getRoom() {
+		RoomPanel rp = getRoomPanel();
+		return rp == null ? null : rp.getRoom();
+	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/KickIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/KickIcon.java
index 74ef4dc..94a5b44 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/KickIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/KickIcon.java
@@ -21,14 +21,13 @@ package org.apache.openmeetings.web.room.sidebar.icon;
 import static org.apache.openmeetings.web.room.sidebar.RoomSidebar.FUNC_ACTION;
 
 import org.apache.openmeetings.db.entity.room.Room.Right;
-import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.RoomPanel.Action;
 
 public class KickIcon extends ClientIcon {
 	private static final long serialVersionUID = 1L;
 
-	public KickIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, room);
+	public KickIcon(String id, String uid) {
+		super(id, uid);
 		mainCssClass = "kick ";
 	}
 
@@ -39,7 +38,7 @@ public class KickIcon extends ClientIcon {
 
 	@Override
 	protected boolean isClickable() {
-		return !self && room.getClient().hasRight(Right.moderator) && !getClient().hasRight(Right.superModerator);
+		return !self && roomHasRight(Right.moderator) && !hasRight(Right.superModerator);
 	}
 
 	@Override
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RefreshIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RefreshIcon.java
index 66e5c3d..13a4b06 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RefreshIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RefreshIcon.java
@@ -24,13 +24,12 @@ import static org.apache.openmeetings.web.pages.BasePage.ALIGN_RIGHT;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.basic.Client.Activity;
 import org.apache.openmeetings.web.pages.BasePage;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class RefreshIcon extends ClientIcon {
 	private static final long serialVersionUID = 1L;
 
-	public RefreshIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, room);
+	public RefreshIcon(String id, String uid) {
+		super(id, uid);
 		mainCssClass = "restart ";
 	}
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
index d19d81f..87219e9 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
@@ -18,13 +18,11 @@
  */
 package org.apache.openmeetings.web.room.sidebar.icon;
 
-import org.apache.openmeetings.web.room.RoomPanel;
-
 public class SettingsIcon extends ClientIcon {
 	private static final long serialVersionUID = 1L;
 
-	public SettingsIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, room);
+	public SettingsIcon(String id, String uid) {
+		super(id, uid);
 		mainCssClass = "settings ";
 	}
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/UserSpeaksIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/UserSpeaksIcon.java
index 9c4aa74..52cdd92 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/UserSpeaksIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/UserSpeaksIcon.java
@@ -20,18 +20,17 @@ package org.apache.openmeetings.web.room.sidebar.icon;
 
 import org.apache.openmeetings.db.entity.basic.Client.Activity;
 import org.apache.openmeetings.db.entity.room.Room;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class UserSpeaksIcon extends ClientIcon {
 	private static final long serialVersionUID = 1L;
 
-	public UserSpeaksIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, room);
+	public UserSpeaksIcon(String id, String uid) {
+		super(id, uid);
 		mainCssClass = "audio-activity ";
 	}
 
 	private boolean isActive() {
-		return getClient().hasActivity(Activity.broadcastA) && room.getClient().hasRight(Room.Right.exclusive);
+		return getClient().hasActivity(Activity.broadcastA) && roomHasRight(Room.Right.exclusive);
 	}
 
 	@Override
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/CamActivityIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/CamActivityIcon.java
index 2f1f5fb..029bee5 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/CamActivityIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/CamActivityIcon.java
@@ -21,13 +21,12 @@ package org.apache.openmeetings.web.room.sidebar.icon.activity;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.basic.Client.Activity;
 import org.apache.openmeetings.db.entity.room.Room.Right;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class CamActivityIcon extends RoomActivityIcon {
 	private static final long serialVersionUID = 1L;
 
-	public CamActivityIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, Activity.broadcastV, room);
+	public CamActivityIcon(String id, String uid) {
+		super(id, uid, Activity.broadcastV);
 		mainCssClass = "activity cam ";
 	}
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/MicActivityIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/MicActivityIcon.java
index 6ae2cbb..890749d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/MicActivityIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/MicActivityIcon.java
@@ -20,13 +20,12 @@ package org.apache.openmeetings.web.room.sidebar.icon.activity;
 
 import org.apache.openmeetings.db.entity.basic.Client.Activity;
 import org.apache.openmeetings.db.entity.room.Room.Right;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class MicActivityIcon extends RoomActivityIcon {
 	private static final long serialVersionUID = 1L;
 
-	public MicActivityIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, Activity.broadcastA, room);
+	public MicActivityIcon(String id, String uid) {
+		super(id, uid, Activity.broadcastA);
 		mainCssClass = "activity mic bumper ";
 	}
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/RoomActivityIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/RoomActivityIcon.java
index e8b772e..c5815e1 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/RoomActivityIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/RoomActivityIcon.java
@@ -24,7 +24,6 @@ import static org.apache.openmeetings.web.room.sidebar.RoomSidebar.activityAllow
 import org.apache.openmeetings.db.entity.basic.Client.Activity;
 import org.apache.openmeetings.db.entity.basic.Client.Pod;
 import org.apache.openmeetings.db.entity.room.Room;
-import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.sidebar.icon.ClientIcon;
 
 public abstract class RoomActivityIcon extends ClientIcon {
@@ -33,8 +32,8 @@ public abstract class RoomActivityIcon extends ClientIcon {
 	private static final String CLS_DISABLED = "disabled";
 	protected final Activity activity;
 
-	public RoomActivityIcon(String id, String uid, Activity activity, RoomPanel room) {
-		super(id, uid, room);
+	public RoomActivityIcon(String id, String uid, Activity activity) {
+		super(id, uid);
 		this.activity = activity;
 	}
 
@@ -44,8 +43,9 @@ public abstract class RoomActivityIcon extends ClientIcon {
 	}
 
 	protected boolean visible() {
-		return Room.Type.interview != room.getRoom().getType()
-				&& activityAllowed(getClient(), activity, room.getRoom());
+		Room r = getRoom();
+		return Room.Type.interview != r.getType()
+				&& activityAllowed(getClient(), activity, r);
 	}
 
 	@Override
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/AudioRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/AudioRightIcon.java
index f34d17c..9af1cad 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/AudioRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/AudioRightIcon.java
@@ -19,13 +19,12 @@
 package org.apache.openmeetings.web.room.sidebar.icon.right;
 
 import org.apache.openmeetings.db.entity.room.Room.Right;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class AudioRightIcon extends RoomRightIcon {
 	private static final long serialVersionUID = 1L;
 
-	public AudioRightIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, Right.audio, room);
+	public AudioRightIcon(String id, String uid) {
+		super(id, uid, Right.audio);
 		mainCssClass = "right audio bumper ";
 	}
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ExclusiveRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ExclusiveRightIcon.java
index 02cab2c..25ef75b 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ExclusiveRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ExclusiveRightIcon.java
@@ -19,13 +19,12 @@
 package org.apache.openmeetings.web.room.sidebar.icon.right;
 
 import org.apache.openmeetings.db.entity.room.Room.Right;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class ExclusiveRightIcon extends RoomRightIcon {
 	private static final long serialVersionUID = 1L;
 
-	public ExclusiveRightIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, Right.exclusive, room);
+	public ExclusiveRightIcon(String id, String uid) {
+		super(id, uid, Right.exclusive);
 		mainCssClass = "exclsv-audio ";
 	}
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ModeratorRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ModeratorRightIcon.java
index 29f7fad..a3b4956 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ModeratorRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ModeratorRightIcon.java
@@ -19,13 +19,12 @@
 package org.apache.openmeetings.web.room.sidebar.icon.right;
 
 import org.apache.openmeetings.db.entity.room.Room.Right;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class ModeratorRightIcon extends RoomRightIcon {
 	private static final long serialVersionUID = 1L;
 
-	public ModeratorRightIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, Right.moderator, room);
+	public ModeratorRightIcon(String id, String uid) {
+		super(id, uid, Right.moderator);
 		mainCssClass = "right moderator bumper ";
 	}
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/PresenterRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/PresenterRightIcon.java
index 748aa36..811a305 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/PresenterRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/PresenterRightIcon.java
@@ -21,20 +21,19 @@ package org.apache.openmeetings.web.room.sidebar.icon.right;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class PresenterRightIcon extends RoomRightIcon {
 	private static final long serialVersionUID = 1L;
 
-	public PresenterRightIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, Right.presenter, room);
+	public PresenterRightIcon(String id, String uid) {
+		super(id, uid, Right.presenter);
 		mainCssClass = "right presenter bumper ";
 	}
 
 	@Override
 	protected String getTitle() {
 		String title;
-		if (getClient().hasRight(right)) {
+		if (hasRight(right)) {
 			title = self ? "right.presenter.allowed.self" : "right.presenter.remove";
 		} else {
 			title = self ? "right.presenter.request.self" : "right.presenter.request";
@@ -44,7 +43,7 @@ public class PresenterRightIcon extends RoomRightIcon {
 
 	@Override
 	protected boolean visible() {
-		Room r = room.getRoom();
+		Room r = getRoom();
 		return Room.Type.interview != r.getType() && !r.isHidden(RoomElement.Whiteboard) && super.visible();
 	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RemoteControlRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RemoteControlRightIcon.java
index 978d9a5..44c21fa 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RemoteControlRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RemoteControlRightIcon.java
@@ -19,13 +19,12 @@
 package org.apache.openmeetings.web.room.sidebar.icon.right;
 
 import org.apache.openmeetings.db.entity.room.Room.Right;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class RemoteControlRightIcon extends RoomRightIcon {
 	private static final long serialVersionUID = 1L;
 
-	public RemoteControlRightIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, Right.remoteControl, room);
+	public RemoteControlRightIcon(String id, String uid) {
+		super(id, uid, Right.remoteControl);
 		mainCssClass = "right remote-control bumper ";
 	}
 
@@ -36,6 +35,6 @@ public class RemoteControlRightIcon extends RoomRightIcon {
 
 	@Override
 	protected boolean visible() {
-		return room.screenShareAllowed() && super.visible();
+		return getRoomPanel().screenShareAllowed() && super.visible();
 	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java
index d0e2dc2..473fd2d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java
@@ -21,7 +21,6 @@ package org.apache.openmeetings.web.room.sidebar.icon.right;
 import static org.apache.openmeetings.web.room.sidebar.RoomSidebar.FUNC_TOGGLE_RIGHT;
 
 import org.apache.openmeetings.db.entity.room.Room.Right;
-import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.sidebar.icon.ClientIcon;
 
 public abstract class RoomRightIcon extends ClientIcon {
@@ -29,18 +28,18 @@ public abstract class RoomRightIcon extends ClientIcon {
 	private static final String CLS_GRANTED = "granted ";
 	protected final Right right;
 
-	public RoomRightIcon(String id, String uid, Right right, RoomPanel room) {
-		super(id, uid, room);
+	public RoomRightIcon(String id, String uid, Right right) {
+		super(id, uid);
 		this.right = right;
 	}
 
 	@Override
 	protected boolean isClickable() {
-		return (self && !hasRight()) || !self && room.getClient().hasRight(Right.moderator);
+		return (self && !hasRight()) || !self && hasRight(Right.moderator);
 	}
 
 	protected boolean hasRight() {
-		return getClient().hasRight(right);
+		return hasRight(right);
 	}
 
 	@Override
@@ -49,9 +48,9 @@ public abstract class RoomRightIcon extends ClientIcon {
 	}
 
 	protected boolean visible() {
-		return !getClient().hasRight(Right.superModerator) && (
-				(self && !hasRight() && room.getRoom().isAllowUserQuestions())
-				|| (!self && room.getClient().hasRight(Right.moderator))
+		return !hasRight(Right.superModerator) && (
+				(self && !hasRight() && getRoom().isAllowUserQuestions())
+				|| (!self && hasRight(Right.moderator))
 			);
 	}
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ScreenShareRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ScreenShareRightIcon.java
index 90fffe7..7cdf982 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ScreenShareRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ScreenShareRightIcon.java
@@ -19,13 +19,12 @@
 package org.apache.openmeetings.web.room.sidebar.icon.right;
 
 import org.apache.openmeetings.db.entity.room.Room.Right;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class ScreenShareRightIcon extends RoomRightIcon {
 	private static final long serialVersionUID = 1L;
 
-	public ScreenShareRightIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, Right.share, room);
+	public ScreenShareRightIcon(String id, String uid) {
+		super(id, uid, Right.share);
 		mainCssClass = "right screen-share ";
 	}
 
@@ -36,6 +35,6 @@ public class ScreenShareRightIcon extends RoomRightIcon {
 
 	@Override
 	protected boolean visible() {
-		return room.screenShareAllowed() && super.visible();
+		return getRoomPanel().screenShareAllowed() && super.visible();
 	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/VideoRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/VideoRightIcon.java
index 7b78592..c63c687 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/VideoRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/VideoRightIcon.java
@@ -19,13 +19,12 @@
 package org.apache.openmeetings.web.room.sidebar.icon.right;
 
 import org.apache.openmeetings.db.entity.room.Room.Right;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class VideoRightIcon extends RoomRightIcon {
 	private static final long serialVersionUID = 1L;
 
-	public VideoRightIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, Right.video, room);
+	public VideoRightIcon(String id, String uid) {
+		super(id, uid, Right.video);
 		mainCssClass = "right camera ";
 	}
 
@@ -36,6 +35,6 @@ public class VideoRightIcon extends RoomRightIcon {
 
 	@Override
 	protected boolean visible() {
-		return !room.getRoom().isAudioOnly() && super.visible();
+		return !getRoom().isAudioOnly() && super.visible();
 	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/WhiteboardRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/WhiteboardRightIcon.java
index 4422264..a8e946b 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/WhiteboardRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/WhiteboardRightIcon.java
@@ -22,13 +22,12 @@ import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
-import org.apache.openmeetings.web.room.RoomPanel;
 
 public class WhiteboardRightIcon extends RoomRightIcon {
 	private static final long serialVersionUID = 1L;
 
-	public WhiteboardRightIcon(String id, String uid, RoomPanel room) {
-		super(id, uid, Right.whiteBoard, room);
+	public WhiteboardRightIcon(String id, String uid) {
+		super(id, uid, Right.whiteBoard);
 		mainCssClass = "right wb bumper ";
 	}
 
@@ -51,7 +50,7 @@ public class WhiteboardRightIcon extends RoomRightIcon {
 
 	@Override
 	protected boolean visible() {
-		Room r = room.getRoom();
+		Room r = getRoom();
 		return Room.Type.interview != r.getType() && !r.isHidden(RoomElement.Whiteboard) && super.visible();
 	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java
index a1b4683..98eecd5 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java
@@ -22,7 +22,6 @@ import static org.apache.openmeetings.core.util.WebSocketHelper.ID_ROOM_PREFIX;
 
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
-import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 import org.apache.wicket.markup.head.IHeaderResponse;
@@ -42,9 +41,9 @@ public class ChatPanel extends Panel {
 		add(chat = new Chat("chat"));
 	}
 
-	public void roomEnter(Room r, AjaxRequestTarget target) {
+	public void roomEnter(Room r, IPartialPageRequestHandler handler) {
 		if (r.isHidden(RoomElement.Chat)) {
-			toggle(target, false);
+			toggle(handler, false);
 			return;
 		}
 		StringBuilder sb = new StringBuilder("$(function() {");
@@ -56,7 +55,7 @@ public class ChatPanel extends Panel {
 			.append("Chat.").append(r.isChatOpened() ? "setOpened" : "close").append("();");
 		chat.processGlobal(sb);
 		sb.append("});");
-		target.appendJavaScript(sb);
+		handler.appendJavaScript(sb);
 	}
 
 	public void roomExit(Room r, IPartialPageRequestHandler handler) {
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/logback-config.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/logback-config.xml
index 6463b06..3d841a5 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/logback-config.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/logback-config.xml
@@ -47,7 +47,7 @@
 	</appender>
 	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
 		<layout class="ch.qos.logback.classic.PatternLayout">
-			<pattern>%5p %d{MM-dd HH:mm:ss.SSS } %r %L %c{15} [%.15thread] - %m%n</pattern>
+			<pattern>%highlight(%-5level) %d{MM-dd HH:mm:ss.SSS } %cyan(%c{15}:%L [%.15thread]) - %m%n</pattern>
 		</layout>
 	</appender>
 	<logger name="com.mchange.v2" level="ERROR" />

-- 
To stop receiving notification emails like this one, please contact
solomax@apache.org.