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/14 21:58:53 UTC

svn commit: r1739179 - in /openmeetings/application: branches/3.2.x/openmeetings-server/src/site/xdoc/ branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/ branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/...

Author: solomax
Date: Thu Apr 14 19:58:52 2016
New Revision: 1739179

URL: http://svn.apache.org/viewvc?rev=1739179&view=rev
Log:
[OPENMEETINGS-1085] additional right are added, ask for moderation seems to work

Added:
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/TextRoomMessage.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-mod.png   (with props)
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-user.png   (with props)
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-wb.png   (with props)
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/TextRoomMessage.java
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-mod.png   (with props)
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-user.png   (with props)
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-wb.png   (with props)
Modified:
    openmeetings/application/branches/3.2.x/openmeetings-server/src/site/xdoc/RTMPSAndHTTPS.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.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/ActivitiesPanel.html
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
    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/message/RoomMessage.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/activities.css
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/room.css
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.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/ActivitiesPanel.html
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
    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/message/RoomMessage.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/activities.css
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/room.css

Modified: openmeetings/application/branches/3.2.x/openmeetings-server/src/site/xdoc/RTMPSAndHTTPS.xml
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-server/src/site/xdoc/RTMPSAndHTTPS.xml?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-server/src/site/xdoc/RTMPSAndHTTPS.xml (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-server/src/site/xdoc/RTMPSAndHTTPS.xml Thu Apr 14 19:58:52 2016
@@ -135,7 +135,7 @@ Enter key password for <red5>
 				<li>Restart red5 and try to connect - your connection should now be
 					made via RTMPS (close port 1935 to be sure)
 				</li>   
-		  </ol>
+			</ol>
 		</section>
 		<section name="SSL for the web interface">
 			<p>If you want to use SSL for the web interface in addition to RTMPS,

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java Thu Apr 14 19:58:52 2016
@@ -39,9 +39,6 @@ import java.util.concurrent.ConcurrentHa
 
 import javax.servlet.ServletContext;
 
-import org.apache.commons.collections4.MapIterator;
-import org.apache.commons.collections4.keyvalue.MultiKey;
-import org.apache.commons.collections4.map.MultiKeyMap;
 import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.remote.MainService;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
@@ -105,9 +102,9 @@ import ro.fortsoft.wicket.dashboard.web.
 public class Application extends AuthenticatedWebApplication implements IApplication {
 	private static final Logger log = getLogger(Application.class, webAppRootKey);
 	private static boolean isInstalled;
-	private static MultiKeyMap<String, org.apache.openmeetings.web.app.Client> ONLINE_USERS = new MultiKeyMap<>(); 
-	private static Map<String, org.apache.openmeetings.web.app.Client> INVALID_SESSIONS = new ConcurrentHashMap<String, org.apache.openmeetings.web.app.Client>();
-	private static Map<Long, Set<Client>> ROOMS = new ConcurrentHashMap<Long, Set<Client>>();
+	private static Map<String, Client> ONLINE_USERS = new ConcurrentHashMap<>(); 
+	private static Map<String, Client> INVALID_SESSIONS = new ConcurrentHashMap<>();
+	private static Map<Long, Set<Client>> ROOMS = new ConcurrentHashMap<>();
 	//additional maps for faster searching should be created
 	private DashboardContext dashboardContext;
 	private static Set<String> STRINGS_WITH_APP = new HashSet<>(); //FIXME need to be removed
@@ -211,30 +208,20 @@ public class Application extends Authent
 		return get().dashboardContext;
 	}
 	
-	public synchronized static void addOnlineUser(org.apache.openmeetings.web.app.Client client) {
-		try {
-			ONLINE_USERS.put("" + client.getUserId(), client.getSessionId(), client);
-		} catch (Exception err) {
-			log.error("[addOnlineUser]", err);
-		}
+	public static void addOnlineUser(Client client) {
+		ONLINE_USERS.put(client.getUid(), client);
 	}
 	
-	public synchronized static void removeOnlineUser(org.apache.openmeetings.web.app.Client c) {
-		try {
-			if (c != null) {
-				ONLINE_USERS.removeAll("" + c.getUserId(), c.getSessionId());
-			}
-		} catch (Exception err) {
-			log.error("[removeOnlineUser]", err);
+	public static void removeOnlineUser(Client c) {
+		if (c != null) {
+			ONLINE_USERS.remove(c.getUid());
 		}
 	}
 	
 	public static boolean isUserOnline(Long userId) {
-		MapIterator<MultiKey<? extends String>, org.apache.openmeetings.web.app.Client> it = ONLINE_USERS.mapIterator();
 		boolean isUserOnline = false;
-		while (it.hasNext()) {
-			MultiKey<? extends String> multi = it.next();
-			if (multi.size() > 0 && userId.equals(multi.getKey(0))) {
+		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
+			if (e.getValue().getUserId().equals(userId)) {
 				isUserOnline = true;
 				break;
 			}
@@ -242,17 +229,15 @@ public class Application extends Authent
 		return isUserOnline;
 	}
 
-	public static List<org.apache.openmeetings.web.app.Client> getClients() {
-		return new ArrayList<org.apache.openmeetings.web.app.Client>(ONLINE_USERS.values());
+	public static List<Client> getClients() {
+		return new ArrayList<Client>(ONLINE_USERS.values());
 	}
 
-	public static List<org.apache.openmeetings.web.app.Client> getClients(Long userId) {
-		List<org.apache.openmeetings.web.app.Client> result =  new ArrayList<org.apache.openmeetings.web.app.Client>();
-		MapIterator<MultiKey<? extends String>, org.apache.openmeetings.web.app.Client> it = ONLINE_USERS.mapIterator();
-		while (it.hasNext()) {
-			MultiKey<? extends String> multi = it.next();
-			if (multi.size() > 1 && userId.equals(multi.getKey(0))) {
-				result.add(getClientByKeys(userId, (String)(multi.getKey(1))));
+	public static List<Client> getClients(Long userId) {
+		List<Client> result =  new ArrayList<>();
+		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
+			if (e.getValue().getUserId().equals(userId)) {
+				result.add(e.getValue());
 				break;
 			}
 		}
@@ -263,13 +248,21 @@ public class Application extends Authent
 		return ONLINE_USERS.size();
 	}
 	
-	public static org.apache.openmeetings.web.app.Client getClientByKeys(Long userId, String sessionId) {
-		return (org.apache.openmeetings.web.app.Client) ONLINE_USERS.get(userId, sessionId);
+	public static Client getClientByKeys(Long userId, String sessionId) {
+		Client client = null;
+		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
+			Client c = e.getValue();
+			if (c.getUserId().equals(userId) && c.getSessionId().equals(sessionId)) {
+				client = c;
+				break;
+			}
+		} 
+		return client;
 	}
 	
 	@Override
 	public void invalidateClient(Long userId, String sessionId) {
-		org.apache.openmeetings.web.app.Client client = getClientByKeys(userId, sessionId);
+		Client client = getClientByKeys(userId, sessionId);
 		if (client != null) {
 			if (!INVALID_SESSIONS.containsKey(client.getSessionId())) {
 				INVALID_SESSIONS.put(client.getSessionId(), client);
@@ -288,13 +281,11 @@ public class Application extends Authent
 		}
 	}
 	
-	public static Client addUserToRoom(Client c, int pageId) {
-		long roomId = c.getRoomId();
+	public static Client addUserToRoom(Client c) {
+		Long roomId = c.getRoomId();
 		if (!ROOMS.containsKey(roomId)) {
 			ROOMS.put(roomId, new ConcurrentHashSet<Client>());
 		}
-		c.setSessionId(WebSession.get().getId());
-		c.setPageId(pageId);
 		ROOMS.get(roomId).add(c);
 		return c;
 	}

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java Thu Apr 14 19:58:52 2016
@@ -35,87 +35,73 @@ public class Client implements IDataProv
 	private static final long serialVersionUID = 1L;
 
 	public enum Right {
-		moderator
+		superModerator
+		, moderator
+		, whiteBoard
+		, share
+		, remoteControl
+		, audio
+		, video
+		, mute
+		, exclusive
 	}
-	private String sessionId;
+	private final String sessionId;
 	private int pageId;
-	private long userId;
-	private long roomId;
-	private String uid;
-	private Set<Right> rights = new HashSet<Right>();
-	private Date connectedSince;
+	private final Long userId;
+	private Long roomId;
+	private final String uid;
+	private final Set<Right> rights = new HashSet<Right>();
+	private final Date connectedSince;
 
-	public Client() {
-		this.connectedSince = new Date();
-	}
-	
-	public Client(long roomId) {
-		this.connectedSince = new Date();
-		this.roomId = roomId;
-		this.userId = WebSession.getUserId();
-		uid = UUID.randomUUID().toString();
+	public Client(String sessionId, Long userId) {
+		this(sessionId, 0, userId);
 	}
 	
-	public Client(String sessionId, IKey key, long userId) {
-		this(sessionId, key.hashCode(), userId);
-	}
-	
-	public Client(String sessionId, int pageId, long userId) {
+	public Client(String sessionId, int pageId, Long userId) {
 		this.sessionId = sessionId;
 		this.pageId = pageId;
 		this.userId = userId;
 		this.connectedSince = new Date();
+		uid = UUID.randomUUID().toString();
 	}
 
 	public String getSessionId() {
 		return sessionId;
 	}
 
-	public void setSessionId(String sessionId) {
-		this.sessionId = sessionId;
-	}
-
 	public int getPageId() {
 		return pageId;
 	}
 
+	public Client setPageId(IKey key) {
+		this.pageId = key.hashCode();
+		return this;
+	}
+
 	public void setPageId(int pageId) {
 		this.pageId = pageId;
 	}
 
-	public long getUserId() {
+	public Long getUserId() {
 		return userId;
 	}
 
-	public void setUserId(long userId) {
-		this.userId = userId;
-	}
-
 	public String getUid() {
 		return uid;
 	}
 
-	public void setUid(String uid) {
-		this.uid = uid;
-	}
-
-
 	public Set<Right> getRights() {
 		return rights;
 	}
 
 	public boolean hasRight(Right right) {
-		return rights.contains(Right.moderator) ? true : rights.contains(right);
+		return rights.contains(Right.superModerator) || rights.contains(Right.moderator) ? true : rights.contains(right);
 	}
 
 	public Date getConnectedSince() {
 		return connectedSince;
 	}
 
-	public void setConnectedSince(Date connectedSince) {
-		this.connectedSince = connectedSince;
-	}
-
 	@Override
 	public Long getId() {
 		return null;
@@ -125,12 +111,13 @@ public class Client implements IDataProv
 	public void setId(Long id) {
 	}
 
-	public long getRoomId() {
+	public Long getRoomId() {
 		return roomId;
 	}
 
-	public void setRoomId(long roomId) {
+	public Client setRoomId(Long roomId) {
 		this.roomId = roomId;
+		return this;
 	}
 
 	@Override
@@ -138,10 +125,8 @@ public class Client implements IDataProv
 		final int prime = 31;
 		int result = 1;
 		result = prime * result + pageId;
-		result = prime * result + (int) (roomId ^ (roomId >>> 32));
 		result = prime * result + ((sessionId == null) ? 0 : sessionId.hashCode());
 		result = prime * result + ((uid == null) ? 0 : uid.hashCode());
-		result = prime * result + (int) (userId ^ (userId >>> 32));
 		return result;
 	}
 
@@ -156,8 +141,6 @@ public class Client implements IDataProv
 		Client other = (Client) obj;
 		if (pageId != other.pageId)
 			return false;
-		if (roomId != other.roomId)
-			return false;
 		if (sessionId == null) {
 			if (other.sessionId != null)
 				return false;
@@ -168,8 +151,6 @@ public class Client implements IDataProv
 				return false;
 		} else if (!uid.equals(other.uid))
 			return false;
-		if (userId != other.userId)
-			return false;
 		return true;
 	}
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java Thu Apr 14 19:58:52 2016
@@ -91,6 +91,7 @@ public class MainPage extends BaseInited
 	private static final long serialVersionUID = 1L;
 	private static final Logger log = Red5LoggerFactory.getLogger(MainPage.class, webAppRootKey);
 	private final static String PARAM_USER_ID = "userId";
+	private Client client;
 	private final MenuPanel menu;
 	private final WebMarkupContainer topControls = new WebMarkupContainer("topControls");
 	private final WebMarkupContainer topLinks = new WebMarkupContainer("topLinks");
@@ -104,6 +105,7 @@ public class MainPage extends BaseInited
 	
 	public MainPage() {
 		super();
+		client = new Client(getSession().getId(), getUserId());
 		getHeader().setVisible(false);
 		add(topControls.setOutputMarkupPlaceholderTag(true).setMarkupId("topControls"));
 		menu = new MenuPanel("menu", getMainMenu());
@@ -147,7 +149,7 @@ public class MainPage extends BaseInited
 		add(about);
 		if (getApplication().getDebugSettings().isDevelopmentUtilitiesEnabled()) {
 			add(dev = new DebugBar("dev"));
-		    dev.setOutputMarkupId(true);
+			dev.setOutputMarkupId(true);
 		} else {
 			dev = null;
 			add(new EmptyPanel("dev").setVisible(false));
@@ -215,7 +217,7 @@ public class MainPage extends BaseInited
 			@Override
 			protected void onConnect(ConnectedMessage message) {
 				super.onConnect(message);
-				addOnlineUser(new Client(message.getSessionId(), message.getKey(), getUserId()));
+				addOnlineUser(client.setPageId(message.getKey()));
 				log.debug(String.format("WebSocketBehavior::onConnect [session: %s, key: %s]", message.getSessionId(), message.getKey()));
 			}
 			
@@ -232,13 +234,12 @@ public class MainPage extends BaseInited
 			}
 			
 			private void closeHandler(AbstractClientMessage message) {
-				Client _c = new Client(message.getSessionId(), message.getKey(), getUserId());
-				removeOnlineUser(_c);
 				log.debug(String.format("WebSocketBehavior::onClose [session: %s, key: %s]", message.getSessionId(), message.getKey()));
 				if (MainPage.this.getCurrentPanel() instanceof RoomPanel) {
 					RoomPanel rp = (RoomPanel)MainPage.this.getCurrentPanel();
 					RoomMenuPanel.roomExit(rp);
 				}
+				removeOnlineUser(client);
 			}
 		});
 		add(new AbstractDefaultAjaxBehavior() {
@@ -351,4 +352,8 @@ public class MainPage extends BaseInited
 	protected boolean isMainPage() {
 		return true;
 	}
+	
+	public Client getClient() {
+		return client;
+	}
 }

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=1739179&r1=1739178&r2=1739179&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 14 19:58:52 2016
@@ -45,6 +45,7 @@ import org.apache.openmeetings.web.room.
 import org.apache.openmeetings.web.room.activities.Activity;
 import org.apache.openmeetings.web.room.menu.RoomMenuPanel;
 import org.apache.openmeetings.web.room.message.RoomMessage;
+import org.apache.openmeetings.web.room.message.TextRoomMessage;
 import org.apache.openmeetings.web.room.sidebar.RoomSidebar;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
@@ -80,9 +81,6 @@ public class RoomPanel extends BasePanel
 	private static final long serialVersionUID = 1L;
 	private static final Logger log = Red5LoggerFactory.getLogger(RoomPanel.class, webAppRootKey);
 	private final Room r;
-	private final Client client;
-	private final RoomMenuPanel menu;
-	private final RoomSidebar sidebar;
 	private final WebMarkupContainer room = new WebMarkupContainer("roomContainer");
 	private final AbstractDefaultAjaxBehavior aab = new AbstractDefaultAjaxBehavior() {
 		private static final long serialVersionUID = 1L;
@@ -103,11 +101,19 @@ public class RoomPanel extends BasePanel
 			}
 		}
 	};
-	private final ActivitiesPanel activities;
+	private RoomMenuPanel menu;
+	private RoomSidebar sidebar;
+	private ActivitiesPanel activities;
 	
 	public RoomPanel(String id, Room r) {
 		super(id);
 		this.r = r;
+	}
+
+	@Override
+	protected void onInitialize() {
+		getClient().setRoomId(r.getId());
+		super.onInitialize();
 		Component accessDenied = new WebMarkupContainer("accessDenied").setVisible(false);
 		boolean allowed = false;
 		String deniedMessage = null;
@@ -160,15 +166,14 @@ public class RoomPanel extends BasePanel
 			accessDenied = new ExpiredMessageDialog("accessDenied", deniedMessage);
 			room.setVisible(false);
 		}
-		client = new Client(r.getId());
 		room.add((menu = new RoomMenuPanel("roomMenu", this)).setVisible(!r.getHideTopBar()));
-		room.add(new SwfPanel("whiteboard", client));
+		room.add(new SwfPanel("whiteboard", getClient()));
 		room.add(aab);
 		room.add(sidebar = new RoomSidebar("sidebar", this));
-		room.add((activities = new ActivitiesPanel("activitiesPanel", r.getId())).setVisible(!r.isActivitiesHidden()));
+		room.add((activities = new ActivitiesPanel("activitiesPanel", this)).setVisible(!r.isActivitiesHidden()));
 		add(room, accessDenied);
 	}
-
+	
 	@Override
 	public void onEvent(IEvent<?> event) {
 		if (event.getPayload() instanceof WebSocketPushPayload) {
@@ -181,28 +186,31 @@ public class RoomPanel extends BasePanel
 						if (getUserId() != m.getUserId()) {
 							menu.pollCreated(handler);
 						}
-					case pollClosed:
-					case pollDeleted:
-					case voted:
 					case rightUpdated:
+						sidebar.updateUsers(handler);
 						menu.update(handler);
 						break;
 					case roomEnter:
-						menu.update(handler);
 						sidebar.updateUsers(handler);
+						menu.update(handler);
 						//activities.addActivity(m.getUid(), m.getSentUserId(), Activity.Type.roomEnter, handler);
 						break;
 					case roomExit:
 						//TODO check user/remove tab
 						sidebar.updateUsers(handler);
-						activities.addActivity(m.getUid(), m.getUserId(), Activity.Type.roomExit, handler);
+						activities.add(new Activity(m.getUid(), m.getUserId(), Activity.Type.roomExit), handler);
 						break;
 					case requestRightModerator:
 						if (isModerator(getUserId(), r.getId())) {
-							activities.addActivity(m.getUid(), m.getUserId(), Activity.Type.requestRightModerator, handler);
+							TextRoomMessage tm = (TextRoomMessage)m;
+							activities.add(new Activity(tm.getText(), m.getUserId(), Activity.Type.requestRightModerator), handler);
 						}
 						break;
-					default:
+					case activityRemove:
+					{
+						TextRoomMessage tm = (TextRoomMessage)m;
+						activities.remove(tm.getText(), handler);
+					}
 						break;
 				}
 			}
@@ -214,19 +222,19 @@ public class RoomPanel extends BasePanel
 	protected void onBeforeRender() {
 		super.onBeforeRender();
 		if (room.isVisible()) {
-			addUserToRoom(client, getPage().getPageId());
+			addUserToRoom(getClient().setRoomId(getRoom().getId()));
 			User u = getBean(UserDao.class).get(getUserId());
 			//TODO do we need to check GroupModerationRights ????
 			if (AuthLevelUtil.hasAdminLevel(u.getRights())) {
-				client.getRights().add(Client.Right.moderator);
+				getClient().getRights().add(Client.Right.moderator);
 			} else {
 				if (!r.isModerated() && 1 == getRoomUsers(r.getId()).size()) {
-					client.getRights().add(Client.Right.moderator);
+					getClient().getRights().add(Client.Right.moderator);
 				} else if (r.isModerated()) {
 					//TODO why do we need supermoderator ????
 					for (RoomModerator rm : r.getModerators()) {
 						if (getUserId() == rm.getUser().getId()) {
-							client.getRights().add(Client.Right.moderator);
+							getClient().getRights().add(Client.Right.moderator);
 							break;
 						}
 					}
@@ -340,7 +348,7 @@ public class RoomPanel extends BasePanel
 	}
 	
 	public Client getClient() {
-		return client;
+		return getMainPage().getClient();
 	}
 	
 	public RoomSidebar getSidebar() {

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.html
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.html?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.html (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.html Thu Apr 14 19:58:52 2016
@@ -26,6 +26,8 @@
 	<div wicket:id="container" class="area ui-widget-content">
 		<div wicket:id="activities" class="activity item ui-helper-clearfix ui-corner-all">
 			<span wicket:id="close" class="ui-icon ui-icon-close ui-corner-all align-right clickable" wicket:message="title:85"></span>
+			<span wicket:id="accept" class="ui-icon ui-icon-check ui-corner-all align-right clickable" wicket:message="title:1360"></span>
+			<span wicket:id="decline" class="ui-icon ui-icon-cancel ui-corner-all align-right clickable" wicket:message="title:1361"></span>
 			<div wicket:id="text"></div>
 		</div>
 	</div>

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java Thu Apr 14 19:58:52 2016
@@ -20,10 +20,12 @@ package org.apache.openmeetings.web.room
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 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 static org.apache.openmeetings.web.room.RoomPanel.isModerator;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
 import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
+import static org.apache.openmeetings.web.room.RoomPanel.broadcast;
 
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
@@ -33,8 +35,12 @@ import java.util.Map;
 
 import org.apache.openmeetings.db.dao.user.UserDao;
 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.common.BasePanel;
-import org.apache.openmeetings.web.room.activities.Activity.Type;
+import org.apache.openmeetings.web.room.RoomPanel;
+import org.apache.openmeetings.web.room.message.RoomMessage;
+import org.apache.openmeetings.web.room.message.TextRoomMessage;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -68,7 +74,7 @@ public class ActivitiesPanel extends Bas
 		};
 	};
 	private final Map<String, Activity> activities = new LinkedHashMap<>();
-	private final long roomId;
+	private final RoomPanel room;
 	private final WebMarkupContainer container = new WebMarkupContainer("container");
 	private final AbstractDefaultAjaxBehavior action = new AbstractDefaultAjaxBehavior() {
 		private static final long serialVersionUID = 1L;
@@ -78,20 +84,41 @@ public class ActivitiesPanel extends Bas
 			try {
 				String uid = getRequest().getRequestParameters().getParameterValue(PARAM_UID).toString(); 
 				long roomId = getRequest().getRequestParameters().getParameterValue(PARAM_ROOM_ID).toLong();
-				assert(ActivitiesPanel.this.roomId == roomId);
+				assert(room.getRoom().getId().equals(roomId));
 				Action action = Action.valueOf(getRequest().getRequestParameters().getParameterValue(ACTION).toString());
 				Activity a = activities.get(uid);
 				if (a != null) {
-					if (action == Action.close && (a.getType() == Type.roomEnter || a.getType() == Type.roomExit)) {
-						activities.remove(uid);
-						update(target);
-					} else if (isModerator(getUserId(), roomId)) {
-						switch (a.getType()) {
-							case requestRightModerator:
-								break;
-							default:
-								break;	
-						}
+					switch (action) {
+						case close:
+							remove(uid, target);
+							break;
+						case decline:
+							if (isModerator(getUserId(), roomId)) {
+								broadcast(new TextRoomMessage(room.getRoom().getId(), RoomMessage.Type.activityRemove, uid));
+							}
+							break;
+						case accept:
+							if (isModerator(getUserId(), roomId)) {
+								switch (a.getType()) {
+									case requestRightModerator:
+										Client client = null;
+										for (Client c : getRoomUsers(room.getRoom().getId())) { //FIXME TODO add Map somewhere
+											if (c.getUid().equals(uid)) {
+												client = c;
+												break;
+											}
+										}
+										if (client != null) {
+											client.getRights().add(Right.moderator);
+											broadcast(new TextRoomMessage(room.getRoom().getId(), RoomMessage.Type.activityRemove, uid));
+											broadcast(new RoomMessage(room.getRoom().getId(), RoomMessage.Type.rightUpdated));
+										}
+										break;
+									default:
+										break;	
+								}
+							}
+							break;
 					}
 				} else {
 					log.error("It seems like we are being hacked!!!!");
@@ -114,6 +141,9 @@ public class ActivitiesPanel extends Bas
 		protected void populateItem(ListItem<Activity> item) {
 			Activity a = item.getModelObject();
 			String text = "";
+			Long roomId = room.getRoom().getId();
+			Component accept = new WebMarkupContainer("accept").add(new AttributeAppender("onclick", String.format("activityAction(%s, '%s', '%s');", roomId, Action.accept.name(), a.getUid()))).setVisible(false);
+			Component decline = new WebMarkupContainer("decline").add(new AttributeAppender("onclick", String.format("activityAction(%s, '%s', '%s');", roomId, Action.decline.name(), a.getUid()))).setVisible(false);
 			switch (a.getType()) {
 				case roomEnter:
 					text = ""; // TODO should this be fixed?
@@ -129,13 +159,14 @@ public class ActivitiesPanel extends Bas
 				{
 					User u = getBean(UserDao.class).get(a.getSender());
 					text = String.format("%s %s %s [%s]", u.getFirstname(), u.getLastname(), getString("room.action.request.right.moderator"), df.get().format(a.getCreated()));
-					//FIXME TODO actions
+					accept.setVisible(true);
+					decline.setVisible(true);
 				}
 				//ask question 693
 					break;
 			}
 			item.add(new WebMarkupContainer("close").add(new AttributeAppender("onclick", String.format("activityAction(%s, '%s', '%s');", roomId, Action.close.name(), a.getUid()))));
-			item.add(new Label("text", text));
+			item.add(accept, decline, new Label("text", text));
 			item.add(AttributeAppender.append("class", getClass(a)));
 		}
 		
@@ -150,11 +181,14 @@ public class ActivitiesPanel extends Bas
 		}
 	};
 
-	public void addActivity(String uid, Long userId, Activity.Type type, IPartialPageRequestHandler handler) {
-		//if (getUserId() != userId) {//FIXME should be replaced with client-id
-			activities.put(uid, new Activity(uid, userId,  type));
-			update(handler);
-		//}
+	public void add(Activity a, IPartialPageRequestHandler handler) {
+		activities.put(a.getUid(), a);
+		update(handler);
+	}
+
+	public void remove(String uid, IPartialPageRequestHandler handler) {
+		activities.remove(uid);
+		update(handler);
 	}
 
 	public void update(IPartialPageRequestHandler handler) {
@@ -162,9 +196,9 @@ public class ActivitiesPanel extends Bas
 		handler.add(container);
 	}
 	
-	public ActivitiesPanel(String id, long roomId) {
+	public ActivitiesPanel(String id, RoomPanel room) {
 		super(id);
-		this.roomId = roomId;
+		this.room = room;
 		setOutputMarkupPlaceholderTag(true);
 		setMarkupId(id);
 		add(container.add(lv).setOutputMarkupId(true));

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=1739179&r1=1739178&r2=1739179&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 14 19:58:52 2016
@@ -42,6 +42,7 @@ import org.apache.openmeetings.web.commo
 import org.apache.openmeetings.web.common.menu.RoomMenuItem;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.message.RoomMessage;
+import org.apache.openmeetings.web.room.message.TextRoomMessage;
 import org.apache.openmeetings.web.room.poll.CreatePollDialog;
 import org.apache.openmeetings.web.room.poll.PollResultsDialog;
 import org.apache.openmeetings.web.room.poll.VoteDialog;
@@ -71,7 +72,7 @@ public class RoomMenuPanel extends Panel
 		}
 		@Override
 		protected void onClick(AjaxRequestTarget target) {
-			RoomPanel.broadcast(new RoomMessage(room.getRoom().getId(), RoomMessage.Type.requestRightModerator));
+			RoomPanel.broadcast(new TextRoomMessage(room.getRoom().getId(), RoomMessage.Type.requestRightModerator, room.getClient().getUid()));
 		}
 	};
 	private final RoomPanel room;

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/RoomMessage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/RoomMessage.java?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/RoomMessage.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/RoomMessage.java Thu Apr 14 19:58:52 2016
@@ -31,10 +31,8 @@ public class RoomMessage implements IWeb
 		roomEnter
 		, roomExit
 		, pollCreated
-		, pollClosed
-		, pollDeleted
-		, voted
 		, rightUpdated
+		, activityRemove
 		, requestRightModerator
 	}
 	private final Date timestamp;

Added: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/TextRoomMessage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/TextRoomMessage.java?rev=1739179&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/TextRoomMessage.java (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/TextRoomMessage.java Thu Apr 14 19:58:52 2016
@@ -0,0 +1,33 @@
+/*
+ * 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.message;
+
+public class TextRoomMessage extends RoomMessage {
+	private static final long serialVersionUID = 1L;
+	private final String text;
+
+	public TextRoomMessage(Long roomId, Type type, String text) {
+		super(roomId, type);
+		this.text = text;
+	}
+	
+	public String getText() {
+		return text;
+	}
+}

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=1739179&r1=1739178&r2=1739179&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 14 19:58:52 2016
@@ -25,6 +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>
 				<div wicket:id="name" class="user name"></div>
 				<div class="user actions">
 					<span wicket:id="privateChat" class="private-chat om-icon align-right clickable" wicket:message="title:1493" onclick="startPrivateChat($(this));"></span>

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=1739179&r1=1739178&r2=1739179&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 14 19:58:52 2016
@@ -28,9 +28,9 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.apache.openmeetings.db.dao.user.UserDao;
-import org.apache.openmeetings.db.entity.room.Room;
 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;
@@ -60,6 +60,15 @@ public class RoomSidebar extends Panel {
 		protected void populateItem(ListItem<RoomClient> item) {
 			RoomClient rc = item.getModelObject();
 			item.setMarkupId(String.format("user%s", rc.c.getUid()));
+			WebMarkupContainer status = new WebMarkupContainer("status");
+			if (rc.c.hasRight(Right.moderator)) {
+				status.add(AttributeAppender.append("class", "status-mod"), AttributeAppender.replace("title", getString("679")));
+			} else if (rc.c.hasRight(Right.whiteBoard)) {
+				status.add(AttributeAppender.append("class", "status-wb"), AttributeAppender.replace("title", getString("678")));
+			} else {
+				status.add(AttributeAppender.append("class", "status-user"), AttributeAppender.replace("title", getString("677")));
+			}
+			item.add(status);
 			item.add(new Label("name", rc.u.getFirstname() + " " + rc.u.getLastname()));
 			item.add(AttributeAppender.append("data-userid", rc.u.getId()));
 			item.add(new WebMarkupContainer("privateChat").setVisible(!room.getRoom().isChatHidden() && getUserId() != rc.u.getId()));
@@ -72,8 +81,7 @@ public class RoomSidebar extends Panel {
 	public RoomSidebar(String id, final RoomPanel room) {
 		super(id);
 		this.room = room;
-		Room r = room.getRoom();
-		showFiles = !r.getHideFilesExplorer();//TODO add moderation check
+		updateShowFiles();
 		
 		userTab = new ITab() {
 			private static final long serialVersionUID = 1L;
@@ -111,15 +119,15 @@ public class RoomSidebar extends Panel {
 				return new FileFragment(containerId, "file-panel");
 			}
 		};
-		add(tabs = new TabbedPanel("tabs", Arrays.asList(userTab, fileTab)).setActiveTab(r.isFilesOpened() ? 1 : 0));
+		add(tabs = new TabbedPanel("tabs", Arrays.asList(userTab, fileTab)).setActiveTab(room.getRoom().isFilesOpened() ? 1 : 0));
 	}
 	
 	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()));
+			super(id, markupId, RoomSidebar.this);
+			add(users.setList(getUsers()));
 		}
 	}
 	
@@ -127,9 +135,9 @@ public class RoomSidebar extends Panel {
 		private static final long serialVersionUID = 1L;
 
 		public FileFragment(String id, String markupId) {
-            super(id, markupId, RoomSidebar.this);
-            add(new RoomFilePanel("tree", room.getRoom().getId()));
-        }
+			super(id, markupId, RoomSidebar.this);
+			add(new RoomFilePanel("tree", room.getRoom().getId()));
+		}
 	}
 
 	private List<RoomClient> getUsers() {
@@ -151,7 +159,12 @@ public class RoomSidebar extends Panel {
 		}
 	}
 	
+	private void updateShowFiles() {
+		showFiles = !room.getRoom().getHideFilesExplorer() && room.getClient().hasRight(Right.whiteBoard);
+	}
+	
 	public void updateUsers(IPartialPageRequestHandler handler) {
+		updateShowFiles();
 		users.setList(getUsers());
 		handler.add(tabs);
 	}

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/activities.css
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/activities.css?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/activities.css (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/activities.css Thu Apr 14 19:58:52 2016
@@ -37,11 +37,11 @@
 }
 .activity.item {
 	position: relative;
-	background: 0;
 	padding: 5px;
 	margin-bottom: 3px
 }
-.activity.item .ui-icon-close {
+.activity.item .ui-icon {
 	border-width: 1px;
 	border-style: solid;
+	margin-left: 2px;
 }

Added: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-mod.png
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-mod.png?rev=1739179&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-mod.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-user.png
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-user.png?rev=1739179&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-user.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-wb.png
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-wb.png?rev=1739179&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/status-wb.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

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=1739179&r1=1739178&r2=1739179&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 14 19:58:52 2016
@@ -25,6 +25,15 @@
 	background-size: 16px 16px;
 	margin-left: 5px;
 }
+.ui-icon.status-user {
+	background-image: url(images/status-user.png);
+}
+.ui-icon.status-wb {
+	background-image: url(images/status-wb.png);
+}
+.ui-icon.status-mod {
+	background-image: url(images/status-mod.png);
+}
 .top.room.menu.exit {
 	padding-left: 30px;
 }

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java Thu Apr 14 19:58:52 2016
@@ -39,9 +39,6 @@ import java.util.concurrent.ConcurrentHa
 
 import javax.servlet.ServletContext;
 
-import org.apache.commons.collections4.MapIterator;
-import org.apache.commons.collections4.keyvalue.MultiKey;
-import org.apache.commons.collections4.map.MultiKeyMap;
 import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.remote.MainService;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
@@ -105,9 +102,9 @@ import ro.fortsoft.wicket.dashboard.web.
 public class Application extends AuthenticatedWebApplication implements IApplication {
 	private static final Logger log = getLogger(Application.class, webAppRootKey);
 	private static boolean isInstalled;
-	private static MultiKeyMap<String, org.apache.openmeetings.web.app.Client> ONLINE_USERS = new MultiKeyMap<>(); 
-	private static Map<String, org.apache.openmeetings.web.app.Client> INVALID_SESSIONS = new ConcurrentHashMap<String, org.apache.openmeetings.web.app.Client>();
-	private static Map<Long, Set<Client>> ROOMS = new ConcurrentHashMap<Long, Set<Client>>();
+	private static Map<String, Client> ONLINE_USERS = new ConcurrentHashMap<>(); 
+	private static Map<String, Client> INVALID_SESSIONS = new ConcurrentHashMap<>();
+	private static Map<Long, Set<Client>> ROOMS = new ConcurrentHashMap<>();
 	//additional maps for faster searching should be created
 	private DashboardContext dashboardContext;
 	private static Set<String> STRINGS_WITH_APP = new HashSet<>(); //FIXME need to be removed
@@ -211,30 +208,20 @@ public class Application extends Authent
 		return get().dashboardContext;
 	}
 	
-	public synchronized static void addOnlineUser(org.apache.openmeetings.web.app.Client client) {
-		try {
-			ONLINE_USERS.put("" + client.getUserId(), client.getSessionId(), client);
-		} catch (Exception err) {
-			log.error("[addOnlineUser]", err);
-		}
+	public static void addOnlineUser(Client client) {
+		ONLINE_USERS.put(client.getUid(), client);
 	}
 	
-	public synchronized static void removeOnlineUser(org.apache.openmeetings.web.app.Client c) {
-		try {
-			if (c != null) {
-				ONLINE_USERS.removeAll("" + c.getUserId(), c.getSessionId());
-			}
-		} catch (Exception err) {
-			log.error("[removeOnlineUser]", err);
+	public static void removeOnlineUser(Client c) {
+		if (c != null) {
+			ONLINE_USERS.remove(c.getUid());
 		}
 	}
 	
 	public static boolean isUserOnline(Long userId) {
-		MapIterator<MultiKey<? extends String>, org.apache.openmeetings.web.app.Client> it = ONLINE_USERS.mapIterator();
 		boolean isUserOnline = false;
-		while (it.hasNext()) {
-			MultiKey<? extends String> multi = it.next();
-			if (multi.size() > 0 && userId.equals(multi.getKey(0))) {
+		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
+			if (e.getValue().getUserId().equals(userId)) {
 				isUserOnline = true;
 				break;
 			}
@@ -242,17 +229,15 @@ public class Application extends Authent
 		return isUserOnline;
 	}
 
-	public static List<org.apache.openmeetings.web.app.Client> getClients() {
-		return new ArrayList<org.apache.openmeetings.web.app.Client>(ONLINE_USERS.values());
+	public static List<Client> getClients() {
+		return new ArrayList<Client>(ONLINE_USERS.values());
 	}
 
-	public static List<org.apache.openmeetings.web.app.Client> getClients(Long userId) {
-		List<org.apache.openmeetings.web.app.Client> result =  new ArrayList<org.apache.openmeetings.web.app.Client>();
-		MapIterator<MultiKey<? extends String>, org.apache.openmeetings.web.app.Client> it = ONLINE_USERS.mapIterator();
-		while (it.hasNext()) {
-			MultiKey<? extends String> multi = it.next();
-			if (multi.size() > 1 && userId.equals(multi.getKey(0))) {
-				result.add(getClientByKeys(userId, (String)(multi.getKey(1))));
+	public static List<Client> getClients(Long userId) {
+		List<Client> result =  new ArrayList<>();
+		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
+			if (e.getValue().getUserId().equals(userId)) {
+				result.add(e.getValue());
 				break;
 			}
 		}
@@ -263,13 +248,21 @@ public class Application extends Authent
 		return ONLINE_USERS.size();
 	}
 	
-	public static org.apache.openmeetings.web.app.Client getClientByKeys(Long userId, String sessionId) {
-		return (org.apache.openmeetings.web.app.Client) ONLINE_USERS.get(userId, sessionId);
+	public static Client getClientByKeys(Long userId, String sessionId) {
+		Client client = null;
+		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
+			Client c = e.getValue();
+			if (c.getUserId().equals(userId) && c.getSessionId().equals(sessionId)) {
+				client = c;
+				break;
+			}
+		} 
+		return client;
 	}
 	
 	@Override
 	public void invalidateClient(Long userId, String sessionId) {
-		org.apache.openmeetings.web.app.Client client = getClientByKeys(userId, sessionId);
+		Client client = getClientByKeys(userId, sessionId);
 		if (client != null) {
 			if (!INVALID_SESSIONS.containsKey(client.getSessionId())) {
 				INVALID_SESSIONS.put(client.getSessionId(), client);
@@ -288,13 +281,11 @@ public class Application extends Authent
 		}
 	}
 	
-	public static Client addUserToRoom(Client c, int pageId) {
-		long roomId = c.getRoomId();
+	public static Client addUserToRoom(Client c) {
+		Long roomId = c.getRoomId();
 		if (!ROOMS.containsKey(roomId)) {
 			ROOMS.put(roomId, new ConcurrentHashSet<Client>());
 		}
-		c.setSessionId(WebSession.get().getId());
-		c.setPageId(pageId);
 		ROOMS.get(roomId).add(c);
 		return c;
 	}

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java Thu Apr 14 19:58:52 2016
@@ -35,87 +35,73 @@ public class Client implements IDataProv
 	private static final long serialVersionUID = 1L;
 
 	public enum Right {
-		moderator
+		superModerator
+		, moderator
+		, whiteBoard
+		, share
+		, remoteControl
+		, audio
+		, video
+		, mute
+		, exclusive
 	}
-	private String sessionId;
+	private final String sessionId;
 	private int pageId;
-	private long userId;
-	private long roomId;
-	private String uid;
-	private Set<Right> rights = new HashSet<Right>();
-	private Date connectedSince;
+	private final Long userId;
+	private Long roomId;
+	private final String uid;
+	private final Set<Right> rights = new HashSet<Right>();
+	private final Date connectedSince;
 
-	public Client() {
-		this.connectedSince = new Date();
-	}
-	
-	public Client(long roomId) {
-		this.connectedSince = new Date();
-		this.roomId = roomId;
-		this.userId = WebSession.getUserId();
-		uid = UUID.randomUUID().toString();
+	public Client(String sessionId, Long userId) {
+		this(sessionId, 0, userId);
 	}
 	
-	public Client(String sessionId, IKey key, long userId) {
-		this(sessionId, key.hashCode(), userId);
-	}
-	
-	public Client(String sessionId, int pageId, long userId) {
+	public Client(String sessionId, int pageId, Long userId) {
 		this.sessionId = sessionId;
 		this.pageId = pageId;
 		this.userId = userId;
 		this.connectedSince = new Date();
+		uid = UUID.randomUUID().toString();
 	}
 
 	public String getSessionId() {
 		return sessionId;
 	}
 
-	public void setSessionId(String sessionId) {
-		this.sessionId = sessionId;
-	}
-
 	public int getPageId() {
 		return pageId;
 	}
 
+	public Client setPageId(IKey key) {
+		this.pageId = key.hashCode();
+		return this;
+	}
+
 	public void setPageId(int pageId) {
 		this.pageId = pageId;
 	}
 
-	public long getUserId() {
+	public Long getUserId() {
 		return userId;
 	}
 
-	public void setUserId(long userId) {
-		this.userId = userId;
-	}
-
 	public String getUid() {
 		return uid;
 	}
 
-	public void setUid(String uid) {
-		this.uid = uid;
-	}
-
-
 	public Set<Right> getRights() {
 		return rights;
 	}
 
 	public boolean hasRight(Right right) {
-		return rights.contains(Right.moderator) ? true : rights.contains(right);
+		return rights.contains(Right.superModerator) || rights.contains(Right.moderator) ? true : rights.contains(right);
 	}
 
 	public Date getConnectedSince() {
 		return connectedSince;
 	}
 
-	public void setConnectedSince(Date connectedSince) {
-		this.connectedSince = connectedSince;
-	}
-
 	@Override
 	public Long getId() {
 		return null;
@@ -125,12 +111,13 @@ public class Client implements IDataProv
 	public void setId(Long id) {
 	}
 
-	public long getRoomId() {
+	public Long getRoomId() {
 		return roomId;
 	}
 
-	public void setRoomId(long roomId) {
+	public Client setRoomId(Long roomId) {
 		this.roomId = roomId;
+		return this;
 	}
 
 	@Override
@@ -138,10 +125,8 @@ public class Client implements IDataProv
 		final int prime = 31;
 		int result = 1;
 		result = prime * result + pageId;
-		result = prime * result + (int) (roomId ^ (roomId >>> 32));
 		result = prime * result + ((sessionId == null) ? 0 : sessionId.hashCode());
 		result = prime * result + ((uid == null) ? 0 : uid.hashCode());
-		result = prime * result + (int) (userId ^ (userId >>> 32));
 		return result;
 	}
 
@@ -156,8 +141,6 @@ public class Client implements IDataProv
 		Client other = (Client) obj;
 		if (pageId != other.pageId)
 			return false;
-		if (roomId != other.roomId)
-			return false;
 		if (sessionId == null) {
 			if (other.sessionId != null)
 				return false;
@@ -168,8 +151,6 @@ public class Client implements IDataProv
 				return false;
 		} else if (!uid.equals(other.uid))
 			return false;
-		if (userId != other.userId)
-			return false;
 		return true;
 	}
 }

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/MainPage.java Thu Apr 14 19:58:52 2016
@@ -91,6 +91,7 @@ public class MainPage extends BaseInited
 	private static final long serialVersionUID = 1L;
 	private static final Logger log = Red5LoggerFactory.getLogger(MainPage.class, webAppRootKey);
 	private final static String PARAM_USER_ID = "userId";
+	private Client client;
 	private final MenuPanel menu;
 	private final WebMarkupContainer topControls = new WebMarkupContainer("topControls");
 	private final WebMarkupContainer topLinks = new WebMarkupContainer("topLinks");
@@ -104,6 +105,7 @@ public class MainPage extends BaseInited
 	
 	public MainPage() {
 		super();
+		client = new Client(getSession().getId(), getUserId());
 		getHeader().setVisible(false);
 		add(topControls.setOutputMarkupPlaceholderTag(true).setMarkupId("topControls"));
 		menu = new MenuPanel("menu", getMainMenu());
@@ -215,7 +217,7 @@ public class MainPage extends BaseInited
 			@Override
 			protected void onConnect(ConnectedMessage message) {
 				super.onConnect(message);
-				addOnlineUser(new Client(message.getSessionId(), message.getKey(), getUserId()));
+				addOnlineUser(client.setPageId(message.getKey()));
 				log.debug(String.format("WebSocketBehavior::onConnect [session: %s, key: %s]", message.getSessionId(), message.getKey()));
 			}
 			
@@ -232,13 +234,12 @@ public class MainPage extends BaseInited
 			}
 			
 			private void closeHandler(AbstractClientMessage message) {
-				Client _c = new Client(message.getSessionId(), message.getKey(), getUserId());
-				removeOnlineUser(_c);
 				log.debug(String.format("WebSocketBehavior::onClose [session: %s, key: %s]", message.getSessionId(), message.getKey()));
 				if (MainPage.this.getCurrentPanel() instanceof RoomPanel) {
 					RoomPanel rp = (RoomPanel)MainPage.this.getCurrentPanel();
 					RoomMenuPanel.roomExit(rp);
 				}
+				removeOnlineUser(client);
 			}
 		});
 		add(new AbstractDefaultAjaxBehavior() {
@@ -351,4 +352,8 @@ public class MainPage extends BaseInited
 	protected boolean isMainPage() {
 		return true;
 	}
+	
+	public Client getClient() {
+		return client;
+	}
 }

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=1739179&r1=1739178&r2=1739179&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 14 19:58:52 2016
@@ -46,6 +46,7 @@ import org.apache.openmeetings.web.room.
 import org.apache.openmeetings.web.room.activities.Activity;
 import org.apache.openmeetings.web.room.menu.RoomMenuPanel;
 import org.apache.openmeetings.web.room.message.RoomMessage;
+import org.apache.openmeetings.web.room.message.TextRoomMessage;
 import org.apache.openmeetings.web.room.sidebar.RoomSidebar;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
@@ -85,9 +86,6 @@ public class RoomPanel extends BasePanel
 	private static final long serialVersionUID = 1L;
 	private static final Logger log = Red5LoggerFactory.getLogger(RoomPanel.class, webAppRootKey);
 	private final Room r;
-	private final Client client;
-	private final RoomMenuPanel menu;
-	private final RoomSidebar sidebar;
 	private final WebMarkupContainer room = new WebMarkupContainer("roomContainer");
 	private final AbstractDefaultAjaxBehavior aab = new AbstractDefaultAjaxBehavior() {
 		private static final long serialVersionUID = 1L;
@@ -102,7 +100,7 @@ public class RoomPanel extends BasePanel
 				String path = url.getPath();
 				path = path.substring(1, path.indexOf('/', 2) + 1);
 				target.appendJavaScript(String.format("initVideo(%s);", new JSONObject()
-						.put("uid", client.getUid())
+						.put("uid", getClient().getUid())
 						.put("audioOnly", r.isAudioOnly())
 						.put("SID", WebSession.getSid())
 						.put("interview", Room.Type.interview == r.getType())
@@ -120,11 +118,19 @@ public class RoomPanel extends BasePanel
 			}
 		}
 	};
-	private final ActivitiesPanel activities;
+	private RoomMenuPanel menu;
+	private RoomSidebar sidebar;
+	private ActivitiesPanel activities;
 	
 	public RoomPanel(String id, Room r) {
 		super(id);
 		this.r = r;
+	}
+
+	@Override
+	protected void onInitialize() {
+		getClient().setRoomId(r.getId());
+		super.onInitialize();
 		Component accessDenied = new WebMarkupContainer("accessDenied").setVisible(false);
 		boolean allowed = false;
 		String deniedMessage = null;
@@ -177,17 +183,16 @@ public class RoomPanel extends BasePanel
 			accessDenied = new ExpiredMessageDialog("accessDenied", deniedMessage);
 			room.setVisible(false);
 		}
-		client = new Client(r.getId());
 		room.add((menu = new RoomMenuPanel("roomMenu", this)).setVisible(!r.getHideTopBar()));
 		WebMarkupContainer wb = new WebMarkupContainer("whiteboard");
 		room.add(wb.setOutputMarkupId(true));
 		room.add(new WhiteboardBehavior("1", wb.getMarkupId(), null, null, null));
 		room.add(aab);
 		room.add(sidebar = new RoomSidebar("sidebar", this));
-		room.add((activities = new ActivitiesPanel("activitiesPanel", r.getId())).setVisible(!r.isActivitiesHidden()));
+		room.add((activities = new ActivitiesPanel("activitiesPanel", this)).setVisible(!r.isActivitiesHidden()));
 		add(room, accessDenied);
 	}
-
+	
 	@Override
 	public void onEvent(IEvent<?> event) {
 		if (event.getPayload() instanceof WebSocketPushPayload) {
@@ -200,28 +205,31 @@ public class RoomPanel extends BasePanel
 						if (getUserId() != m.getUserId()) {
 							menu.pollCreated(handler);
 						}
-					case pollClosed:
-					case pollDeleted:
-					case voted:
 					case rightUpdated:
+						sidebar.updateUsers(handler);
 						menu.update(handler);
 						break;
 					case roomEnter:
-						menu.update(handler);
 						sidebar.updateUsers(handler);
+						menu.update(handler);
 						//activities.addActivity(m.getUid(), m.getSentUserId(), Activity.Type.roomEnter, handler);
 						break;
 					case roomExit:
 						//TODO check user/remove tab
 						sidebar.updateUsers(handler);
-						activities.addActivity(m.getUid(), m.getUserId(), Activity.Type.roomExit, handler);
+						activities.add(new Activity(m.getUid(), m.getUserId(), Activity.Type.roomExit), handler);
 						break;
 					case requestRightModerator:
 						if (isModerator(getUserId(), r.getId())) {
-							activities.addActivity(m.getUid(), m.getUserId(), Activity.Type.requestRightModerator, handler);
+							TextRoomMessage tm = (TextRoomMessage)m;
+							activities.add(new Activity(tm.getText(), m.getUserId(), Activity.Type.requestRightModerator), handler);
 						}
 						break;
-					default:
+					case activityRemove:
+					{
+						TextRoomMessage tm = (TextRoomMessage)m;
+						activities.remove(tm.getText(), handler);
+					}
 						break;
 				}
 			}
@@ -245,19 +253,19 @@ public class RoomPanel extends BasePanel
 	protected void onBeforeRender() {
 		super.onBeforeRender();
 		if (room.isVisible()) {
-			addUserToRoom(client, getPage().getPageId());
+			addUserToRoom(getClient().setRoomId(getRoom().getId()));
 			User u = getBean(UserDao.class).get(getUserId());
 			//TODO do we need to check GroupModerationRights ????
 			if (AuthLevelUtil.hasAdminLevel(u.getRights())) {
-				client.getRights().add(Client.Right.moderator);
+				getClient().getRights().add(Client.Right.moderator);
 			} else {
 				if (!r.isModerated() && 1 == getRoomUsers(r.getId()).size()) {
-					client.getRights().add(Client.Right.moderator);
+					getClient().getRights().add(Client.Right.moderator);
 				} else if (r.isModerated()) {
 					//TODO why do we need supermoderator ????
 					for (RoomModerator rm : r.getModerators()) {
 						if (getUserId() == rm.getUser().getId()) {
-							client.getRights().add(Client.Right.moderator);
+							getClient().getRights().add(Client.Right.moderator);
 							break;
 						}
 					}
@@ -371,7 +379,7 @@ public class RoomPanel extends BasePanel
 	}
 	
 	public Client getClient() {
-		return client;
+		return getMainPage().getClient();
 	}
 	
 	public RoomSidebar getSidebar() {

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.html
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.html?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.html (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.html Thu Apr 14 19:58:52 2016
@@ -26,6 +26,8 @@
 	<div wicket:id="container" class="area ui-widget-content">
 		<div wicket:id="activities" class="activity item ui-helper-clearfix ui-corner-all">
 			<span wicket:id="close" class="ui-icon ui-icon-close ui-corner-all align-right clickable" wicket:message="title:85"></span>
+			<span wicket:id="accept" class="ui-icon ui-icon-check ui-corner-all align-right clickable" wicket:message="title:1360"></span>
+			<span wicket:id="decline" class="ui-icon ui-icon-cancel ui-corner-all align-right clickable" wicket:message="title:1361"></span>
 			<div wicket:id="text"></div>
 		</div>
 	</div>

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java Thu Apr 14 19:58:52 2016
@@ -20,10 +20,12 @@ package org.apache.openmeetings.web.room
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 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 static org.apache.openmeetings.web.room.RoomPanel.isModerator;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
 import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
+import static org.apache.openmeetings.web.room.RoomPanel.broadcast;
 
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
@@ -33,8 +35,12 @@ import java.util.Map;
 
 import org.apache.openmeetings.db.dao.user.UserDao;
 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.common.BasePanel;
-import org.apache.openmeetings.web.room.activities.Activity.Type;
+import org.apache.openmeetings.web.room.RoomPanel;
+import org.apache.openmeetings.web.room.message.RoomMessage;
+import org.apache.openmeetings.web.room.message.TextRoomMessage;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -68,7 +74,7 @@ public class ActivitiesPanel extends Bas
 		};
 	};
 	private final Map<String, Activity> activities = new LinkedHashMap<>();
-	private final long roomId;
+	private final RoomPanel room;
 	private final WebMarkupContainer container = new WebMarkupContainer("container");
 	private final AbstractDefaultAjaxBehavior action = new AbstractDefaultAjaxBehavior() {
 		private static final long serialVersionUID = 1L;
@@ -78,20 +84,41 @@ public class ActivitiesPanel extends Bas
 			try {
 				String uid = getRequest().getRequestParameters().getParameterValue(PARAM_UID).toString(); 
 				long roomId = getRequest().getRequestParameters().getParameterValue(PARAM_ROOM_ID).toLong();
-				assert(ActivitiesPanel.this.roomId == roomId);
+				assert(room.getRoom().getId().equals(roomId));
 				Action action = Action.valueOf(getRequest().getRequestParameters().getParameterValue(ACTION).toString());
 				Activity a = activities.get(uid);
 				if (a != null) {
-					if (action == Action.close && (a.getType() == Type.roomEnter || a.getType() == Type.roomExit)) {
-						activities.remove(uid);
-						update(target);
-					} else if (isModerator(getUserId(), roomId)) {
-						switch (a.getType()) {
-							case requestRightModerator:
-								break;
-							default:
-								break;	
-						}
+					switch (action) {
+						case close:
+							remove(uid, target);
+							break;
+						case decline:
+							if (isModerator(getUserId(), roomId)) {
+								broadcast(new TextRoomMessage(room.getRoom().getId(), RoomMessage.Type.activityRemove, uid));
+							}
+							break;
+						case accept:
+							if (isModerator(getUserId(), roomId)) {
+								switch (a.getType()) {
+									case requestRightModerator:
+										Client client = null;
+										for (Client c : getRoomUsers(room.getRoom().getId())) { //FIXME TODO add Map somewhere
+											if (c.getUid().equals(uid)) {
+												client = c;
+												break;
+											}
+										}
+										if (client != null) {
+											client.getRights().add(Right.moderator);
+											broadcast(new TextRoomMessage(room.getRoom().getId(), RoomMessage.Type.activityRemove, uid));
+											broadcast(new RoomMessage(room.getRoom().getId(), RoomMessage.Type.rightUpdated));
+										}
+										break;
+									default:
+										break;	
+								}
+							}
+							break;
 					}
 				} else {
 					log.error("It seems like we are being hacked!!!!");
@@ -114,6 +141,9 @@ public class ActivitiesPanel extends Bas
 		protected void populateItem(ListItem<Activity> item) {
 			Activity a = item.getModelObject();
 			String text = "";
+			Long roomId = room.getRoom().getId();
+			Component accept = new WebMarkupContainer("accept").add(new AttributeAppender("onclick", String.format("activityAction(%s, '%s', '%s');", roomId, Action.accept.name(), a.getUid()))).setVisible(false);
+			Component decline = new WebMarkupContainer("decline").add(new AttributeAppender("onclick", String.format("activityAction(%s, '%s', '%s');", roomId, Action.decline.name(), a.getUid()))).setVisible(false);
 			switch (a.getType()) {
 				case roomEnter:
 					text = ""; // TODO should this be fixed?
@@ -129,13 +159,14 @@ public class ActivitiesPanel extends Bas
 				{
 					User u = getBean(UserDao.class).get(a.getSender());
 					text = String.format("%s %s %s [%s]", u.getFirstname(), u.getLastname(), getString("room.action.request.right.moderator"), df.get().format(a.getCreated()));
-					//FIXME TODO actions
+					accept.setVisible(true);
+					decline.setVisible(true);
 				}
 				//ask question 693
 					break;
 			}
 			item.add(new WebMarkupContainer("close").add(new AttributeAppender("onclick", String.format("activityAction(%s, '%s', '%s');", roomId, Action.close.name(), a.getUid()))));
-			item.add(new Label("text", text));
+			item.add(accept, decline, new Label("text", text));
 			item.add(AttributeAppender.append("class", getClass(a)));
 		}
 		
@@ -150,11 +181,14 @@ public class ActivitiesPanel extends Bas
 		}
 	};
 
-	public void addActivity(String uid, Long userId, Activity.Type type, IPartialPageRequestHandler handler) {
-		//if (getUserId() != userId) {//FIXME should be replaced with client-id
-			activities.put(uid, new Activity(uid, userId,  type));
-			update(handler);
-		//}
+	public void add(Activity a, IPartialPageRequestHandler handler) {
+		activities.put(a.getUid(), a);
+		update(handler);
+	}
+
+	public void remove(String uid, IPartialPageRequestHandler handler) {
+		activities.remove(uid);
+		update(handler);
 	}
 
 	public void update(IPartialPageRequestHandler handler) {
@@ -162,9 +196,9 @@ public class ActivitiesPanel extends Bas
 		handler.add(container);
 	}
 	
-	public ActivitiesPanel(String id, long roomId) {
+	public ActivitiesPanel(String id, RoomPanel room) {
 		super(id);
-		this.roomId = roomId;
+		this.room = room;
 		setOutputMarkupPlaceholderTag(true);
 		setMarkupId(id);
 		add(container.add(lv).setOutputMarkupId(true));

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=1739179&r1=1739178&r2=1739179&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 14 19:58:52 2016
@@ -42,6 +42,7 @@ import org.apache.openmeetings.web.commo
 import org.apache.openmeetings.web.common.menu.RoomMenuItem;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.message.RoomMessage;
+import org.apache.openmeetings.web.room.message.TextRoomMessage;
 import org.apache.openmeetings.web.room.poll.CreatePollDialog;
 import org.apache.openmeetings.web.room.poll.PollResultsDialog;
 import org.apache.openmeetings.web.room.poll.VoteDialog;
@@ -71,7 +72,7 @@ public class RoomMenuPanel extends Panel
 		}
 		@Override
 		protected void onClick(AjaxRequestTarget target) {
-			RoomPanel.broadcast(new RoomMessage(room.getRoom().getId(), RoomMessage.Type.requestRightModerator));
+			RoomPanel.broadcast(new TextRoomMessage(room.getRoom().getId(), RoomMessage.Type.requestRightModerator, room.getClient().getUid()));
 		}
 	};
 	private final RoomPanel room;

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/RoomMessage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/RoomMessage.java?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/RoomMessage.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/RoomMessage.java Thu Apr 14 19:58:52 2016
@@ -31,10 +31,8 @@ public class RoomMessage implements IWeb
 		roomEnter
 		, roomExit
 		, pollCreated
-		, pollClosed
-		, pollDeleted
-		, voted
 		, rightUpdated
+		, activityRemove
 		, requestRightModerator
 	}
 	private final Date timestamp;

Added: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/TextRoomMessage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/TextRoomMessage.java?rev=1739179&view=auto
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/TextRoomMessage.java (added)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/message/TextRoomMessage.java Thu Apr 14 19:58:52 2016
@@ -0,0 +1,33 @@
+/*
+ * 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.message;
+
+public class TextRoomMessage extends RoomMessage {
+	private static final long serialVersionUID = 1L;
+	private final String text;
+
+	public TextRoomMessage(Long roomId, Type type, String text) {
+		super(roomId, type);
+		this.text = text;
+	}
+	
+	public String getText() {
+		return text;
+	}
+}

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html Thu Apr 14 19:58:52 2016
@@ -25,6 +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>
 				<div wicket:id="name" class="user name"></div>
 				<div class="user actions">
 					<span wicket:id="privateChat" class="private-chat om-icon align-right clickable" wicket:message="title:1493" onclick="startPrivateChat($(this));"></span>

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java Thu Apr 14 19:58:52 2016
@@ -28,9 +28,9 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.apache.openmeetings.db.dao.user.UserDao;
-import org.apache.openmeetings.db.entity.room.Room;
 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;
@@ -60,6 +60,15 @@ public class RoomSidebar extends Panel {
 		protected void populateItem(ListItem<RoomClient> item) {
 			RoomClient rc = item.getModelObject();
 			item.setMarkupId(String.format("user%s", rc.c.getUid()));
+			WebMarkupContainer status = new WebMarkupContainer("status");
+			if (rc.c.hasRight(Right.moderator)) {
+				status.add(AttributeAppender.append("class", "status-mod"), AttributeAppender.replace("title", getString("679")));
+			} else if (rc.c.hasRight(Right.whiteBoard)) {
+				status.add(AttributeAppender.append("class", "status-wb"), AttributeAppender.replace("title", getString("678")));
+			} else {
+				status.add(AttributeAppender.append("class", "status-user"), AttributeAppender.replace("title", getString("677")));
+			}
+			item.add(status);
 			item.add(new Label("name", rc.u.getFirstname() + " " + rc.u.getLastname()));
 			item.add(AttributeAppender.append("data-userid", rc.u.getId()));
 			item.add(new WebMarkupContainer("privateChat").setVisible(!room.getRoom().isChatHidden() && getUserId() != rc.u.getId()));
@@ -72,8 +81,7 @@ public class RoomSidebar extends Panel {
 	public RoomSidebar(String id, final RoomPanel room) {
 		super(id);
 		this.room = room;
-		Room r = room.getRoom();
-		showFiles = !r.getHideFilesExplorer();//TODO add moderation check
+		updateShowFiles();
 		
 		userTab = new ITab() {
 			private static final long serialVersionUID = 1L;
@@ -111,15 +119,15 @@ public class RoomSidebar extends Panel {
 				return new FileFragment(containerId, "file-panel");
 			}
 		};
-		add(tabs = new TabbedPanel("tabs", Arrays.asList(userTab, fileTab)).setActiveTab(r.isFilesOpened() ? 1 : 0));
+		add(tabs = new TabbedPanel("tabs", Arrays.asList(userTab, fileTab)).setActiveTab(room.getRoom().isFilesOpened() ? 1 : 0));
 	}
 	
 	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()));
+			super(id, markupId, RoomSidebar.this);
+			add(users.setList(getUsers()));
 		}
 	}
 	
@@ -127,9 +135,9 @@ public class RoomSidebar extends Panel {
 		private static final long serialVersionUID = 1L;
 
 		public FileFragment(String id, String markupId) {
-            super(id, markupId, RoomSidebar.this);
-            add(new RoomFilePanel("tree", room.getRoom().getId()));
-        }
+			super(id, markupId, RoomSidebar.this);
+			add(new RoomFilePanel("tree", room.getRoom().getId()));
+		}
 	}
 
 	private List<RoomClient> getUsers() {
@@ -151,7 +159,12 @@ public class RoomSidebar extends Panel {
 		}
 	}
 	
+	private void updateShowFiles() {
+		showFiles = !room.getRoom().getHideFilesExplorer() && room.getClient().hasRight(Right.whiteBoard);
+	}
+	
 	public void updateUsers(IPartialPageRequestHandler handler) {
+		updateShowFiles();
 		users.setList(getUsers());
 		handler.add(tabs);
 	}

Modified: openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/activities.css
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/activities.css?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/activities.css (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/activities.css Thu Apr 14 19:58:52 2016
@@ -37,11 +37,11 @@
 }
 .activity.item {
 	position: relative;
-	background: 0;
 	padding: 5px;
 	margin-bottom: 3px
 }
-.activity.item .ui-icon-close {
+.activity.item .ui-icon {
 	border-width: 1px;
 	border-style: solid;
+	margin-left: 2px;
 }

Added: openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-mod.png
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-mod.png?rev=1739179&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-mod.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-user.png
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-user.png?rev=1739179&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-user.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-wb.png
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-wb.png?rev=1739179&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/status-wb.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/room.css
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/room.css?rev=1739179&r1=1739178&r2=1739179&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/room.css (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/room.css Thu Apr 14 19:58:52 2016
@@ -25,6 +25,15 @@
 	background-size: 16px 16px;
 	margin-left: 5px;
 }
+.ui-icon.status-user {
+	background-image: url(images/status-user.png);
+}
+.ui-icon.status-wb {
+	background-image: url(images/status-wb.png);
+}
+.ui-icon.status-mod {
+	background-image: url(images/status-mod.png);
+}
 .top.room.menu.exit {
 	padding-left: 30px;
 }