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 2017/02/17 05:55:26 UTC

svn commit: r1783331 - in /openmeetings/application: branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/ branches/3.2.x/openmeetings-db/sr...

Author: solomax
Date: Fri Feb 17 05:55:26 2017
New Revision: 1783331

URL: http://svn.apache.org/viewvc?rev=1783331&view=rev
Log:
[OPENMEETINGS-1553] more work on mobile service and chat

Modified:
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
    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/user/chat/Chat.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
    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/user/chat/Chat.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js

Modified: openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java Fri Feb 17 05:55:26 2017
@@ -29,6 +29,7 @@ import static org.apache.openmeetings.ut
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -37,8 +38,10 @@ import java.util.TimeZone;
 import java.util.UUID;
 
 import org.apache.commons.lang3.time.FastDateFormat;
+import org.apache.openmeetings.core.remote.LanguageService.Language;
 import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.core.remote.util.SessionVariablesUtil;
+import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.basic.ChatDao;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
@@ -94,6 +97,21 @@ public class MobileService {
 		return "ok";
 	}
 
+	/**
+	 * @return - List of all available Languages
+	 */
+	public List<Language> getLanguages() {
+		List<Language> result = new ArrayList<Language>();
+		for (Map.Entry<Long, Locale> e : LabelDao.languages.entrySet()) {
+			result.add(new Language(e.getKey(), e.getValue().toLanguageTag(), e.getValue().getDisplayName(Locale.ENGLISH)));
+		}
+		return result;
+	}
+
+	public long switchMicMuted(String publicSID, boolean mute) {
+		return scopeAdapter.switchMicMuted(publicSID, mute);
+	}
+
 	public Map<String, Object> checkServer() {
 		Map<String, Object> result = new HashMap<>();
 		result.put("allowSelfRegister",  "1".equals(cfgDao.getConfValue(CONFIG_FRONTEND_REGISTER_KEY, String.class, "0")));
@@ -336,30 +354,44 @@ public class MobileService {
 		return result;
 	}
 
-	public void sendChatMessage(String message) {
+	public void sendChatMessage(String msg) {
 		IConnection current = Red5.getConnectionLocal();
-		Client client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-		List<String> msg = new ArrayList<String>();
-		msg.add("chat"); //'privatechat'
-		msg.add(""); //date-time
-		msg.add("newtextmessage");
-		msg.add(client.getUsername());
-		msg.add(message);
-		msg.add(client.getUsercolor());
-		msg.add(client.getPublicSID()); //om[6] = parent.parent.isPrivate ? parent.parent.parent.refObj.publicSID : canvas.publicSID;
-		msg.add("false");// canvas.isrtl;
-		msg.add("" + client.getUserId());
-		Room room = roomDao.get(client.getRoomId());
-		msg.add("" + (room.isChatModerated() && !(client.getIsMod() || client.getIsSuperModerator())));
-		//sendMessageWithClient(msg);
+		Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 
-		//"sendVarsToMessageWithClient"
+		ChatMessage m = new ChatMessage();
+		m.setMessage(msg);
+		m.setSent(new Date());
+		User u = userDao.get(c.getUserId());
+		m.setFromUser(u);
+		Room r = roomDao.get(c.getRoomId());
+		m.setToRoom(r);
+		m.setNeedModeration(r.isChatModerated() && !isModerator(c));
+		chatDao.update(m);
+		FastDateFormat fmt = getFmt(u);
+		scopeAdapter.sendMessageWithClient(Arrays.asList("chat", encodeChatMessage(m, fmt)));
+		WebSocketHelper.sendRoom(m, WebSocketHelper.getMessage(u.getId(), Arrays.asList(m), fmt, null));
 	}
 
 	private static boolean isModerator(Client c) {
 		return c.getIsMod() || c.getIsSuperModerator();
 	}
 
+	private static FastDateFormat getFmt(User u) {
+		return FastDateFormat.getDateTimeInstance(
+				FastDateFormat.SHORT
+				, FastDateFormat.SHORT
+				, TimeZone.getTimeZone(u.getTimeZoneId())
+				, LocaleHelper.getLocale(u));
+	}
+
+	private static Map<String, Object> encodeChatMessage(ChatMessage m, FastDateFormat fmt) {
+		Map<String, Object> mm = new HashMap<>();
+		mm.put("from", String.format("%s %s", m.getFromUser().getFirstname(), m.getFromUser().getLastname()));
+		mm.put("time", fmt.format(m.getSent()));
+		mm.put("msg", m.getMessage());
+		return mm;
+	}
+
 	public List<Map<String, Object>> getRoomChatHistory() {
 		List<Map<String,Object>> myChatList = new ArrayList<>();
 		try {
@@ -371,17 +403,9 @@ public class MobileService {
 
 			Room r = roomDao.get(roomId);
 			User u = userDao.get(c.getUserId());
-			FastDateFormat format = FastDateFormat.getDateTimeInstance(
-					FastDateFormat.SHORT
-					, FastDateFormat.SHORT
-					, TimeZone.getTimeZone(u.getTimeZoneId())
-					, LocaleHelper.getLocale(u));
+			FastDateFormat fmt = getFmt(u);
 			for (ChatMessage m : chatDao.getRoom(roomId, 0, 30, !r.isChatModerated() || isModerator(c))) {
-				Map<String, Object> mm = new HashMap<>();
-				mm.put("from", String.format("%s %s", m.getFromUser().getFirstname(), m.getFromUser().getLastname()));
-				mm.put("time", format.format(m.getSent()));
-				mm.put("msg", m.getMessage());
-				myChatList.add(mm);
+				myChatList.add(encodeChatMessage(m, fmt));
 			}
 
 		} catch (Exception err) {

Modified: openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java Fri Feb 17 05:55:26 2017
@@ -23,12 +23,17 @@ import static org.apache.openmeetings.ut
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
+import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 
+import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.openmeetings.IApplication;
+import org.apache.openmeetings.db.entity.basic.ChatMessage;
 import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.db.entity.room.Room.Right;
+import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.util.message.TextRoomMessage;
@@ -38,11 +43,17 @@ import org.apache.wicket.protocol.ws.api
 import org.apache.wicket.protocol.ws.api.registry.IWebSocketConnectionRegistry;
 import org.apache.wicket.protocol.ws.api.registry.PageIdKey;
 import org.apache.wicket.protocol.ws.concurrent.Executor;
+import org.json.JSONArray;
+import org.json.JSONObject;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
 public class WebSocketHelper {
 	private static final Logger log = Red5LoggerFactory.getLogger(WebSocketHelper.class, webAppRootKey);
+	public static final String ID_TAB_PREFIX = "chatTab-";
+	public static final String ID_ALL = ID_TAB_PREFIX + "all";
+	public static final String ID_ROOM_PREFIX = ID_TAB_PREFIX + "r";
+	public static final String ID_USER_PREFIX = ID_TAB_PREFIX + "u";
 
 	public static void sendClient(final Client c, byte[] b) {
 		if (c != null) {
@@ -65,6 +76,49 @@ public class WebSocketHelper {
 		sendRoom(roomId, m, null);
 	}
 
+	private static JSONObject setScope(JSONObject o, ChatMessage m, long curUserId) {
+		String scope, scopeName = null;
+		if (m.getToUser() != null) {
+			User u = curUserId == m.getToUser().getId() ? m.getFromUser() : m.getToUser();
+			scope = ID_USER_PREFIX + u.getId();
+			scopeName = String.format("%s %s", u.getFirstname(), u.getLastname());
+		} else if (m.getToRoom() != null) {
+			scope = ID_ROOM_PREFIX + m.getToRoom().getId();
+			o.put("needModeration", m.isNeedModeration());
+		} else {
+			scope = ID_ALL;
+		}
+		return o.put("scope", scope).put("scopeName", scopeName);
+	}
+
+	public static JSONObject getMessage(long curUserId, List<ChatMessage> list, FastDateFormat fmt, BiConsumer<JSONObject, User> uFmt) {
+		JSONArray arr = new JSONArray();
+		for (ChatMessage m : list) {
+			String smsg = m.getMessage();
+			smsg = smsg == null ? smsg : " " + smsg.replaceAll("&nbsp;", " ") + " ";
+			JSONObject from = new JSONObject()
+					.put("id", m.getFromUser().getId())
+					.put("name", m.getFromUser().getFirstname() + " " + m.getFromUser().getLastname());
+			if (uFmt != null) {
+				uFmt.accept(from, m.getFromUser());
+			}
+			arr.put(setScope(new JSONObject(), m, curUserId)
+				.put("id", m.getId())
+				.put("message", smsg)
+				.put("from", from)
+				.put("actions", curUserId == m.getFromUser().getId() ? "short" : "full")
+				.put("sent", fmt.format(m.getSent())));
+		}
+		return new JSONObject()
+			.put("type", "chat")
+			.put("msg", arr);
+	}
+
+	public static void sendRoom(ChatMessage m, JSONObject msg) {
+		sendRoom(m.getToRoom().getId(), msg.toString()
+				, c -> !m.isNeedModeration() || (m.isNeedModeration() && c.hasRight(Right.moderator)));
+	}
+
 	public static void sendRoom(final Long roomId, final String m, Predicate<Client> check) {
 		log.debug("Sending WebSocket message: {}", m);
 		sendRoom(roomId, (t) -> {

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java Fri Feb 17 05:55:26 2017
@@ -28,14 +28,14 @@ import org.apache.openmeetings.db.entity
 
 /**
  * Methods to add/get/remove {@link Client}s to the session
- * 
- * 
+ *
+ *
  * @author sebawagner
  *
  */
 public interface ISessionManager {
 	void clearCache();
-	
+
 	/**
 	 * Notified on server start, when the session manager should be started and
 	 * eventually caches cleared/setup
@@ -45,7 +45,7 @@ public interface ISessionManager {
 	Client add(Client c, Server server);
 	/**
 	 * add a new client item
-	 * 
+	 *
 	 * @param streamId
 	 * @param scopeName
 	 * @param remotePort
@@ -57,17 +57,17 @@ public interface ISessionManager {
 	Client addClientListItem(String streamId, String scopeName, int remotePort, String remoteAddress, String swfUrl, Server server);
 
 	Collection<Client> getClients();
-	
+
 	/**
 	 * loads the server into the client (only if database cache is used)
-	 * 
+	 *
 	 * @return
 	 */
 	Collection<Client> getClientsWithServer();
 
 	/**
 	 * Get a client by its streamId
-	 * 
+	 *
 	 * @param streamId
 	 * @param server
 	 * @return
@@ -75,42 +75,43 @@ public interface ISessionManager {
 	Client getClientByStreamId(String streamId, Server server);
 
 	/**
-	 * get a client by its publicSID and the server, 
-	 * 
+	 * get a client by its publicSID and the server,
+	 *
 	 * @param publicSID
 	 * @param server
 	 * @return
 	 */
 	Client getClientByPublicSID(String publicSID, Server server);
-	
+
 	/**
-	 * same as {@link #getClientByPublicSID(String, boolean, Server)} but it ignores 
+	 * same as {@link #getClientByPublicSID(String, boolean, Server)} but it ignores
 	 * if the server part, so it will deliver any client just by its publicSID.<br/>
 	 * <br/>
 	 * <b>Note:</b>
-	 * This method requires more time to find the user, so under normal circumstances 
+	 * This method requires more time to find the user, so under normal circumstances
 	 * you should use {@link #getClientByPublicSID(String, boolean, Server)}!
-	 * 
+	 *
 	 * @param publicSID
 	 * @return
 	 */
 	ClientSessionInfo getClientByPublicSIDAnyServer(String publicSID);
 
 	/**
-	 * 
+	 *
 	 * @param userId
 	 * @return
-	 * 
+	 *
 	 * @deprecated There could be multiple users logged in with the same userid,
 	 *             then this call would return a list not a single user
 	 */
+	@Deprecated
 	Client getClientByUserId(Long userId);
 
 	/**
 	 * Update the session object of the audio/video-connection and additionally
 	 * swap the values to the session object of the user that holds the full
 	 * session object
-	 * 
+	 *
 	 * @param streamId
 	 * @param rcm
 	 * @return
@@ -119,11 +120,11 @@ public interface ISessionManager {
 
 	/**
 	 * Update the session object
-	 * 
+	 *
 	 * updateRoomCount is only <i>one</i> time true, in
 	 * ScopeApplicationAdapter#setRoomValues(Long, Boolean, Boolean, String)
 	 * .
-	 * 
+	 *
 	 * @param streamId
 	 * @param rcm
 	 * @param updateRoomCount
@@ -134,7 +135,7 @@ public interface ISessionManager {
 
 	/**
 	 * Remove a client from the session store
-	 * 
+	 *
 	 * @param streamId
 	 * @return
 	 */
@@ -145,16 +146,16 @@ public interface ISessionManager {
 	 * needed cause it is invoked internally AFTER the current user has been
 	 * already removed from the ClientList to see if the Room is empty again and
 	 * the PollList can be removed
-	 * @param roomId 
+	 * @param roomId
 	 * @return
 	 */
 	List<Client> getClientListByRoom(Long roomId);
-	
+
 	Collection<Client> getClientListByRoomAll(Long roomId);
 
 	/**
 	 * get the current Moderator in this room
-	 * 
+	 *
 	 * @param roomname
 	 * @return
 	 */
@@ -162,7 +163,7 @@ public interface ISessionManager {
 
 	/**
 	 * Get list of current client sessions
-	 * 
+	 *
 	 * @param start
 	 * @param max
 	 * @param orderby
@@ -173,7 +174,7 @@ public interface ISessionManager {
 
 	/**
 	 * returns number of current users recording
-	 * 
+	 *
 	 * @param roomId
 	 * @return
 	 */
@@ -181,16 +182,16 @@ public interface ISessionManager {
 
 	/**
 	 * returns a number of current users publishing screensharing
-	 * 
+	 *
 	 * @param roomId
 	 * @return
 	 */
 	long getPublishingCount(long roomId);
-	
+
 	/**
-	 * Get a list of all servers of all rooms on that server, serverId = null 
+	 * Get a list of all servers of all rooms on that server, serverId = null
 	 * means it is a local session on the master.
-	 * 
+	 *
 	 * @param server
 	 * @return a set, a roomId can be only one time in this list
 	 */
@@ -198,7 +199,7 @@ public interface ISessionManager {
 
 	/**
 	 * Get some statistics about the current sessions
-	 * 
+	 *
 	 * @return
 	 */
 	String getSessionStatistics();

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=1783331&r1=1783330&r2=1783331&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 Fri Feb 17 05:55:26 2017
@@ -207,7 +207,7 @@ public class Application extends Authent
 	}
 
 	public static Application get() {
-		return (Application) WebApplication.get();
+		return (Application) WebApplication.get(wicketApplicationName);
 	}
 
 	public static DashboardContext getDashboardContext() {

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java Fri Feb 17 05:55:26 2017
@@ -18,6 +18,9 @@
  */
 package org.apache.openmeetings.web.user.chat;
 
+import static org.apache.openmeetings.core.util.WebSocketHelper.ID_ALL;
+import static org.apache.openmeetings.core.util.WebSocketHelper.ID_ROOM_PREFIX;
+import static org.apache.openmeetings.core.util.WebSocketHelper.ID_USER_PREFIX;
 import static org.apache.openmeetings.db.util.AuthLevelUtil.hasAdminLevel;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
@@ -46,7 +49,6 @@ import org.apache.openmeetings.db.dao.ro
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.basic.ChatMessage;
 import org.apache.openmeetings.db.entity.room.Room;
-import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
@@ -62,7 +64,6 @@ import org.apache.wicket.markup.html.for
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
-import org.json.JSONArray;
 import org.json.JSONObject;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -73,10 +74,6 @@ import com.googlecode.wicket.jquery.ui.p
 public class Chat extends Panel {
 	private static final long serialVersionUID = 1L;
 	private static final Logger log = Red5LoggerFactory.getLogger(Chat.class, webAppRootKey);
-	private static final String ID_TAB_PREFIX = "chatTab-";
-	private static final String ID_USER_PREFIX = ID_TAB_PREFIX + "u";
-	public static final String ID_ROOM_PREFIX = ID_TAB_PREFIX + "r";
-	private static final String ID_ALL = ID_TAB_PREFIX + "all";
 	private static final String PARAM_MSG_ID = "msgid";
 	private static final String PARAM_ROOM_ID = "roomid";
 	private final AbstractDefaultAjaxBehavior acceptMessage = new AbstractDefaultAjaxBehavior() {
@@ -92,7 +89,7 @@ public class Chat extends Panel {
 				if (m.isNeedModeration() && isModerator(getUserId(), roomId)) {
 					m.setNeedModeration(false);
 					dao.update(m);
-					sendRoom(m, getMessage(Arrays.asList(m)).put("mode",  "accept").toString());
+					WebSocketHelper.sendRoom(m, getMessage(Arrays.asList(m)).put("mode",  "accept"));
 				} else {
 					log.error("It seems like we are being hacked!!!!");
 				}
@@ -102,47 +99,12 @@ public class Chat extends Panel {
 		}
 	};
 
-	private static JSONObject setScope(JSONObject o, ChatMessage m, long curUserId) {
-		String scope, scopeName;
-		if (m.getToUser() != null) {
-			User u = curUserId == m.getToUser().getId() ? m.getFromUser() : m.getToUser();
-			scope = ID_USER_PREFIX + u.getId();
-			scopeName = String.format("%s %s", u.getFirstname(), u.getLastname());
-		} else if (m.getToRoom() != null) {
-			scope = ID_ROOM_PREFIX + m.getToRoom().getId();
-			scopeName = String.format("%s %s", Application.getString(406), m.getToRoom().getId());
-			o.put("needModeration", m.isNeedModeration());
-		} else {
-			scope = ID_ALL;
-			scopeName = Application.getString(1494);
-		}
-		return o.put("scope", scope).put("scopeName", scopeName);
-	}
-
 	public JSONObject getMessage(List<ChatMessage> list) {
 		return getMessage(getUserId(), list);
 	}
 
-	private JSONObject getMessage(long curUserId, List<ChatMessage> list) {
-		JSONArray arr = new JSONArray();
-		for (ChatMessage m : list) {
-			String smsg = m.getMessage();
-			smsg = smsg == null ? smsg : " " + smsg.replaceAll("&nbsp;", " ") + " ";
-			arr.put(setScope(new JSONObject(), m, curUserId)
-				.put("id", m.getId())
-				.put("message", smsg)
-				.put("from", new JSONObject()
-						.put("id", m.getFromUser().getId())
-						.put("name", m.getFromUser().getFirstname() + " " + m.getFromUser().getLastname())
-						.put("img", getUrl(getRequestCycle(), m.getFromUser().getId()))
-
-					)
-				.put("actions", curUserId == m.getFromUser().getId() ? "short" : "full")
-				.put("sent", getDateFormat().format(m.getSent())));
-		}
-		return new JSONObject()
-			.put("type", "chat")
-			.put("msg", arr);
+	public JSONObject getMessage(Long userId, List<ChatMessage> list) {
+		return WebSocketHelper.getMessage(getUserId(), list, getDateFormat(), (o, u) -> o.put("img", getUrl(getRequestCycle(), u)));
 	}
 
 	public Chat(String id) {
@@ -154,6 +116,13 @@ public class Chat extends Panel {
 		add(new ChatForm("sendForm"));
 	}
 
+	public static CharSequence getReinit() {
+		StringBuilder sb = new StringBuilder("chatReinit(");
+		sb.append('\'').append(ID_ALL).append('\'')
+		.append(',').append('\'').append(ID_ROOM_PREFIX).append('\'');
+		return sb.append("); ");
+	}
+
 	public CharSequence addRoom(Room r) {
 		StringBuilder sb = new StringBuilder();
 		sb.append(String.format("addChatTab('%1$s%2$d', '%3$s %2$d');", ID_ROOM_PREFIX, r.getId(), Application.getString(406)));
@@ -181,16 +150,11 @@ public class Chat extends Panel {
 			list.addAll(dao.getRoom(roomId, 0, 30, !r.isChatModerated() || isModerator(getUserId(), roomId)));
 		}
 		list.addAll(dao.getUserRecent(getUserId(), Date.from(Instant.now().minus(Duration.ofHours(1L))), 0, 30));
+		StringBuilder sb = new StringBuilder(getReinit());
 		if (list.size() > 0) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("chatReinit(); addChatMessage(").append(getMessage(list).toString()).append(");");
-			response.render(OnDomReadyHeaderItem.forScript(sb.toString()));
+			sb.append("addChatMessage(").append(getMessage(list).toString()).append(");");
 		}
-	}
-
-	private static void sendRoom(ChatMessage m, String msg) {
-		WebSocketHelper.sendRoom(m.getToRoom().getId(), msg
-				, c -> !m.isNeedModeration() || (m.isNeedModeration() && c.hasRight(Right.moderator)));
+		response.render(OnDomReadyHeaderItem.forScript(sb.toString()));
 	}
 
 	private class ChatForm extends Form<Void> {
@@ -237,15 +201,15 @@ public class Chat extends Panel {
 							//no-op
 						}
 						dao.update(m);
-						String msg = getMessage(Arrays.asList(m)).toString();
+						JSONObject msg = getMessage(Arrays.asList(m));
 						if (m.getToRoom() != null) {
-							sendRoom(m, msg);
+							WebSocketHelper.sendRoom(m, msg);
 						} else if (m.getToUser() != null) {
-							WebSocketHelper.sendUser(getUserId(), msg);
-							msg = getMessage(m.getToUser().getId(), Arrays.asList(m)).toString();
-							WebSocketHelper.sendUser(m.getToUser().getId(), msg);
+							WebSocketHelper.sendUser(getUserId(), msg.toString());
+							msg = getMessage(m.getToUser().getId(), Arrays.asList(m));
+							WebSocketHelper.sendUser(m.getToUser().getId(), msg.toString());
 						} else {
-							WebSocketHelper.sendAll(msg);
+							WebSocketHelper.sendAll(msg.toString());
 						}
 						chatMessage.setDefaultModelObject("");
 						target.add(chatMessage);

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java Fri Feb 17 05:55:26 2017
@@ -18,8 +18,10 @@
  */
 package org.apache.openmeetings.web.user.chat;
 
+import static org.apache.openmeetings.core.util.WebSocketHelper.ID_ROOM_PREFIX;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_SHOW_CHAT;
 import static org.apache.openmeetings.web.app.Application.getBean;
+import static org.apache.openmeetings.web.user.chat.Chat.getReinit;
 
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.entity.room.Room;
@@ -65,7 +67,7 @@ public class ChatPanel extends BasePanel
 		if (r.isHidden(RoomElement.Chat)) {
 			return;
 		}
-		handler.appendJavaScript(String.format("if (typeof removeChatTab == 'function') { removeChatTab('%1$s%2$d'); }", Chat.ID_ROOM_PREFIX, r.getId()));
+		handler.appendJavaScript(String.format("if (typeof removeChatTab == 'function') { removeChatTab('%1$s%2$d'); }", ID_ROOM_PREFIX, r.getId()));
 		if (!showDashboardChat) {
 			StringBuilder sb = new StringBuilder();
 			sb.append("$(function() {");
@@ -80,7 +82,7 @@ public class ChatPanel extends BasePanel
 		if (handler != null) {
 			handler.add(this);
 			if (visible) {
-				handler.appendJavaScript("chatReinit();");
+				handler.appendJavaScript(getReinit());
 			}
 		}
 	}

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js Fri Feb 17 05:55:26 2017
@@ -27,6 +27,7 @@ var chatTabs, tabTemplate = "<li><a href
 	, closeBlock = "<span class='ui-icon ui-icon-close' role='presentation'></span>"
 	, closedHeight = "20px", openedHeight = "345px";
 var emoticon = new CSSEmoticon();
+var allPrefix = "All", roomPrefix = "Room ";
 $(function() {
 	Wicket.Event.subscribe("/websocket/message", function(jqEvent, msg) {
 		try {
@@ -42,9 +43,10 @@ $(function() {
 			//no-op
 		}
 	});
-	chatReinit();
 });
-function chatReinit() {
+function chatReinit(_allPrefix, _roomPrefix) {
+	allPrefix = _allPrefix;
+	roomPrefix = _roomPrefix;
 	initChatToolbar();
 	chatTabs = $("#chatTabs").tabs({
 		activate: function(event, ui) {
@@ -95,6 +97,9 @@ function addChatTab(id, label) {
 	if ($('#chat').length < 1 || $('#' + id).length) {
 		return;
 	}
+	if (!label) {
+		label = id == "chatTab-all" ? allPrefix : roomPrefix + id.substr(9);
+	}
 	var li = $(tabTemplate.replace(/#\{href\}/g, "#" + id).replace(/#\{label\}/g, label));
 	if (id.indexOf("chatTab-r") != 0) {
 		li.append(closeBlock);

Modified: openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java (original)
+++ openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java Fri Feb 17 05:55:26 2017
@@ -29,6 +29,7 @@ import static org.apache.openmeetings.ut
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -37,8 +38,10 @@ import java.util.TimeZone;
 import java.util.UUID;
 
 import org.apache.commons.lang3.time.FastDateFormat;
+import org.apache.openmeetings.core.remote.LanguageService.Language;
 import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.core.remote.util.SessionVariablesUtil;
+import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.basic.ChatDao;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
@@ -94,6 +97,21 @@ public class MobileService {
 		return "ok";
 	}
 
+	/**
+	 * @return - List of all available Languages
+	 */
+	public List<Language> getLanguages() {
+		List<Language> result = new ArrayList<Language>();
+		for (Map.Entry<Long, Locale> e : LabelDao.languages.entrySet()) {
+			result.add(new Language(e.getKey(), e.getValue().toLanguageTag(), e.getValue().getDisplayName(Locale.ENGLISH)));
+		}
+		return result;
+	}
+
+	public long switchMicMuted(String publicSID, boolean mute) {
+		return scopeAdapter.switchMicMuted(publicSID, mute);
+	}
+
 	public Map<String, Object> checkServer() {
 		Map<String, Object> result = new HashMap<>();
 		result.put("allowSelfRegister",  "1".equals(cfgDao.getConfValue(CONFIG_FRONTEND_REGISTER_KEY, String.class, "0")));
@@ -336,30 +354,44 @@ public class MobileService {
 		return result;
 	}
 
-	public void sendChatMessage(String message) {
+	public void sendChatMessage(String msg) {
 		IConnection current = Red5.getConnectionLocal();
-		Client client = sessionManager.getClientByStreamId(current.getClient().getId(), null);
-		List<String> msg = new ArrayList<String>();
-		msg.add("chat"); //'privatechat'
-		msg.add(""); //date-time
-		msg.add("newtextmessage");
-		msg.add(client.getUsername());
-		msg.add(message);
-		msg.add(client.getUsercolor());
-		msg.add(client.getPublicSID()); //om[6] = parent.parent.isPrivate ? parent.parent.parent.refObj.publicSID : canvas.publicSID;
-		msg.add("false");// canvas.isrtl;
-		msg.add("" + client.getUserId());
-		Room room = roomDao.get(client.getRoomId());
-		msg.add("" + (room.isChatModerated() && !(client.getIsMod() || client.getIsSuperModerator())));
-		//sendMessageWithClient(msg);
+		Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 
-		//"sendVarsToMessageWithClient"
+		ChatMessage m = new ChatMessage();
+		m.setMessage(msg);
+		m.setSent(new Date());
+		User u = userDao.get(c.getUserId());
+		m.setFromUser(u);
+		Room r = roomDao.get(c.getRoomId());
+		m.setToRoom(r);
+		m.setNeedModeration(r.isChatModerated() && !isModerator(c));
+		chatDao.update(m);
+		FastDateFormat fmt = getFmt(u);
+		scopeAdapter.sendMessageWithClient(Arrays.asList("chat", encodeChatMessage(m, fmt)));
+		WebSocketHelper.sendRoom(m, WebSocketHelper.getMessage(u.getId(), Arrays.asList(m), fmt, null));
 	}
 
 	private static boolean isModerator(Client c) {
 		return c.getIsMod() || c.getIsSuperModerator();
 	}
 
+	private static FastDateFormat getFmt(User u) {
+		return FastDateFormat.getDateTimeInstance(
+				FastDateFormat.SHORT
+				, FastDateFormat.SHORT
+				, TimeZone.getTimeZone(u.getTimeZoneId())
+				, LocaleHelper.getLocale(u));
+	}
+
+	private static Map<String, Object> encodeChatMessage(ChatMessage m, FastDateFormat fmt) {
+		Map<String, Object> mm = new HashMap<>();
+		mm.put("from", String.format("%s %s", m.getFromUser().getFirstname(), m.getFromUser().getLastname()));
+		mm.put("time", fmt.format(m.getSent()));
+		mm.put("msg", m.getMessage());
+		return mm;
+	}
+
 	public List<Map<String, Object>> getRoomChatHistory() {
 		List<Map<String,Object>> myChatList = new ArrayList<>();
 		try {
@@ -371,17 +403,9 @@ public class MobileService {
 
 			Room r = roomDao.get(roomId);
 			User u = userDao.get(c.getUserId());
-			FastDateFormat format = FastDateFormat.getDateTimeInstance(
-					FastDateFormat.SHORT
-					, FastDateFormat.SHORT
-					, TimeZone.getTimeZone(u.getTimeZoneId())
-					, LocaleHelper.getLocale(u));
+			FastDateFormat fmt = getFmt(u);
 			for (ChatMessage m : chatDao.getRoom(roomId, 0, 30, !r.isChatModerated() || isModerator(c))) {
-				Map<String, Object> mm = new HashMap<>();
-				mm.put("from", String.format("%s %s", m.getFromUser().getFirstname(), m.getFromUser().getLastname()));
-				mm.put("time", format.format(m.getSent()));
-				mm.put("msg", m.getMessage());
-				myChatList.add(mm);
+				myChatList.add(encodeChatMessage(m, fmt));
 			}
 
 		} catch (Exception err) {

Modified: openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java (original)
+++ openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java Fri Feb 17 05:55:26 2017
@@ -23,12 +23,17 @@ import static org.apache.openmeetings.ut
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
+import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 
+import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.openmeetings.IApplication;
+import org.apache.openmeetings.db.entity.basic.ChatMessage;
 import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.db.entity.room.Room.Right;
+import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.util.message.TextRoomMessage;
@@ -38,11 +43,17 @@ import org.apache.wicket.protocol.ws.api
 import org.apache.wicket.protocol.ws.api.registry.IWebSocketConnectionRegistry;
 import org.apache.wicket.protocol.ws.api.registry.PageIdKey;
 import org.apache.wicket.protocol.ws.concurrent.Executor;
+import org.json.JSONArray;
+import org.json.JSONObject;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
 public class WebSocketHelper {
 	private static final Logger log = Red5LoggerFactory.getLogger(WebSocketHelper.class, webAppRootKey);
+	public static final String ID_TAB_PREFIX = "chatTab-";
+	public static final String ID_ALL = ID_TAB_PREFIX + "all";
+	public static final String ID_ROOM_PREFIX = ID_TAB_PREFIX + "r";
+	public static final String ID_USER_PREFIX = ID_TAB_PREFIX + "u";
 
 	public static void sendClient(final Client c, byte[] b) {
 		if (c != null) {
@@ -65,6 +76,49 @@ public class WebSocketHelper {
 		sendRoom(roomId, m, null);
 	}
 
+	private static JSONObject setScope(JSONObject o, ChatMessage m, long curUserId) {
+		String scope, scopeName = null;
+		if (m.getToUser() != null) {
+			User u = curUserId == m.getToUser().getId() ? m.getFromUser() : m.getToUser();
+			scope = ID_USER_PREFIX + u.getId();
+			scopeName = String.format("%s %s", u.getFirstname(), u.getLastname());
+		} else if (m.getToRoom() != null) {
+			scope = ID_ROOM_PREFIX + m.getToRoom().getId();
+			o.put("needModeration", m.isNeedModeration());
+		} else {
+			scope = ID_ALL;
+		}
+		return o.put("scope", scope).put("scopeName", scopeName);
+	}
+
+	public static JSONObject getMessage(long curUserId, List<ChatMessage> list, FastDateFormat fmt, BiConsumer<JSONObject, User> uFmt) {
+		JSONArray arr = new JSONArray();
+		for (ChatMessage m : list) {
+			String smsg = m.getMessage();
+			smsg = smsg == null ? smsg : " " + smsg.replaceAll("&nbsp;", " ") + " ";
+			JSONObject from = new JSONObject()
+					.put("id", m.getFromUser().getId())
+					.put("name", m.getFromUser().getFirstname() + " " + m.getFromUser().getLastname());
+			if (uFmt != null) {
+				uFmt.accept(from, m.getFromUser());
+			}
+			arr.put(setScope(new JSONObject(), m, curUserId)
+				.put("id", m.getId())
+				.put("message", smsg)
+				.put("from", from)
+				.put("actions", curUserId == m.getFromUser().getId() ? "short" : "full")
+				.put("sent", fmt.format(m.getSent())));
+		}
+		return new JSONObject()
+			.put("type", "chat")
+			.put("msg", arr);
+	}
+
+	public static void sendRoom(ChatMessage m, JSONObject msg) {
+		sendRoom(m.getToRoom().getId(), msg.toString()
+				, c -> !m.isNeedModeration() || (m.isNeedModeration() && c.hasRight(Right.moderator)));
+	}
+
 	public static void sendRoom(final Long roomId, final String m, Predicate<Client> check) {
 		log.debug("Sending WebSocket message: {}", m);
 		sendRoom(roomId, (t) -> {

Modified: openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java (original)
+++ openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java Fri Feb 17 05:55:26 2017
@@ -28,14 +28,14 @@ import org.apache.openmeetings.db.entity
 
 /**
  * Methods to add/get/remove {@link Client}s to the session
- * 
- * 
+ *
+ *
  * @author sebawagner
  *
  */
 public interface ISessionManager {
 	void clearCache();
-	
+
 	/**
 	 * Notified on server start, when the session manager should be started and
 	 * eventually caches cleared/setup
@@ -45,7 +45,7 @@ public interface ISessionManager {
 	Client add(Client c, Server server);
 	/**
 	 * add a new client item
-	 * 
+	 *
 	 * @param streamId
 	 * @param scopeName
 	 * @param remotePort
@@ -57,17 +57,17 @@ public interface ISessionManager {
 	Client addClientListItem(String streamId, String scopeName, int remotePort, String remoteAddress, String swfUrl, Server server);
 
 	Collection<Client> getClients();
-	
+
 	/**
 	 * loads the server into the client (only if database cache is used)
-	 * 
+	 *
 	 * @return
 	 */
 	Collection<Client> getClientsWithServer();
 
 	/**
 	 * Get a client by its streamId
-	 * 
+	 *
 	 * @param streamId
 	 * @param server
 	 * @return
@@ -75,42 +75,43 @@ public interface ISessionManager {
 	Client getClientByStreamId(String streamId, Server server);
 
 	/**
-	 * get a client by its publicSID and the server, 
-	 * 
+	 * get a client by its publicSID and the server,
+	 *
 	 * @param publicSID
 	 * @param server
 	 * @return
 	 */
 	Client getClientByPublicSID(String publicSID, Server server);
-	
+
 	/**
-	 * same as {@link #getClientByPublicSID(String, boolean, Server)} but it ignores 
+	 * same as {@link #getClientByPublicSID(String, boolean, Server)} but it ignores
 	 * if the server part, so it will deliver any client just by its publicSID.<br/>
 	 * <br/>
 	 * <b>Note:</b>
-	 * This method requires more time to find the user, so under normal circumstances 
+	 * This method requires more time to find the user, so under normal circumstances
 	 * you should use {@link #getClientByPublicSID(String, boolean, Server)}!
-	 * 
+	 *
 	 * @param publicSID
 	 * @return
 	 */
 	ClientSessionInfo getClientByPublicSIDAnyServer(String publicSID);
 
 	/**
-	 * 
+	 *
 	 * @param userId
 	 * @return
-	 * 
+	 *
 	 * @deprecated There could be multiple users logged in with the same userid,
 	 *             then this call would return a list not a single user
 	 */
+	@Deprecated
 	Client getClientByUserId(Long userId);
 
 	/**
 	 * Update the session object of the audio/video-connection and additionally
 	 * swap the values to the session object of the user that holds the full
 	 * session object
-	 * 
+	 *
 	 * @param streamId
 	 * @param rcm
 	 * @return
@@ -119,11 +120,11 @@ public interface ISessionManager {
 
 	/**
 	 * Update the session object
-	 * 
+	 *
 	 * updateRoomCount is only <i>one</i> time true, in
 	 * ScopeApplicationAdapter#setRoomValues(Long, Boolean, Boolean, String)
 	 * .
-	 * 
+	 *
 	 * @param streamId
 	 * @param rcm
 	 * @param updateRoomCount
@@ -134,7 +135,7 @@ public interface ISessionManager {
 
 	/**
 	 * Remove a client from the session store
-	 * 
+	 *
 	 * @param streamId
 	 * @return
 	 */
@@ -145,16 +146,16 @@ public interface ISessionManager {
 	 * needed cause it is invoked internally AFTER the current user has been
 	 * already removed from the ClientList to see if the Room is empty again and
 	 * the PollList can be removed
-	 * @param roomId 
+	 * @param roomId
 	 * @return
 	 */
 	List<Client> getClientListByRoom(Long roomId);
-	
+
 	Collection<Client> getClientListByRoomAll(Long roomId);
 
 	/**
 	 * get the current Moderator in this room
-	 * 
+	 *
 	 * @param roomname
 	 * @return
 	 */
@@ -162,7 +163,7 @@ public interface ISessionManager {
 
 	/**
 	 * Get list of current client sessions
-	 * 
+	 *
 	 * @param start
 	 * @param max
 	 * @param orderby
@@ -173,7 +174,7 @@ public interface ISessionManager {
 
 	/**
 	 * returns number of current users recording
-	 * 
+	 *
 	 * @param roomId
 	 * @return
 	 */
@@ -181,16 +182,16 @@ public interface ISessionManager {
 
 	/**
 	 * returns a number of current users publishing screensharing
-	 * 
+	 *
 	 * @param roomId
 	 * @return
 	 */
 	long getPublishingCount(long roomId);
-	
+
 	/**
-	 * Get a list of all servers of all rooms on that server, serverId = null 
+	 * Get a list of all servers of all rooms on that server, serverId = null
 	 * means it is a local session on the master.
-	 * 
+	 *
 	 * @param server
 	 * @return a set, a roomId can be only one time in this list
 	 */
@@ -198,7 +199,7 @@ public interface ISessionManager {
 
 	/**
 	 * Get some statistics about the current sessions
-	 * 
+	 *
 	 * @return
 	 */
 	String getSessionStatistics();

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=1783331&r1=1783330&r2=1783331&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 Fri Feb 17 05:55:26 2017
@@ -207,7 +207,7 @@ public class Application extends Authent
 	}
 
 	public static Application get() {
-		return (Application) WebApplication.get();
+		return (Application) WebApplication.get(wicketApplicationName);
 	}
 
 	public static DashboardContext getDashboardContext() {

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java Fri Feb 17 05:55:26 2017
@@ -18,6 +18,9 @@
  */
 package org.apache.openmeetings.web.user.chat;
 
+import static org.apache.openmeetings.core.util.WebSocketHelper.ID_ALL;
+import static org.apache.openmeetings.core.util.WebSocketHelper.ID_ROOM_PREFIX;
+import static org.apache.openmeetings.core.util.WebSocketHelper.ID_USER_PREFIX;
 import static org.apache.openmeetings.db.util.AuthLevelUtil.hasAdminLevel;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
@@ -46,7 +49,6 @@ import org.apache.openmeetings.db.dao.ro
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.basic.ChatMessage;
 import org.apache.openmeetings.db.entity.room.Room;
-import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
@@ -62,7 +64,6 @@ import org.apache.wicket.markup.html.for
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
-import org.json.JSONArray;
 import org.json.JSONObject;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -73,10 +74,6 @@ import com.googlecode.wicket.jquery.ui.p
 public class Chat extends Panel {
 	private static final long serialVersionUID = 1L;
 	private static final Logger log = Red5LoggerFactory.getLogger(Chat.class, webAppRootKey);
-	private static final String ID_TAB_PREFIX = "chatTab-";
-	private static final String ID_USER_PREFIX = ID_TAB_PREFIX + "u";
-	public static final String ID_ROOM_PREFIX = ID_TAB_PREFIX + "r";
-	private static final String ID_ALL = ID_TAB_PREFIX + "all";
 	private static final String PARAM_MSG_ID = "msgid";
 	private static final String PARAM_ROOM_ID = "roomid";
 	private final AbstractDefaultAjaxBehavior acceptMessage = new AbstractDefaultAjaxBehavior() {
@@ -92,7 +89,7 @@ public class Chat extends Panel {
 				if (m.isNeedModeration() && isModerator(getUserId(), roomId)) {
 					m.setNeedModeration(false);
 					dao.update(m);
-					sendRoom(m, getMessage(Arrays.asList(m)).put("mode",  "accept").toString());
+					WebSocketHelper.sendRoom(m, getMessage(Arrays.asList(m)).put("mode",  "accept"));
 				} else {
 					log.error("It seems like we are being hacked!!!!");
 				}
@@ -102,47 +99,12 @@ public class Chat extends Panel {
 		}
 	};
 
-	private static JSONObject setScope(JSONObject o, ChatMessage m, long curUserId) {
-		String scope, scopeName;
-		if (m.getToUser() != null) {
-			User u = curUserId == m.getToUser().getId() ? m.getFromUser() : m.getToUser();
-			scope = ID_USER_PREFIX + u.getId();
-			scopeName = String.format("%s %s", u.getFirstname(), u.getLastname());
-		} else if (m.getToRoom() != null) {
-			scope = ID_ROOM_PREFIX + m.getToRoom().getId();
-			scopeName = String.format("%s %s", Application.getString(406), m.getToRoom().getId());
-			o.put("needModeration", m.isNeedModeration());
-		} else {
-			scope = ID_ALL;
-			scopeName = Application.getString(1494);
-		}
-		return o.put("scope", scope).put("scopeName", scopeName);
-	}
-
 	public JSONObject getMessage(List<ChatMessage> list) {
 		return getMessage(getUserId(), list);
 	}
 
-	private JSONObject getMessage(long curUserId, List<ChatMessage> list) {
-		JSONArray arr = new JSONArray();
-		for (ChatMessage m : list) {
-			String smsg = m.getMessage();
-			smsg = smsg == null ? smsg : " " + smsg.replaceAll("&nbsp;", " ") + " ";
-			arr.put(setScope(new JSONObject(), m, curUserId)
-				.put("id", m.getId())
-				.put("message", smsg)
-				.put("from", new JSONObject()
-						.put("id", m.getFromUser().getId())
-						.put("name", m.getFromUser().getFirstname() + " " + m.getFromUser().getLastname())
-						.put("img", getUrl(getRequestCycle(), m.getFromUser().getId()))
-
-					)
-				.put("actions", curUserId == m.getFromUser().getId() ? "short" : "full")
-				.put("sent", getDateFormat().format(m.getSent())));
-		}
-		return new JSONObject()
-			.put("type", "chat")
-			.put("msg", arr);
+	public JSONObject getMessage(Long userId, List<ChatMessage> list) {
+		return WebSocketHelper.getMessage(getUserId(), list, getDateFormat(), (o, u) -> o.put("img", getUrl(getRequestCycle(), u)));
 	}
 
 	public Chat(String id) {
@@ -154,6 +116,13 @@ public class Chat extends Panel {
 		add(new ChatForm("sendForm"));
 	}
 
+	public static CharSequence getReinit() {
+		StringBuilder sb = new StringBuilder("chatReinit(");
+		sb.append('\'').append(ID_ALL).append('\'')
+		.append(',').append('\'').append(ID_ROOM_PREFIX).append('\'');
+		return sb.append("); ");
+	}
+
 	public CharSequence addRoom(Room r) {
 		StringBuilder sb = new StringBuilder();
 		sb.append(String.format("addChatTab('%1$s%2$d', '%3$s %2$d');", ID_ROOM_PREFIX, r.getId(), Application.getString(406)));
@@ -181,16 +150,11 @@ public class Chat extends Panel {
 			list.addAll(dao.getRoom(roomId, 0, 30, !r.isChatModerated() || isModerator(getUserId(), roomId)));
 		}
 		list.addAll(dao.getUserRecent(getUserId(), Date.from(Instant.now().minus(Duration.ofHours(1L))), 0, 30));
+		StringBuilder sb = new StringBuilder(getReinit());
 		if (list.size() > 0) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("chatReinit(); addChatMessage(").append(getMessage(list).toString()).append(");");
-			response.render(OnDomReadyHeaderItem.forScript(sb.toString()));
+			sb.append("addChatMessage(").append(getMessage(list).toString()).append(");");
 		}
-	}
-
-	private static void sendRoom(ChatMessage m, String msg) {
-		WebSocketHelper.sendRoom(m.getToRoom().getId(), msg
-				, c -> !m.isNeedModeration() || (m.isNeedModeration() && c.hasRight(Right.moderator)));
+		response.render(OnDomReadyHeaderItem.forScript(sb.toString()));
 	}
 
 	private class ChatForm extends Form<Void> {
@@ -237,15 +201,15 @@ public class Chat extends Panel {
 							//no-op
 						}
 						dao.update(m);
-						String msg = getMessage(Arrays.asList(m)).toString();
+						JSONObject msg = getMessage(Arrays.asList(m));
 						if (m.getToRoom() != null) {
-							sendRoom(m, msg);
+							WebSocketHelper.sendRoom(m, msg);
 						} else if (m.getToUser() != null) {
-							WebSocketHelper.sendUser(getUserId(), msg);
-							msg = getMessage(m.getToUser().getId(), Arrays.asList(m)).toString();
-							WebSocketHelper.sendUser(m.getToUser().getId(), msg);
+							WebSocketHelper.sendUser(getUserId(), msg.toString());
+							msg = getMessage(m.getToUser().getId(), Arrays.asList(m));
+							WebSocketHelper.sendUser(m.getToUser().getId(), msg.toString());
 						} else {
-							WebSocketHelper.sendAll(msg);
+							WebSocketHelper.sendAll(msg.toString());
 						}
 						chatMessage.setDefaultModelObject("");
 						target.add(chatMessage);

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.java Fri Feb 17 05:55:26 2017
@@ -18,8 +18,10 @@
  */
 package org.apache.openmeetings.web.user.chat;
 
+import static org.apache.openmeetings.core.util.WebSocketHelper.ID_ROOM_PREFIX;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_SHOW_CHAT;
 import static org.apache.openmeetings.web.app.Application.getBean;
+import static org.apache.openmeetings.web.user.chat.Chat.getReinit;
 
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.entity.room.Room;
@@ -65,7 +67,7 @@ public class ChatPanel extends BasePanel
 		if (r.isHidden(RoomElement.Chat)) {
 			return;
 		}
-		handler.appendJavaScript(String.format("if (typeof removeChatTab == 'function') { removeChatTab('%1$s%2$d'); }", Chat.ID_ROOM_PREFIX, r.getId()));
+		handler.appendJavaScript(String.format("if (typeof removeChatTab == 'function') { removeChatTab('%1$s%2$d'); }", ID_ROOM_PREFIX, r.getId()));
 		if (!showDashboardChat) {
 			StringBuilder sb = new StringBuilder();
 			sb.append("$(function() {");
@@ -80,7 +82,7 @@ public class ChatPanel extends BasePanel
 		if (handler != null) {
 			handler.add(this);
 			if (visible) {
-				handler.appendJavaScript("chatReinit();");
+				handler.appendJavaScript(getReinit());
 			}
 		}
 	}

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js?rev=1783331&r1=1783330&r2=1783331&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/chat.js Fri Feb 17 05:55:26 2017
@@ -27,6 +27,7 @@ var chatTabs, tabTemplate = "<li><a href
 	, closeBlock = "<span class='ui-icon ui-icon-close' role='presentation'></span>"
 	, closedHeight = "20px", openedHeight = "345px";
 var emoticon = new CSSEmoticon();
+var allPrefix = "All", roomPrefix = "Room ";
 $(function() {
 	Wicket.Event.subscribe("/websocket/message", function(jqEvent, msg) {
 		try {
@@ -42,9 +43,10 @@ $(function() {
 			//no-op
 		}
 	});
-	chatReinit();
 });
-function chatReinit() {
+function chatReinit(_allPrefix, _roomPrefix) {
+	allPrefix = _allPrefix;
+	roomPrefix = _roomPrefix;
 	initChatToolbar();
 	chatTabs = $("#chatTabs").tabs({
 		activate: function(event, ui) {
@@ -95,6 +97,9 @@ function addChatTab(id, label) {
 	if ($('#chat').length < 1 || $('#' + id).length) {
 		return;
 	}
+	if (!label) {
+		label = id == "chatTab-all" ? allPrefix : roomPrefix + id.substr(9);
+	}
 	var li = $(tabTemplate.replace(/#\{href\}/g, "#" + id).replace(/#\{label\}/g, label));
 	if (id.indexOf("chatTab-r") != 0) {
 		li.append(closeBlock);